Skip to content

Commit

Permalink
Synchronize urllib3 to 1.10.4
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukasa committed May 3, 2015
1 parent 6acca21 commit ee7389d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 53 deletions.
7 changes: 4 additions & 3 deletions requests/packages/urllib3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

__author__ = 'Andrey Petrov ([email protected])'
__license__ = 'MIT'
__version__ = '1.10.3'
__version__ = '1.10.4'


from .connectionpool import (
Expand Down Expand Up @@ -57,9 +57,10 @@ def add_stderr_logger(level=logging.DEBUG):

import warnings
# SecurityWarning's always go off by default.
warnings.simplefilter('always', exceptions.SecurityWarning)
warnings.simplefilter('always', exceptions.SecurityWarning, append=True)
# InsecurePlatformWarning's don't vary between requests, so we keep it default.
warnings.simplefilter('default', exceptions.InsecurePlatformWarning)
warnings.simplefilter('default', exceptions.InsecurePlatformWarning,
append=True)

def disable_warnings(category=exceptions.HTTPWarning):
"""
Expand Down
122 changes: 72 additions & 50 deletions requests/packages/urllib3/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,15 @@ def __init__(self, body='', headers=None, status=0, version=0, reason=None,
# Are we using the chunked-style of transfer encoding?
self.chunked = False
self.chunk_left = None
tr_enc = self.headers.get('transfer-encoding', '')
if tr_enc.lower() == "chunked":
tr_enc = self.headers.get('transfer-encoding', '').lower()
# Don't incur the penalty of creating a list and then discarding it
encodings = (enc.strip() for enc in tr_enc.split(","))
if "chunked" in encodings:
self.chunked = True

# We certainly don't want to preload content when the response is chunked.
if not self.chunked:
if preload_content and not self._body:
self._body = self.read(decode_content=decode_content)
if not self.chunked and preload_content and not self._body:
self._body = self.read(decode_content=decode_content)

def get_redirect_location(self):
"""
Expand Down Expand Up @@ -179,9 +180,8 @@ def _init_decoder(self):
# Note: content-encoding value should be case-insensitive, per RFC 7230
# Section 3.2
content_encoding = self.headers.get('content-encoding', '').lower()
if self._decoder is None:
if content_encoding in self.CONTENT_DECODERS:
self._decoder = _get_decoder(content_encoding)
if self._decoder is None and content_encoding in self.CONTENT_DECODERS:
self._decoder = _get_decoder(content_encoding)

def _decode(self, data, decode_content, flush_decoder):
"""
Expand Down Expand Up @@ -299,10 +299,9 @@ def stream(self, amt=2**16, decode_content=None):
If True, will attempt to decode the body based on the
'content-encoding' header.
"""
self._init_decoder()
if self.chunked:
for line in self.read_chunked(amt):
yield self._decode(line, decode_content, True)
for line in self.read_chunked(amt, decode_content=decode_content):
yield line
else:
while not is_fp_closed(self._fp):
data = self.read(amt=amt, decode_content=decode_content)
Expand Down Expand Up @@ -387,48 +386,70 @@ def readinto(self, b):
b[:len(temp)] = temp
return len(temp)

def read_chunked(self, amt=None):
# FIXME: Rewrite this method and make it a class with
# a better structured logic.
def _update_chunk_length(self):
# First, we'll figure out length of a chunk and then
# we'll try to read it from socket.
if self.chunk_left is not None:
return
line = self._fp.fp.readline()
line = line.split(b';', 1)[0]
try:
self.chunk_left = int(line, 16)
except ValueError:
# Invalid chunked protocol response, abort.
self.close()
raise httplib.IncompleteRead(line)

def _handle_chunk(self, amt):
returned_chunk = None
if amt is None:
chunk = self._fp._safe_read(self.chunk_left)
returned_chunk = chunk
self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
self.chunk_left = None
elif amt < self.chunk_left:
value = self._fp._safe_read(amt)
self.chunk_left = self.chunk_left - amt
returned_chunk = value
elif amt == self.chunk_left:
value = self._fp._safe_read(amt)
self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
self.chunk_left = None
returned_chunk = value
else: # amt > self.chunk_left
returned_chunk = self._fp._safe_read(self.chunk_left)
self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
self.chunk_left = None
return returned_chunk

def read_chunked(self, amt=None, decode_content=None):
"""
Similar to :meth:`HTTPResponse.read`, but with an additional
parameter: ``decode_content``.
:param decode_content:
If True, will attempt to decode the body based on the
'content-encoding' header.
"""
self._init_decoder()
# FIXME: Rewrite this method and make it a class with a better structured logic.
if not self.chunked:
raise ResponseNotChunked("Response is not chunked. "
"Header 'transfer-encoding: chunked' is missing.")

if self._original_response and self._original_response._method.upper() == 'HEAD':
# Don't bother reading the body of a HEAD request.
# FIXME: Can we do this somehow without accessing private httplib _method?
self._original_response.close()
return

while True:
# First, we'll figure out length of a chunk and then
# we'll try to read it from socket.
if self.chunk_left is None:
line = self._fp.fp.readline()
line = line.decode()
# See RFC 7230: Chunked Transfer Coding.
i = line.find(';')
if i >= 0:
line = line[:i] # Strip chunk-extensions.
try:
self.chunk_left = int(line, 16)
except ValueError:
# Invalid chunked protocol response, abort.
self.close()
raise httplib.IncompleteRead(''.join(line))
if self.chunk_left == 0:
break
if amt is None:
chunk = self._fp._safe_read(self.chunk_left)
yield chunk
self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
self.chunk_left = None
elif amt < self.chunk_left:
value = self._fp._safe_read(amt)
self.chunk_left = self.chunk_left - amt
yield value
elif amt == self.chunk_left:
value = self._fp._safe_read(amt)
self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
self.chunk_left = None
yield value
else: # amt > self.chunk_left
yield self._fp._safe_read(self.chunk_left)
self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
self.chunk_left = None
self._update_chunk_length()
if self.chunk_left == 0:
break
chunk = self._handle_chunk(amt)
yield self._decode(chunk, decode_content=decode_content,
flush_decoder=True)

# Chunk content ends with \r\n: discard it.
while True:
Expand All @@ -440,5 +461,6 @@ def read_chunked(self, amt=None):
break

# We read everything; close the "file".
if self._original_response:
self._original_response.close()
self.release_conn()

2 changes: 2 additions & 0 deletions requests/packages/urllib3/util/url.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class Url(namedtuple('Url', url_attrs)):

def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None,
query=None, fragment=None):
if path and not path.startswith('/'):
path = '/' + path
return super(Url, cls).__new__(cls, scheme, auth, host, port, path,
query, fragment)

Expand Down

0 comments on commit ee7389d

Please sign in to comment.