mercurial/hgweb/server.py
author Gregory Szorc <gregory.szorc@gmail.com>
Wed, 30 Jan 2019 11:44:34 -0800
changeset 41462 9b2b8794f801
parent 41430 52a4a3e7cc6a
child 41479 6bbb12cba5a8
permissions -rw-r--r--
hgweb: log error before attempting I/O Previously, an uncaught exception during HTTP request serving would attempt to send an error response then log the exception. If an exception occurred during I/O, this exception would be raised and the original exception wouldn't be logged. This commit changes behavior so the original exception is logged first, before we attempt to do anything else. This ensures the exception is logged. This change resulted in new tracebacks appearing in various tests. Because tracebacks can vary between Python versions, we added a simple script to filter the stack part of traceback lines. This makes testing much simpler, as we don't need to glob over lines and make lines conditional. Differential Revision: https://phab.mercurial-scm.org/D5749
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2391
d351a3be3371 Fixing up comment headers for split up code.
Eric Hopper <hopper@omnifarious.org>
parents: 2355
diff changeset
     1
# hgweb/server.py - The standalone hg web server.
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     2
#
238
3b92f8fe47ae hgweb.py: kill #! line, clean up copyright notice
mpm@selenic.com
parents: 222
diff changeset
     3
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
     4
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8224
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9037
diff changeset
     7
# GNU General Public License version 2 or any later version.
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     8
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
     9
from __future__ import absolute_import
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    10
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    11
import errno
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    12
import os
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    13
import socket
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    14
import sys
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    15
import traceback
36803
8e1556ac01bb hgweb: validate WSGI environment dict
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
    16
import wsgiref.validate
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    17
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    18
from ..i18n import _
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    19
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    20
from .. import (
34706
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    21
    encoding,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    22
    error,
30639
d524c88511a7 py3: replace os.name with pycompat.osname (part 1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30264
diff changeset
    23
    pycompat,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    24
    util,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    25
)
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    26
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29555
diff changeset
    27
httpservermod = util.httpserver
29433
33770d2b6cf9 py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28883
diff changeset
    28
socketserver = util.socketserver
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 27046
diff changeset
    29
urlerr = util.urlerr
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 27046
diff changeset
    30
urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 27046
diff changeset
    31
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    32
from . import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    33
    common,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
    34
)
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    35
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    36
def _splitURI(uri):
17427
57c6c24b9bc4 improve some comments and docstrings, fixing issues found when spell checking
Mads Kiilerich <mads@kiilerich.com>
parents: 17424
diff changeset
    37
    """Return path and query that has been split from uri
2123
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    38
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    39
    Just like CGI environment, the path is unquoted, the query is
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    40
    not.
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    41
    """
34700
8e5132ece156 hgweb: more native string treatment in query string parsing
Augie Fackler <augie@google.com>
parents: 34645
diff changeset
    42
    if r'?' in uri:
8e5132ece156 hgweb: more native string treatment in query string parsing
Augie Fackler <augie@google.com>
parents: 34645
diff changeset
    43
        path, query = uri.split(r'?', 1)
2123
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    44
    else:
34700
8e5132ece156 hgweb: more native string treatment in query string parsing
Augie Fackler <augie@google.com>
parents: 34645
diff changeset
    45
        path, query = uri, r''
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 27046
diff changeset
    46
    return urlreq.unquote(path), query
2123
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    47
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    48
class _error_logger(object):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    49
    def __init__(self, handler):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    50
        self.handler = handler
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    51
    def flush(self):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    52
        pass
3130
2e043c9a38a6 hgweb: fix errors spotted by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3079
diff changeset
    53
    def write(self, str):
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    54
        self.writelines(str.split('\n'))
3130
2e043c9a38a6 hgweb: fix errors spotted by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3079
diff changeset
    55
    def writelines(self, seq):
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    56
        for msg in seq:
41430
52a4a3e7cc6a py3: force hgweb.server error log to internally write unicode
Matt Harbison <matt_harbison@yahoo.com>
parents: 41428
diff changeset
    57
            self.handler.log_error(r"HG error:  %s", encoding.strfromlocal(msg))
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    58
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29555
diff changeset
    59
class _httprequesthandler(httpservermod.basehttprequesthandler):
4870
8f430b1b3025 Make hg serve set the wsgi.url_scheme property correctly.
Wesley J. Landaker <wjl@icecavern.net>
parents: 4868
diff changeset
    60
8f430b1b3025 Make hg serve set the wsgi.url_scheme property correctly.
Wesley J. Landaker <wjl@icecavern.net>
parents: 4868
diff changeset
    61
    url_scheme = 'http'
4957
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4871
diff changeset
    62
