comparison mercurial/hgweb/server.py @ 43077:687b865b95ad

formatting: byteify all mercurial/ and hgext/ string literals Done with python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py') black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**') # skip-blame mass-reformatting only Differential Revision: https://phab.mercurial-scm.org/D6972
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:48:39 -0400
parents 2372284d9457
children eef9a2d67051
comparison
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
52 52
53 def flush(self): 53 def flush(self):
54 pass 54 pass
55 55
56 def write(self, str): 56 def write(self, str):
57 self.writelines(str.split('\n')) 57 self.writelines(str.split(b'\n'))
58 58
59 def writelines(self, seq): 59 def writelines(self, seq):
60 for msg in seq: 60 for msg in seq:
61 self.handler.log_error(r"HG error: %s", encoding.strfromlocal(msg)) 61 self.handler.log_error(r"HG error: %s", encoding.strfromlocal(msg))
62 62
63 63
64 class _httprequesthandler(httpservermod.basehttprequesthandler): 64 class _httprequesthandler(httpservermod.basehttprequesthandler):
65 65
66 url_scheme = 'http' 66 url_scheme = b'http'
67 67
68 @staticmethod 68 @staticmethod
69 def preparehttpserver(httpserver, ui): 69 def preparehttpserver(httpserver, ui):
70 """Prepare .socket of new HTTPServer instance""" 70 """Prepare .socket of new HTTPServer instance"""
71 71
81 self.client_address[0], 81 self.client_address[0],
82 self.log_date_time_string(), 82 self.log_date_time_string(),
83 format % args, 83 format % args,
84 ) 84 )
85 ) 85 )
86 + '\n' 86 + b'\n'
87 ) 87 )
88 fp.flush() 88 fp.flush()
89 89
90 def log_error(self, format, *args): 90 def log_error(self, format, *args):
91 self._log_any(self.server.errorlog, format, *args) 91 self._log_any(self.server.errorlog, format, *args)
93 def log_message(self, format, *args): 93 def log_message(self, format, *args):
94 self._log_any(self.server.accesslog, format, *args) 94 self._log_any(self.server.accesslog, format, *args)
95 95
96 def log_request(self, code=r'-', size=r'-'): 96 def log_request(self, code=r'-', size=r'-'):
97 xheaders = [] 97 xheaders = []
98 if util.safehasattr(self, 'headers'): 98 if util.safehasattr(self, b'headers'):
99 xheaders = [ 99 xheaders = [
100 h for h in self.headers.items() if h[0].startswith(r'x-') 100 h for h in self.headers.items() if h[0].startswith(r'x-')
101 ] 101 ]
102 self.log_message( 102 self.log_message(
103 r'"%s" %s %s%s', 103 r'"%s" %s %s%s',
154 # Ensure the slicing of path below is valid 154 # Ensure the slicing of path below is valid
155 if path != self.server.prefix and not path.startswith( 155 if path != self.server.prefix and not path.startswith(
156 self.server.prefix + b'/' 156 self.server.prefix + b'/'
157 ): 157 ):
158 self._start_response(pycompat.strurl(common.statusmessage(404)), []) 158 self._start_response(pycompat.strurl(common.statusmessage(404)), [])
159 if self.command == 'POST': 159 if self.command == b'POST':
160 # Paranoia: tell the client we're going to close the 160 # Paranoia: tell the client we're going to close the
161 # socket so they don't try and reuse a socket that 161 # socket so they don't try and reuse a socket that
162 # might have a POST body waiting to confuse us. We do 162 # might have a POST body waiting to confuse us. We do
163 # this by directly munging self.saved_headers because 163 # this by directly munging self.saved_headers because
164 # self._start_response ignores Connection headers. 164 # self._start_response ignores Connection headers.
204 if hval: 204 if hval:
205 env[hkey] = hval 205 env[hkey] = hval
206 env[r'SERVER_PROTOCOL'] = self.request_version 206 env[r'SERVER_PROTOCOL'] = self.request_version
207 env[r'wsgi.version'] = (1, 0) 207 env[r'wsgi.version'] = (1, 0)
208 env[r'wsgi.url_scheme'] = pycompat.sysstr(self.url_scheme) 208 env[r'wsgi.url_scheme'] = pycompat.sysstr(self.url_scheme)
209 if env.get(r'HTTP_EXPECT', '').lower() == '100-continue': 209 if env.get(r'HTTP_EXPECT', b'').lower() == b'100-continue':
210 self.rfile = common.continuereader(self.rfile, self.wfile.write) 210 self.rfile = common.continuereader(self.rfile, self.wfile.write)
211 211
212 env[r'wsgi.input'] = self.rfile 212 env[r'wsgi.input'] = self.rfile
213 env[r'wsgi.errors'] = _error_logger(self) 213 env[r'wsgi.errors'] = _error_logger(self)
214 env[r'wsgi.multithread'] = isinstance( 214 env[r'wsgi.multithread'] = isinstance(
215 self.server, socketserver.ThreadingMixIn 215 self.server, socketserver.ThreadingMixIn
216 ) 216 )
217 if util.safehasattr(socketserver, 'ForkingMixIn'): 217 if util.safehasattr(socketserver, b'ForkingMixIn'):
218 env[r'wsgi.multiprocess'] = isinstance( 218 env[r'wsgi.multiprocess'] = isinstance(
219 self.server, socketserver.ForkingMixIn 219 self.server, socketserver.ForkingMixIn
220 ) 220 )
221 else: 221 else:
222 env[r'wsgi.multiprocess'] = False 222 env[r'wsgi.multiprocess'] = False
236 self._done() 236 self._done()
237 237
238 def send_headers(self): 238 def send_headers(self):
239 if not self.saved_status: 239 if not self.saved_status:
240 raise AssertionError( 240 raise AssertionError(
241 "Sending headers before " "start_response() called" 241 b"Sending headers before " b"start_response() called"
242 ) 242 )
243 saved_status = self.saved_status.split(None, 1) 243 saved_status = self.saved_status.split(None, 1)
244 saved_status[0] = int(saved_status[0]) 244 saved_status[0] = int(saved_status[0])
245 self.send_response(*saved_status) 245 self.send_response(*saved_status)
246 self.length = None 246 self.length = None
272 ] 272 ]
273 return self._write 273 return self._write
274 274
275 def _write(self, data): 275 def _write(self, data):
276 if not self.saved_status: 276 if not self.saved_status:
277 raise AssertionError("data written before start_response() called") 277 raise AssertionError(b"data written before start_response() called")
278 elif not self.sent_headers: 278 elif not self.sent_headers:
279 self.send_headers() 279 self.send_headers()
280 if self.length is not None: 280 if self.length is not None:
281 if len(data) > self.length: 281 if len(data) > self.length:
282 raise AssertionError( 282 raise AssertionError(
283 "Content-length header sent, but more " 283 b"Content-length header sent, but more "
284 "bytes than specified are being written." 284 b"bytes than specified are being written."
285 ) 285 )
286 self.length = self.length - len(data) 286 self.length = self.length - len(data)
287 elif self._chunked and data: 287 elif self._chunked and data:
288 data = '%x\r\n%s\r\n' % (len(data), data) 288 data = b'%x\r\n%s\r\n' % (len(data), data)
289 self.wfile.write(data) 289 self.wfile.write(data)
290 self.wfile.flush() 290 self.wfile.flush()
291 291
292 def _done(self): 292 def _done(self):
293 if self._chunked: 293 if self._chunked:
294 self.wfile.write('0\r\n\r\n') 294 self.wfile.write(b'0\r\n\r\n')
295 self.wfile.flush() 295 self.wfile.flush()
296 296
297 def version_string(self): 297 def version_string(self):
298 if self.server.serverheader: 298 if self.server.serverheader:
299 return encoding.strfromlocal(self.server.serverheader) 299 return encoding.strfromlocal(self.server.serverheader)
301 301
302 302
303 class _httprequesthandlerssl(_httprequesthandler): 303 class _httprequesthandlerssl(_httprequesthandler):
304 """HTTPS handler based on Python's ssl module""" 304 """HTTPS handler based on Python's ssl module"""
305 305
306 url_scheme = 'https' 306 url_scheme = b'https'
307 307
308 @staticmethod 308 @staticmethod
309 def preparehttpserver(httpserver, ui): 309 def preparehttpserver(httpserver, ui):
310 try: 310 try:
311 from .. import sslutil 311 from .. import sslutil
312 312
313 sslutil.modernssl 313 sslutil.modernssl
314 except ImportError: 314 except ImportError:
315 raise error.Abort(_("SSL support is unavailable")) 315 raise error.Abort(_(b"SSL support is unavailable"))
316 316
317 certfile = ui.config('web', 'certificate') 317 certfile = ui.config(b'web', b'certificate')
318 318
319 # These config options are currently only meant for testing. Use 319 # These config options are currently only meant for testing. Use
320 # at your own risk. 320 # at your own risk.
321 cafile = ui.config('devel', 'servercafile') 321 cafile = ui.config(b'devel', b'servercafile')
322 reqcert = ui.configbool('devel', 'serverrequirecert') 322 reqcert = ui.configbool(b'devel', b'serverrequirecert')
323 323
324 httpserver.socket = sslutil.wrapserversocket( 324 httpserver.socket = sslutil.wrapserversocket(
325 httpserver.socket, 325 httpserver.socket,
326 ui, 326 ui,
327 certfile=certfile, 327 certfile=certfile,
339 import threading 339 import threading
340 340
341 threading.activeCount() # silence pyflakes and bypass demandimport 341 threading.activeCount() # silence pyflakes and bypass demandimport
342 _mixin = socketserver.ThreadingMixIn 342 _mixin = socketserver.ThreadingMixIn
343 except ImportError: 343 except ImportError:
344 if util.safehasattr(os, "fork"): 344 if util.safehasattr(os, b"fork"):
345 _mixin = socketserver.ForkingMixIn 345 _mixin = socketserver.ForkingMixIn
346 else: 346 else:
347 347
348 class _mixin(object): 348 class _mixin(object):
349 pass 349 pass
350 350
351 351
352 def openlog(opt, default): 352 def openlog(opt, default):
353 if opt and opt != '-': 353 if opt and opt != b'-':
354 return open(opt, 'ab') 354 return open(opt, b'ab')
355 return default 355 return default
356 356
357 357
358 class MercurialHTTPServer(_mixin, httpservermod.httpserver, object): 358 class MercurialHTTPServer(_mixin, httpservermod.httpserver, object):
359 359
366 self.daemon_threads = True 366 self.daemon_threads = True
367 self.application = app 367 self.application = app
368 368
369 handler.preparehttpserver(self, ui) 369 handler.preparehttpserver(self, ui)
370 370
371 prefix = ui.config('web', 'prefix') 371 prefix = ui.config(b'web', b'prefix')
372 if prefix: 372 if prefix:
373 prefix = '/' + prefix.strip('/') 373 prefix = b'/' + prefix.strip(b'/')
374 self.prefix = prefix 374 self.prefix = prefix
375 375
376 alog = openlog(ui.config('web', 'accesslog'), ui.fout) 376 alog = openlog(ui.config(b'web', b'accesslog'), ui.fout)
377 elog = openlog(ui.config('web', 'errorlog'), ui.ferr) 377 elog = openlog(ui.config(b'web', b'errorlog'), ui.ferr)
378 self.accesslog = alog 378 self.accesslog = alog
379 self.errorlog = elog 379 self.errorlog = elog
380 380
381 self.addr, self.port = self.socket.getsockname()[0:2] 381 self.addr, self.port = self.socket.getsockname()[0:2]
382 self.fqaddr = socket.getfqdn(addr[0]) 382 self.fqaddr = socket.getfqdn(addr[0])
383 383
384 self.serverheader = ui.config('web', 'server-header') 384 self.serverheader = ui.config(b'web', b'server-header')
385 385
386 386
387 class IPv6HTTPServer(MercurialHTTPServer): 387 class IPv6HTTPServer(MercurialHTTPServer):
388 address_family = getattr(socket, 'AF_INET6', None) 388 address_family = getattr(socket, 'AF_INET6', None)
389 389
390 def __init__(self, *args, **kwargs): 390 def __init__(self, *args, **kwargs):
391 if self.address_family is None: 391 if self.address_family is None:
392 raise error.RepoError(_('IPv6 is not available on this system')) 392 raise error.RepoError(_(b'IPv6 is not available on this system'))
393 super(IPv6HTTPServer, self).__init__(*args, **kwargs) 393 super(IPv6HTTPServer, self).__init__(*args, **kwargs)
394 394
395 395
396 def create_server(ui, app): 396 def create_server(ui, app):
397 397
398 if ui.config('web', 'certificate'): 398 if ui.config(b'web', b'certificate'):
399 handler = _httprequesthandlerssl 399 handler = _httprequesthandlerssl
400 else: 400 else:
401 handler = _httprequesthandler 401 handler = _httprequesthandler
402 402
403 if ui.configbool('web', 'ipv6'): 403 if ui.configbool(b'web', b'ipv6'):
404 cls = IPv6HTTPServer 404 cls = IPv6HTTPServer
405 else: 405 else:
406 cls = MercurialHTTPServer 406 cls = MercurialHTTPServer
407 407
408 # ugly hack due to python issue5853 (for threaded use) 408 # ugly hack due to python issue5853 (for threaded use)
421 try: 421 try:
422 importlib.reload(sys) 422 importlib.reload(sys)
423 except AttributeError: 423 except AttributeError:
424 reload(sys) 424 reload(sys)
425 oldenc = sys.getdefaultencoding() 425 oldenc = sys.getdefaultencoding()
426 sys.setdefaultencoding("latin1") # or any full 8-bit encoding 426 sys.setdefaultencoding(b"latin1") # or any full 8-bit encoding
427 mimetypes.init() 427 mimetypes.init()
428 sys.setdefaultencoding(oldenc) 428 sys.setdefaultencoding(oldenc)
429 429
430 address = ui.config('web', 'address') 430 address = ui.config(b'web', b'address')
431 port = util.getport(ui.config('web', 'port')) 431 port = util.getport(ui.config(b'web', b'port'))
432 try: 432 try:
433 return cls(ui, app, (address, port), handler) 433 return cls(ui, app, (address, port), handler)
434 except socket.error as inst: 434 except socket.error as inst:
435 raise error.Abort( 435 raise error.Abort(
436 _("cannot start server at '%s:%d': %s") 436 _(b"cannot start server at '%s:%d': %s")
437 % (address, port, encoding.strtolocal(inst.args[1])) 437 % (address, port, encoding.strtolocal(inst.args[1]))
438 ) 438 )