hgweb: parse and store HTTP request headers
WSGI transmits HTTP request headers as HTTP_* environment variables.
We teach our parser about these and hook up a dict-like data
structure that supports case insensitive header manipulation.
Differential Revision: https://phab.mercurial-scm.org/D2742
--- a/mercurial/hgweb/hgweb_mod.py Thu Mar 08 16:43:32 2018 -0800
+++ b/mercurial/hgweb/hgweb_mod.py Thu Mar 08 16:22:25 2018 -0800
@@ -351,7 +351,7 @@
if args:
wsgireq.form['file'] = args
- ua = wsgireq.env.get('HTTP_USER_AGENT', '')
+ ua = req.headers.get('User-Agent', '')
if cmd == 'rev' and 'mercurial' in ua:
wsgireq.form['style'] = ['raw']
--- a/mercurial/hgweb/request.py Thu Mar 08 16:43:32 2018 -0800
+++ b/mercurial/hgweb/request.py Thu Mar 08 16:22:25 2018 -0800
@@ -11,6 +11,7 @@
import cgi
import errno
import socket
+import wsgiref.headers as wsgiheaders
#import wsgiref.validate
from .common import (
@@ -85,6 +86,9 @@
querystringlist = attr.ib()
# Dict of query string arguments. Values are lists with at least 1 item.
querystringdict = attr.ib()
+ # wsgiref.headers.Headers instance. Operates like a dict with case
+ # insensitive keys.
+ headers = attr.ib()
def parserequestfromenv(env):
"""Parse URL components from environment variables.
@@ -186,6 +190,16 @@
else:
querystringdict[k] = [v]
+ # HTTP_* keys contain HTTP request headers. The Headers structure should
+ # perform case normalization for us. We just rewrite underscore to dash
+ # so keys match what likely went over the wire.
+ headers = []
+ for k, v in env.iteritems():
+ if k.startswith('HTTP_'):
+ headers.append((k[len('HTTP_'):].replace('_', '-'), v))
+
+ headers = wsgiheaders.Headers(headers)
+
return parsedrequest(url=fullurl, baseurl=baseurl,
advertisedurl=advertisedfullurl,
advertisedbaseurl=advertisedbaseurl,
@@ -194,7 +208,8 @@
havepathinfo='PATH_INFO' in env,
querystring=querystring,
querystringlist=querystringlist,
- querystringdict=querystringdict)
+ querystringdict=querystringdict,
+ headers=headers)
class wsgirequest(object):
"""Higher-level API for a WSGI request.