##// END OF EJS Templates
httppeer: extract code for HTTP header spanning...
Gregory Szorc -
r30759:3f5f0c98 default
parent child Browse files
Show More
@@ -25,6 +25,20 b' urlreq = util.urlreq'
25 HGTYPE = 'application/mercurial-0.1'
25 HGTYPE = 'application/mercurial-0.1'
26 HGERRTYPE = 'application/hg-error'
26 HGERRTYPE = 'application/hg-error'
27
27
28 def decodevaluefromheaders(req, headerprefix):
29 """Decode a long value from multiple HTTP request headers."""
30 chunks = []
31 i = 1
32 while True:
33 v = req.env.get('HTTP_%s_%d' % (
34 headerprefix.upper().replace('-', '_'), i))
35 if v is None:
36 break
37 chunks.append(v)
38 i += 1
39
40 return ''.join(chunks)
41
28 class webproto(wireproto.abstractserverproto):
42 class webproto(wireproto.abstractserverproto):
29 def __init__(self, req, ui):
43 def __init__(self, req, ui):
30 self.req = req
44 self.req = req
@@ -53,15 +67,9 b' class webproto(wireproto.abstractserverp'
53 args.update(cgi.parse_qs(
67 args.update(cgi.parse_qs(
54 self.req.read(postlen), keep_blank_values=True))
68 self.req.read(postlen), keep_blank_values=True))
55 return args
69 return args
56 chunks = []
70
57 i = 1
71 argvalue = decodevaluefromheaders(self.req, 'X-HgArg')
58 while True:
72 args.update(cgi.parse_qs(argvalue, keep_blank_values=True))
59 h = self.req.env.get('HTTP_X_HGARG_' + str(i))
60 if h is None:
61 break
62 chunks += [h]
63 i += 1
64 args.update(cgi.parse_qs(''.join(chunks), keep_blank_values=True))
65 return args
73 return args
66 def getfile(self, fp):
74 def getfile(self, fp):
67 length = int(self.req.env['CONTENT_LENGTH'])
75 length = int(self.req.env['CONTENT_LENGTH'])
@@ -53,6 +53,26 b' def decompressresponse(response, engine)'
53 reader.__class__ = readerproxy
53 reader.__class__ = readerproxy
54 return reader
54 return reader
55
55
56 def encodevalueinheaders(value, header, limit):
57 """Encode a string value into multiple HTTP headers.
58
59 ``value`` will be encoded into 1 or more HTTP headers with the names
60 ``header-<N>`` where ``<N>`` is an integer starting at 1. Each header
61 name + value will be at most ``limit`` bytes long.
62
63 Returns an iterable of 2-tuples consisting of header names and values.
64 """
65 fmt = header + '-%s'
66 valuelen = limit - len(fmt % '000') - len(': \r\n')
67 result = []
68
69 n = 0
70 for i in xrange(0, len(value), valuelen):
71 n += 1
72 result.append((fmt % str(n), value[i:i + valuelen]))
73
74 return result
75
56 class httppeer(wireproto.wirepeer):
76 class httppeer(wireproto.wirepeer):
57 def __init__(self, ui, path):
77 def __init__(self, ui, path):
58 self.path = path
78 self.path = path
@@ -135,13 +155,9 b' class httppeer(wireproto.wirepeer):'
135 if headersize > 0:
155 if headersize > 0:
136 # The headers can typically carry more data than the URL.
156 # The headers can typically carry more data than the URL.
137 encargs = urlreq.urlencode(sorted(args.items()))
157 encargs = urlreq.urlencode(sorted(args.items()))
138 headerfmt = 'X-HgArg-%s'
158 for header, value in encodevalueinheaders(encargs, 'X-HgArg',
139 contentlen = headersize - len(headerfmt % '000' + ': \r\n')
159 headersize):
140 headernum = 0
160 headers[header] = value
141 for i in xrange(0, len(encargs), contentlen):
142 headernum += 1
143 header = headerfmt % str(headernum)
144 headers[header] = encargs[i:i + contentlen]
145 varyheaders.append(header)
161 varyheaders.append(header)
146 else:
162 else:
147 q += sorted(args.items())
163 q += sorted(args.items())
General Comments 0
You need to be logged in to leave comments. Login now