Commits

Paul Tan committed 0831ef3

Fixed requests and curl adapters to not provide cookies param to Request.
curl: --data-urlencoded can now load files with @.
core: Support binary parameters
NOTE: We are using a temporary stop-gap solution in code to allow tumblr to work. See #TODO in core

Comments (0)

Files changed (3)

oauth1client/__init__.py

 
 """ Applying oauth parameters to request """
 def req_apply_oauth_header(req: Request, oauth_params) -> Request:
-    x = ",".join(['{0}="{1}"'.format(urlquote(str(k)), urlquote(str(v)))
+    def handle_val(x):
+        if isinstance(x, bytes):
+            return x
+        else:
+            return str(x).encode("utf-8")
+    x = ",".join(['{0}="{1}"'.format(urlquote(handle_val(k)), urlquote(handle_val(v)))
             for k, v in oauth_params.items()])
     return apply_headers_to_req(req, {"Authorization": "OAuth {0}".format(x)})
 
     if "oauth_signature" in query: 
         del query["oauth_signature"]
     #Parameter normalization
-    params = [(urlquote(str(k)), urlquote(str(v))) for k, v in query.items()]
+    def handle_val(x):
+        if isinstance(x, bytes):
+            return x
+        else:
+            return str(x).encode("utf-8")
+    #TODO: We use tumblr's broken implementation
+    params = [(str(k), urlquote(handle_val(v))) for k, v in query.items()]
+    #Spec-compliant one is:
+    #params = [(urlquote(handle_val(k)), urlquote(handle_val(v))) for k, v in query.items()]
     params.sort()
     return '&'.join(['{0}={1}'.format(k, v) for k, v in params])
 

oauth1client/curl.py

 from oauth1client import Request
 import sys
 import subprocess
-from urllib.parse import unquote
+from urllib.parse import unquote, quote
 
 class FriendlyArgumentParser(ArgumentParser):
     """An ArgumentParser that does not call sys.exit
         self.cred = cred
 
     @staticmethod
-    def req_to_curl_args(req):
+    def req_to_curl_args(req, data_urlencode_content = {}):
         from urllib.parse import urlencode
         #Reconstruct CURL Request
         args = []
         #Data
         if req.data:
             for x, y in req.data.items():
-                args.append("-d")
-                args.append(urlencode({x: y}))
+                if x in data_urlencode_content:
+                    args.append("--data-urlencode")
+                    args.append("{}@{}".format(quote(x), data_urlencode_content[x]))
+                else:
+                    args.append("-d")
+                    args.append(urlencode({x: y}))
         #Finally, URL
         args.append(req.url)
         return args
             before_rest.append("-H")
             before_rest.append(x)
         data = {}
+        data_urlencode_content = {}
         if "content-type" in headers and headers["content-type"] != "application/x-www-form-urlencoded":
             #No data required since it is not needed in oauth signature.
             #However, we need to add back the arguments later
                     key, _, value = x.partition("=")
                 data[key] = unquote(value) #Expected to be urlencoded already
             for x in args.data_urlencode:
-                if x.find("=") != -1:
+                if "=" in x:
                     key, _, value = x.partition("=")
                     if key:
+                        #name=content
                         data[key] = value #Will urlencode later
+                    elif value:
+                        #=content
+                        #TODO: Support this!
+                        raise ValueError("Sorry, =content not supported")
                     else:
                         raise ValueError("--data-urlencode {} not supported".format(x))
+                elif "@" in x:
+                    key, _, value = x.partition("@")
+                    if key and value:
+                        #name@filename
+                        key = unquote(key)
+                        data[key] = open(value, "rb").read()
+                        data_urlencode_content[key] = value
+                    elif value:
+                        #@filename
+                        raise ValueError("Sorry, --data-urlencode @filename not supported")
+                    else:
+                        raise ValueError("--data-urlencode {} not supported".format(x))
+                else:
+                    raise ValueError("--data-urlencode {} not supported".format(x))
         if args.method:
             method = args.method[-1].upper()
         elif (args.data or args.data_urlencode or 
             method = "POST"
         else:
             method = "GET"
-        req = Request(method = method, url = url, data = data, headers = {}, cookies = {})
+        req = Request(method = method, url = url, data = data, headers = {})
         if self.cred:
             req = self.cred.oauth_req(req)
-        return before_rest + rest + self.req_to_curl_args(req)
+        return before_rest + rest + self.req_to_curl_args(req, data_urlencode_content)
 
     def main(self, args = None):
         x = self.transform_args(args, parser_class = ArgumentParser)

oauth1client/requests.py

         else:
             replace_data = True
             data = x.data
-        y = Request(x.method, x.full_url, data, x.headers, x.cookies)
+        y = Request(x.method, x.full_url, data, x.headers)
         y = self.cred.oauth_req(y)
         x.method = y.method
         x.url = y.url
         if replace_data: 
             x.data = y.data
         x.headers.update(y.headers)
-        x.cookies = y.cookies
         return x