| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import base64 | 5 import base64 |
| 6 import posixpath | 6 import posixpath |
| 7 | 7 |
| 8 from appengine_wrappers import urlfetch | 8 from appengine_wrappers import urlfetch |
| 9 from environment import GetAppVersion | 9 from environment import GetAppVersion |
| 10 from future import Future | 10 from future import Future |
| 11 | 11 |
| 12 | 12 |
| 13 def _MakeHeaders(username, password): | 13 def _MakeHeaders(username, password, access_token): |
| 14 headers = { | 14 headers = { |
| 15 'User-Agent': 'Chromium docserver %s' % GetAppVersion(), | 15 'User-Agent': 'Chromium docserver %s' % GetAppVersion(), |
| 16 'Cache-Control': 'max-age=0', | 16 'Cache-Control': 'max-age=0', |
| 17 } | 17 } |
| 18 if username is not None and password is not None: | 18 if username is not None and password is not None: |
| 19 headers['Authorization'] = 'Basic %s' % base64.b64encode( | 19 headers['Authorization'] = 'Basic %s' % base64.b64encode( |
| 20 '%s:%s' % (username, password)) | 20 '%s:%s' % (username, password)) |
| 21 if access_token is not None: |
| 22 headers['Authorization'] = 'OAuth %s' % access_token |
| 21 return headers | 23 return headers |
| 22 | 24 |
| 23 | 25 |
| 24 class AppEngineUrlFetcher(object): | 26 class AppEngineUrlFetcher(object): |
| 25 """A wrapper around the App Engine urlfetch module that allows for easy | 27 """A wrapper around the App Engine urlfetch module that allows for easy |
| 26 async fetches. | 28 async fetches. |
| 27 """ | 29 """ |
| 28 def __init__(self, base_path=None): | 30 def __init__(self, base_path=None): |
| 29 assert base_path is None or not base_path.endswith('/'), base_path | 31 assert base_path is None or not base_path.endswith('/'), base_path |
| 30 self._base_path = base_path | 32 self._base_path = base_path |
| 31 | 33 |
| 32 def Fetch(self, url, username=None, password=None): | 34 def Fetch(self, url, username=None, password=None, access_token=None): |
| 33 """Fetches a file synchronously. | 35 """Fetches a file synchronously. |
| 34 """ | 36 """ |
| 35 return urlfetch.fetch(self._FromBasePath(url), | 37 return urlfetch.fetch(self._FromBasePath(url), |
| 36 headers=_MakeHeaders(username, password)) | 38 deadline=20, |
| 39 headers=_MakeHeaders(username, |
| 40 password, |
| 41 access_token)) |
| 37 | 42 |
| 38 def FetchAsync(self, url, username=None, password=None): | 43 def FetchAsync(self, url, username=None, password=None, access_token=None): |
| 39 """Fetches a file asynchronously, and returns a Future with the result. | 44 """Fetches a file asynchronously, and returns a Future with the result. |
| 40 """ | 45 """ |
| 41 rpc = urlfetch.create_rpc() | 46 rpc = urlfetch.create_rpc(deadline=20) |
| 42 urlfetch.make_fetch_call(rpc, | 47 urlfetch.make_fetch_call(rpc, |
| 43 self._FromBasePath(url), | 48 self._FromBasePath(url), |
| 44 headers=_MakeHeaders(username, password)) | 49 headers=_MakeHeaders(username, |
| 50 password, |
| 51 access_token)) |
| 45 return Future(callback=lambda: rpc.get_result()) | 52 return Future(callback=lambda: rpc.get_result()) |
| 46 | 53 |
| 47 def _FromBasePath(self, url): | 54 def _FromBasePath(self, url): |
| 48 assert not url.startswith('/'), url | 55 assert not url.startswith('/'), url |
| 49 if self._base_path is not None: | 56 if self._base_path is not None: |
| 50 url = posixpath.join(self._base_path, url) if url else self._base_path | 57 url = posixpath.join(self._base_path, url) if url else self._base_path |
| 51 return url | 58 return url |
| OLD | NEW |