Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/url.py @ 49287:127d33e63d1a
branching: merge stable into default
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Wed, 08 Jun 2022 15:46:04 +0200 |
parents | 642e31cb55f0 51b07ac1991c |
children | 9f3edb305261 |
comparison
equal
deleted
inserted
replaced
49286:c6a3243567b6 | 49287:127d33e63d1a |
---|---|
10 | 10 |
11 import base64 | 11 import base64 |
12 import socket | 12 import socket |
13 | 13 |
14 from .i18n import _ | 14 from .i18n import _ |
15 from .pycompat import getattr | |
16 from . import ( | 15 from . import ( |
17 encoding, | 16 encoding, |
18 error, | 17 error, |
19 httpconnection as httpconnectionmod, | 18 httpconnection as httpconnectionmod, |
20 keepalive, | 19 keepalive, |
196 | 195 |
197 class httpconnection(keepalive.HTTPConnection): | 196 class httpconnection(keepalive.HTTPConnection): |
198 # must be able to send big bundle as stream. | 197 # must be able to send big bundle as stream. |
199 send = _gen_sendfile(keepalive.HTTPConnection.send) | 198 send = _gen_sendfile(keepalive.HTTPConnection.send) |
200 | 199 |
201 def getresponse(self): | |
202 proxyres = getattr(self, 'proxyres', None) | |
203 if proxyres: | |
204 if proxyres.will_close: | |
205 self.close() | |
206 self.proxyres = None | |
207 return proxyres | |
208 return keepalive.HTTPConnection.getresponse(self) | |
209 | |
210 | 200 |
211 # Large parts of this function have their origin from before Python 2.6 | 201 # Large parts of this function have their origin from before Python 2.6 |
212 # and could potentially be removed. | 202 # and could potentially be removed. |
213 def _generic_start_transaction(handler, h, req): | 203 def _generic_start_transaction(handler, h, req): |
214 tunnel_host = req._tunnel_host | 204 tunnel_host = req._tunnel_host |
253 version, status, reason = res._read_status() | 243 version, status, reason = res._read_status() |
254 if status != httplib.CONTINUE: | 244 if status != httplib.CONTINUE: |
255 break | 245 break |
256 # skip lines that are all whitespace | 246 # skip lines that are all whitespace |
257 list(iter(lambda: res.fp.readline().strip(), b'')) | 247 list(iter(lambda: res.fp.readline().strip(), b'')) |
258 res.status = status | 248 |
259 res.reason = reason.strip() | 249 if status == 200: |
260 | |
261 if res.status == 200: | |
262 # skip lines until we find a blank line | 250 # skip lines until we find a blank line |
263 list(iter(res.fp.readline, b'\r\n')) | 251 list(iter(res.fp.readline, b'\r\n')) |
264 return True | |
265 | |
266 if version == b'HTTP/1.0': | |
267 res.version = 10 | |
268 elif version.startswith(b'HTTP/1.'): | |
269 res.version = 11 | |
270 elif version == b'HTTP/0.9': | |
271 res.version = 9 | |
272 else: | 252 else: |
273 raise httplib.UnknownProtocol(version) | 253 self.close() |
274 | 254 raise socket.error( |
275 if res.version == 9: | 255 "Tunnel connection failed: %d %s" % (status, reason.strip()) |
276 res.length = None | 256 ) |
277 res.chunked = 0 | |
278 res.will_close = 1 | |
279 res.msg = httplib.HTTPMessage(stringio()) | |
280 return False | |
281 | |
282 res.msg = httplib.HTTPMessage(res.fp) | |
283 res.msg.fp = None | |
284 | |
285 # are we using the chunked-style of transfer encoding? | |
286 trenc = res.msg.getheader(b'transfer-encoding') | |
287 if trenc and trenc.lower() == b"chunked": | |
288 res.chunked = 1 | |
289 res.chunk_left = None | |
290 else: | |
291 res.chunked = 0 | |
292 | |
293 # will the connection close at the end of the response? | |
294 res.will_close = res._check_close() | |
295 | |
296 # do we have a Content-Length? | |
297 # NOTE: RFC 2616, section 4.4, #3 says we ignore this if | |
298 # transfer-encoding is "chunked" | |
299 length = res.msg.getheader(b'content-length') | |
300 if length and not res.chunked: | |
301 try: | |
302 res.length = int(length) | |
303 except ValueError: | |
304 res.length = None | |
305 else: | |
306 if res.length < 0: # ignore nonsensical negative lengths | |
307 res.length = None | |
308 else: | |
309 res.length = None | |
310 | |
311 # does the body have a fixed length? (of zero) | |
312 if ( | |
313 status == httplib.NO_CONTENT | |
314 or status == httplib.NOT_MODIFIED | |
315 or 100 <= status < 200 | |
316 or res._method == b'HEAD' # 1xx codes | |
317 ): | |
318 res.length = 0 | |
319 | |
320 # if the connection remains open, and we aren't using chunked, and | |
321 # a content-length was not provided, then assume that the connection | |
322 # WILL close. | |
323 if not res.will_close and not res.chunked and res.length is None: | |
324 res.will_close = 1 | |
325 | |
326 self.proxyres = res | |
327 | |
328 return False | |
329 | 257 |
330 | 258 |
331 class httphandler(keepalive.HTTPHandler): | 259 class httphandler(keepalive.HTTPHandler): |
332 def http_open(self, req): | 260 def http_open(self, req): |
333 return self.do_open(httpconnection, req) | 261 return self.do_open(httpconnection, req) |