diff --git a/oauth2/__init__.py b/oauth2/__init__.py index b0f61fa5..a965fc71 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -309,8 +309,14 @@ def to_header(self, realm=''): def to_postdata(self): """Serialize as post data for a POST request.""" - return urllib.urlencode(self) - + return self.encode_postdata(self) + + def encode_postdata(self, data): + # tell urlencode to deal with sequence values and map them correctly + # to resulting querystring. for example self["k"] = ["v1", "v2"] will + # result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D + return urllib.urlencode(data, True) + def to_url(self): """Serialize as a URL for a GET request.""" return '%s?%s' % (self.url, self.to_postdata()) @@ -325,7 +331,7 @@ def get_parameter(self, parameter): def get_normalized_parameters(self): """Return a string that contains the parameters that must be signed.""" items = [(k, v) for k, v in self.items() if k != 'oauth_signature'] - encoded_str = urllib.urlencode(sorted(items)) + encoded_str = urllib.urlencode(sorted(items), True) # Encode signature parameters per Oauth Core 1.0 protocol # spec draft 7, section 3.6 # (http://tools.ietf.org/html/draft-hammer-oauth-07#section-3.6) @@ -571,7 +577,8 @@ def set_signature_method(self, method): self.method = method def request(self, uri, method="GET", body=None, headers=None, - redirections=httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None): + redirections=httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None, + force_auth_header=False): if not isinstance(headers, dict): headers = {} @@ -589,13 +596,23 @@ def request(self, uri, method="GET", body=None, headers=None, req.sign_request(self.method, self.consumer, self.token) + if force_auth_header: + # ensure we always send Authorization + headers.update(req.to_header()) + if method == "POST": - body = req.to_postdata() + if not force_auth_header: + body = req.to_postdata() + else: + body = req.encode_postdata(req.get_nonoauth_parameters()) headers['Content-Type'] = 'application/x-www-form-urlencoded' elif method == "GET": - uri = req.to_url() + if not force_auth_header: + uri = req.to_url() else: - headers.update(req.to_header()) + if not force_auth_header: + # don't call update twice. + headers.update(req.to_header()) return httplib2.Http.request(self, uri, method=method, body=body, headers=headers, redirections=redirections,