def test_incremental_data(): msg_list = [ #msg1 'INVITE sip:[email protected]', # msg2 ' SIP/2.0\r\n', #msg3 'Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + '\r\nMax-Forwards: 70' + '\r\nTo: Bob <sip:[email protected]>' + '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + '\r\nCall-ID: a84b4c76e66710@pc33', #msg4 '.atlanta.com' + '\r\nCSeq: 314159 INVITE' + '\r\nContact: <sip:[email protected]>' + '\r\nContent-Type: application/sdp' + '\r\nContent-Length: 1' + '0\r\n\r\n01234' ] p = Parser.new() for msg in msg_list: p.add(msg) more_data, data = Parser.parse(p) assert isinstance(more_data, MoreDataRequired) p.add('56789') p_msg, d = Parser.parse(p) assert p_msg.body == '0123456789'
def test_too_long_on_first_line(): msg = 'INVITE sip:[email protected] SIP/2.0' p = Parser.new({'max_message_len': len(msg) - 1}) p.add(msg) with pytest.raises(TransportParserError) as excinfo: Parser.parse(p) assert 'too long' in str(excinfo.value)
def test_no_content_len(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\n\r\nTest' p = Parser.new_dgram(msg) pm, d = Parser.parse(p) assert pm.body == 'Test'
def test_not_too_long(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' p = Parser.new({'max_message_len': len(msg)}) p.add(msg) Parser.parse(p)
def test_request_without_body(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 0' + \ '\r\n\r\n' p = Parser.new_dgram(msg) parsed_msg, data = Parser.parse(p) assert parsed_msg.method == INVITE
def test_invalid_method(): msg = 'INV@TE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' p = Parser.new_dgram(msg) with pytest.raises(TransportParserError): Parser.parse(p)
def test_too_long_on_header_parse(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' p = Parser.new({'max_message_len': len(msg) - 1}) p.add(msg) with pytest.raises(TransportParserError) as excinfo: Parser.parse(p) assert 'too long' in str(excinfo.value)
def test_invalid_content_len_stream(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: invalid' + \ '\r\n\r\nTest' p = Parser.new() p.add(msg) with pytest.raises(TransportParserError) as excinfo: Parser.parse(p) assert 'invalid content length' in str(excinfo.value)
def parse(message, headers_list): """Parses specified headers from string, SipMessage or Message objects and sets it to SIP message. Args: message (str or Message or SipMessage) headers_list (list or ALL): headers to be parsed Returns: :obj:SipMessage """ if isinstance(message, SipMessage): known_headers = headers_list if headers_list == ALL: known_headers = KNOWN_HEADER_KEY_MAP.values() already_parsed = message.headers.keys() headers_to_parse = set(known_headers).difference( set(already_parsed)) for header in headers_to_parse: SipMessage.maybe_parse_header(header, message) return message elif isinstance(message, str): p = Parser.new_dgram(message) try: parsed_msg, data = Parser.parse(p) except Exception as e: raise SIPMessageParseError( f'Cannot parse message {message}: {e}') if isinstance(parsed_msg, MoreDataRequired): raise SIPMessageParseError( f'Cannot parse message {message}: truncated message.') return SipMessage.parse(parsed_msg, headers_list) elif isinstance(message, Message): headers_to_parse = headers_list if headers_list == ALL: headers_to_parse = KNOWN_HEADER_KEY_MAP.keys() maybe_msg = SipMessage.create_from_raw(message) for header in headers_to_parse: header_key = KNOWN_HEADER_KEY_MAP[header.lower()] SipMessage.maybe_parse_header(header_key, maybe_msg) SipMessage.parse_validate_cseq(maybe_msg) return maybe_msg else: raise SipMessageError( f'Cannot parse message {message}: wrong type {type(message)}')
def test_basic_response(): msg = 'SIP/2.0 200 OK' + \ '\r\nVia: SIP/2.0/UDP server10.biloxi.com' + \ '\r\n ;branch=z9hG4bKnashds8;received=192.0.2.3' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com"' + \ '\r\n ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com' + \ '\r\n ;branch=z9hG4bK776asdhds ;received=192.0.2.1' + \ '\r\nTo: Bob <sip:[email protected]>;tag=a6c85cf' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' p = Parser.new_dgram(msg) parsed_msg, data = Parser.parse(p) assert parsed_msg.body == 'Test'
def connection_data(self, string): """ Args: string (str): connection data to be parsed Returns: """ print(f'StatelessProxy.connection_data()') if self.parser is None: dgram = Parser.new_dgram(string) try: parsed, data = Parser.parse(dgram) if not isinstance(parsed, MoreDataRequired): return self.receive_raw(parsed) return self.return_side_effects('sf') except Exception as e: self.return_side_effects(e) else: print(f'SipConnection.connection_data(): datagram transport') print(f'SipConnection.connection_data(): string {string}') self.parser.add(string) return self.parse_data([])
def parse_data(self, side_effects): print(f'StatelessProxy.parse_data()') try: msg, data = Parser.parse(self.parser) if isinstance(msg, MoreDataRequired): return side_effects else: print(f'StatelessProxy.parse_data(): parsed {msg}') result = self.receive_raw(msg) print(f'StatelessProxy.parse_data(): receive result {result}') side_effects = self.add_side_effects_to_head([result], side_effects) print(f'StatelessProxy.parse_data(): side effects {side_effects}') return self.parse_data(side_effects) except Exception as e: return self, side_effects + [Disconnect(e)]
def __init__(self, local_addr=None, local_port=None, remote_addr=None, remote_port=None, transport=None, options=None): self.local_addr = local_addr self.local_port = local_port self.remote_addr = remote_addr self.remote_port = remote_port self.transport = transport if options is None: options = dict() self.options = options self.parser = None parser_options = self.options.get(PARSER_OPTIONS_KEY, dict()) if transport.is_datagram(): self.parser = Parser.new(parser_options) print(f'SipConnection(local_addr={self.local_addr}, local_port={local_port}, remote_addr={self.remote_addr}, ' f'remote_port={self.remote_port}, transport={self.transport}, options={self.options})')
def rebuild_sip_msg(sip_msg): sip_msg_str = sip_msg.serialize() p = Parser.new_dgram(sip_msg_str) msg, rest = Parser.parse(p) return SipMessage.parse(msg, ALL)
def raw_message(msg_string): p = Parser.new_dgram(msg_string) sip_msg, rest = Parser.parse(p) return sip_msg
def test_negative_cases(err_msg, msg): p = Parser.new() p.add(msg) with pytest.raises(TransportParserError) as excinfo: Parser.parse(p) assert err_msg in str(excinfo.value)