229 def _start_transaction(self, h, req): |
229 def _start_transaction(self, h, req): |
230 _generic_start_transaction(self, h, req) |
230 _generic_start_transaction(self, h, req) |
231 return keepalive.HTTPHandler._start_transaction(self, h, req) |
231 return keepalive.HTTPHandler._start_transaction(self, h, req) |
232 |
232 |
233 |
233 |
234 class logginghttpconnection(keepalive.HTTPConnection): |
|
235 def __init__(self, createconn, *args, **kwargs): |
|
236 keepalive.HTTPConnection.__init__(self, *args, **kwargs) |
|
237 self._create_connection = createconn |
|
238 |
|
239 |
|
240 class logginghttphandler(httphandler): |
234 class logginghttphandler(httphandler): |
241 """HTTP handler that logs socket I/O.""" |
235 """HTTP(S) handler that logs socket I/O.""" |
242 |
236 |
243 def __init__(self, logfh, name, observeropts, timeout=None): |
237 def __init__(self, logfh, name, observeropts, *args, **kwargs): |
244 super(logginghttphandler, self).__init__(timeout=timeout) |
238 super().__init__(*args, **kwargs) |
245 |
239 |
246 self._logfh = logfh |
240 self._logfh = logfh |
247 self._logname = name |
241 self._logname = name |
248 self._observeropts = observeropts |
242 self._observeropts = observeropts |
249 |
243 |
250 # do_open() calls the passed class to instantiate an HTTPConnection. We |
244 def do_open(self, http_class, *args, **kwargs): |
251 # pass in a callable method that creates a custom HTTPConnection instance |
245 _logfh = self._logfh |
252 # whose callback to create the socket knows how to proxy the socket. |
246 _logname = self._logname |
253 def http_open(self, req): |
247 _observeropts = self._observeropts |
254 return self.do_open(self._makeconnection, req) |
248 |
255 |
249 class logginghttpconnection(http_class): |
256 def _makeconnection(self, *args, **kwargs): |
250 def connect(self): |
257 def createconnection(*args, **kwargs): |
251 super().connect() |
258 sock = socket.create_connection(*args, **kwargs) |
252 self.sock = util.makeloggingsocket( |
259 return util.makeloggingsocket( |
253 _logfh, self.sock, _logname, **_observeropts |
260 self._logfh, sock, self._logname, **self._observeropts |
254 ) |
261 ) |
255 |
262 |
256 return super().do_open(logginghttpconnection, *args, **kwargs) |
263 return logginghttpconnection(createconnection, *args, **kwargs) |
|
264 |
257 |
265 |
258 |
266 if has_https: |
259 if has_https: |
267 |
260 |
268 def _generic_proxytunnel(self: "httpsconnection"): |
261 def _generic_proxytunnel(self: "httpsconnection"): |
555 handlers.append( |
548 handlers.append( |
556 logginghttphandler( |
549 logginghttphandler( |
557 loggingfh, loggingname, loggingopts or {}, timeout=timeout |
550 loggingfh, loggingname, loggingopts or {}, timeout=timeout |
558 ) |
551 ) |
559 ) |
552 ) |
560 # We don't yet support HTTPS when logging I/O. If we attempt to open |
|
561 # an HTTPS URL, we'll likely fail due to unknown protocol. |
|
562 |
|
563 else: |
553 else: |
564 handlers.append(httphandler(timeout=timeout)) |
554 handlers.append(httphandler(timeout=timeout)) |
565 if has_https: |
555 if has_https: |
566 # pytype get confused about the conditional existence for httpshandler here. |
556 # pytype get confused about the conditional existence for httpshandler here. |
567 handlers.append( |
557 handlers.append( |
568 httpshandler(ui, timeout=timeout) # pytype: disable=name-error |
558 httpshandler(ui, timeout=timeout) # pytype: disable=name-error |
569 ) |
559 ) |
570 |
560 |
571 handlers.append(proxyhandler(ui)) |
561 handlers.append(proxyhandler(ui)) |
572 |
562 |
573 passmgr = passwordmgr(ui, ui.httppasswordmgrdb) |
563 passmgr = passwordmgr(ui, ui.httppasswordmgrdb) |
574 if authinfo is not None: |
564 if authinfo is not None: |