diff 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
line wrap: on
line diff
--- a/mercurial/url.py	Thu Mar 09 22:35:10 2017 -0800
+++ b/mercurial/url.py	Thu Mar 09 22:40:52 2017 -0800
@@ -417,6 +417,35 @@
         else:
             return None
 
+class cookiehandler(urlreq.basehandler):
+    def __init__(self, ui):
+        self.cookiejar = None
+
+        cookiefile = ui.config('auth', 'cookiefile')
+        if not cookiefile:
+            return
+
+        cookiefile = util.expandpath(cookiefile)
+        try:
+            cookiejar = util.cookielib.MozillaCookieJar(cookiefile)
+            cookiejar.load()
+            self.cookiejar = cookiejar
+        except util.cookielib.LoadError as e:
+            ui.warn(_('(error loading cookie file %s: %s; continuing without '
+                      'cookies)\n') % (cookiefile, str(e)))
+
+    def http_request(self, request):
+        if self.cookiejar:
+            self.cookiejar.add_cookie_header(request)
+
+        return request
+
+    def https_request(self, request):
+        if self.cookiejar:
+            self.cookiejar.add_cookie_header(request)
+
+        return request
+
 handlerfuncs = []
 
 def opener(ui, authinfo=None):
@@ -450,6 +479,7 @@
     handlers.extend((httpbasicauthhandler(passmgr),
                      httpdigestauthhandler(passmgr)))
     handlers.extend([h(ui, passmgr) for h in handlerfuncs])
+    handlers.append(cookiehandler(ui))
     opener = urlreq.buildopener(*handlers)
 
     # The user agent should should *NOT* be used by servers for e.g.