def test_binary_body_invalid_eof(self): parser = StompParser() body = b'MESSAGE\ncontent-length:4\n\n\xf0\x00\n\t\x00' parser.add(body) self.assertEqual(binaryType(parser.get()), body) self.assertRaises( StompFrameError, parser.add, b'MESSAGE\ncontent-length:4\n\n\xf0\n\t\xff\x01\n\nCONNECT\n\x00' ) # \x00 behind invalid EOF parser.add(body) self.assertEqual(binaryType(parser.get()), body) self.assertRaises(StompFrameError, parser.add, b'MESSAGE\ncontent-length:4\n\n\xf0\n\t\xff\x01\x00' ) # \x00 just behind invalid EOF parser.add(body) self.assertEqual(binaryType(parser.get()), body) self.assertRaises(StompFrameError, parser.add, b'MESSAGE\ncontent-length:4\n\n\xf0\x00\n\t\x01' ) # \x00 before invalid EOF parser.add(body) self.assertEqual(binaryType(parser.get()), body) self.assertRaises(StompFrameError, parser.add, b'MESSAGE\ncontent-length:4\n\n\xf0\n\t\x00\x01' ) # \x00 just before invalid EOF parser.add(body) self.assertEqual(binaryType(parser.get()), body)
def test_dont_unescape_bad_characters(self): parser = StompParser(StompSpec.VERSION_1_2) frame = commands.send('*queue') parser.add(binaryType(frame)) self.assertEqual(parser.get(), frame) for badCharacter in (b'\r', b'\n', b'\c', b'\\', b':', b'\\h'): self.assertRaises(StompFrameError, parser.add, binaryType(frame).replace(b'*', badCharacter)) self.assertRaises(StompFrameError, parser.add, binaryType(commands.send('queue\\'))) self.assertIsNone(parser.get())
def test_unescape(self): frameBytes = ("""%s \\n\\\\:\\c\t\\n \x00""" % StompSpec.DISCONNECT).encode() frame = StompFrame(command=StompSpec.DISCONNECT, headers={'\n\\': ':\t\n'}, version=StompSpec.VERSION_1_1) self.assertEqual(binaryType(frame), frameBytes) frameBytes = ("""%s \\n\\\\:\\c\t\\r \x00""" % StompSpec.DISCONNECT).encode() frame = StompFrame(command=StompSpec.DISCONNECT, headers={'\n\\': ':\t\r'}, version=StompSpec.VERSION_1_2) self.assertEqual(binaryType(frame), frameBytes) frameBytes = ("""%s \\n\\\\:\\c\t\r \x00""" % StompSpec.DISCONNECT).encode() frame = StompFrame(command=StompSpec.DISCONNECT, headers={'\n\\': ':\t\r'}, version=StompSpec.VERSION_1_1) self.assertEqual(binaryType(frame), frameBytes) frameBytes = ("""%s \\::\t\r \x00""" % StompSpec.DISCONNECT).encode() frame = StompFrame(command=StompSpec.DISCONNECT, headers={'\n\\': ':\t\r\n'}, version=StompSpec.VERSION_1_0) self.assertEqual(binaryType(frame), frameBytes) frameBytes = ("""%s \\::\t\r \x00""" % StompSpec.CONNECT).encode() frame = StompFrame(command=StompSpec.CONNECT, headers={'\n\\': ':\t\r\n'}) for version in StompSpec.VERSIONS: frame.version = version self.assertEqual(binaryType(frame), frameBytes)
def main(): parser = StompParser(version=StompSpec.VERSION_1_2) frame = binaryType(binaryFrame) + binaryType(textFrame) + binaryType(heartBeatFrame) for _ in createRange(N): for j in itertools.count(): packet = frame[j * SLICE:(j + 1) * SLICE] if not packet: break parser.add(packet) while parser.canRead(): parser.get()
def test_non_string_headers(self): message = {'command': 'MESSAGE', 'headers': {123: 456}} frame = StompFrame(**message) self.assertEqual(frame.command, 'MESSAGE') self.assertEqual(frame.headers, {123: 456}) self.assertEqual(dict(frame), {'command': 'MESSAGE', 'headers': {123: 456}}) self.assertEqual(binaryType(frame), b'MESSAGE\n123:456\n\n\x00') message = {'command': 'MESSAGE', 'headers': {123: 456}} frame = StompFrame(**message) self.assertEqual(binaryType(frame), b'MESSAGE\n123:456\n\n\x00') self.assertEqual(eval(repr(frame)), frame)
def test_reset_succeeds(self): frame = StompFrame( command=StompSpec.SEND, headers={'foo': 'bar', 'hello ': 'there-world with space ', 'empty-value':'', '':'empty-header', StompSpec.DESTINATION_HEADER: '/queue/blah'}, body=b'some stuff\nand more' ) parser = StompParser() parser.add(binaryType(frame)) parser.reset() self.assertIsNone(parser.get()) parser.add(binaryType(frame)[:20]) self.assertIsNone(parser.get())
def test_receive_multiple_frames_extra_newlines(self): headers = {'x': 'y'} body = b'testing 1 2 3' frame = StompFrame(StompSpec.MESSAGE, headers, body) transport = self._get_receive_mock(b'\n\n' + binaryType(frame) + b'\n' + binaryType(frame) + b'\n') frame_ = transport.receive() self.assertEqual(frame, frame_) frame_ = transport.receive() self.assertEqual(frame, frame_) self.assertEqual(1, transport._socket.recv.call_count) self.assertRaises(StompConnectionError, transport.receive) self.assertEqual(transport._socket, None)
def test_binary_body(self): body = b'\xf0\x00\x0a\x09' headers = {'content-length': str(len(body))} frame = StompFrame(StompSpec.MESSAGE, headers, body) self.assertEqual(frame.body, body) self.assertEqual(binaryType(frame), b'MESSAGE\ncontent-length:4\n\n\xf0\x00\n\t\x00')
def test_encoding(self): key = b'fen\xc3\xaatre'.decode('utf-8') value = b'\xc2\xbfqu\xc3\xa9 tal?'.decode('utf-8') command = StompSpec.DISCONNECT message = { 'command': command, 'headers': { key: value }, 'version': StompSpec.VERSION_1_1 } frame = StompFrame(**message) self.assertEqual(message['headers'], frame.headers) self.assertEqual(dict(frame), message) self.assertEqual(eval(repr(frame)), frame) frame.version = StompSpec.VERSION_1_1 self.assertEqual(eval(repr(frame)), frame) expectedResult = (command + '\n' + key + ':' + value + '\n\n\x00').encode('utf-8') self.assertEqual(binaryType(frame), expectedResult) otherFrame = StompFrame(**message) self.assertEqual(frame, otherFrame) frame.version = StompSpec.VERSION_1_0 self.assertRaises(UnicodeEncodeError, binaryType, frame)
def test_binary_body(self): body = b'\xf0\x00\x0a\x09' headers = {StompSpec.CONTENT_LENGTH_HEADER: textType(len(body))} frame = StompFrame(StompSpec.MESSAGE, body=body) frame.setContentLength() frameBytes = binaryType(frame) self.assertTrue(frameBytes.endswith(b'\x00')) parser = StompParser() for _ in range(2): for (j, _) in enumerate(frameBytes): parser.add(frameBytes[j:j + 1]) frame = parser.get() self.assertEqual(StompSpec.MESSAGE, frame.command) self.assertEqual(headers, frame.headers) self.assertEqual(body, frame.body) self.assertEqual(parser.get(), None) frames = 2 * frameBytes split = len(frameBytes) - 1 chunks = [frames[:split], frames[split:]] parser.add(chunks.pop(0)) self.assertEqual(parser.get(), None) parser.add(chunks.pop(0)) self.assertEqual(parser.get(), frame) self.assertEqual(parser.get(), frame) self.assertEqual(parser.get(), None) split = len(frameBytes) + 1 chunks = [frames[:split], frames[split:]] parser.add(chunks.pop(0)) self.assertEqual(parser.get(), frame) self.assertEqual(parser.get(), None) parser.add(chunks.pop(0)) self.assertEqual(parser.get(), frame) self.assertEqual(parser.get(), None)
def test_send(self): frame = StompFrame(StompSpec.MESSAGE) transport = self._get_send_mock() transport.send(frame) self.assertEqual(1, transport._socket.sendall.call_count) args, _ = transport._socket.sendall.call_args self.assertEqual(binaryType(frame), args[0])
def test_frames_with_optional_newlines_succeeds(self): parser = StompParser() disconnect = commands.disconnect() frame = b'\n' + binaryType(disconnect) + b'\n' parser.add(2 * frame) for _ in range(2): self.assertEqual(parser.get(), disconnect) self.assertIsNone(parser.get())
def test_strip_line_delimiter(self): queue = '/queue/test' frame = commands.send(queue) frameWithStripLineDelimiter = commands.send(queue + '\r') for (version, stripLineDelimiter) in [ (StompSpec.VERSION_1_0, False), (StompSpec.VERSION_1_1, False), (StompSpec.VERSION_1_2, True) ]: parser = StompParser(version) parser.add(binaryType(frameWithStripLineDelimiter)) self.assertEqual(parser.get(), frame if stripLineDelimiter else frameWithStripLineDelimiter) frameWithCarriageReturn = commands.send(queue + '\r', version=StompSpec.VERSION_1_2) parser = StompParser(StompSpec.VERSION_1_2) parser.add(binaryType(frameWithCarriageReturn)) self.assertEqual(parser.get().headers[StompSpec.DESTINATION_HEADER], queue + '\r')
def test_binary_body_invalid_eof(self): parser = StompParser() body = b'MESSAGE\ncontent-length:4\n\n\xf0\x00\n\t\x00' parser.add(body) self.assertEqual(binaryType(parser.get()), body) self.assertRaises(StompFrameError, parser.add, b'MESSAGE\ncontent-length:4\n\n\xf0\n\t\xff\x01\n\nCONNECT\n\x00') # \x00 behind invalid EOF parser.add(body) self.assertEqual(binaryType(parser.get()), body) self.assertRaises(StompFrameError, parser.add, b'MESSAGE\ncontent-length:4\n\n\xf0\n\t\xff\x01\x00') # \x00 just behind invalid EOF parser.add(body) self.assertEqual(binaryType(parser.get()), body) self.assertRaises(StompFrameError, parser.add, b'MESSAGE\ncontent-length:4\n\n\xf0\x00\n\t\x01') # \x00 before invalid EOF parser.add(body) self.assertEqual(binaryType(parser.get()), body) self.assertRaises(StompFrameError, parser.add, b'MESSAGE\ncontent-length:4\n\n\xf0\n\t\x00\x01') # \x00 just before invalid EOF parser.add(body) self.assertEqual(binaryType(parser.get()), body)
def test_non_string_headers(self): message = {'command': 'MESSAGE', 'headers': {123: 456}} frame = StompFrame(**message) self.assertEqual(frame.command, 'MESSAGE') self.assertEqual(frame.headers, {123: 456}) self.assertEqual(dict(frame), { 'command': 'MESSAGE', 'headers': { 123: 456 } }) self.assertEqual(binaryType(frame), b'MESSAGE\n123:456\n\n\x00') message = {'command': 'MESSAGE', 'headers': {123: 456}} frame = StompFrame(**message) self.assertEqual(binaryType(frame), b'MESSAGE\n123:456\n\n\x00') self.assertEqual(eval(repr(frame)), frame)
def test_reset_succeeds(self): frame = StompFrame(command=StompSpec.SEND, headers={ 'foo': 'bar', 'hello ': 'there-world with space ', 'empty-value': '', '': 'empty-header', StompSpec.DESTINATION_HEADER: '/queue/blah' }, body=b'some stuff\nand more') parser = StompParser() parser.add(binaryType(frame)) parser.reset() self.assertIsNone(parser.get()) parser.add(binaryType(frame)[:20]) self.assertIsNone(parser.get())
def test_frames_with_heart_beats_succeeds(self): parser = StompParser(version=StompSpec.VERSION_1_1) disconnect = commands.disconnect() frame = b'\n' + binaryType(disconnect) + b'\n' parser.add(2 * frame) frames = [] while parser.canRead(): frames.append(parser.get()) self.assertEqual(frames, [StompHeartBeat(), disconnect, StompHeartBeat(), StompHeartBeat(), disconnect, StompHeartBeat()]) self.assertIsNone(parser.get())
def test_frame_without_headers_and_body(self): message = {'command': StompSpec.DISCONNECT} frame = StompFrame(**message) self.assertEqual(frame.headers, {}) self.assertEqual(dict(frame), message) self.assertEqual(binaryType(frame), ("""\ %s \x00""" % StompSpec.DISCONNECT).encode()) self.assertEqual(eval(repr(frame)), frame)
def test_add_multiple_frames_per_read(self): body1 = b'boo' body2 = b'hoo' headers = {'x': 'y'} frameBytes = binaryType(StompFrame(StompSpec.MESSAGE, headers, body1)) + binaryType(StompFrame(StompSpec.MESSAGE, headers, body2)) parser = StompParser() parser.add(frameBytes) frame = parser.get() self.assertEqual(StompSpec.MESSAGE, frame.command) self.assertEqual(headers, frame.headers) self.assertEqual(body1, frame.body) frame = parser.get() self.assertEqual(StompSpec.MESSAGE, frame.command) self.assertEqual(headers, frame.headers) self.assertEqual(body2, frame.body) self.assertIsNone(parser.get())
def test_duplicate_headers(self): rawHeaders = (('foo', 'bar1'), ('foo', 'bar2')) headers = dict(reversed(rawHeaders)) message = { 'command': StompSpec.SEND, 'body': b'some stuff\nand more', 'rawHeaders': rawHeaders } frame = StompFrame(**message) self.assertEqual(frame.headers, headers) self.assertEqual(frame.rawHeaders, rawHeaders) rawFrame = b'SEND\nfoo:bar1\nfoo:bar2\n\nsome stuff\nand more\x00' self.assertEqual(binaryType(frame), rawFrame) frame.unraw() self.assertEqual(frame.headers, headers) self.assertEqual(frame.rawHeaders, None) rawFrame = b'SEND\nfoo:bar1\n\nsome stuff\nand more\x00' self.assertEqual(binaryType(frame), rawFrame)
def test_strip_line_delimiter(self): queue = '/queue/test' frame = commands.send(queue) frameWithStripLineDelimiter = commands.send(queue + '\r') for (version, stripLineDelimiter) in [(StompSpec.VERSION_1_0, False), (StompSpec.VERSION_1_1, False), (StompSpec.VERSION_1_2, True)]: parser = StompParser(version) parser.add(binaryType(frameWithStripLineDelimiter)) self.assertEqual( parser.get(), frame if stripLineDelimiter else frameWithStripLineDelimiter) frameWithCarriageReturn = commands.send(queue + '\r', version=StompSpec.VERSION_1_2) parser = StompParser(StompSpec.VERSION_1_2) parser.add(binaryType(frameWithCarriageReturn)) self.assertEqual(parser.get().headers[StompSpec.DESTINATION_HEADER], queue + '\r')
def test_frame_parse_succeeds(self): frame = StompFrame( StompSpec.SEND, {'foo': 'bar', 'hello ': 'there-world with space ', 'empty-value':'', '':'empty-header', StompSpec.DESTINATION_HEADER: '/queue/blah'}, b'some stuff\nand more' ) parser = StompParser() parser.add(binaryType(frame)) self.assertEqual(parser.get(), frame) self.assertIsNone(parser.get())
def test_frame(self): message = {'command': StompSpec.SEND, 'headers': {StompSpec.DESTINATION_HEADER: '/queue/world'}, 'body': b'two\nlines'} frame = StompFrame(**message) self.assertEqual(message['headers'], frame.headers) self.assertEqual(dict(frame), message) self.assertEqual(binaryType(frame), ("""\ %s %s:/queue/world two lines\x00""" % (StompSpec.SEND, StompSpec.DESTINATION_HEADER)).encode()) self.assertEqual(eval(repr(frame)), frame)
def test_no_newline(self): headers = {'x': 'y'} body = b'testing 1 2 3' frameBytes = binaryType(StompFrame(StompSpec.MESSAGE, headers, body)) self.assertTrue(frameBytes.endswith(b'\x00')) parser = StompParser() parser.add(frameBytes) frame = parser.get() self.assertEqual(StompSpec.MESSAGE, frame.command) self.assertEqual(headers, frame.headers) self.assertEqual(body, frame.body) self.assertEqual(parser.get(), None)
def test_receive_binary(self): body = binascii.a2b_hex('f0000a09') headers = {StompSpec.CONTENT_LENGTH_HEADER: str(len(body))} frame = StompFrame(StompSpec.MESSAGE, headers, body) transport = self._get_receive_mock(binaryType(frame)) frame_ = transport.receive() self.assertEqual(frame, frame_) self.assertEqual(1, transport._socket.recv.call_count) self.assertRaises(StompConnectionError, transport.receive) self.assertEqual(transport._socket, None)
def test_add_multiple_frames_per_read(self): body1 = b'boo' body2 = b'hoo' headers = {'x': 'y'} frameBytes = binaryType(StompFrame( StompSpec.MESSAGE, headers, body1)) + binaryType( StompFrame(StompSpec.MESSAGE, headers, body2)) parser = StompParser() parser.add(frameBytes) frame = parser.get() self.assertEqual(StompSpec.MESSAGE, frame.command) self.assertEqual(headers, frame.headers) self.assertEqual(body1, frame.body) frame = parser.get() self.assertEqual(StompSpec.MESSAGE, frame.command) self.assertEqual(headers, frame.headers) self.assertEqual(body2, frame.body) self.assertIsNone(parser.get())
def test_receive_multiple_frames_per_read(self): body1 = b'boo' body2 = b'hoo' headers = {'x': 'y'} frameBytes = binaryType(StompFrame(StompSpec.MESSAGE, headers, body1)) + binaryType(StompFrame(StompSpec.MESSAGE, headers, body2)) transport = self._get_receive_mock(frameBytes) frame = transport.receive() self.assertEqual(StompSpec.MESSAGE, frame.command) self.assertEqual(headers, frame.headers) self.assertEqual(body1, frame.body) self.assertEqual(1, transport._socket.recv.call_count) frame = transport.receive() self.assertEqual(StompSpec.MESSAGE, frame.command) self.assertEqual(headers, frame.headers) self.assertEqual(body2, frame.body) self.assertEqual(1, transport._socket.recv.call_count) self.assertRaises(StompConnectionError, transport.receive) self.assertEqual(transport._socket, None)
def test_decode(self): key = b'fen\xc3\xaatre'.decode('utf-8') value = b'\xc2\xbfqu\xc3\xa9 tal?'.decode('utf-8') headers = {key: value} frameBytes = binaryType(StompFrame(command=StompSpec.DISCONNECT, headers=headers, version=StompSpec.VERSION_1_1)) parser = StompParser(version=StompSpec.VERSION_1_1) parser.add(frameBytes) frame = parser.get() self.assertEqual(frame.headers, headers) parser = StompParser(version=StompSpec.VERSION_1_0) self.assertRaises(UnicodeDecodeError, parser.add, frameBytes)
def test_frame_parse_succeeds(self): frame = StompFrame( StompSpec.SEND, { 'foo': 'bar', 'hello ': 'there-world with space ', 'empty-value': '', '': 'empty-header', StompSpec.DESTINATION_HEADER: '/queue/blah' }, b'some stuff\nand more') parser = StompParser() parser.add(binaryType(frame)) self.assertEqual(parser.get(), frame) self.assertIsNone(parser.get())
def test_frames_with_heart_beats_succeeds(self): parser = StompParser(version=StompSpec.VERSION_1_1) disconnect = commands.disconnect() frame = b'\n' + binaryType(disconnect) + b'\n' parser.add(2 * frame) frames = [] while parser.canRead(): frames.append(parser.get()) self.assertEqual(frames, [ StompHeartBeat(), disconnect, StompHeartBeat(), StompHeartBeat(), disconnect, StompHeartBeat() ]) self.assertIsNone(parser.get())
def test_decode(self): key = b'fen\xc3\xaatre'.decode('utf-8') value = b'\xc2\xbfqu\xc3\xa9 tal?'.decode('utf-8') headers = {key: value} frameBytes = binaryType( StompFrame(command=StompSpec.DISCONNECT, headers=headers, version=StompSpec.VERSION_1_1)) parser = StompParser(version=StompSpec.VERSION_1_1) parser.add(frameBytes) frame = parser.get() self.assertEqual(frame.headers, headers) parser = StompParser(version=StompSpec.VERSION_1_0) self.assertRaises(UnicodeDecodeError, parser.add, frameBytes)
def test_frame(self): message = { 'command': StompSpec.SEND, 'headers': { StompSpec.DESTINATION_HEADER: '/queue/world' }, 'body': b'two\nlines' } frame = StompFrame(**message) self.assertEqual(message['headers'], frame.headers) self.assertEqual(dict(frame), message) self.assertEqual(binaryType(frame), ("""\ %s %s:/queue/world two lines\x00""" % (StompSpec.SEND, StompSpec.DESTINATION_HEADER)).encode()) self.assertEqual(eval(repr(frame)), frame)
def test_body_allowed_commands(self): head = binaryType(commands.disconnect()).rstrip( StompSpec.FRAME_DELIMITER.encode()) for (version, bodyAllowed) in [(StompSpec.VERSION_1_0, True), (StompSpec.VERSION_1_1, False), (StompSpec.VERSION_1_2, False)]: parser = StompParser(version) parser.add(head) parser.add(b'ouch!') try: parser.add(StompSpec.FRAME_DELIMITER.encode()) except StompFrameError: if bodyAllowed: raise except: raise else: if not bodyAllowed: raise
def test_body_allowed_commands(self): head = binaryType(commands.disconnect()).rstrip(StompSpec.FRAME_DELIMITER.encode()) for (version, bodyAllowed) in [ (StompSpec.VERSION_1_0, True), (StompSpec.VERSION_1_1, False), (StompSpec.VERSION_1_2, False) ]: parser = StompParser(version) parser.add(head) parser.add(b'ouch!') try: parser.add(StompSpec.FRAME_DELIMITER.encode()) except StompFrameError: if bodyAllowed: raise except: raise else: if not bodyAllowed: raise
def test_encoding(self): key = b'fen\xc3\xaatre'.decode('utf-8') value = b'\xc2\xbfqu\xc3\xa9 tal?'.decode('utf-8') command = StompSpec.DISCONNECT message = {'command': command, 'headers': {key: value}, 'version': StompSpec.VERSION_1_1} frame = StompFrame(**message) self.assertEqual(message['headers'], frame.headers) self.assertEqual(dict(frame), message) self.assertEqual(eval(repr(frame)), frame) frame.version = StompSpec.VERSION_1_1 self.assertEqual(eval(repr(frame)), frame) expectedResult = (command + '\n' + key + ':' + value + '\n\n\x00').encode('utf-8') self.assertEqual(binaryType(frame), expectedResult) otherFrame = StompFrame(**message) self.assertEqual(frame, otherFrame) frame.version = StompSpec.VERSION_1_0 self.assertRaises(UnicodeEncodeError, binaryType, frame)
def send(self, frame): self._write(binaryType(frame))
def test_frame_without_header_or_body_succeeds(self): parser = StompParser() parser.add(binaryType(commands.disconnect())) self.assertEqual(parser.get(), commands.disconnect())
def getFrame(self, command, headers, body): return binaryType(StompFrame(command, headers, body, version=self._parser.version))
def __eq__(self, other): """Two frames are considered equal if, and only if, they render the same wire-level frame, that is, if their string representation is identical.""" try: return binaryType(other) == binaryType(self) except: return False
def send(self, frame): if self.log.isEnabledFor(logging.DEBUG): self.log.debug('Sending %s' % frame.info()) self.transport.write(binaryType(frame))
def getFrame(self, command, headers, body): return binaryType( StompFrame(command, headers, body, version=self._parser.version))
def send(self, frame): if self.log.isEnabledFor(logging.DEBUG): self.log.debug("Sending %s" % frame.info()) self.transport.write(binaryType(frame))