]> git-server-git.apps.pok.os.sepia.ceph.com Git - radosgw-agent.git/commitdiff
re-purpose urlencode to craft the query string for us without quoting again
authorAlfredo Deza <alfredo.deza@inktank.com>
Thu, 18 Dec 2014 21:18:42 +0000 (15:18 -0600)
committerJosh Durgin <jdurgin@redhat.com>
Fri, 19 Dec 2014 11:17:03 +0000 (03:17 -0800)
Signed-off-by: Alfredo Deza <alfredo.deza@inktank.com>
radosgw_agent/request.py

index 56c45ff254c82ee1e164c702f37e34f62b1509ed..86cc0667c47c9a26deb5ff82b5c712bd3856f536 100644 (file)
@@ -1,11 +1,80 @@
 import boto
 import logging
+import sys
 from boto.connection import AWSAuthConnection
-from urllib import urlencode
 
 log = logging.getLogger(__name__)
 
 
+def urlencode(query, doseq=0):
+    """
+    Note: ported from urllib.urlencode, but with the ability to craft the query
+    string without quoting the params again.
+
+    Encode a sequence of two-element tuples or dictionary into a URL query
+    string.
+
+    If any values in the query arg are sequences and doseq is true, each
+    sequence element is converted to a separate parameter.
+
+    If the query arg is a sequence of two-element tuples, the order of the
+    parameters in the output will match the order of parameters in the
+    input.
+    """
+
+    if hasattr(query, "items"):
+        # mapping objects
+        query = query.items()
+    else:
+        # it's a bother at times that strings and string-like objects are
+        # sequences...
+        try:
+            # non-sequence items should not work with len()
+            # non-empty strings will fail this
+            if len(query) and not isinstance(query[0], tuple):
+                raise TypeError
+            # zero-length sequences of all types will get here and succeed,
+            # but that's a minor nit - since the original implementation
+            # allowed empty dicts that type of behavior probably should be
+            # preserved for consistency
+        except TypeError:
+            ty, va, tb = sys.exc_info()
+            raise TypeError, "not a valid non-string sequence or mapping object", tb
+
+    l = []
+    if not doseq:
+        # preserve old behavior
+        for k, v in query:
+            k = str(k)
+            v = str(v)
+            l.append(k + '=' + v)
+        print l
+    else:
+        for k, v in query:
+            k = str(k)
+            if isinstance(v, str):
+                l.append(k + '=' + v)
+            elif isinstance(v, unicode):
+                # is there a reasonable way to convert to ASCII?
+                # encode generates a string, but "replace" or "ignore"
+                # lose information and "strict" can raise UnicodeError
+                v = v.encode("ASCII", "replace")
+                l.append(k + '=' + v)
+            else:
+                try:
+                    # is this a sufficient test for sequence-ness?
+                    len(v)
+                except TypeError:
+                    # not a sequence
+                    v = str(v)
+                    l.append(k + '=' + v)
+                else:
+                    # loop over the sequence
+                    for elt in v:
+                        l.append(k + '=' + str(elt))
+    return '&'.join(l)
+
+
 class MetaData(object):
     """
     A basic container class that other than the method, it just registers