def __init__( self, protocol: ItemType, status: ItemType, status_msg: ItemType, headers: HeadersType = None, body: ItemType = None, ) -> None: """Python object representation of an HTTP/1.x response. Args: protocol: "<major>.<minor>" numbering scheme to indicate versions of the protocol. status: Numberical value designating a specific return value. status_msg: Message related to the status code. headers: Collection of case-insensitive name followed by a colon (:). body: Data associated with the message. """ self._status = Item(status) self._status_msg = Item(status_msg) super().__init__(protocol, headers, body) first_line = self._protocol.raw, self._status.raw, self._status_msg.raw self._first_line = Item(b"%b %b %b" % first_line)
def __init__( self, method: ItemType, target: ItemType, protocol: HeadersType, headers: ItemType = None, body: ItemType = None, ) -> None: """Python object representation of an HTTP/1.x request." Args: method: Indicates the desired action on the server's resource. target: Resource location in the server for which the client is requesting. protocol: "<major>.<minor>" numbering scheme to indicate versions of the protocol. headers: Collection of case-insensitive name followed by a colon (:). body: Data associated with the message. """ self._method = Item(method) self._target = Item(target) super().__init__(protocol, headers, body) first_line = (self._method.raw, self._target.raw, self._protocol.raw) self._first_line = Item(b"%b %b %b" % first_line)
def __setattr__(self, key: str, value: str) -> None: """Sets a new attribute inside Headers. Notes: If "_" is present in the key it gets replaced with "-". This is so, example, "headers.User_Agent" is equivalent to "headers['User-Agent']". """ key_mod = key.replace("_", "-").encode(ENCODE) self[Item(key_mod)] = Item(value)
def __iadd__(self, other: Union[dict, "Headers"]) -> "Headers": """Adds current headers with passed other and returns self. Args: other: Headers or dictionary to be added. Returns: Headers: Self after addition of other to itself. """ self._check(other) itemized_values = {Item(k): Item(v) for k, v in other.items()} self.update(itemized_values) return self
def __init__(self, headers: HeadersType = None) -> None: """Initializes the Headers object. Args: value: Dictionary, headers, or None object that represents the headers. """ if headers is None: headers = {} self._check(headers) if isinstance(headers, dict): for key, value in headers.items(): self[Item(key)] = Item(value) super().__init__()
def _compile_first_line(self) -> None: """Compiles the first line of the message. Notes: Sets self._first_line to self.protocol, self.status, self.status_msg. """ first_line = self._protocol.raw, self._status.raw, self._status_msg.raw self._first_line = Item(b"%b %b %b" % first_line)
def _compile_first_line(self) -> None: """Compiles the first line of the message. Notes: Sets self._first_line to self.protocol, self.method, self.target. """ first_line = (self._method.raw, self._target.raw, self._protocol.raw) self._first_line = Item(b"%b %b %b" % first_line)
def __add__(self, other: Union[dict, "Headers"]) -> "Headers": """Adds item with passed other and returns new Headers. Args: other: Headers or dictionary to be added. Returns: Headers: New resulting Headers object. """ self._check(other) if isinstance(other, Headers): current = self.copy() current.update(other) return Headers(current) elif isinstance(other, dict): itemized_values = {Item(k): Item(v) for k, v in other.items()} copy = self.copy() copy.update(itemized_values) return copy
def __init__( self, protocol: ItemType, headers: HeadersType = None, body: ItemType = None ) -> None: """Initializes an HTTP Message. Args: protocol: "<major>.<minor>" numbering scheme to indicate versions of the protocol. headers: Collection of case-insensitive name followed by a colon (:). body: Data associated with the message. """ self._first_line = None self._protocol = Item(protocol) if isinstance(headers, Headers): self._headers = headers elif headers is None: self._headers = Headers() else: self._headers = Headers(headers) self._body = Item(body)
def parse(cls: Union["Message", "Response", "Request"], message: Any) -> None: """Parses a raw HTTP message (in bytes or string) to an object instance of class 'cls'. Args: message: The primative or object to convert into a Request or Response object. Returns: An initialized object of class 'cls'. """ if isinstance(cls, Message): err = "You can only use .parse() with either the Request or Response class." raise ValueError(err) if not isinstance(message, Item): message = Item(message) first_line = b"" headers = Headers({}) body = b"" top_frame = True for index, line in enumerate(message.raw.splitlines()): if line == b"": top_frame = False if top_frame: if index == 0: first_line = line elif b":" in line: key, value = line.split(b":", 1) headers += {key: value.lstrip(b" ")} else: body += line args = (*first_line.split(b" "), headers, body) try: return cls(*args) except TypeError as error: # pragma: no cover err = "Error parsing the message due to {}.".format(error) raise TypeError(err) from error
def status_msg(self, value: ItemType) -> None: self._status_msg = Item(value)
def status(self, value: ItemType) -> None: self._status = Item(value)
def target(self, value: ItemType) -> None: self._target = Item(value)
def method(self, value: ItemType) -> None: self._method = Item(value)
def body(self, value: ItemType) -> None: self._body = Item(value)
def protocol(self, value: ItemType) -> None: self._protocol = Item(value)