From e9fe45f3f404bb1c762dfb13477072c06d4b74ec Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Mon, 21 Sep 2015 18:38:50 +0200 Subject: [PATCH] backport changes --- netlib/http/models.py | 36 ++++++++++++++++++------------------ netlib/tcp.py | 1 + 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/netlib/http/models.py b/netlib/http/models.py index 3c360a371..512a764d4 100644 --- a/netlib/http/models.py +++ b/netlib/http/models.py @@ -216,7 +216,7 @@ class Message(object): def body(self, body): self._body = body if isinstance(body, bytes): - self.headers[b"Content-Length"] = str(len(body)).encode() + self.headers[b"content-length"] = str(len(body)).encode() content = body @@ -268,8 +268,8 @@ class Request(Message): response. That is, we remove ETags and If-Modified-Since headers. """ delheaders = [ - b"If-Modified-Since", - b"If-None-Match", + b"if-modified-since", + b"if-none-match", ] for i in delheaders: self.headers.pop(i, None) @@ -279,16 +279,16 @@ class Request(Message): Modifies this request to remove headers that will compress the resource's data. """ - self.headers["Accept-Encoding"] = "identity" + self.headers["accept-encoding"] = b"identity" def constrain_encoding(self): """ Limits the permissible Accept-Encoding values, based on what we can decode appropriately. """ - accept_encoding = native(self.headers.get("Accept-Encoding"), "ascii") + accept_encoding = native(self.headers.get("accept-encoding"), "ascii") if accept_encoding: - self.headers["Accept-Encoding"] = ( + self.headers["accept-encoding"] = ( ', '.join( e for e in encoding.ENCODINGS @@ -300,7 +300,7 @@ class Request(Message): """ Update the host header to reflect the current target. """ - self.headers["Host"] = self.host + self.headers["host"] = self.host def get_form(self): """ @@ -309,9 +309,9 @@ class Request(Message): indicates non-form data. """ if self.body: - if HDR_FORM_URLENCODED in self.headers.get("Content-Type", b"").lower(): + if HDR_FORM_URLENCODED in self.headers.get("content-type", b"").lower(): return self.get_form_urlencoded() - elif HDR_FORM_MULTIPART in self.headers.get("Content-Type", b"").lower(): + elif HDR_FORM_MULTIPART in self.headers.get("content-type", b"").lower(): return self.get_form_multipart() return ODict([]) @@ -321,12 +321,12 @@ class Request(Message): Returns an empty ODict if there is no data or the content-type indicates non-form data. """ - if self.body and HDR_FORM_URLENCODED in self.headers.get("Content-Type", b"").lower(): + if self.body and HDR_FORM_URLENCODED in self.headers.get("content-type", b"").lower(): return ODict(utils.urldecode(self.body)) return ODict([]) def get_form_multipart(self): - if self.body and HDR_FORM_MULTIPART in self.headers.get("Content-Type", b"").lower(): + if self.body and HDR_FORM_MULTIPART in self.headers.get("content-type", b"").lower(): return ODict( utils.multipartdecode( self.headers, @@ -341,7 +341,7 @@ class Request(Message): """ # FIXME: If there's an existing content-type header indicating a # url-encoded form, leave it alone. - self.headers[b"Content-Type"] = HDR_FORM_URLENCODED + self.headers[b"content-type"] = HDR_FORM_URLENCODED self.body = utils.urlencode(odict.lst) def get_path_components(self): @@ -398,9 +398,9 @@ class Request(Message): but not the resolved name. This is disabled by default, as an attacker may spoof the host header to confuse an analyst. """ - if hostheader and "Host" in self.headers: + if hostheader and "host" in self.headers: try: - return self.headers["Host"].decode("idna") + return self.headers["host"].decode("idna") except ValueError: pass if self.host: @@ -429,7 +429,7 @@ class Request(Message): headers. """ v = cookies.format_cookie_header(odict) - self.headers["Cookie"] = v + self.headers["cookie"] = v @property def url(self): @@ -485,7 +485,7 @@ class Response(Message): return "".format( status_code=self.status_code, msg=self.msg, - contenttype=self.headers.get("Content-Type", "unknown content type"), + contenttype=self.headers.get("content-type", "unknown content type"), size=size) def get_cookies(self): @@ -498,7 +498,7 @@ class Response(Message): attributes (e.g. HTTPOnly) are indicated by a Null value. """ ret = [] - for header in self.headers.get_all("Set-Cookie"): + for header in self.headers.get_all("set-cookie"): v = cookies.parse_set_cookie_header(native(header, "ascii")) if v: name, value, attrs = v @@ -521,4 +521,4 @@ class Response(Message): i[1][1] ) ) - self.headers.set_all("Set-Cookie", values) + self.headers.set_all("set-cookie", values) diff --git a/netlib/tcp.py b/netlib/tcp.py index 40ffbd486..b751d71f4 100644 --- a/netlib/tcp.py +++ b/netlib/tcp.py @@ -279,6 +279,7 @@ class Reader(_FileLike): if tuple(int(x) for x in OpenSSL.__version__.split(".")[:2]) > (0, 15): return self.o.recv(length, socket.MSG_PEEK) else: + # TODO: remove once a new version is released # Polyfill for pyOpenSSL <= 0.15.1 # Taken from https://github.com/pyca/pyopenssl/commit/1d95dea7fea03c7c0df345a5ea30c12d8a0378d2 buf = SSL._ffi.new("char[]", length)