28
28
import sys
29
29
import tempfile
30
30
31
- import httplib2
32
31
import six
33
32
from six .moves import http_client
34
33
from six .moves import urllib
39
38
from oauth2client import GOOGLE_REVOKE_URI
40
39
from oauth2client import GOOGLE_TOKEN_INFO_URI
41
40
from oauth2client import GOOGLE_TOKEN_URI
41
+ from oauth2client import transport
42
42
from oauth2client import util
43
43
from oauth2client ._helpers import _from_bytes
44
- from oauth2client ._helpers import _to_bytes
45
44
from oauth2client ._helpers import _urlsafe_b64decode
46
45
47
46
71
70
# Constant to use for the out of band OAuth 2.0 flow.
72
71
OOB_CALLBACK_URN = 'urn:ietf:wg:oauth:2.0:oob'
73
72
74
- # Google Data client libraries may need to set this to [401, 403].
75
- REFRESH_STATUS_CODES = (http_client .UNAUTHORIZED ,)
76
-
77
73
# The value representing user credentials.
78
74
AUTHORIZED_USER = 'authorized_user'
79
75
120
116
# easier testing (by replacing with a stub).
121
117
_UTCNOW = datetime .datetime .utcnow
122
118
119
+ # NOTE: These names were previously defined in this module but have been
120
+ # moved into `oauth2client.transport`,
121
+ clean_headers = transport .clean_headers
122
+ MemoryCache = transport .MemoryCache
123
+ REFRESH_STATUS_CODES = transport .REFRESH_STATUS_CODES
124
+
123
125
124
126
class SETTINGS (object ):
125
127
"""Settings namespace for globally defined values."""
@@ -177,22 +179,6 @@ class CryptoUnavailableError(Error, NotImplementedError):
177
179
"""Raised when a crypto library is required, but none is available."""
178
180
179
181
180
- class MemoryCache (object ):
181
- """httplib2 Cache implementation which only caches locally."""
182
-
183
- def __init__ (self ):
184
- self .cache = {}
185
-
186
- def get (self , key ):
187
- return self .cache .get (key )
188
-
189
- def set (self , key , value ):
190
- self .cache [key ] = value
191
-
192
- def delete (self , key ):
193
- self .cache .pop (key , None )
194
-
195
-
196
182
def _parse_expiry (expiry ):
197
183
if expiry and isinstance (expiry , datetime .datetime ):
198
184
return expiry .strftime (EXPIRY_FORMAT )
@@ -451,32 +437,6 @@ def delete(self):
451
437
self .release_lock ()
452
438
453
439
454
- def clean_headers (headers ):
455
- """Forces header keys and values to be strings, i.e not unicode.
456
-
457
- The httplib module just concats the header keys and values in a way that
458
- may make the message header a unicode string, which, if it then tries to
459
- contatenate to a binary request body may result in a unicode decode error.
460
-
461
- Args:
462
- headers: dict, A dictionary of headers.
463
-
464
- Returns:
465
- The same dictionary but with all the keys converted to strings.
466
- """
467
- clean = {}
468
- try :
469
- for k , v in six .iteritems (headers ):
470
- if not isinstance (k , six .binary_type ):
471
- k = str (k )
472
- if not isinstance (v , six .binary_type ):
473
- v = str (v )
474
- clean [_to_bytes (k )] = _to_bytes (v )
475
- except UnicodeEncodeError :
476
- raise NonAsciiHeaderError (k , ': ' , v )
477
- return clean
478
-
479
-
480
440
def _update_query_params (uri , params ):
481
441
"""Updates a URI with new query parameters.
482
442
@@ -494,26 +454,6 @@ def _update_query_params(uri, params):
494
454
return urllib .parse .urlunparse (new_parts )
495
455
496
456
497
- def _initialize_headers (headers ):
498
- """Creates a copy of the headers."""
499
- if headers is None :
500
- headers = {}
501
- else :
502
- headers = dict (headers )
503
- return headers
504
-
505
-
506
- def _apply_user_agent (headers , user_agent ):
507
- """Adds a user-agent to the headers."""
508
- if user_agent is not None :
509
- if 'user-agent' in headers :
510
- headers ['user-agent' ] = (user_agent + ' ' + headers ['user-agent' ])
511
- else :
512
- headers ['user-agent' ] = user_agent
513
-
514
- return headers
515
-
516
-
517
457
class OAuth2Credentials (Credentials ):
518
458
"""Credentials object for OAuth 2.0.
519
459
@@ -604,58 +544,7 @@ def authorize(self, http):
604
544
that adds in the Authorization header and then calls the original
605
545
version of 'request()'.
606
546
"""
607
- request_orig = http .request
608
-
609
- # The closure that will replace 'httplib2.Http.request'.
610
- def new_request (uri , method = 'GET' , body = None , headers = None ,
611
- redirections = httplib2 .DEFAULT_MAX_REDIRECTS ,
612
- connection_type = None ):
613
- if not self .access_token :
614
- logger .info ('Attempting refresh to obtain '
615
- 'initial access_token' )
616
- self ._refresh (request_orig )
617
-
618
- # Clone and modify the request headers to add the appropriate
619
- # Authorization header.
620
- headers = _initialize_headers (headers )
621
- self .apply (headers )
622
- _apply_user_agent (headers , self .user_agent )
623
-
624
- body_stream_position = None
625
- if all (getattr (body , stream_prop , None ) for stream_prop in
626
- ('read' , 'seek' , 'tell' )):
627
- body_stream_position = body .tell ()
628
-
629
- resp , content = request_orig (uri , method , body ,
630
- clean_headers (headers ),
631
- redirections , connection_type )
632
-
633
- # A stored token may expire between the time it is retrieved and
634
- # the time the request is made, so we may need to try twice.
635
- max_refresh_attempts = 2
636
- for refresh_attempt in range (max_refresh_attempts ):
637
- if resp .status not in REFRESH_STATUS_CODES :
638
- break
639
- logger .info ('Refreshing due to a %s (attempt %s/%s)' ,
640
- resp .status , refresh_attempt + 1 ,
641
- max_refresh_attempts )
642
- self ._refresh (request_orig )
643
- self .apply (headers )
644
- if body_stream_position is not None :
645
- body .seek (body_stream_position )
646
-
647
- resp , content = request_orig (uri , method , body ,
648
- clean_headers (headers ),
649
- redirections , connection_type )
650
-
651
- return (resp , content )
652
-
653
- # Replace the request method with our own closure.
654
- http .request = new_request
655
-
656
- # Set credentials as a property of the request method.
657
- setattr (http .request , 'credentials' , self )
658
-
547
+ transport .wrap_http_for_auth (self , http )
659
548
return http
660
549
661
550
def refresh (self , http ):
@@ -781,7 +670,7 @@ def get_access_token(self, http=None):
781
670
"""
782
671
if not self .access_token or self .access_token_expired :
783
672
if not http :
784
- http = httplib2 . Http ()
673
+ http = transport . get_http_object ()
785
674
self .refresh (http )
786
675
return AccessTokenInfo (access_token = self .access_token ,
787
676
expires_in = self ._expires_in ())
@@ -1654,11 +1543,6 @@ def _require_crypto_or_die():
1654
1543
raise CryptoUnavailableError ('No crypto library available' )
1655
1544
1656
1545
1657
- # Only used in verify_id_token(), which is always calling to the same URI
1658
- # for the certs.
1659
- _cached_http = httplib2 .Http (MemoryCache ())
1660
-
1661
-
1662
1546
@util .positional (2 )
1663
1547
def verify_id_token (id_token , audience , http = None ,
1664
1548
cert_uri = ID_TOKEN_VERIFICATION_CERTS ):
@@ -1684,7 +1568,7 @@ def verify_id_token(id_token, audience, http=None,
1684
1568
"""
1685
1569
_require_crypto_or_die ()
1686
1570
if http is None :
1687
- http = _cached_http
1571
+ http = transport . get_cached_http ()
1688
1572
1689
1573
resp , content = http .request (cert_uri )
1690
1574
if resp .status == http_client .OK :
@@ -2027,7 +1911,7 @@ def step1_get_device_and_user_codes(self, http=None):
2027
1911
headers ['user-agent' ] = self .user_agent
2028
1912
2029
1913
if http is None :
2030
- http = httplib2 . Http ()
1914
+ http = transport . get_http_object ()
2031
1915
2032
1916
resp , content = http .request (self .device_uri , method = 'POST' , body = body ,
2033
1917
headers = headers )
@@ -2110,7 +1994,7 @@ def step2_exchange(self, code=None, http=None, device_flow_info=None):
2110
1994
headers ['user-agent' ] = self .user_agent
2111
1995
2112
1996
if http is None :
2113
- http = httplib2 . Http ()
1997
+ http = transport . get_http_object ()
2114
1998
2115
1999
resp , content = http .request (self .token_uri , method = 'POST' , body = body ,
2116
2000
headers = headers )
0 commit comments