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.