Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Unified Diff: third_party/gsutil/oauth2_plugin/oauth2_client.py

Issue 10199002: Upgrade gsutil to 3.4 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/gsutil/oauth2_plugin/oauth2_client.py
diff --git a/third_party/gsutil/20110627/oauth2_plugin/oauth2_client.py b/third_party/gsutil/oauth2_plugin/oauth2_client.py
similarity index 93%
rename from third_party/gsutil/20110627/oauth2_plugin/oauth2_client.py
rename to third_party/gsutil/oauth2_plugin/oauth2_client.py
index c83a40e26871df136f99f59801ac470c32c1bac0..4ba2cfff3fb8702fa65dd8ef1a9a5090fdec8828 100644
--- a/third_party/gsutil/20110627/oauth2_plugin/oauth2_client.py
+++ b/third_party/gsutil/oauth2_plugin/oauth2_client.py
@@ -42,6 +42,7 @@ from hashlib import sha1
import logging
import os
import tempfile
+import threading
import urllib
import urllib2
import urlparse
@@ -60,6 +61,9 @@ except ImportError:
import simplejson as json
LOG = logging.getLogger('oauth2_client')
+# Lock used for checking/exchanging refresh token, so multithreaded
+# operation doesn't attempt concurrent refreshes.
+token_exchange_lock = threading.Lock()
# SHA1 sum of the CA certificates file imported from boto.
CACERTS_FILE_SHA1SUM = 'ed024a78d9327f8669b3b117d9eac9e3c9460e9b'
@@ -365,16 +369,24 @@ class OAuth2Client(object):
Raises:
AccessTokenRefreshError if an error occurs.
"""
- cache_key = refresh_token.CacheKey()
- LOG.info('GetAccessToken: checking cache for key %s', cache_key)
- access_token = self.access_token_cache.GetToken(cache_key)
- LOG.debug('GetAccessToken: token from cache: %s', access_token)
- if access_token is None or access_token.ShouldRefresh():
- LOG.info('GetAccessToken: fetching fresh access token...')
- access_token = self.FetchAccessToken(refresh_token)
- LOG.debug('GetAccessToken: fresh access token: %s', access_token)
- self.access_token_cache.PutToken(cache_key, access_token)
- return access_token
+ # Ensure only one thread at a time attempts to get (and possibly refresh)
+ # the access token. This doesn't prevent concurrent refresh attempts across
+ # multiple gsutil instances, but at least protects against multiple threads
+ # simultaneously attempting to refresh when gsutil -m is used.
+ token_exchange_lock.acquire()
+ try:
+ cache_key = refresh_token.CacheKey()
+ LOG.info('GetAccessToken: checking cache for key %s', cache_key)
+ access_token = self.access_token_cache.GetToken(cache_key)
+ LOG.debug('GetAccessToken: token from cache: %s', access_token)
+ if access_token is None or access_token.ShouldRefresh():
+ LOG.info('GetAccessToken: fetching fresh access token...')
+ access_token = self.FetchAccessToken(refresh_token)
+ LOG.debug('GetAccessToken: fresh access token: %s', access_token)
+ self.access_token_cache.PutToken(cache_key, access_token)
+ return access_token
+ finally:
+ token_exchange_lock.release()
def FetchAccessToken(self, refresh_token):
"""Fetches an access token from the provider's token endpoint.
@@ -404,14 +416,14 @@ class OAuth2Client(object):
if error:
oauth2_error = ''
if response and response['error']:
- oauth2_error = '; OAuth2 error: %s', response['error']
+ oauth2_error = '; OAuth2 error: %s' % response['error']
raise AccessTokenRefreshError(
'Failed to exchange refresh token into access token; '
- 'request failed: %s%s', error, oauth2_error)
+ 'request failed: %s%s' % (error, oauth2_error))
if 'access_token' not in response:
raise AccessTokenRefreshError(
- 'Failed to exchange refresh token into access token; response: %s',
+ 'Failed to exchange refresh token into access token; response: %s' %
response)
token_expiry = None
@@ -502,15 +514,15 @@ class OAuth2Client(object):
if error:
oauth2_error = ''
if response and response['error']:
- oauth2_error = '; OAuth2 error: %s', response['error']
+ oauth2_error = '; OAuth2 error: %s' % response['error']
raise AuthorizationCodeExchangeError(
'Failed to exchange refresh token into access token; '
- 'request failed: %s%s', error, oauth2_error)
+ 'request failed: %s%s' % (str(error), oauth2_error))
if not 'access_token' in response:
raise AuthorizationCodeExchangeError(
'Failed to exchange authorization code into access token; '
- 'response: %s', response)
+ 'response: %s' % response)
token_expiry = None
if 'expires_in' in response:
@@ -623,4 +635,4 @@ class RefreshToken(object):
The value of an Authorization HTTP header that authenticates
requests with an OAuth2 access token based on this refresh token.
"""
- return 'OAuth %s' % self.oauth2_client.GetAccessToken(self).token
+ return 'Bearer %s' % self.oauth2_client.GetAccessToken(self).token
« no previous file with comments | « third_party/gsutil/oauth2_plugin/__init__.py ('k') | third_party/gsutil/oauth2_plugin/oauth2_client_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698