##// END OF EJS Templates
subsetmaker: stabilize the computation of `scratch` subset...
subsetmaker: stabilize the computation of `scratch` subset `heads` is set, order of the element are not deterministic and we need to stabilize that if we want to get reproducible results. Differential Revision: https://phab.mercurial-scm.org/D12394

File last commit:

r49801:642e31cb default
r49877:18622379 default
Show More
server.py
436 lines | 13.4 KiB | text/x-python | PythonLexer
Eric Hopper
Fixing up comment headers for split up code.
r2391 # hgweb/server.py - The standalone hg web server.
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 #
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Yuya Nishihara
hgweb: use absolute_import
r27046
import errno
Gregory Szorc
hgweb: use importlib.reload() if available...
r43339 import importlib
Yuya Nishihara
hgweb: use absolute_import
r27046 import os
import socket
import sys
import traceback
Gregory Szorc
hgweb: validate WSGI environment dict...
r36821 import wsgiref.validate
Yuya Nishihara
hgweb: use absolute_import
r27046
from ..i18n import _
Gregory Szorc
py3: manually import getattr where it is needed...
r43359 from ..pycompat import (
getattr,
open,
)
Yuya Nishihara
hgweb: use absolute_import
r27046
from .. import (
Augie Fackler
hgweb: fix logging to use native strings as appropriate...
r34707 encoding,
Yuya Nishihara
hgweb: use absolute_import
r27046 error,
Pulkit Goyal
py3: replace os.name with pycompat.osname (part 1 of 2)...
r30639 pycompat,
Yuya Nishihara
hgweb: use absolute_import
r27046 util,
)
urlutil: extract `url` related code from `util` into the new module...
r47669 from ..utils import (
urlutil,
)
Yuya Nishihara
hgweb: use absolute_import
r27046
Pulkit Goyal
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import...
r29566 httpservermod = util.httpserver
Pulkit Goyal
py3: conditionalize SocketServer import...
r29433 socketserver = util.socketserver
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 urlerr = util.urlerr
urlreq = util.urlreq
Augie Fackler
formatting: blacken the codebase...
r43346 from . import common
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
def _splitURI(uri):
Mads Kiilerich
improve some comments and docstrings, fixing issues found when spell checking
r17427 """Return path and query that has been split from uri
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Just like CGI environment, the path is unquoted, the query is
not.
"""
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if '?' in uri:
path, query = uri.split('?', 1)
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 else:
Augie Fackler
hgweb: more native string treatment in query string parsing...
r34701 path, query = uri, r''
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 return urlreq.unquote(path), query
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class _error_logger:
Eric Hopper
This patch make several WSGI related alterations....
r2506 def __init__(self, handler):
self.handler = handler
Augie Fackler
formatting: blacken the codebase...
r43346
Eric Hopper
This patch make several WSGI related alterations....
r2506 def flush(self):
pass
Augie Fackler
formatting: blacken the codebase...
r43346
Benoit Boissinot
hgweb: fix errors spotted by pychecker
r3130 def write(self, str):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.writelines(str.split(b'\n'))
Augie Fackler
formatting: blacken the codebase...
r43346
Benoit Boissinot
hgweb: fix errors spotted by pychecker
r3130 def writelines(self, seq):
Eric Hopper
This patch make several WSGI related alterations....
r2506 for msg in seq:
Augie Fackler
cleanup: remove pointless r-prefixes on double-quoted strings...
r43809 self.handler.log_error("HG error: %s", encoding.strfromlocal(msg))
Eric Hopper
This patch make several WSGI related alterations....
r2506
Augie Fackler
formatting: blacken the codebase...
r43346
Pulkit Goyal
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import...
r29566 class _httprequesthandler(httpservermod.basehttprequesthandler):
Wesley J. Landaker
Make hg serve set the wsgi.url_scheme property correctly....
r4870
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 url_scheme = b'http'
Thomas Arendsen Hein
removed trailing whitespace
r4957
Mads Kiilerich
hgweb: refactor all pyOpenSSL references into one class
r12783 @staticmethod
Gregory Szorc
hgweb: pass ui into preparehttpserver...
r29553 def preparehttpserver(httpserver, ui):
Mads Kiilerich
hgweb: refactor all pyOpenSSL references into one class
r12783 """Prepare .socket of new HTTPServer instance"""
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 def __init__(self, *args, **kargs):
Augie Fackler
hgweb: when constructing or adding to a wsgi environ dict, use native strs...
r34513 self.protocol_version = r'HTTP/1.1'
Pulkit Goyal
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import...
r29566 httpservermod.basehttprequesthandler.__init__(self, *args, **kargs)
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Patrick Mezard
hgweb.server: flush log files after every access
r5549 def _log_any(self, fp, format, *args):
Augie Fackler
formatting: blacken the codebase...
r43346 fp.write(
pycompat.sysbytes(
r"%s - - [%s] %s"
% (
self.client_address[0],
self.log_date_time_string(),
format % args,
)
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 + b'\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
hgweb.server: flush log files after every access
r5549 fp.flush()
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 def log_error(self, format, *args):
Patrick Mezard
hgweb.server: flush log files after every access
r5549 self._log_any(self.server.errorlog, format, *args)
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
def log_message(self, format, *args):
Patrick Mezard
hgweb.server: flush log files after every access
r5549 self._log_any(self.server.accesslog, format, *args)
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 def log_request(self, code='-', size='-'):
David Soria Parra
hgweb: log headers only if headers were successfully parsed...
r19877 xheaders = []
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if util.safehasattr(self, b'headers'):
Augie Fackler
formatting: blacken the codebase...
r43346 xheaders = [
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 h for h in self.headers.items() if h[0].startswith('x-')
Augie Fackler
formatting: blacken the codebase...
r43346 ]
self.log_message(
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 '"%s" %s %s%s',
Augie Fackler
formatting: blacken the codebase...
r43346 self.requestline,
str(code),
str(size),
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 ''.join([' %s:%s' % h for h in sorted(xheaders)]),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Steven Brown
httprepo: long arguments support (issue2126)...
r14093
Brendan Cully
Add SSL support to hg serve, activated via --certificate option
r4860 def do_write(self):
try:
self.do_hgweb()
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except socket.error as inst:
Matt Harbison
py3: stop subscripting socket.error...
r40909 if inst.errno != errno.EPIPE:
Brendan Cully
Add SSL support to hg serve, activated via --certificate option
r4860 raise
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 def do_POST(self):
try:
Brendan Cully
Add SSL support to hg serve, activated via --certificate option
r4860 self.do_write()
Augie Fackler
server: skip logging of ECONNRESET...
r41620 except Exception as e:
Gregory Szorc
hgweb: log error before attempting I/O...
r41603 # I/O below could raise another exception. So log the original
# exception first to ensure it is recorded.
Augie Fackler
formatting: blacken the codebase...
r43346 if not (
isinstance(e, (OSError, socket.error))
and e.errno == errno.ECONNRESET
):
Augie Fackler
cleanup: remove pointless r-prefixes on double-quoted strings...
r43809 tb = "".join(traceback.format_exception(*sys.exc_info()))
Augie Fackler
server: skip logging of ECONNRESET...
r41620 # We need a native-string newline to poke in the log
# message, because we won't get a newline when using an
# r-string. This is the easy way out.
newline = chr(10)
Augie Fackler
formatting: blacken the codebase...
r43346 self.log_error(
r"Exception happened during processing "
Augie Fackler
cleanup: remove pointless r-prefixes on double-quoted strings...
r43809 "request '%s':%s%s",
Augie Fackler
formatting: blacken the codebase...
r43346 self.path,
newline,
tb,
)
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Augie Fackler
cleanup: remove pointless r-prefixes on double-quoted strings...
r43809 self._start_response("500 Internal Server Error", [])
Gregory Szorc
hgweb: log error before attempting I/O...
r41603 self._write(b"Internal Server Error")
self._done()
Matt Harbison
lfs: add basic routing for the server side wire protocol processing...
r37165 def do_PUT(self):
self.do_POST()
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 def do_GET(self):
self.do_POST()
def do_hgweb(self):
Augie Fackler
hgweb: set sent_headers attr as early as practical...
r34721 self.sent_headers = False
Michele Cella
adding "prefix" option to "hg serve" (command line and [web] section)...
r5835 path, query = _splitURI(self.path)
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Matt Harbison
server: ensure the incoming request falls under the prefix value...
r37288 # Ensure the slicing of path below is valid
Augie Fackler
formatting: blacken the codebase...
r43346 if path != self.server.prefix and not path.startswith(
self.server.prefix + b'/'
):
self._start_response(pycompat.strurl(common.statusmessage(404)), [])
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if self.command == 'POST':
Augie Fackler
server: always close http socket if responding with an error (issue6033)...
r41161 # Paranoia: tell the client we're going to close the
# socket so they don't try and reuse a socket that
# might have a POST body waiting to confuse us. We do
# this by directly munging self.saved_headers because
# self._start_response ignores Connection headers.
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 self.saved_headers = [('Connection', 'Close')]
Augie Fackler
hgweb: pass a sysstr to low-level _start_response method...
r38316 self._write(b"Not Found")
Matt Harbison
server: ensure the incoming request falls under the prefix value...
r37288 self._done()
return
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 env = {}
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 env['GATEWAY_INTERFACE'] = 'CGI/1.1'
env['REQUEST_METHOD'] = self.command
env['SERVER_NAME'] = self.server.server_name
env['SERVER_PORT'] = str(self.server.server_port)
env['REQUEST_URI'] = self.path
env['SCRIPT_NAME'] = pycompat.sysstr(self.server.prefix)
env['PATH_INFO'] = pycompat.sysstr(path[len(self.server.prefix) :])
env['REMOTE_HOST'] = self.client_address[0]
env['REMOTE_ADDR'] = self.client_address[0]
env['QUERY_STRING'] = query or ''
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Gregory Szorc
hgweb: remove Python 2 support code...
r49761 if self.headers.get_content_type() is None:
env['CONTENT_TYPE'] = self.headers.get_default_type()
Augie Fackler
hgweb: detect Python 3-era libraries and use modern attribute names...
r34720 else:
Gregory Szorc
hgweb: remove Python 2 support code...
r49761 env['CONTENT_TYPE'] = self.headers.get_content_type()
length = self.headers.get('content-length')
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355 if length:
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 env['CONTENT_LENGTH'] = length
Augie Fackler
formatting: blacken the codebase...
r43346 for header in [
h
for h in self.headers.keys()
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if h.lower() not in ('content-type', 'content-length')
Augie Fackler
formatting: blacken the codebase...
r43346 ]:
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 hkey = 'HTTP_' + header.replace('-', '_').upper()
Augie Fackler
hgweb: when constructing or adding to a wsgi environ dict, use native strs...
r34513 hval = self.headers.get(header)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 hval = hval.replace('\n', '').strip()
Eric Hopper
Fix server to set up a more WSGI compliant environment.
r2505 if hval:
env[hkey] = hval
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 env['SERVER_PROTOCOL'] = self.request_version
env['wsgi.version'] = (1, 0)
env['wsgi.url_scheme'] = pycompat.sysstr(self.url_scheme)
if env.get('HTTP_EXPECT', b'').lower() == b'100-continue':
Augie Fackler
hgweb: add support for 100-continue as recommended by PEP 333.
r13570 self.rfile = common.continuereader(self.rfile, self.wfile.write)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 env['wsgi.input'] = self.rfile
env['wsgi.errors'] = _error_logger(self)
env['wsgi.multithread'] = isinstance(
Augie Fackler
formatting: blacken the codebase...
r43346 self.server, socketserver.ThreadingMixIn
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if util.safehasattr(socketserver, b'ForkingMixIn'):
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 env['wsgi.multiprocess'] = isinstance(
Augie Fackler
formatting: blacken the codebase...
r43346 self.server, socketserver.ForkingMixIn
)
Matt Harbison
py3: conditionalize access to socketserver.ForkingMixIn...
r39866 else:
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 env['wsgi.multiprocess'] = False
Matt Harbison
py3: conditionalize access to socketserver.ForkingMixIn...
r39866
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 env['wsgi.run_once'] = 0
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Gregory Szorc
hgweb: validate WSGI environment dict...
r36821 wsgiref.validate.check_environ(env)
Eric Hopper
This patch make several WSGI related alterations....
r2506 self.saved_status = None
self.saved_headers = []
Eric Hopper
Put support for persistent connections back in.
r2508 self.length = None
Mads Kiilerich
serve: use chunked encoding in hgweb responses...
r18354 self._chunked = None
Dirkjan Ochtman
hgweb: all protocol functions have become generators...
r6784 for chunk in self.server.application(env, self._start_response):
self._write(chunk)
Mads Kiilerich
serve: send response headers even if response has no body...
r18349 if not self.sent_headers:
self.send_headers()
Mads Kiilerich
serve: use chunked encoding in hgweb responses...
r18354 self._done()
Eric Hopper
This patch make several WSGI related alterations....
r2506
def send_headers(self):
if not self.saved_status:
Augie Fackler
formatting: blacken the codebase...
r43346 raise AssertionError(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 b"Sending headers before start_response() called"
Augie Fackler
formatting: blacken the codebase...
r43346 )
Eric Hopper
This patch make several WSGI related alterations....
r2506 saved_status = self.saved_status.split(None, 1)
saved_status[0] = int(saved_status[0])
self.send_response(*saved_status)
Mads Kiilerich
serve: use chunked encoding in hgweb responses...
r18354 self.length = None
self._chunked = False
Eric Hopper
This patch make several WSGI related alterations....
r2506 for h in self.saved_headers:
self.send_header(*h)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if h[0].lower() == 'content-length':
Eric Hopper
Put support for persistent connections back in.
r2508 self.length = int(h[1])
Augie Fackler
formatting: blacken the codebase...
r43346 if self.length is None and saved_status[0] != common.HTTP_NOT_MODIFIED:
self._chunked = (
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 not self.close_connection and self.request_version == 'HTTP/1.1'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Mads Kiilerich
serve: use chunked encoding in hgweb responses...
r18354 if self._chunked:
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 self.send_header('Transfer-Encoding', 'chunked')
Mads Kiilerich
serve: use chunked encoding in hgweb responses...
r18354 else:
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 self.send_header('Connection', 'close')
Eric Hopper
This patch make several WSGI related alterations....
r2506 self.end_headers()
self.sent_headers = True
def _start_response(self, http_status, headers, exc_info=None):
Augie Fackler
hgweb: insist http_status value is a sysstr...
r38317 assert isinstance(http_status, str)
Eric Hopper
This patch make several WSGI related alterations....
r2506 code, msg = http_status.split(None, 1)
code = int(code)
self.saved_status = http_status
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 bad_headers = ('connection', 'transfer-encoding')
Augie Fackler
formatting: blacken the codebase...
r43346 self.saved_headers = [
h for h in headers if h[0].lower() not in bad_headers
]
Eric Hopper
This patch make several WSGI related alterations....
r2506 return self._write
def _write(self, data):
if not self.saved_status:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise AssertionError(b"data written before start_response() called")
Eric Hopper
This patch make several WSGI related alterations....
r2506 elif not self.sent_headers:
self.send_headers()
Eric Hopper
Put support for persistent connections back in.
r2508 if self.length is not None:
if len(data) > self.length:
Augie Fackler
formatting: blacken the codebase...
r43346 raise AssertionError(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"Content-length header sent, but more "
b"bytes than specified are being written."
Augie Fackler
formatting: blacken the codebase...
r43346 )
Eric Hopper
Put support for persistent connections back in.
r2508 self.length = self.length - len(data)
Mads Kiilerich
serve: use chunked encoding in hgweb responses...
r18354 elif self._chunked and data:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 data = b'%x\r\n%s\r\n' % (len(data), data)
Eric Hopper
This patch make several WSGI related alterations....
r2506 self.wfile.write(data)
self.wfile.flush()
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Mads Kiilerich
serve: use chunked encoding in hgweb responses...
r18354 def _done(self):
if self._chunked:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.wfile.write(b'0\r\n\r\n')
Mads Kiilerich
serve: use chunked encoding in hgweb responses...
r18354 self.wfile.flush()
Gregory Szorc
hgweb: allow defining Server response header for HTTP server...
r37027 def version_string(self):
if self.server.serverheader:
Yuya Nishihara
py3: convert server-string to unicode to make http library happy
r38613 return encoding.strfromlocal(self.server.serverheader)
Gregory Szorc
hgweb: allow defining Server response header for HTTP server...
r37027 return httpservermod.basehttprequesthandler.version_string(self)
Augie Fackler
formatting: blacken the codebase...
r43346
Mads Kiilerich
hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later...
r12784 class _httprequesthandlerssl(_httprequesthandler):
timeless@mozdev.org
hgweb.server: fix _httprequesthandlerssl help text
r26202 """HTTPS handler based on Python's ssl module"""
Mads Kiilerich
hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later...
r12784
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 url_scheme = b'https'
Mads Kiilerich
hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later...
r12784
@staticmethod
Gregory Szorc
hgweb: pass ui into preparehttpserver...
r29553 def preparehttpserver(httpserver, ui):
Mads Kiilerich
hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later...
r12784 try:
Gregory Szorc
hgweb: use sslutil.wrapserversocket()...
r29555 from .. import sslutil
Augie Fackler
formatting: blacken the codebase...
r43346
Manuel Jacob
hgweb: avoid using `sslutil.modernssl`...
r45413 sslutil.wrapserversocket
Mads Kiilerich
hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later...
r12784 except ImportError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"SSL support is unavailable"))
Gregory Szorc
hgweb: pass ui into preparehttpserver...
r29553
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 certfile = ui.config(b'web', b'certificate')
Gregory Szorc
hgweb: use sslutil.wrapserversocket()...
r29555
# These config options are currently only meant for testing. Use
# at your own risk.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cafile = ui.config(b'devel', b'servercafile')
reqcert = ui.configbool(b'devel', b'serverrequirecert')
Gregory Szorc
hgweb: use sslutil.wrapserversocket()...
r29555
Augie Fackler
formatting: blacken the codebase...
r43346 httpserver.socket = sslutil.wrapserversocket(
httpserver.socket,
ui,
certfile=certfile,
cafile=cafile,
requireclientcert=reqcert,
)
Mads Kiilerich
hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later...
r12784
def setup(self):
self.connection = self.request
Augie Fackler
cleanup: remove pointless r-prefixes on double-quoted strings...
r43809 self.rfile = self.request.makefile("rb", self.rbufsize)
self.wfile = self.request.makefile("wb", self.wbufsize)
Mads Kiilerich
hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later...
r12784
Augie Fackler
formatting: blacken the codebase...
r43346
Dirkjan Ochtman
server: externalize and streamline mixin setup
r10639 try:
Yuya Nishihara
hgweb: use absolute_import
r27046 import threading
Augie Fackler
formatting: blacken the codebase...
r43346
Karthikeyan Singaravelan
hgweb: Fix deprecation warning in Python 3.10 (issue6520)...
r47965 threading.active_count() # silence pyflakes and bypass demandimport
Pulkit Goyal
py3: conditionalize SocketServer import...
r29433 _mixin = socketserver.ThreadingMixIn
Dirkjan Ochtman
server: externalize and streamline mixin setup
r10639 except ImportError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if util.safehasattr(os, b"fork"):
Pulkit Goyal
py3: conditionalize SocketServer import...
r29433 _mixin = socketserver.ForkingMixIn
Dirkjan Ochtman
server: externalize and streamline mixin setup
r10639 else:
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class _mixin:
Dirkjan Ochtman
server: externalize and streamline mixin setup
r10639 pass
Augie Fackler
formatting: blacken the codebase...
r43346
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 def openlog(opt, default):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opt and opt != b'-':
return open(opt, b'ab')
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 return default
Augie Fackler
formatting: blacken the codebase...
r43346
Martijn Pieters
hgweb: fix the MRO in Python 3...
r30082 class MercurialHTTPServer(_mixin, httpservermod.httpserver, object):
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643
# SO_REUSEADDR has broken semantics on windows
Jun Wu
codemod: use pycompat.iswindows...
r34646 if pycompat.iswindows:
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 allow_reuse_address = 0
def __init__(self, ui, app, addr, handler, **kwargs):
Pulkit Goyal
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import...
r29566 httpservermod.httpserver.__init__(self, addr, handler, **kwargs)
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 self.daemon_threads = True
self.application = app
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Gregory Szorc
hgweb: pass ui into preparehttpserver...
r29553 handler.preparehttpserver(self, ui)
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prefix = ui.config(b'web', b'prefix')
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 if prefix:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prefix = b'/' + prefix.strip(b'/')
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 self.prefix = prefix
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 alog = openlog(ui.config(b'web', b'accesslog'), ui.fout)
elog = openlog(ui.config(b'web', b'errorlog'), ui.ferr)
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 self.accesslog = alog
self.errorlog = elog
self.addr, self.port = self.socket.getsockname()[0:2]
Manuel Jacob
py3: fix crash when server address is 0.0.0.0 (issue6362)...
r45578 self.fqaddr = self.server_name
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.serverheader = ui.config(b'web', b'server-header')
Gregory Szorc
hgweb: allow defining Server response header for HTTP server...
r37027
Augie Fackler
formatting: blacken the codebase...
r43346
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 class IPv6HTTPServer(MercurialHTTPServer):
address_family = getattr(socket, 'AF_INET6', None)
Augie Fackler
formatting: blacken the codebase...
r43346
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 def __init__(self, *args, **kwargs):
if self.address_family is None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.RepoError(_(b'IPv6 is not available on this system'))
Dirkjan Ochtman
server: unnest server classes into module namespace
r10643 super(IPv6HTTPServer, self).__init__(*args, **kwargs)
Augie Fackler
formatting: blacken the codebase...
r43346
Dirkjan Ochtman
server: initialize wsgi app in command, then wrap server around it
r10644 def create_server(ui, app):
Eric Hopper
Splitting up hgweb so it's easier to change.
r2355
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if ui.config(b'web', b'certificate'):
Siddharth Agarwal
hgweb.server: drop support for Python 2.4
r26848 handler = _httprequesthandlerssl
Brendan Cully
Add SSL support to hg serve, activated via --certificate option
r4860 else:
Mads Kiilerich
hgweb: refactor all pyOpenSSL references into one class
r12783 handler = _httprequesthandler
Brendan Cully
Add SSL support to hg serve, activated via --certificate option
r4860
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if ui.configbool(b'web', b'ipv6'):
Dirkjan Ochtman
server: abstract setup of ipv6 vs. normal server
r10641 cls = IPv6HTTPServer
else:
cls = MercurialHTTPServer
Dirkjan Ochtman
hgweb: pre-init mimetypes module (fixes ugly bug in python-2.6.2 mimetypes)...
r8224 # ugly hack due to python issue5853 (for threaded use)
Matt Mackall
hgweb: hack around mimetypes encoding thinko (issue4160)...
r20357 try:
import mimetypes
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
hgweb: hack around mimetypes encoding thinko (issue4160)...
r20357 mimetypes.init()
except UnicodeDecodeError:
# Python 2.x's mimetypes module attempts to decode strings
# from Windows' ANSI APIs as ascii (fail), then re-encode them
# as ascii (clown fail), because the default Python Unicode
# codec is hardcoded as ascii.
Augie Fackler
formatting: blacken the codebase...
r43346 sys.argv # unwrap demand-loader so that reload() works
Gregory Szorc
hgweb: use importlib.reload() if available...
r43339 # resurrect sys.setdefaultencoding()
try:
importlib.reload(sys)
except AttributeError:
reload(sys)
Matt Mackall
hgweb: hack around mimetypes encoding thinko (issue4160)...
r20357 oldenc = sys.getdefaultencoding()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 sys.setdefaultencoding(b"latin1") # or any full 8-bit encoding
Matt Mackall
hgweb: hack around mimetypes encoding thinko (issue4160)...
r20357 mimetypes.init()
sys.setdefaultencoding(oldenc)
Dirkjan Ochtman
hgweb: pre-init mimetypes module (fixes ugly bug in python-2.6.2 mimetypes)...
r8224
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 address = ui.config(b'web', b'address')
urlutil: extract `url` related code from `util` into the new module...
r47669 port = urlutil.getport(ui.config(b'web', b'port'))
Matt Mackall
hgweb: internalize some socket details
r3628 try:
Dirkjan Ochtman
server: initialize wsgi app in command, then wrap server around it
r10644 return cls(ui, app, (address, port), handler)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except socket.error as inst:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"cannot start server at '%s:%d': %s")
Augie Fackler
formatting: blacken the codebase...
r43346 % (address, port, encoding.strtolocal(inst.args[1]))
)