Mercurial > hg
comparison mercurial/url.py @ 31936:806f9a883b4f
url: support auth.cookiesfile for adding cookies to HTTP requests
Mercurial can't currently send cookies as part of HTTP requests.
Some authentication systems use cookies. So, it seems like adding
support for sending cookies seems like a useful feature.
This patch implements support for reading cookies from a file
and automatically sending them as part of the request. We rely
on the "cookiejar" Python module to do the heavy lifting of
parsing cookies files. We currently only support the Mozilla
(really Netscape-era) cookie format. There is another format
supported by cookielib and we may want to consider using that,
especially since the Netscape cookie parser can't parse ports.
It wasn't immediately obvious to me what the format of the other
parser is, so I didn't know how to test it. I /think/ it might
be literal "Cookie" header values, but I'm not sure. If it is
more robust than the Netscape format, we may want to just
support it.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 09 Mar 2017 22:40:52 -0800 |
parents | 6a70cf94d1b5 |
children | 0407a51b9d8c |
comparison
equal
deleted
inserted
replaced
31935:566cb89050b7 | 31936:806f9a883b4f |
---|---|
414 self.auth = auth | 414 self.auth = auth |
415 req.add_unredirected_header(self.auth_header, auth) | 415 req.add_unredirected_header(self.auth_header, auth) |
416 return self.parent.open(req) | 416 return self.parent.open(req) |
417 else: | 417 else: |
418 return None | 418 return None |
419 | |
420 class cookiehandler(urlreq.basehandler): | |
421 def __init__(self, ui): | |
422 self.cookiejar = None | |
423 | |
424 cookiefile = ui.config('auth', 'cookiefile') | |
425 if not cookiefile: | |
426 return | |
427 | |
428 cookiefile = util.expandpath(cookiefile) | |
429 try: | |
430 cookiejar = util.cookielib.MozillaCookieJar(cookiefile) | |
431 cookiejar.load() | |
432 self.cookiejar = cookiejar | |
433 except util.cookielib.LoadError as e: | |
434 ui.warn(_('(error loading cookie file %s: %s; continuing without ' | |
435 'cookies)\n') % (cookiefile, str(e))) | |
436 | |
437 def http_request(self, request): | |
438 if self.cookiejar: | |
439 self.cookiejar.add_cookie_header(request) | |
440 | |
441 return request | |
442 | |
443 def https_request(self, request): | |
444 if self.cookiejar: | |
445 self.cookiejar.add_cookie_header(request) | |
446 | |
447 return request | |
419 | 448 |
420 handlerfuncs = [] | 449 handlerfuncs = [] |
421 | 450 |
422 def opener(ui, authinfo=None): | 451 def opener(ui, authinfo=None): |
423 ''' | 452 ''' |
448 (user, passwd and '*' * len(passwd) or 'not set')) | 477 (user, passwd and '*' * len(passwd) or 'not set')) |
449 | 478 |
450 handlers.extend((httpbasicauthhandler(passmgr), | 479 handlers.extend((httpbasicauthhandler(passmgr), |
451 httpdigestauthhandler(passmgr))) | 480 httpdigestauthhandler(passmgr))) |
452 handlers.extend([h(ui, passmgr) for h in handlerfuncs]) | 481 handlers.extend([h(ui, passmgr) for h in handlerfuncs]) |
482 handlers.append(cookiehandler(ui)) | |
453 opener = urlreq.buildopener(*handlers) | 483 opener = urlreq.buildopener(*handlers) |
454 | 484 |
455 # The user agent should should *NOT* be used by servers for e.g. | 485 # The user agent should should *NOT* be used by servers for e.g. |
456 # protocol detection or feature negotiation: there are other | 486 # protocol detection or feature negotiation: there are other |
457 # facilities for that. | 487 # facilities for that. |