12783
191d0fd5c2fd hgweb: refactor all pyOpenSSL references into one class
Mads Kiilerich <mads@kiilerich.com>
parents: 12740
diff changeset
    63
    @staticmethod
29553
cd3e58862cab hgweb: pass ui into preparehttpserver
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29433
diff changeset
    64
    def preparehttpserver(httpserver, ui):
12783
191d0fd5c2fd hgweb: refactor all pyOpenSSL references into one class
Mads Kiilerich <mads@kiilerich.com>
parents: 12740
diff changeset
    65
        """Prepare .socket of new HTTPServer instance"""
191d0fd5c2fd hgweb: refactor all pyOpenSSL references into one class
Mads Kiilerich <mads@kiilerich.com>
parents: 12740
diff changeset
    66
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    67
    def __init__(self, *args, **kargs):
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
    68
        self.protocol_version = r'HTTP/1.1'
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29555
diff changeset
    69
        httpservermod.basehttprequesthandler.__init__(self, *args, **kargs)
1498
78590fb4a82b hgweb: Added archive download buttons to manifest page.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1473
diff changeset
    70
5549
f2f42262adbd hgweb.server: flush log files after every access
Patrick Mezard <pmezard@gmail.com>
parents: 5150
diff changeset
    71
    def _log_any(self, fp, format, *args):
34706
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    72
        fp.write(pycompat.sysbytes(
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    73
            r"%s - - [%s] %s" % (self.client_address[0],
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    74
                                 self.log_date_time_string(),
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    75
                                 format % args)) + '\n')
5549
f2f42262adbd hgweb.server: flush log files after every access
Patrick Mezard <pmezard@gmail.com>
parents: 5150
diff changeset
    76
        fp.flush()
f2f42262adbd hgweb.server: flush log files after every access
Patrick Mezard <pmezard@gmail.com>
parents: 5150
diff changeset
    77
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    78
    def log_error(self, format, *args):
5549
f2f42262adbd hgweb.server: flush log files after every access
Patrick Mezard <pmezard@gmail.com>
parents: 5150
diff changeset
    79
        self._log_any(self.server.errorlog, format, *args)
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
    80
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    81
    def log_message(self, format, *args):
5549
f2f42262adbd hgweb.server: flush log files after every access
Patrick Mezard <pmezard@gmail.com>
parents: 5150
diff changeset
    82
        self._log_any(self.server.accesslog, format, *args)
538
7140bc781655 Add multiple keyword search to hgweb
mpm@selenic.com
parents: 536
diff changeset
    83
34706
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    84
    def log_request(self, code=r'-', size=r'-'):
19877
52ed85d9ac26 hgweb: log headers only if headers were successfully parsed
David Soria Parra <dsp@experimentalworks.net>
parents: 18380
diff changeset
    85
        xheaders = []
52ed85d9ac26 hgweb: log headers only if headers were successfully parsed
David Soria Parra <dsp@experimentalworks.net>
parents: 18380
diff changeset
    86
        if util.safehasattr(self, 'headers'):
52ed85d9ac26 hgweb: log headers only if headers were successfully parsed
David Soria Parra <dsp@experimentalworks.net>
parents: 18380
diff changeset
    87
            xheaders = [h for h in self.headers.items()
34706
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    88
                        if h[0].startswith(r'x-')]
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    89
        self.log_message(r'"%s" %s %s%s',
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13570
diff changeset
    90
                         self.requestline, str(code), str(size),
34706
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
    91
                         r''.join([r' %s:%s' % h for h in sorted(xheaders)]))
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 13570
diff changeset
    92
4860
f3802f9f1840 Add SSL support to hg serve, activated via --certificate option
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
    93
    def do_write(self):
f3802f9f1840 Add SSL support to hg serve, activated via --certificate option
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
    94
        try:
f3802f9f1840 Add SSL support to hg serve, activated via --certificate option
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
    95
            self.do_hgweb()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
    96
        except socket.error as inst:
40874
348352658e4b py3: stop subscripting socket.error
Matt Harbison <matt_harbison@yahoo.com>
parents: 39954
diff changeset
    97
            if inst.errno != errno.EPIPE:
4860
f3802f9f1840 Add SSL support to hg serve, activated via --certificate option
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
    98
                raise
f3802f9f1840 Add SSL support to hg serve, activated via --certificate option
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
    99
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   100
    def do_POST(self):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   101
        try:
4860
f3802f9f1840 Add SSL support to hg serve, activated via --certificate option
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
   102
            self.do_write()
13443
8fa83d7159eb serve: catch and log all Exceptions, not only StandardException
Mads Kiilerich <mads@kiilerich.com>
parents: 12797
diff changeset
   103
        except Exception:
41462
9b2b8794f801 hgweb: log error before attempting I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41430
diff changeset
   104
            # I/O below could raise another exception. So log the original
