comparison mercurial/hgweb/request.py @ 36814:f9078c6caeb6

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
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 08 Mar 2018 16:22:25 -0800
parents cfb9ef24968c
children ed0456fde625
comparison
equal deleted inserted replaced
36813:5a3c83412f79 36814:f9078c6caeb6
9 from __future__ import absolute_import 9 from __future__ import absolute_import
10 10
11 import cgi 11 import cgi
12 import errno 12 import errno
13 import socket 13 import socket
14 import wsgiref.headers as wsgiheaders
14 #import wsgiref.validate 15 #import wsgiref.validate
15 16
16 from .common import ( 17 from .common import (
17 ErrorResponse, 18 ErrorResponse,
18 HTTP_NOT_MODIFIED, 19 HTTP_NOT_MODIFIED,
83 querystring = attr.ib() 84 querystring = attr.ib()
84 # List of 2-tuples of query string arguments. 85 # List of 2-tuples of query string arguments.
85 querystringlist = attr.ib() 86 querystringlist = attr.ib()
86 # Dict of query string arguments. Values are lists with at least 1 item. 87 # Dict of query string arguments. Values are lists with at least 1 item.
87 querystringdict = attr.ib() 88 querystringdict = attr.ib()
89 # wsgiref.headers.Headers instance. Operates like a dict with case
90 # insensitive keys.
91 headers = attr.ib()
88 92
89 def parserequestfromenv(env): 93 def parserequestfromenv(env):
90 """Parse URL components from environment variables. 94 """Parse URL components from environment variables.
91 95
92 WSGI defines request attributes via environment variables. This function 96 WSGI defines request attributes via environment variables. This function
184 if k in querystringdict: 188 if k in querystringdict:
185 querystringdict[k].append(v) 189 querystringdict[k].append(v)
186 else: 190 else:
187 querystringdict[k] = [v] 191 querystringdict[k] = [v]
188 192
193 # HTTP_* keys contain HTTP request headers. The Headers structure should
194 # perform case normalization for us. We just rewrite underscore to dash
195 # so keys match what likely went over the wire.
196 headers = []
197 for k, v in env.iteritems():
198 if k.startswith('HTTP_'):
199 headers.append((k[len('HTTP_'):].replace('_', '-'), v))
200
201 headers = wsgiheaders.Headers(headers)
202
189 return parsedrequest(url=fullurl, baseurl=baseurl, 203 return parsedrequest(url=fullurl, baseurl=baseurl,
190 advertisedurl=advertisedfullurl, 204 advertisedurl=advertisedfullurl,
191 advertisedbaseurl=advertisedbaseurl, 205 advertisedbaseurl=advertisedbaseurl,
192 apppath=apppath, 206 apppath=apppath,
193 dispatchparts=dispatchparts, dispatchpath=dispatchpath, 207 dispatchparts=dispatchparts, dispatchpath=dispatchpath,
194 havepathinfo='PATH_INFO' in env, 208 havepathinfo='PATH_INFO' in env,
195 querystring=querystring, 209 querystring=querystring,
196 querystringlist=querystringlist, 210 querystringlist=querystringlist,
197 querystringdict=querystringdict) 211 querystringdict=querystringdict,
212 headers=headers)
198 213
199 class wsgirequest(object): 214 class wsgirequest(object):
200 """Higher-level API for a WSGI request. 215 """Higher-level API for a WSGI request.
201 216
202 WSGI applications are invoked with 2 arguments. They are used to 217 WSGI applications are invoked with 2 arguments. They are used to