Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: swarm_client/third_party/requests/cookies.py

Issue 69143004: Delete swarm_client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- coding: utf-8 -*-
2
3 """
4 Compatibility code to be able to use `cookielib.CookieJar` with requests.
5
6 requests.utils imports from here, so be careful with imports.
7 """
8
9 import time
10 import collections
11 from .compat import cookielib, urlparse, Morsel
12
13 try:
14 import threading
15 # grr, pyflakes: this fixes "redefinition of unused 'threading'"
16 threading
17 except ImportError:
18 import dummy_threading as threading
19
20
21 class MockRequest(object):
22 """Wraps a `requests.Request` to mimic a `urllib2.Request`.
23
24 The code in `cookielib.CookieJar` expects this interface in order to correct ly
25 manage cookie policies, i.e., determine whether a cookie can be set, given t he
26 domains of the request and the cookie.
27
28 The original request object is read-only. The client is responsible for coll ecting
29 the new headers via `get_new_headers()` and interpreting them appropriately. You
30 probably want `get_cookie_header`, defined below.
31 """
32
33 def __init__(self, request):
34 self._r = request
35 self._new_headers = {}
36 self.type = urlparse(self._r.url).scheme
37
38 def get_type(self):
39 return self.type
40
41 def get_host(self):
42 return urlparse(self._r.url).netloc
43
44 def get_origin_req_host(self):
45 return self.get_host()
46
47 def get_full_url(self):
48 return self._r.url
49
50 def is_unverifiable(self):
51 return True
52
53 def has_header(self, name):
54 return name in self._r.headers or name in self._new_headers
55
56 def get_header(self, name, default=None):
57 return self._r.headers.get(name, self._new_headers.get(name, default))
58
59 def add_header(self, key, val):
60 """cookielib has no legitimate use for this method; add it back if you f ind one."""
61 raise NotImplementedError("Cookie headers should be added with add_unred irected_header()")
62
63 def add_unredirected_header(self, name, value):
64 self._new_headers[name] = value
65
66 def get_new_headers(self):
67 return self._new_headers
68
69 @property
70 def unverifiable(self):
71 return self.is_unverifiable()
72
73 @property
74 def origin_req_host(self):
75 return self.get_origin_req_host()
76
77 @property
78 def host(self):
79 return self.get_host()
80
81
82 class MockResponse(object):
83 """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
84
85 ...what? Basically, expose the parsed HTTP headers from the server response
86 the way `cookielib` expects to see them.
87 """
88
89 def __init__(self, headers):
90 """Make a MockResponse for `cookielib` to read.
91
92 :param headers: a httplib.HTTPMessage or analogous carrying the headers
93 """
94 self._headers = headers
95
96 def info(self):
97 return self._headers
98
99 def getheaders(self, name):
100 self._headers.getheaders(name)
101
102
103 def extract_cookies_to_jar(jar, request, response):
104 """Extract the cookies from the response into a CookieJar.
105
106 :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar)
107 :param request: our own requests.Request object
108 :param response: urllib3.HTTPResponse object
109 """
110 if not (hasattr(response, '_original_response') and
111 response._original_response):
112 return
113 # the _original_response field is the wrapped httplib.HTTPResponse object,
114 req = MockRequest(request)
115 # pull out the HTTPMessage with the headers and put it in the mock:
116 res = MockResponse(response._original_response.msg)
117 jar.extract_cookies(res, req)
118
119
120 def get_cookie_header(jar, request):
121 """Produce an appropriate Cookie header string to be sent with `request`, or None."""
122 r = MockRequest(request)
123 jar.add_cookie_header(r)
124 return r.get_new_headers().get('Cookie')
125
126
127 def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
128 """Unsets a cookie by name, by default over all domains and paths.
129
130 Wraps CookieJar.clear(), is O(n).
131 """
132 clearables = []
133 for cookie in cookiejar:
134 if cookie.name == name:
135 if domain is None or domain == cookie.domain:
136 if path is None or path == cookie.path:
137 clearables.append((cookie.domain, cookie.path, cookie.name))
138
139 for domain, path, name in clearables:
140 cookiejar.clear(domain, path, name)
141
142
143 class CookieConflictError(RuntimeError):
144 """There are two cookies that meet the criteria specified in the cookie jar.
145 Use .get and .set and include domain and path args in order to be more speci fic."""
146
147
148 class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
149 """Compatibility class; is a cookielib.CookieJar, but exposes a dict interfa ce.
150
151 This is the CookieJar we create by default for requests and sessions that
152 don't specify one, since some clients may expect response.cookies and
153 session.cookies to support dict operations.
154
155 Don't use the dict interface internally; it's just for compatibility with
156 with external client code. All `requests` code should work out of the box
157 with externally provided instances of CookieJar, e.g., LWPCookieJar and
158 FileCookieJar.
159
160 Caution: dictionary operations that are normally O(1) may be O(n).
161
162 Unlike a regular CookieJar, this class is pickleable.
163 """
164
165 def get(self, name, default=None, domain=None, path=None):
166 """Dict-like get() that also supports optional domain and path args in
167 order to resolve naming collisions from using one cookie jar over
168 multiple domains. Caution: operation is O(n), not O(1)."""
169 try:
170 return self._find_no_duplicates(name, domain, path)
171 except KeyError:
172 return default
173
174 def set(self, name, value, **kwargs):
175 """Dict-like set() that also supports optional domain and path args in
176 order to resolve naming collisions from using one cookie jar over
177 multiple domains."""
178 # support client code that unsets cookies by assignment of a None value:
179 if value is None:
180 remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path= kwargs.get('path'))
181 return
182
183 if isinstance(value, Morsel):
184 c = morsel_to_cookie(value)
185 else:
186 c = create_cookie(name, value, **kwargs)
187 self.set_cookie(c)
188 return c
189
190 def keys(self):
191 """Dict-like keys() that returns a list of names of cookies from the jar .
192 See values() and items()."""
193 keys = []
194 for cookie in iter(self):
195 keys.append(cookie.name)
196 return keys
197
198 def values(self):
199 """Dict-like values() that returns a list of values of cookies from the jar.
200 See keys() and items()."""
201 values = []
202 for cookie in iter(self):
203 values.append(cookie.value)
204 return values
205
206 def items(self):
207 """Dict-like items() that returns a list of name-value tuples from the j ar.
208 See keys() and values(). Allows client-code to call "dict(RequestsCookie Jar)
209 and get a vanilla python dict of key value pairs."""
210 items = []
211 for cookie in iter(self):
212 items.append((cookie.name, cookie.value))
213 return items
214
215 def list_domains(self):
216 """Utility method to list all the domains in the jar."""
217 domains = []
218 for cookie in iter(self):
219 if cookie.domain not in domains:
220 domains.append(cookie.domain)
221 return domains
222
223 def list_paths(self):
224 """Utility method to list all the paths in the jar."""
225 paths = []
226 for cookie in iter(self):
227 if cookie.path not in paths:
228 paths.append(cookie.path)
229 return paths
230
231 def multiple_domains(self):
232 """Returns True if there are multiple domains in the jar.
233 Returns False otherwise."""
234 domains = []
235 for cookie in iter(self):
236 if cookie.domain is not None and cookie.domain in domains:
237 return True
238 domains.append(cookie.domain)
239 return False # there is only one domain in jar
240
241 def get_dict(self, domain=None, path=None):
242 """Takes as an argument an optional domain and path and returns a plain old
243 Python dict of name-value pairs of cookies that meet the requirements."" "
244 dictionary = {}
245 for cookie in iter(self):
246 if (domain is None or cookie.domain == domain) and (path is None
247 or cookie.path == path):
248 dictionary[cookie.name] = cookie.value
249 return dictionary
250
251 def __getitem__(self, name):
252 """Dict-like __getitem__() for compatibility with client code. Throws ex ception
253 if there are more than one cookie with name. In that case, use the more
254 explicit get() method instead. Caution: operation is O(n), not O(1)."""
255
256 return self._find_no_duplicates(name)
257
258 def __setitem__(self, name, value):
259 """Dict-like __setitem__ for compatibility with client code. Throws exce ption
260 if there is already a cookie of that name in the jar. In that case, use the more
261 explicit set() method instead."""
262
263 self.set(name, value)
264
265 def __delitem__(self, name):
266 """Deletes a cookie given a name. Wraps cookielib.CookieJar's remove_coo kie_by_name()."""
267 remove_cookie_by_name(self, name)
268
269 def set_cookie(self, cookie, *args, **kwargs):
270 if cookie.value.startswith('"') and cookie.value.endswith('"'):
271 cookie.value = cookie.value.replace('\\"', '')
272 return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs )
273
274 def update(self, other):
275 """Updates this jar with cookies from another CookieJar or dict-like"""
276 if isinstance(other, cookielib.CookieJar):
277 for cookie in other:
278 self.set_cookie(cookie)
279 else:
280 super(RequestsCookieJar, self).update(other)
281
282 def _find(self, name, domain=None, path=None):
283 """Requests uses this method internally to get cookie values. Takes as a rgs name
284 and optional domain and path. Returns a cookie.value. If there are confl icting cookies,
285 _find arbitrarily chooses one. See _find_no_duplicates if you want an ex ception thrown
286 if there are conflicting cookies."""
287 for cookie in iter(self):
288 if cookie.name == name:
289 if domain is None or cookie.domain == domain:
290 if path is None or cookie.path == path:
291 return cookie.value
292
293 raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
294
295 def _find_no_duplicates(self, name, domain=None, path=None):
296 """__get_item__ and get call _find_no_duplicates -- never used in Reques ts internally.
297 Takes as args name and optional domain and path. Returns a cookie.value.
298 Throws KeyError if cookie is not found and CookieConflictError if there are
299 multiple cookies that match name and optionally domain and path."""
300 toReturn = None
301 for cookie in iter(self):
302 if cookie.name == name:
303 if domain is None or cookie.domain == domain:
304 if path is None or cookie.path == path:
305 if toReturn is not None: # if there are multiple cookie s that meet passed in criteria
306 raise CookieConflictError('There are multiple cookie s with name, %r' % (name))
307 toReturn = cookie.value # we will eventually return thi s as long as no cookie conflict
308
309 if toReturn:
310 return toReturn
311 raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
312
313 def __getstate__(self):
314 """Unlike a normal CookieJar, this class is pickleable."""
315 state = self.__dict__.copy()
316 # remove the unpickleable RLock object
317 state.pop('_cookies_lock')
318 return state
319
320 def __setstate__(self, state):
321 """Unlike a normal CookieJar, this class is pickleable."""
322 self.__dict__.update(state)
323 if '_cookies_lock' not in self.__dict__:
324 self._cookies_lock = threading.RLock()
325
326 def copy(self):
327 """Return a copy of this RequestsCookieJar."""
328 new_cj = RequestsCookieJar()
329 new_cj.update(self)
330 return new_cj
331
332
333 def create_cookie(name, value, **kwargs):
334 """Make a cookie from underspecified parameters.
335
336 By default, the pair of `name` and `value` will be set for the domain ''
337 and sent on every request (this is sometimes called a "supercookie").
338 """
339 result = dict(
340 version=0,
341 name=name,
342 value=value,
343 port=None,
344 domain='',
345 path='/',
346 secure=False,
347 expires=None,
348 discard=True,
349 comment=None,
350 comment_url=None,
351 rest={'HttpOnly': None},
352 rfc2109=False,)
353
354 badargs = set(kwargs) - set(result)
355 if badargs:
356 err = 'create_cookie() got unexpected keyword arguments: %s'
357 raise TypeError(err % list(badargs))
358
359 result.update(kwargs)
360 result['port_specified'] = bool(result['port'])
361 result['domain_specified'] = bool(result['domain'])
362 result['domain_initial_dot'] = result['domain'].startswith('.')
363 result['path_specified'] = bool(result['path'])
364
365 return cookielib.Cookie(**result)
366
367
368 def morsel_to_cookie(morsel):
369 """Convert a Morsel object into a Cookie containing the one k/v pair."""
370 expires = None
371 if morsel["max-age"]:
372 expires = time.time() + morsel["max-age"]
373 elif morsel['expires']:
374 expires = morsel['expires']
375 if type(expires) == type(""):
376 time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
377 expires = time.mktime(time.strptime(expires, time_template))
378 c = create_cookie(
379 name=morsel.key,
380 value=morsel.value,
381 version=morsel['version'] or 0,
382 port=None,
383 domain=morsel['domain'],
384 path=morsel['path'],
385 secure=bool(morsel['secure']),
386 expires=expires,
387 discard=False,
388 comment=morsel['comment'],
389 comment_url=bool(morsel['comment']),
390 rest={'HttpOnly': morsel['httponly']},
391 rfc2109=False,)
392 return c
393
394
395 def cookiejar_from_dict(cookie_dict, cookiejar=None):
396 """Returns a CookieJar from a key/value dictionary.
397
398 :param cookie_dict: Dict of key/values to insert into CookieJar.
399 """
400 if cookiejar is None:
401 cookiejar = RequestsCookieJar()
402
403 if cookie_dict is not None:
404 for name in cookie_dict:
405 cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
406 return cookiejar
OLDNEW
« no previous file with comments | « swarm_client/third_party/requests/compat.py ('k') | swarm_client/third_party/requests/exceptions.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698