9b2b8794f801 hgweb: log error before attempting I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41430
diff changeset
   105
            # exception first to ensure it is recorded.
34706
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
   106
            tb = r"".join(traceback.format_exception(*sys.exc_info()))
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
   107
            # We need a native-string newline to poke in the log
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
   108
            # message, because we won't get a newline when using an
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
   109
            # r-string. This is the easy way out.
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
   110
            newline = chr(10)
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
   111
            self.log_error(r"Exception happened during processing "
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
   112
                           r"request '%s':%s%s", self.path, newline, tb)
133
fb84d3e71042 added template support for some hgweb output, also, template files for
jake@edge2.net
parents: 132
diff changeset
   113
41462
9b2b8794f801 hgweb: log error before attempting I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41430
diff changeset
   114
            self._start_response(r"500 Internal Server Error", [])
9b2b8794f801 hgweb: log error before attempting I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41430
diff changeset
   115
            self._write(b"Internal Server Error")
9b2b8794f801 hgweb: log error before attempting I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41430
diff changeset
   116
            self._done()
9b2b8794f801 hgweb: log error before attempting I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41430
diff changeset
   117
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 37009
diff changeset
   118
    def do_PUT(self):
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 37009
diff changeset
   119
        self.do_POST()
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 37009
diff changeset
   120
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   121
    def do_GET(self):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   122
        self.do_POST()
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
   123
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   124
    def do_hgweb(self):
34720
60e7da55e5e6 hgweb: set sent_headers attr as early as practical
Augie Fackler <augie@google.com>
parents: 34719
diff changeset
   125
        self.sent_headers = False
5835
bd34f0ac3cb0 adding "prefix" option to "hg serve" (command line and [web] section)
Michele Cella <michele.cella@gmail.com>
parents: 5690
diff changeset
   126
        path, query = _splitURI(self.path)
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
   127
37156
7de7bd407251 server: ensure the incoming request falls under the prefix value
Matt Harbison <matt_harbison@yahoo.com>
parents: 34740
diff changeset
   128
        # Ensure the slicing of path below is valid
7de7bd407251 server: ensure the incoming request falls under the prefix value
Matt Harbison <matt_harbison@yahoo.com>
parents: 34740
diff changeset
   129
        if (path != self.server.prefix
7de7bd407251 server: ensure the incoming request falls under the prefix value
Matt Harbison <matt_harbison@yahoo.com>
parents: 34740
diff changeset
   130
            and not path.startswith(self.server.prefix + b'/')):
38297
9f499d28efb4 hgweb: pass a sysstr to low-level _start_response method
Augie Fackler <augie@google.com>
parents: 37788
diff changeset
   131
            self._start_response(pycompat.strurl(common.statusmessage(404)),
9f499d28efb4 hgweb: pass a sysstr to low-level _start_response method
Augie Fackler <augie@google.com>
parents: 37788
diff changeset
   132
                                 [])
41023
197f092b2cd9 server: always close http socket if responding with an error (issue6033)
Augie Fackler <raf@durin42.com>
parents: 39954
diff changeset
   133
            if self.command == 'POST':
197f092b2cd9 server: always close http socket if responding with an error (issue6033)
Augie Fackler <raf@durin42.com>
parents: 39954
diff changeset
   134
                # Paranoia: tell the client we're going to close the
197f092b2cd9 server: always close http socket if responding with an error (issue6033)
Augie Fackler <raf@durin42.com>
parents: 39954
diff changeset
   135
                # socket so they don't try and reuse a socket that
197f092b2cd9 server: always close http socket if responding with an error (issue6033)
Augie Fackler <raf@durin42.com>
parents: 39954
diff changeset
   136
                # might have a POST body waiting to confuse us. We do
197f092b2cd9 server: always close http socket if responding with an error (issue6033)
Augie Fackler <raf@durin42.com>
parents: 39954
diff changeset
   137
                # this by directly munging self.saved_headers because
197f092b2cd9 server: always close http socket if responding with an error (issue6033)
Augie Fackler <raf@durin42.com>
parents: 39954
diff changeset
   138
                # self._start_response ignores Connection headers.
197f092b2cd9 server: always close http socket if responding with an error (issue6033)
Augie Fackler <raf@durin42.com>
parents: 39954
diff changeset
   139
                self.saved_headers = [(r'Connection', r'Close')]
38297
9f499d28efb4 hgweb: pass a sysstr to low-level _start_response method
Augie Fackler <augie@google.com>
parents: 37788
diff changeset
   140
            self._write(b"Not Found")
37156
7de7bd407251 server: ensure the incoming request falls under the prefix value
Matt Harbison <matt_harbison@yahoo.com>
parents: 34740
diff changeset
   141
            self._done()
7de7bd407251 server: ensure the incoming request falls under the prefix value
Matt Harbison <matt_harbison@yahoo.com>
parents: 34740
diff changeset
   142
            return
7de7bd407251 server: ensure the incoming request falls under the prefix value
Matt Harbison <matt_harbison@yahoo.com>
parents: 34740
diff changeset
   143
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   144
        env = {}
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   145
        env[r'GATEWAY_INTERFACE'] = r'CGI/1.1'
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   146
        env[r'REQUEST_METHOD'] = self.command
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   147
        env[r'SERVER_NAME'] = self.server.server_name
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   148
        env[r'SERVER_PORT'] = str(self.server.server_port)
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   149
        env[r'REQUEST_URI'] = self.path
36802
7fc80c982656 hgweb: ensure all wsgi environment values are str
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36779
diff changeset
   150
        env[r'SCRIPT_NAME'] = pycompat.sysstr(self.server.prefix)
7fc80c982656 hgweb: ensure all wsgi environment values are str
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36779
diff changeset
   151
        env[r'PATH_INFO'] = pycompat.sysstr(path[len(self.server.prefix):])
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   152
        env[r'REMOTE_HOST'] = self.client_address[0]
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   153
        env[r'REMOTE_ADDR'] = self.client_address[0]
36803
8e1556ac01bb hgweb: validate WSGI environment dict
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   154
        env[r'QUERY_STRING'] = query or r''
1579
85803ec2daab Remove tabs, and trailing whitespace from hgweb.py
Josef "Jeff" Sipek <jeffpc@optonline.net>
parents: 1575
diff changeset
   155
34719
6e1b05692b2c hgweb: detect Python 3-era libraries and use modern attribute names
Augie Fackler <augie@google.com>
parents: 34718
diff changeset
   156
        if pycompat.ispy3:
6e1b05692b2c hgweb: detect Python 3-era libraries and use modern attribute names
Augie Fackler <augie@google.com>
parents: 34718
diff changeset
   157
            if self.headers.get_content_type() is None:
6e1b05692b2c hgweb: detect Python 3-era libraries and use modern attribute names
Augie Fackler <augie@google.com>
parents: 34718
diff changeset
   158
                env[r'CONTENT_TYPE'] = self.headers.get_default_type()
6e1b05692b2c hgweb: detect Python 3-era libraries and use modern attribute names
Augie Fackler <augie@google.com>
parents: 34718
diff changeset
   159
            else:
6e1b05692b2c hgweb: detect Python 3-era libraries and use modern attribute names
Augie Fackler <augie@google.com>
parents: 34718
diff changeset
   160
                env[r'CONTENT_TYPE'] = self.headers.get_content_type()
37591
b5ca5d34fe8d hgweb: use native strings when interfacing with stdlib headers
Augie Fackler <augie@google.com>
parents: 37147
diff changeset
   161
            length = self.headers.get(r'content-length')
34719
6e1b05692b2c hgweb: detect Python 3-era libraries and use modern attribute names
Augie Fackler <augie@google.com>
parents: 34718
diff changeset
   162
        else:
34718
01206460897a server: indent block that's about to get conditionalized
Augie Fackler <augie@google.com>
parents: 34706
diff changeset
   163
            if self.headers.typeheader is None:
01206460897a server: indent block that's about to get conditionalized
Augie Fackler <augie@google.com>
parents: 34706
diff changeset
   164
                env[r'CONTENT_TYPE'] = self.headers.type
01206460897a server: indent block that's about to get conditionalized
Augie Fackler <augie@google.com>
parents: 34706
diff changeset
   165
            else:
01206460897a server: indent block that's about to get conditionalized
Augie Fackler <augie@google.com>
parents: 34706
diff changeset
   166
                env[r'CONTENT_TYPE'] = self.headers.typeheader
37591
b5ca5d34fe8d hgweb: use native strings when interfacing with stdlib headers
Augie Fackler <augie@google.com>
parents: 37147
diff changeset
   167
            length = self.headers.getheader(r'content-length')
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   168
        if length:
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   169
            env[r'CONTENT_LENGTH'] = length
4633
ff7253a0d1da Cleanup of whitespace, indentation and line continuation.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4534
diff changeset
   170
        for header in [h for h in self.headers.keys()
41428
4045ab21945a hgweb: ensure Content-Length and Content-Type are not promoted to HTTP_ on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 41129
diff changeset
   171
                      if h.lower() not in (r'content-type', r'content-length')]:
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   172
            hkey = r'HTTP_' + header.replace(r'-', r'_').upper()
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   173
            hval = self.headers.get(header)
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   174
            hval = hval.replace(r'\n', r'').strip()
2505
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
   175
            if hval:
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
   176
                env[hkey] = hval
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   177
        env[r'SERVER_PROTOCOL'] = self.request_version
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   178
        env[r'wsgi.version'] = (1, 0)
36802
7fc80c982656 hgweb: ensure all wsgi environment values are str
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36779
diff changeset
   179
        env[r'wsgi.url_scheme'] = pycompat.sysstr(self.url_scheme)
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   180
        if env.get(r'HTTP_EXPECT', '').lower() == '100-continue':
13570
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13443
diff changeset
   181
            self.rfile = common.continuereader(self.rfile, self.wfile.write)
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13443
diff changeset
   182
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   183
        env[r'wsgi.input'] = self.rfile
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   184
        env[r'wsgi.errors'] = _error_logger(self)
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   185
        env[r'wsgi.multithread'] = isinstance(self.server,
29433
33770d2b6cf9 py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28883
diff changeset
   186
                                             socketserver.ThreadingMixIn)
39834
d1e0b905c59d py3: conditionalize access to socketserver.ForkingMixIn
Matt Harbison <matt_harbison@yahoo.com>
parents: 39827
diff changeset
   187
        if util.safehasattr(socketserver, 'ForkingMixIn'):
d1e0b905c59d py3: conditionalize access to socketserver.ForkingMixIn
Matt Harbison <matt_harbison@yahoo.com>
parents: 39827
diff changeset
   188
            env[r'wsgi.multiprocess'] = isinstance(self.server,
d1e0b905c59d py3: conditionalize access to socketserver.ForkingMixIn
Matt Harbison <matt_harbison@yahoo.com>
parents: 39827
diff changeset
   189
                                                   socketserver.ForkingMixIn)
d1e0b905c59d py3: conditionalize access to socketserver.ForkingMixIn
Matt Harbison <matt_harbison@yahoo.com>
parents: 39827
diff changeset
   190
        else:
d1e0b905c59d py3: conditionalize access to socketserver.ForkingMixIn
Matt Harbison <matt_harbison@yahoo.com>
parents: 39827
diff changeset
   191
            env[r'wsgi.multiprocess'] = False
d1e0b905c59d py3: conditionalize access to socketserver.ForkingMixIn
Matt Harbison <matt_harbison@yahoo.com>
parents: 39827
diff changeset
   192
34512
482d6f6dba91 hgweb: when constructing or adding to a wsgi environ dict, use native strs
Augie Fackler <augie@google.com>
parents: 34376
diff changeset
   193
        env[r'wsgi.run_once'] = 0
601
8865eb8ade99 Add globals to templater/fixup RSS
mpm@selenic.com
parents: 600
diff changeset
   194
36803
8e1556ac01bb hgweb: validate WSGI environment dict
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   195
        wsgiref.validate.check_environ(env)
8e1556ac01bb hgweb: validate WSGI environment dict
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   196
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   197
        self.saved_status = None
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   198
        self.saved_headers = []
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   199
        self.length = None
18354
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   200
        self._chunked = None
6784
18c429ea3a0e hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6403
diff changeset
   201
        for chunk in self.server.application(env, self._start_response):
18c429ea3a0e hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6403
diff changeset
   202
            self._write(chunk)
18349
c007e5c54b16 serve: send response headers even if response has no body
Mads Kiilerich <mads@kiilerich.com>
parents: 17427
diff changeset
   203
        if not self.sent_headers:
c007e5c54b16 serve: send response headers even if response has no body
Mads Kiilerich <mads@kiilerich.com>
parents: 17427
diff changeset
   204
            self.send_headers()
18354
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   205
        self._done()
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   206
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   207
    def send_headers(self):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   208
        if not self.saved_status:
8663
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
   209
            raise AssertionError("Sending headers before "
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
   210
                                 "start_response() called")
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   211
        saved_status = self.saved_status.split(None, 1)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   212
        saved_status[0] = int(saved_status[0])
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   213
        self.send_response(*saved_status)
18354
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   214
        self.length = None
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   215
        self._chunked = False
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   216
        for h in self.saved_headers:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   217
            self.send_header(*h)
39954
8c7ecd32ccce py3: use system strings in HTTP server code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39834
diff changeset
   218
            if h[0].lower() == r'content-length':
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   219
                self.length = int(h[1])
18380
a4d7fd7ad1f7 serve: don't send any content headers with 304 responses
Mads Kiilerich <madski@unity3d.com>
parents: 18354
diff changeset
   220
        if (self.length is None and
a4d7fd7ad1f7 serve: don't send any content headers with 304 responses
Mads Kiilerich <madski@unity3d.com>
parents: 18354
diff changeset
   221
            saved_status[0] != common.HTTP_NOT_MODIFIED):
