Skip to content
This repository has been archived by the owner on Aug 30, 2024. It is now read-only.

fix compatibility with requests >=2.11.0 #83

Merged
merged 1 commit into from
Sep 27, 2016
Merged

Conversation

mastier
Copy link
Contributor

@mastier mastier commented Sep 22, 2016

There is an issue starting from requests >=2.11.0

$ euca-upload-bundle -m rh6.7_15-09-16_0100.img.manifest.xml -b images3
requestbuilder.exceptions.ClientError: Header value 10485760 must be of type str or bytes, not <type 'int'>

here are two excerpts

diff --git a/docs/api.rst b/docs/api.rst
index 59b0523..08e2b6e 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -258,6 +258,10 @@ Behavioural Changes

 * Keys in the ``headers`` dictionary are now native strings on all Python
   versions, i.e. bytestrings on Python 2 and unicode on Python 3. If the
-  keys are not native strings (unicode on Python2 or bytestrings on Python 3)
+  keys are not native strings (unicode on Python 2 or bytestrings on Python 3)
   they will be converted to the native string type assuming UTF-8 encoding.

+* Values in the ``headers`` dictionary should always be strings. This has
+  been the project's position since before 1.0 but a recent change
+  (since version 2.11.0) enforces this more strictly. It's advised to avoid
+  passing header values as unicode when possible.

and here

diff --git a/tests/test_structures.py b/tests/test_structures.py
index 1c332bb..e4d2459 100644
--- a/tests/test_structures.py
+++ b/tests/test_structures.py
@@ -713,10 +731,33 @@ def to_native_string(string, encoding='ascii'):
     return out


-def urldefragauth(url):
-    """
-    Given a url remove the fragment and the authentication part
+# Moved outside of function to avoid recompile every call
+_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$')
+_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$')
+
+def check_header_validity(header):
+    """Verifies that header value is a string which doesn't contain
+    leading whitespace or return characters. This prevents unintended
+    header injection.
+
+    :param header: tuple, in the format (name, value).
     """
+    name, value = header
+
+    if isinstance(value, bytes):
+        pat = _CLEAN_HEADER_REGEX_BYTE
+    else:
+        pat = _CLEAN_HEADER_REGEX_STR
+    try:
+        if not pat.match(value):
+            raise InvalidHeader("Invalid return character or leading space in header: %s" % name)
+    except TypeError:
+        raise InvalidHeader("Header value %s must be of type str or bytes, "
+                            "not %s" % (value, type(value)))
+
+
+def urldefragauth(url):
+    """Given a url remove the fragment and the authentication part"""
     scheme, netloc, path, params, query, fragment = urlparse(url)

     # see func:`prepend_scheme_if_needed`

I cannot change the behaviours for FileObjectExtent, because its size parameter is used for comparison. Therefore I construct bytes directly in PutObject .

@gholms gholms merged commit 4d3f5dd into eucalyptus:master Sep 27, 2016
@boltronics
Copy link
Contributor

For anyone else who ended up here, this is the associated python-requests issue: psf/requests#3477

This fix is found in 3.3.2 and above. Debian GNU/Linux (Stretch) ships with euca2ools 3.3.1 and python-requests 2.12.4 so Debian's euca-upload-bundle command is broken.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants