summaryrefslogtreecommitdiff
path: root/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py')
-rw-r--r--venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py
new file mode 100644
index 0000000..03c95c9
--- /dev/null
+++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py
@@ -0,0 +1,134 @@
1import types
2import functools
3import zlib
4
5from pip._vendor.requests.adapters import HTTPAdapter
6
7from .controller import CacheController
8from .cache import DictCache
9from .filewrapper import CallbackFileWrapper
10
11
12class CacheControlAdapter(HTTPAdapter):
13 invalidating_methods = set(['PUT', 'DELETE'])
14
15 def __init__(self, cache=None,
16 cache_etags=True,
17 controller_class=None,
18 serializer=None,
19 heuristic=None,
20 cacheable_methods=None,
21 *args, **kw):
22 super(CacheControlAdapter, self).__init__(*args, **kw)
23 self.cache = cache or DictCache()
24 self.heuristic = heuristic
25 self.cacheable_methods = cacheable_methods or ('GET',)
26
27 controller_factory = controller_class or CacheController
28 self.controller = controller_factory(
29 self.cache,
30 cache_etags=cache_etags,
31 serializer=serializer,
32 )
33
34 def send(self, request, cacheable_methods=None, **kw):
35 """
36 Send a request. Use the request information to see if it
37 exists in the cache and cache the response if we need to and can.
38 """
39 cacheable = cacheable_methods or self.cacheable_methods
40 if request.method in cacheable:
41 try:
42 cached_response = self.controller.cached_request(request)
43 except zlib.error:
44 cached_response = None
45 if cached_response:
46 return self.build_response(request, cached_response,
47 from_cache=True)
48
49 # check for etags and add headers if appropriate
50 request.headers.update(
51 self.controller.conditional_headers(request)
52 )
53
54 resp = super(CacheControlAdapter, self).send(request, **kw)
55
56 return resp
57
58 def build_response(self, request, response, from_cache=False,
59 cacheable_methods=None):
60 """
61 Build a response by making a request or using the cache.
62
63 This will end up calling send and returning a potentially
64 cached response
65 """
66 cacheable = cacheable_methods or self.cacheable_methods
67 if not from_cache and request.method in cacheable:
68 # Check for any heuristics that might update headers
69 # before trying to cache.
70 if self.heuristic:
71 response = self.heuristic.apply(response)
72
73 # apply any expiration heuristics
74 if response.status == 304:
75 # We must have sent an ETag request. This could mean
76 # that we've been expired already or that we simply
77 # have an etag. In either case, we want to try and
78 # update the cache if that is the case.
79 cached_response = self.controller.update_cached_response(
80 request, response
81 )
82
83 if cached_response is not response:
84 from_cache = True
85
86 # We are done with the server response, read a
87 # possible response body (compliant servers will
88 # not return one, but we cannot be 100% sure) and
89 # release the connection back to the pool.
90 response.read(decode_content=False)
91 response.release_conn()
92
93 response = cached_response
94
95 # We always cache the 301 responses
96 elif response.status == 301:
97 self.controller.cache_response(request, response)
98 else:
99 # Wrap the response file with a wrapper that will cache the
100 # response when the stream has been consumed.
101 response._fp = CallbackFileWrapper(
102 response._fp,
103 functools.partial(
104 self.controller.cache_response,
105 request,
106 response,
107 )
108 )
109 if response.chunked:
110 super_update_chunk_length = response._update_chunk_length
111
112 def _update_chunk_length(self):
113 super_update_chunk_length()
114 if self.chunk_left == 0:
115 self._fp._close()
116 response._update_chunk_length = types.MethodType(_update_chunk_length, response)
117
118 resp = super(CacheControlAdapter, self).build_response(
119 request, response
120 )
121
122 # See if we should invalidate the cache.
123 if request.method in self.invalidating_methods and resp.ok:
124 cache_url = self.controller.cache_url(request.url)
125 self.cache.delete(cache_url)
126
127 # Give the request a from_cache attr to let people use it
128 resp.from_cache = from_cache
129
130 return resp
131
132 def close(self):
133 self.cache.close()
134 super(CacheControlAdapter, self).close()