예제 #1
0
 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())
예제 #2
0
 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)
예제 #3
0
    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())
예제 #4
0
 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
예제 #5
0
파일: hdr.py 프로젝트: yurifil/pysip
 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)
예제 #6
0
    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
예제 #7
0
    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
예제 #8
0
 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
예제 #9
0
    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)
예제 #10
0
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)
예제 #11
0
 def delete_header(self, header_name):
     self._headers.pop(make_key(header_name), None)
예제 #12
0
파일: hdr.py 프로젝트: yurifil/pysip
    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,
예제 #13
0
 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)
예제 #14
0
 def remove_header(header, msg):
     msg.headers.pop(make_key(header), None)
     msg.raw_message.delete_header(header)