aboutsummaryrefslogtreecommitdiff
path: root/requests/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'requests/utils.py')
-rw-r--r--requests/utils.py92
1 files changed, 59 insertions, 33 deletions
diff --git a/requests/utils.py b/requests/utils.py
index f31cad8..0e0f69e 100644
--- a/requests/utils.py
+++ b/requests/utils.py
@@ -4,23 +4,35 @@
requests.utils
~~~~~~~~~~~~~~
-This module provides utlity functions that are used within Requests
+This module provides utility functions that are used within Requests
that are also useful for external consumption.
"""
import cgi
import codecs
-import cookielib
import os
import random
import re
import zlib
-import urllib
-from urllib2 import parse_http_list as _parse_list_header
+from .compat import parse_http_list as _parse_list_header
+from .compat import quote, unquote, cookielib, SimpleCookie, is_py2
+def dict_from_string(s):
+ """Returns a MultiDict with Cookies."""
+
+ cookies = dict()
+
+ c = SimpleCookie()
+ c.load(s)
+
+ for k,v in list(c.items()):
+ cookies.update({k: v.value})
+
+ return cookies
+
def guess_filename(obj):
"""Tries to guess the filename of the given object."""
name = getattr(obj, 'name', None)
@@ -132,16 +144,16 @@ def header_expand(headers):
collector = []
if isinstance(headers, dict):
- headers = headers.items()
+ headers = list(headers.items())
- elif isinstance(headers, basestring):
+ elif isinstance(headers, str):
return headers
for i, (value, params) in enumerate(headers):
_params = []
- for (p_k, p_v) in params.items():
+ for (p_k, p_v) in list(params.items()):
_params.append('%s=%s' % (p_k, p_v))
@@ -166,17 +178,11 @@ def header_expand(headers):
def randombytes(n):
"""Return n random bytes."""
- # Use /dev/urandom if it is available. Fall back to random module
- # if not. It might be worthwhile to extend this function to use
- # other platform-specific mechanisms for getting random bytes.
- if os.path.exists("/dev/urandom"):
- f = open("/dev/urandom")
- s = f.read(n)
- f.close()
- return s
- else:
+ if is_py2:
L = [chr(random.randrange(0, 256)) for i in range(n)]
- return "".join(L)
+ else:
+ L = [chr(random.randrange(0, 256)).encode('utf-8') for i in range(n)]
+ return b"".join(L)
def dict_from_cookiejar(cj):
@@ -187,9 +193,9 @@ def dict_from_cookiejar(cj):
cookie_dict = {}
- for _, cookies in cj._cookies.items():
- for _, cookies in cookies.items():
- for cookie in cookies.values():
+ for _, cookies in list(cj._cookies.items()):
+ for _, cookies in list(cookies.items()):
+ for cookie in list(cookies.values()):
# print cookie
cookie_dict[cookie.name] = cookie.value
@@ -221,7 +227,7 @@ def add_dict_to_cookiejar(cj, cookie_dict):
:param cookie_dict: Dict of key/values to insert into CookieJar.
"""
- for k, v in cookie_dict.items():
+ for k, v in list(cookie_dict.items()):
cookie = cookielib.Cookie(
version=0,
@@ -276,6 +282,9 @@ def get_encoding_from_headers(headers):
if 'charset' in params:
return params['charset'].strip("'\"")
+ if 'text' in content_type:
+ return 'ISO-8859-1'
+
def unicode_from_html(content):
"""Attempts to decode an HTML string into unicode.
@@ -287,7 +296,7 @@ def unicode_from_html(content):
for encoding in encodings:
try:
- return unicode(content, encoding)
+ return str(content, encoding)
except (UnicodeError, TypeError):
pass
@@ -334,13 +343,13 @@ def get_unicode_from_response(r):
if encoding:
try:
- return unicode(r.content, encoding)
+ return str(r.content, encoding)
except UnicodeError:
tried_encodings.append(encoding)
# Fall back:
try:
- return unicode(r.content, encoding, errors='replace')
+ return str(r.content, encoding, errors='replace')
except TypeError:
return r.content
@@ -354,28 +363,45 @@ def decode_gzip(content):
return zlib.decompress(content, 16 + zlib.MAX_WBITS)
-def stream_decode_gzip(iterator):
- """Stream decodes a gzip-encoded iterator"""
+def stream_decompress(iterator, mode='gzip'):
+ """
+ Stream decodes an iterator over compressed data
+
+ :param iterator: An iterator over compressed data
+ :param mode: 'gzip' or 'deflate'
+ :return: An iterator over decompressed data
+ """
+
+ if mode not in ['gzip', 'deflate']:
+ raise ValueError('stream_decompress mode must be gzip or deflate')
+
+ zlib_mode = 16 + zlib.MAX_WBITS if mode == 'gzip' else -zlib.MAX_WBITS
+ dec = zlib.decompressobj(zlib_mode)
try:
- dec = zlib.decompressobj(16 + zlib.MAX_WBITS)
for chunk in iterator:
rv = dec.decompress(chunk)
if rv:
yield rv
+ except zlib.error:
+ # If there was an error decompressing, just return the raw chunk
+ yield chunk
+ # Continue to return the rest of the raw data
+ for chunk in iterator:
+ yield chunk
+ else:
+ # Make sure everything has been returned from the decompression object
buf = dec.decompress('')
rv = buf + dec.flush()
if rv:
yield rv
- except zlib.error:
- pass
def requote_path(path):
"""Re-quote the given URL path component.
This function passes the given path through an unquote/quote cycle to
- ensure that it is fully and consistenty quoted.
+ ensure that it is fully and consistently quoted.
"""
- parts = path.split("/")
- parts = (urllib.quote(urllib.unquote(part), safe="") for part in parts)
- return "/".join(parts)
+ parts = path.split(b"/")
+ parts = (quote(unquote(part), safe=b"") for part in parts)
+ return b"/".join(parts)