18354
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   222
            self._chunked = (not self.close_connection and
39954
8c7ecd32ccce py3: use system strings in HTTP server code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39834
diff changeset
   223
                             self.request_version == r'HTTP/1.1')
18354
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   224
            if self._chunked:
34740
b2601c5977a4 hgweb: more "http headers are native strs" cleanup
Augie Fackler <augie@google.com>
parents: 34720
diff changeset
   225
                self.send_header(r'Transfer-Encoding', r'chunked')
18354
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   226
            else:
34740
b2601c5977a4 hgweb: more "http headers are native strs" cleanup
Augie Fackler <augie@google.com>
parents: 34720
diff changeset
   227
                self.send_header(r'Connection', r'close')
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   228
        self.end_headers()
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   229
        self.sent_headers = True
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   230
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   231
    def _start_response(self, http_status, headers, exc_info=None):
38298
af0e88e64ede hgweb: insist http_status value is a sysstr
Augie Fackler <augie@google.com>
parents: 38297
diff changeset
   232
        assert isinstance(http_status, str)
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   233
        code, msg = http_status.split(None, 1)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   234
        code = int(code)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   235
        self.saved_status = http_status
39954
8c7ecd32ccce py3: use system strings in HTTP server code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39834
diff changeset
   236
        bad_headers = (r'connection', r'transfer-encoding')
4633
ff7253a0d1da Cleanup of whitespace, indentation and line continuation.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4534
diff changeset
   237
        self.saved_headers = [h for h in headers
ff7253a0d1da Cleanup of whitespace, indentation and line continuation.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4534
diff changeset
   238
                              if h[0].lower() not in bad_headers]
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   239
        return self._write
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   240
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   241
    def _write(self, data):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   242
        if not self.saved_status:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   243
            raise AssertionError("data written before start_response() called")
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   244
        elif not self.sent_headers:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   245
            self.send_headers()
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   246
        if self.length is not None:
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   247
            if len(data) > self.length:
8663
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
   248
                raise AssertionError("Content-length header sent, but more "
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
   249
                                     "bytes than specified are being written.")
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   250
            self.length = self.length - len(data)
18354
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   251
        elif self._chunked and data:
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   252
            data = '%x\r\n%s\r\n' % (len(data), data)
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   253
        self.wfile.write(data)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   254
        self.wfile.flush()
136
0e8d60d2bb2b added annotate
jake@edge2.net
parents: 135
diff changeset
   255
18354
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   256
    def _done(self):
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   257
        if self._chunked:
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   258
            self.wfile.write('0\r\n\r\n')
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   259
            self.wfile.flush()
cf5c76017e11 serve: use chunked encoding in hgweb responses
Mads Kiilerich <mads@kiilerich.com>
parents: 18353
diff changeset
   260
37009
5890e5872f36 hgweb: allow defining Server response header for HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36803
diff changeset
   261
    def version_string(self):
5890e5872f36 hgweb: allow defining Server response header for HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36803
diff changeset
   262
        if self.server.serverheader:
38594
b263133eeb5a py3: convert server-string to unicode to make http library happy
Yuya Nishihara <yuya@tcha.org>
parents: 38298
diff changeset
   263
            return encoding.strfromlocal(self.server.serverheader)
37009
5890e5872f36 hgweb: allow defining Server response header for HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36803
diff changeset
   264
        return httpservermod.basehttprequesthandler.version_string(self)
5890e5872f36 hgweb: allow defining Server response header for HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36803
diff changeset
   265
12784
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   266
class _httprequesthandlerssl(_httprequesthandler):
26202
04af43009c8b hgweb.server: fix _httprequesthandlerssl help text
timeless@mozdev.org
parents: 25660
diff changeset
   267
    """HTTPS handler based on Python's ssl module"""
12784
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   268
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   269
    url_scheme = 'https'
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   270
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   271
    @staticmethod
29553
cd3e58862cab hgweb: pass ui into preparehttpserver
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29433
diff changeset
   272
    def preparehttpserver(httpserver, ui):
12784
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   273
        try:
29555
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   274
            from .. import sslutil
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   275
            sslutil.modernssl
12784
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   276
        except ImportError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26202
diff changeset
   277
            raise error.Abort(_("SSL support is unavailable"))
29553
cd3e58862cab hgweb: pass ui into preparehttpserver
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29433
diff changeset
   278
cd3e58862cab hgweb: pass ui into preparehttpserver
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29433
diff changeset
   279
        certfile = ui.config('web', 'certificate')
29555
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   280
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   281
        # These config options are currently only meant for testing. Use
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   282
        # at your own risk.
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   283
        cafile = ui.config('devel', 'servercafile')
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   284
        reqcert = ui.configbool('devel', 'serverrequirecert')
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   285
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   286
        httpserver.socket = sslutil.wrapserversocket(httpserver.socket,
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   287
                                                     ui,
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   288
                                                     certfile=certfile,
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   289
                                                     cafile=cafile,
121d11814c62 hgweb: use sslutil.wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29553
diff changeset
   290
                                                     requireclientcert=reqcert)
