29
29
import hmac
30
30
import binascii
31
31
import httplib2
32
+ from types import ListType
32
33
33
34
try :
34
35
from urlparse import parse_qs , parse_qsl
@@ -309,7 +310,10 @@ def to_header(self, realm=''):
309
310
310
311
def to_postdata (self ):
311
312
"""Serialize as post data for a POST request."""
312
- return urllib .urlencode (self )
313
+ # tell urlencode to deal with sequence values and map them correctly
314
+ # to resulting querystring. for example self["k"] = ["v1", "v2"] will
315
+ # result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D
316
+ return urllib .urlencode (self , True )
313
317
314
318
def to_url (self ):
315
319
"""Serialize as a URL for a GET request."""
@@ -324,8 +328,9 @@ def get_parameter(self, parameter):
324
328
325
329
def get_normalized_parameters (self ):
326
330
"""Return a string that contains the parameters that must be signed."""
327
- items = [(k , v ) for k , v in self .items () if k != 'oauth_signature' ]
328
- encoded_str = urllib .urlencode (sorted (items ))
331
+ # 1.0a/9.1.1 states that kvp must be sorted by key, then by value
332
+ items = [(k , v if type (v ) != ListType else sorted (v )) for k ,v in sorted (self .items ()) if k != 'oauth_signature' ]
333
+ encoded_str = urllib .urlencode (items , True )
329
334
# Encode signature parameters per Oauth Core 1.0 protocol
330
335
# spec draft 7, section 3.6
331
336
# (http://tools.ietf.org/html/draft-hammer-oauth-07#section-3.6)
@@ -580,7 +585,7 @@ def request(self, uri, method="GET", body=None, headers=None,
580
585
parameters = dict (parse_qsl (body ))
581
586
elif method == "GET" :
582
587
parsed = urlparse .urlparse (uri )
583
- parameters = parse_qs (parsed .query )
588
+ parameters = parse_qsl (parsed .query )
584
589
else :
585
590
parameters = None
586
591
0 commit comments