def add(self, name, value): if not make_key(name) in self._headers: self._headers[make_key(name)] = Header(name) if not isinstance(value, str): raise MessageError( f'Cannot add header {name}={value} to message {self.serialize()}: value should be ' f'string not ({type(value)}).') self._headers[make_key(name)].add_value(value.lstrip())
def set_header(header_name, header_value, msg): descr = SipHeader.header_descr(header_name) print_name = PRINT_FORM_MAP.get(make_key(header_name), header_name) raw_hdr = Header(print_name) if header_value.assemble(): raw_hdr.add_value(header_value.assemble()) if not raw_hdr.values: msg.headers.pop(make_key(header_name), None) msg.raw_message.delete_header(make_key(header_name)) else: msg.headers[make_key(header_name)] = header_value msg.raw_message.set_header(raw_hdr)
def add(self, headername, value): """Adds value to header. Args: headername (str or HeaderKey): header name. value (str): header value. """ if not make_key(headername) in self.headers: self.headers[make_key(headername)] = Header(headername) if not isinstance(value, str): raise SipMessageError( f'Cannot add header {headername}={value} to message {self.serialize()}: value should be ' f'string not ({type(value)}).') self.headers[make_key(headername)].add_value(value.lstrip())
def get(self, item): if item == ITEM_TYPE: return self._type.name elif item == ITEM_STATUS: if not isinstance(self._type, ResponseType): raise MessageError( f'Cannot get message status for {self}: message should be of type ResponseType' ) return self._type.status elif item == ITEM_REASON: if not isinstance(self._type, ResponseType): raise MessageError( f'Cannot get message reason for {self}: message should be of type ResponseType' ) return self._type.reason elif item == ITEM_METHOD: if not isinstance(self._type, RequestType): raise MessageError( f'Cannot get message method for {self}: message should be of type RequestType' ) return self._type.method elif item == ITEM_RURI: if not isinstance(self._type, RequestType): raise MessageError( f'Cannot get message ruri for {self}: message should be of type RequestType' ) return self._type.ruri elif item == ITEM_BODY: return self.body else: hdr = self._headers.get(make_key(item), Header(item)) return hdr
def __init__(self, name): if isinstance(name, HeaderKey): name = PRINT_FORM_MAP.get(name, name.header) self.name = to_string(name, encoding=self.ENCODING) self.values = [] self.key = make_key(self.name) self.allow_multiple_values = may_have_multiple_values(self.key)
def find(self, header): """Find specified header Args: header (str or HeaderKey) Returns: BaseSipHeader subclass instance """ if make_key(header) in self.headers: return self.headers[make_key(header)] else: try: hdr = SipHeader.parse_header(header, self) except SipHeaderError as e: raise e if not hdr or isinstance(hdr, NoHeader): return NotFound() return hdr
def parse_validate_cseq(message): """ Args: message (SipMessage) Returns: True if no cseq is defined, True if SIP message method equals to method defined in CSeq header, False otherwise. """ cseq = message.headers.get(make_key('cseq')) if cseq: return message.method == cseq.method return True
def set(self, name, value): if name == ITEM_TYPE: self.type = value elif name == ITEM_BODY: self.body = value elif name == ITEM_REASON: self.reason = value elif name == ITEM_STATUS: self.status = value elif name == ITEM_METHOD: self.method = value elif name == ITEM_RURI: self.ruri = value else: key = make_key(name) hdr = Header(name) if isinstance(value, list): for v in value: hdr.add_value(v) elif isinstance(value, str): hdr.add_value(value) self._headers[key] = hdr
def copy_header(header, src_msg, dst_msg): """ Args: header: header name to be copied src_msg (SipMessage): SipMessage to be copied from dst_msg (SipMessage): message to be copied to Returns: """ if make_key(header) in src_msg.headers: dst_msg.headers[make_key(header)] = src_msg.headers[make_key( header)] else: SipHeader.copy_raw_header(make_key(header), src_msg, dst_msg) if make_key(header) not in ALL_KNOWN_HEADERS_KEYS: SipHeader.copy_raw_header(make_key(header), src_msg, dst_msg)
class Message(object): HEADERS_KEYS_ORDER = [ make_key('via'), make_key('to'), make_key('from'), make_key('call-id'), make_key('cseq'), make_key('max-forwards') ] def __init__(self): self._type = None self._headers = dict() self.body = None self.source = None def __repr__(self): return f'Message: type={self._type} headers={self._headers} body={self.body}' @property def headers(self): return list(self._headers.values()) def clear_header(self): self._headers = dict() def get(self, item): if item == ITEM_TYPE: return self._type.name elif item == ITEM_STATUS: if not isinstance(self._type, ResponseType): raise MessageError( f'Cannot get message status for {self}: message should be of type ResponseType' ) return self._type.status elif item == ITEM_REASON: if not isinstance(self._type, ResponseType): raise MessageError( f'Cannot get message reason for {self}: message should be of type ResponseType' ) return self._type.reason elif item == ITEM_METHOD: if not isinstance(self._type, RequestType): raise MessageError( f'Cannot get message method for {self}: message should be of type RequestType' ) return self._type.method elif item == ITEM_RURI: if not isinstance(self._type, RequestType): raise MessageError( f'Cannot get message ruri for {self}: message should be of type RequestType' ) return self._type.ruri elif item == ITEM_BODY: return self.body else: hdr = self._headers.get(make_key(item), Header(item)) return hdr @property def reason(self): return self.get(ITEM_REASON) @reason.setter def reason(self, reason): if isinstance(self._type, ResponseType): self._type.reason = reason else: raise MessageError( f'Cannot set reason {reason} for message {self.serialize()}: message should be response,' f'not {type(self._type)}.') @property def status(self): return self.get(ITEM_STATUS) @status.setter def status(self, status): if isinstance(self._type, ResponseType): self._type.status = status else: raise MessageError( f'Cannot set status {status} for message {self.serialize()}: message should be response,' f'not {type(self._type)}.') @property def method(self): return self.get(ITEM_METHOD) @method.setter def method(self, method): if isinstance(self._type, RequestType): if isinstance(method, Method): self._type.method = method elif isinstance(method, str): self._type.method = Method(method) else: raise MessageError( f'Cannot set method {method} for message {self.serialize()}: method should be of ' f'type Method or str, not {type(method)}') else: raise MessageError( f'Cannot set method {method} for message {self.serialize()}: message should be request, ' f'not {type(self._type)}') @property def ruri(self): return self.get(ITEM_RURI) @ruri.setter def ruri(self, ruri): if isinstance(self._type, RequestType): self._type.ruri = ruri else: raise MessageError( f'Cannot set ruri {ruri} for message {self.serialize()}: message should be request, ' f'not {type(self._type)}') @property def type(self): return self.get(ITEM_TYPE) @type.setter def type(self, value): if isinstance(value, (RequestType, ResponseType)): self._type = value else: raise MessageError( f'Cannot set type {value} for message {self.serialize()}: type should be a subclass of ' f'MessageType.') def add(self, name, value): if not make_key(name) in self._headers: self._headers[make_key(name)] = Header(name) if not isinstance(value, str): raise MessageError( f'Cannot add header {name}={value} to message {self.serialize()}: value should be ' f'string not ({type(value)}).') self._headers[make_key(name)].add_value(value.lstrip()) def set(self, name, value): if name == ITEM_TYPE: self.type = value elif name == ITEM_BODY: self.body = value elif name == ITEM_REASON: self.reason = value elif name == ITEM_STATUS: self.status = value elif name == ITEM_METHOD: self.method = value elif name == ITEM_RURI: self.ruri = value else: key = make_key(name) hdr = Header(name) if isinstance(value, list): for v in value: hdr.add_value(v) elif isinstance(value, str): hdr.add_value(value) self._headers[key] = hdr def set_header(self, header): self._headers[header.key] = header def serialize_first_line(self): if isinstance(self._type, RequestType): return f'{self._type.method} {self._type.ruri} SIP/2.0' elif isinstance(self._type, ResponseType): return f'SIP/2.0 {self._type.status} {self._type.reason}' def serialize(self): first_line = self.serialize_first_line() headers = self.serialize_headers() body = self.body if body is None: body = '' return f'{first_line}\r\n{headers}{body}' def serialize_headers_in_order(self, header_key_iterable): headers_list = [] for key in header_key_iterable: if key in self._headers: headers_list.append(self._headers[key].serialize_to_string()) return '\r\n'.join(headers_list) def serialize_headers(self): not_ordered_keys_set = set(self._headers.keys()).difference( Message.HEADERS_KEYS_ORDER) ordered_headers = self.serialize_headers_in_order( Message.HEADERS_KEYS_ORDER) not_ordered_headers = self.serialize_headers_in_order( not_ordered_keys_set) if not_ordered_headers: not_ordered_headers = '\r\n' + not_ordered_headers return ordered_headers + not_ordered_headers + '\r\n\r\n' def delete_header(self, header_name): self._headers.pop(make_key(header_name), None)
def delete_header(self, header_name): self._headers.pop(make_key(header_name), None)
ALLOW_HEADER, ROUTE_HEADER, RECORD_ROUTE_HEADER, REQUIRE_HEADER, PROXY_REQUIRE_HEADER, ACCEPT_HEADER, \ ACCEPT_ENCODING_HEADER, ACCEPT_LANGUAGE_HEADER, WWW_AUTHENTICATE_HEADER, AUTHORIZATION_HEADER, \ PROXY_AUTHENTICATE_HEADER, PROXY_AUTHORIZATION_HEADER from pysip import PySIPException def may_have_multiple_values(header_key): return MAY_HAVE_MULTIPLE_VALUE_MAP.get(header_key, False) class NoHeaderError(PySIPException): pass MAY_HAVE_MULTIPLE_VALUE_MAP = { make_key(FROM_HEADER): False, # From make_key(TO_HEADER): False, # To make_key(CALLID_HEADER): False, # Call-ad make_key(MAXFORWARDS_HEADER): False, make_key(EXPIRES_HEADER): False, make_key(CSEQ_HEADER): False, make_key(VIA_HEADER): True, # Via make_key(CONTACT_HEADER): False, # Contact make_key(SUPPORTED_HEADER): True, # Supported make_key(UNSUPPORTED_HEADER): True, make_key(ALLOW_HEADER): True, make_key(ROUTE_HEADER): True, make_key(RECORD_ROUTE_HEADER): True, make_key(REQUIRE_HEADER): True, make_key(PROXY_REQUIRE_HEADER): True, make_key(ACCEPT_HEADER): True,
def header_descr(header): header_key = make_key(header) if header_key == make_key(FROM_HEADER) or header_key == make_key( TO_HEADER): return Description(required=REQUIRED_ALL, header_class=FromToHeader) elif header_key == make_key(CSEQ_HEADER): return Description(required=REQUIRED_ALL, header_class=CSeqHeader) elif header_key == make_key(CALLID_HEADER): return Description(required=REQUIRED_ALL, header_class=CallIDHeader) elif header_key == make_key(MAXFORWARDS_HEADER): return Description(required=REQUIRED_OPTIONAL, header_class=MaxForwardsHeader) elif header_key == make_key(VIA_HEADER): return Description(required=REQUIRED_REQUESTS, header_class=ViaHeader) elif header_key == make_key(CONTENT_TYPE_HEADER): return Description(required=REQUIRED_WITH_BODY, header_class=ContentTypeHeader) elif header_key == make_key(ROUTE_HEADER) or header_key == make_key( RECORD_ROUTE_HEADER): return Description(required=REQUIRED_OPTIONAL, header_class=RouteHeader) elif header_key == make_key(ALLOW_HEADER): return Description(required=REQUIRED_OPTIONAL, header_class=AllowHeader) elif header_key in (make_key(SUPPORTED_HEADER), make_key(UNSUPPORTED_HEADER), make_key(REQUIRE_HEADER), make_key(PROXY_REQUIRE_HEADER)): return Description(required=REQUIRED_OPTIONAL, header_class=OptTagListHeader) elif header_key == make_key(CONTACT_HEADER): return Description(required=REQUIRED_OPTIONAL, header_class=ContactHeaderList) elif header_key == make_key(EXPIRES_HEADER) or header_key == make_key( MIN_EXPIRES_HEADER): return Description(required=REQUIRED_OPTIONAL, header_class=ExpiresHeader) elif header_key == make_key(DATE_HEADER): return Description(required=REQUIRED_OPTIONAL, header_class=DateHeader)
def remove_header(header, msg): msg.headers.pop(make_key(header), None) msg.raw_message.delete_header(header)