1 # Copyright 2015 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.
7 from environment
import GetAppVersion
8 from future
import Future
9 from urllib
import urlencode
10 from urlparse
import urlparse
, parse_qs
12 def _MakeHeaders(headers
={}):
13 headers
['User-Agent'] = 'Chromium-Docserver/%s' % GetAppVersion()
14 headers
['Cache-Control'] = 'max-age=0'
18 def _AddQueryToUrl(url
, new_query
):
19 """Adds query paramters to a URL. This merges the given set of query params
20 with any that were already a part of the URL.
22 parsed_url
= urlparse(url
)
23 query
= parse_qs(parsed_url
.query
)
24 query
.update(new_query
)
25 query_string
= urlencode(query
, True)
26 return '%s://%s%s?%s#%s' % (parsed_url
.scheme
, parsed_url
.netloc
,
27 parsed_url
.path
, query_string
, parsed_url
.fragment
)
30 class UrlFetcher(object):
32 self
._base
_path
= None
34 def SetBasePath(self
, base_path
):
35 assert base_path
is None or not base_path
.endswith('/'), base_path
36 self
._base
_path
= base_path
38 def Fetch(self
, url
, headers
={}, query
={}):
39 return self
.FetchImpl(_AddQueryToUrl(self
._FromBasePath
(url
), query
),
40 _MakeHeaders(headers
))
42 def FetchAsync(self
, url
, headers
={}, query
={}):
43 return self
.FetchAsyncImpl(_AddQueryToUrl(self
._FromBasePath
(url
), query
),
44 _MakeHeaders(headers
))
46 def FetchImpl(self
, url
, headers
):
47 """Fetches a URL synchronously.
49 raise NotImplementedError(self
.__class
__)
51 def FetchAsyncImpl(self
, url
, headers
):
52 """Fetches a URL asynchronously and returns a Future with the result.
54 raise NotImplementedError(self
.__class
__)
56 def _FromBasePath(self
, url
):
57 assert not url
.startswith('/'), url
58 if self
._base
_path
is not None:
59 url
= posixpath
.join(self
._base
_path
, url
) if url
else self
._base
_path