12784
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   291
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   292
    def setup(self):
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   293
        self.connection = self.request
36779
bf9a04d78084 hgweb: adapt to socket._fileobject changes in Python 3
Augie Fackler <augie@google.com>
parents: 36257
diff changeset
   294
        self.rfile = self.request.makefile(r"rb", self.rbufsize)
bf9a04d78084 hgweb: adapt to socket._fileobject changes in Python 3
Augie Fackler <augie@google.com>
parents: 36257
diff changeset
   295
        self.wfile = self.request.makefile(r"wb", self.wbufsize)
12784
763be3cd084a hgweb: use Pythons ssl module for HTTPS serve when using Python 2.6 or later
Mads Kiilerich <mads@kiilerich.com>
parents: 12783
diff changeset
   296
10639
a6808629f450 server: externalize and streamline mixin setup
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10638
diff changeset
   297
try:
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
   298
    import threading
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26848
diff changeset
   299
    threading.activeCount() # silence pyflakes and bypass demandimport
29433
33770d2b6cf9 py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28883
diff changeset
   300
    _mixin = socketserver.ThreadingMixIn
10639
a6808629f450 server: externalize and streamline mixin setup
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10638
diff changeset
   301
except ImportError:
14957
16e5271b216f hgweb: move remaining hasattr calls to safehasattr
Augie Fackler <durin42@gmail.com>
parents: 14764
diff changeset
   302
    if util.safehasattr(os, "fork"):
29433
33770d2b6cf9 py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28883
diff changeset
   303
        _mixin = socketserver.ForkingMixIn
10639
a6808629f450 server: externalize and streamline mixin setup
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10638
diff changeset
   304
    else:
14764
a7d5816087a9 classes: fix class style problems found by b071cd58af50
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14093
diff changeset
   305
        class _mixin(object):
10639
a6808629f450 server: externalize and streamline mixin setup
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10638
diff changeset
   306
            pass
a6808629f450 server: externalize and streamline mixin setup
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10638
diff changeset
   307
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   308
def openlog(opt, default):
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   309
    if opt and opt != '-':
36257
46c97973ee46 hgweb: open server logs in binary mode
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
   310
        return open(opt, 'ab')
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   311
    return default
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   312
30082
ebc03e64548a hgweb: fix the MRO in Python 3
Martijn Pieters <mjpieters@fb.com>
parents: 29566
diff changeset
   313
class MercurialHTTPServer(_mixin, httpservermod.httpserver, object):
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   314
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   315
    # SO_REUSEADDR has broken semantics on windows
34645
75979c8d4572 codemod: use pycompat.iswindows
Jun Wu <quark@fb.com>
parents: 34512
diff changeset
   316
    if pycompat.iswindows:
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   317
        allow_reuse_address = 0
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   318
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   319
    def __init__(self, ui, app, addr, handler, **kwargs):
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29555
diff changeset
   320
        httpservermod.httpserver.__init__(self, addr, handler, **kwargs)
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   321
        self.daemon_threads = True
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   322
        self.application = app
2124
27fd8b7a6c51 Cleaned trailing whitespace in hgweb.py, removed command line shortcut for webdir-conf.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2123
diff changeset
   323
29553
cd3e58862cab hgweb: pass ui into preparehttpserver
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29433
diff changeset
   324
        handler.preparehttpserver(self, ui)
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   325
34243
d24816dfdcff configitems: register the 'web.prefix' config
Boris Feld <boris.feld@octobus.net>
parents: 34242
diff changeset
   326
        prefix = ui.config('web', 'prefix')
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   327
        if prefix:
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   328
            prefix = '/' + prefix.strip('/')
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   329
        self.prefix = prefix
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   330
34227
ac96ff471c9a configitems: register the 'web.accesslog' config
Boris Feld <boris.feld@octobus.net>
parents: 30639
diff changeset
   331
        alog = openlog(ui.config('web', 'accesslog'), ui.fout)
34240
c97a750c28a5 configitems: register the 'web.errorlog' config
Boris Feld <boris.feld@octobus.net>
parents: 34228
diff changeset
   332
        elog = openlog(ui.config('web', 'errorlog'), ui.ferr)
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   333
        self.accesslog = alog
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   334
        self.errorlog = elog
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   335
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   336
        self.addr, self.port = self.socket.getsockname()[0:2]
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   337
        self.fqaddr = socket.getfqdn(addr[0])
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   338
37009
5890e5872f36 hgweb: allow defining Server response header for HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36803
diff changeset
   339
        self.serverheader = ui.config('web', 'server-header')
