Mercurial > repos > guerler > hhblits
comparison lib/python3.8/site-packages/pip/_vendor/cachecontrol/adapter.py @ 0:9e54283cc701 draft
"planemo upload commit d12c32a45bcd441307e632fca6d9af7d60289d44"
author | guerler |
---|---|
date | Mon, 27 Jul 2020 03:47:31 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:9e54283cc701 |
---|---|
1 import types | |
2 import functools | |
3 import zlib | |
4 | |
5 from pip._vendor.requests.adapters import HTTPAdapter | |
6 | |
7 from .controller import CacheController | |
8 from .cache import DictCache | |
9 from .filewrapper import CallbackFileWrapper | |
10 | |
11 | |
12 class CacheControlAdapter(HTTPAdapter): | |
13 invalidating_methods = {"PUT", "DELETE"} | |
14 | |
15 def __init__( | |
16 self, | |
17 cache=None, | |
18 cache_etags=True, | |
19 controller_class=None, | |
20 serializer=None, | |
21 heuristic=None, | |
22 cacheable_methods=None, | |
23 *args, | |
24 **kw | |
25 ): | |
26 super(CacheControlAdapter, self).__init__(*args, **kw) | |
27 self.cache = DictCache() if cache is None else cache | |
28 self.heuristic = heuristic | |
29 self.cacheable_methods = cacheable_methods or ("GET",) | |
30 | |
31 controller_factory = controller_class or CacheController | |
32 self.controller = controller_factory( | |
33 self.cache, cache_etags=cache_etags, serializer=serializer | |
34 ) | |
35 | |
36 def send(self, request, cacheable_methods=None, **kw): | |
37 """ | |
38 Send a request. Use the request information to see if it | |
39 exists in the cache and cache the response if we need to and can. | |
40 """ | |
41 cacheable = cacheable_methods or self.cacheable_methods | |
42 if request.method in cacheable: | |
43 try: | |
44 cached_response = self.controller.cached_request(request) | |
45 except zlib.error: | |
46 cached_response = None | |
47 if cached_response: | |
48 return self.build_response(request, cached_response, from_cache=True) | |
49 | |
50 # check for etags and add headers if appropriate | |
51 request.headers.update(self.controller.conditional_headers(request)) | |
52 | |
53 resp = super(CacheControlAdapter, self).send(request, **kw) | |
54 | |
55 return resp | |
56 | |
57 def build_response( | |
58 self, request, response, from_cache=False, cacheable_methods=None | |
59 ): | |
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, request, response | |
105 ), | |
106 ) | |
107 if response.chunked: | |
108 super_update_chunk_length = response._update_chunk_length | |
109 | |
110 def _update_chunk_length(self): | |
111 super_update_chunk_length() | |
112 if self.chunk_left == 0: | |
113 self._fp._close() | |
114 | |
115 response._update_chunk_length = types.MethodType( | |
116 _update_chunk_length, response | |
117 ) | |
118 | |
119 resp = super(CacheControlAdapter, self).build_response(request, response) | |
120 | |
121 # See if we should invalidate the cache. | |
122 if request.method in self.invalidating_methods and resp.ok: | |
123 cache_url = self.controller.cache_url(request.url) | |
124 self.cache.delete(cache_url) | |
125 | |
126 # Give the request a from_cache attr to let people use it | |
127 resp.from_cache = from_cache | |
128 | |
129 return resp | |
130 | |
131 def close(self): | |
132 self.cache.close() | |
133 super(CacheControlAdapter, self).close() |