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('/')
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('/')
56 if self
._base
_path
is not None:
57 url
= posixpath
.join(self
._base
_path
, url
) if url
else self
._base
_path