5890e5872f36 hgweb: allow defining Server response header for HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36803
diff changeset
   340
10643
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   341
class IPv6HTTPServer(MercurialHTTPServer):
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   342
    address_family = getattr(socket, 'AF_INET6', None)
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   343
    def __init__(self, *args, **kwargs):
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   344
        if self.address_family is None:
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   345
            raise error.RepoError(_('IPv6 is not available on this system'))
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   346
        super(IPv6HTTPServer, self).__init__(*args, **kwargs)
1874697a8863 server: unnest server classes into module namespace
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10642
diff changeset
   347
10644
63948e7d37f7 server: initialize wsgi app in command, then wrap server around it
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10643
diff changeset
   348
def create_server(ui, app):
938
54b2a42e501e hgweb: add [web] section to hgrc
mpm@selenic.com
parents: 937
diff changeset
   349
10644
63948e7d37f7 server: initialize wsgi app in command, then wrap server around it
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10643
diff changeset
   350
    if ui.config('web', 'certificate'):
26848
d962e955da08 hgweb.server: drop support for Python 2.4
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
   351
        handler = _httprequesthandlerssl
4860
f3802f9f1840 Add SSL support to hg serve, activated via --certificate option
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
   352
    else:
12783
191d0fd5c2fd hgweb: refactor all pyOpenSSL references into one class
Mads Kiilerich <mads@kiilerich.com>
parents: 12740
diff changeset
   353
        handler = _httprequesthandler
4860
f3802f9f1840 Add SSL support to hg serve, activated via --certificate option
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
   354
10644
63948e7d37f7 server: initialize wsgi app in command, then wrap server around it
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10643
diff changeset
   355
    if ui.configbool('web', 'ipv6'):
10641
dedf88fe945a server: abstract setup of ipv6 vs. normal server
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10640
diff changeset
   356
        cls = IPv6HTTPServer
dedf88fe945a server: abstract setup of ipv6 vs. normal server
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10640
diff changeset
   357
    else:
dedf88fe945a server: abstract setup of ipv6 vs. normal server
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10640
diff changeset
   358
        cls = MercurialHTTPServer
dedf88fe945a server: abstract setup of ipv6 vs. normal server
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10640
diff changeset
   359
8224
1075f5c1b3fa hgweb: pre-init mimetypes module (fixes ugly bug in python-2.6.2 mimetypes)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7928
diff changeset
   360
    # ugly hack due to python issue5853 (for threaded use)
20357
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   361
    try:
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   362
        import mimetypes
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   363
        mimetypes.init()
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   364
    except UnicodeDecodeError:
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   365
        # Python 2.x's mimetypes module attempts to decode strings
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   366
        # from Windows' ANSI APIs as ascii (fail), then re-encode them
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   367
        # as ascii (clown fail), because the default Python Unicode
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   368
        # codec is hardcoded as ascii.
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   369
20529
ca970d6acedb hgweb: make sure sys module is loaded prior to reload hack
Yuya Nishihara <yuya@tcha.org>
parents: 20357
diff changeset
   370
        sys.argv # unwrap demand-loader so that reload() works
20357
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   371
        reload(sys) # resurrect sys.setdefaultencoding()
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   372
        oldenc = sys.getdefaultencoding()
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   373
        sys.setdefaultencoding("latin1") # or any full 8-bit encoding
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   374
        mimetypes.init()
6863d42eb59a hgweb: hack around mimetypes encoding thinko (issue4160)
Matt Mackall <mpm@selenic.com>
parents: 19877
diff changeset
   375
        sys.setdefaultencoding(oldenc)
8224
1075f5c1b3fa hgweb: pre-init mimetypes module (fixes ugly bug in python-2.6.2 mimetypes)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7928
diff changeset
   376
34228
af4f0c74f8b5 configitems: register the 'web.address' config
Boris Feld <boris.feld@octobus.net>
parents: 34227
diff changeset
   377
    address = ui.config('web', 'address')
34242
e2d633f8ee65 configitems: register the 'web.port' config
Boris Feld <boris.feld@octobus.net>
parents: 34240
diff changeset
   378
    port = util.getport(ui.config('web', 'port'))
3628
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   379
    try:
10644
63948e7d37f7 server: initialize wsgi app in command, then wrap server around it
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10643
diff changeset
   380
        return cls(ui, app, (address, port), handler)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   381
    except socket.error as inst:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26202
diff changeset
   382
        raise error.Abort(_("cannot start server at '%s:%d': %s")
34706
8782076874f5 hgweb: fix logging to use native strings as appropriate
Augie Fackler <augie@google.com>
parents: 34700
diff changeset
   383
                          % (address, port, encoding.strtolocal(inst.args[1])))