Show More
@@ -75,6 +75,9 b' class webproto(wireproto.abstractserverp' | |||
|
75 | 75 | return args |
|
76 | 76 | def getfile(self, fp): |
|
77 | 77 | length = int(self.req.env['CONTENT_LENGTH']) |
|
78 | # If httppostargs is used, we need to read Content-Length | |
|
79 | # minus the amount that was consumed by args. | |
|
80 | length -= int(self.req.env.get('HTTP_X_HGARGS_POST', 0)) | |
|
78 | 81 | for s in util.filechunkiter(self.req, limit=length): |
|
79 | 82 | fp.write(s) |
|
80 | 83 | def redirect(self): |
@@ -9,6 +9,7 b'' | |||
|
9 | 9 | from __future__ import absolute_import |
|
10 | 10 | |
|
11 | 11 | import errno |
|
12 | import io | |
|
12 | 13 | import os |
|
13 | 14 | import socket |
|
14 | 15 | import struct |
@@ -86,6 +87,45 b' def _wraphttpresponse(resp):' | |||
|
86 | 87 | |
|
87 | 88 | resp.__class__ = readerproxy |
|
88 | 89 | |
|
90 | class _multifile(object): | |
|
91 | def __init__(self, *fileobjs): | |
|
92 | for f in fileobjs: | |
|
93 | if not util.safehasattr(f, 'length'): | |
|
94 | raise ValueError( | |
|
95 | '_multifile only supports file objects that ' | |
|
96 | 'have a length but this one does not:', type(f), f) | |
|
97 | self._fileobjs = fileobjs | |
|
98 | self._index = 0 | |
|
99 | ||
|
100 | @property | |
|
101 | def length(self): | |
|
102 | return sum(f.length for f in self._fileobjs) | |
|
103 | ||
|
104 | def read(self, amt=None): | |
|
105 | if amt <= 0: | |
|
106 | return ''.join(f.read() for f in self._fileobjs) | |
|
107 | parts = [] | |
|
108 | while amt and self._index < len(self._fileobjs): | |
|
109 | parts.append(self._fileobjs[self._index].read(amt)) | |
|
110 | got = len(parts[-1]) | |
|
111 | if got < amt: | |
|
112 | self._index += 1 | |
|
113 | amt -= got | |
|
114 | return ''.join(parts) | |
|
115 | ||
|
116 | def seek(self, offset, whence=os.SEEK_SET): | |
|
117 | if whence != os.SEEK_SET: | |
|
118 | raise NotImplementedError( | |
|
119 | '_multifile does not support anything other' | |
|
120 | ' than os.SEEK_SET for whence on seek()') | |
|
121 | if offset != 0: | |
|
122 | raise NotImplementedError( | |
|
123 | '_multifile only supports seeking to start, but that ' | |
|
124 | 'could be fixed if you need it') | |
|
125 | for f in self._fileobjs: | |
|
126 | f.seek(0) | |
|
127 | self._index = 0 | |
|
128 | ||
|
89 | 129 | class httppeer(wireproto.wirepeer): |
|
90 | 130 | def __init__(self, ui, path): |
|
91 | 131 | self._path = path |
@@ -169,16 +209,18 b' class httppeer(wireproto.wirepeer):' | |||
|
169 | 209 | # with infinite recursion when trying to look up capabilities |
|
170 | 210 | # for the first time. |
|
171 | 211 | postargsok = self._caps is not None and 'httppostargs' in self._caps |
|
172 | # TODO: support for httppostargs when data is a file-like | |
|
173 | # object rather than a basestring | |
|
174 | canmungedata = not data or isinstance(data, basestring) | |
|
175 | if postargsok and canmungedata: | |
|
212 | if postargsok and args: | |
|
176 | 213 | strargs = urlreq.urlencode(sorted(args.items())) |
|
177 | if strargs: | |
|
178 | 214 |
|
|
179 | 215 |
|
|
180 | elif isinstance(data, basestring): | |
|
181 | data = strargs + data | |
|
216 | else: | |
|
217 | if isinstance(data, basestring): | |
|
218 | i = io.BytesIO(data) | |
|
219 | i.length = len(data) | |
|
220 | data = i | |
|
221 | argsio = io.BytesIO(strargs) | |
|
222 | argsio.length = len(strargs) | |
|
223 | data = _multifile(argsio, data) | |
|
182 | 224 |
|
|
183 | 225 | else: |
|
184 | 226 | if len(args) > 0: |
General Comments 0
You need to be logged in to leave comments.
Login now