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
3 # found in the LICENSE file.
8 from appengine_wrappers import GetAppVersion, urlfetch
9 from future import Future
12 class _AsyncFetchDelegate(object):
13 def __init__(self, rpc):
17 return self._rpc.get_result()
20 def _MakeHeaders(username, password):
22 'User-Agent': 'Chromium docserver %s' % GetAppVersion(),
23 'Cache-Control': 'max-age=0',
25 if username is not None and password is not None:
26 headers['Authorization'] = 'Basic %s' % base64.b64encode(
27 '%s:%s' % (username, password))
31 class AppEngineUrlFetcher(object):
32 """A wrapper around the App Engine urlfetch module that allows for easy
35 def __init__(self, base_path=None):
36 assert base_path is None or not base_path.endswith('/'), base_path
37 self._base_path = base_path
39 def Fetch(self, url, username=None, password=None):
40 """Fetches a file synchronously.
42 return urlfetch.fetch(self._FromBasePath(url),
43 headers=_MakeHeaders(username, password))
45 def FetchAsync(self, url, username=None, password=None):
46 """Fetches a file asynchronously, and returns a Future with the result.
48 rpc = urlfetch.create_rpc()
49 urlfetch.make_fetch_call(rpc,
50 self._FromBasePath(url),
51 headers=_MakeHeaders(username, password))
52 return Future(delegate=_AsyncFetchDelegate(rpc))
54 def _FromBasePath(self, url):
55 assert not url.startswith('/'), url
56 if self._base_path is not None:
57 url = posixpath.join(self._base_path, url) if url else self._base_path