Mercurial > public > mercurial-scm > hg
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 |