mercurial/hgweb/server.py
author Brendan Cully <brendan@kublai.com>
Mon, 02 Jul 2007 22:34:38 -0700
changeset 4781 38bf55d2e41f
parent 4635 63b9d2deed48
child 4835 9858477ed74c
child 4860 f3802f9f1840
permissions -rw-r--r--
Merge with tah
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
#
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     6
# This software may be used and distributed according to the terms
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     7
# of the GNU General Public License, incorporated herein by reference.
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     8
4016
a195f11ed1a2 sync with -stable
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3877 4015
diff changeset
     9
import os, sys, errno, urllib, BaseHTTPServer, socket, SocketServer, traceback
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3836
diff changeset
    10
from mercurial import ui, hg, util, templater
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3836
diff changeset
    11
from hgweb_mod import hgweb
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3836
diff changeset
    12
from hgwebdir_mod import hgwebdir
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3836
diff changeset
    13
from request import wsgiapplication
2311
b832b6eb65ab Moving hgweb.py into it's own module in preparation for breaking it up.
Eric Hopper <hopper@omnifarious.org>
parents: 2275
diff changeset
    14
from mercurial.i18n import gettext as _
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    15
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    16
def _splitURI(uri):
2123
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    17
    """ Return path and query splited from uri
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    18
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    19
    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
    20
    not.
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    21
    """
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    22
    if '?' in uri:
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    23
        path, query = uri.split('?', 1)
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    24
    else:
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    25
        path, query = uri, ''
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    26
    return urllib.unquote(path), query
c0729a7f6f8a Fixed path handling of the standalone server, fixed typo.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2122
diff changeset
    27
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    28
class _error_logger(object):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    29
    def __init__(self, handler):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    30
        self.handler = handler
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    31
    def flush(self):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    32
        pass
3130
2e043c9a38a6 hgweb: fix errors spotted by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3079
diff changeset
    33
    def write(self, str):
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    34
        self.writelines(str.split('\n'))
3130
2e043c9a38a6 hgweb: fix errors spotted by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3079
diff changeset
    35
    def writelines(self, seq):
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    36
        for msg in seq:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    37
            self.handler.log_error("HG error:  %s", msg)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
    38
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    39
class _hgwebhandler(object, BaseHTTPServer.BaseHTTPRequestHandler):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    40
    def __init__(self, *args, **kargs):
2434
a2df85adface http server: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2404
diff changeset
    41
        self.protocol_version = 'HTTP/1.1'
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    42
        BaseHTTPServer.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
    43
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    44
    def log_error(self, format, *args):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    45
        errorlog = self.server.errorlog
4359
80d3f6f0d8e5 hg serve: don't do DNS lookups
Matt Mackall <mpm@selenic.com>
parents: 4245
diff changeset
    46
        errorlog.write("%s - - [%s] %s\n" % (self.client_address[0],
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    47
                                             self.log_date_time_string(),
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    48
                                             format % args))
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
    49
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    50
    def log_message(self, format, *args):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    51
        accesslog = self.server.accesslog
4359
80d3f6f0d8e5 hg serve: don't do DNS lookups
Matt Mackall <mpm@selenic.com>
parents: 4245
diff changeset
    52
        accesslog.write("%s - - [%s] %s\n" % (self.client_address[0],
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    53
                                              self.log_date_time_string(),
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    54
                                              format % args))
538
7140bc781655 Add multiple keyword search to hgweb
mpm@selenic.com
parents: 536
diff changeset
    55
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    56
    def do_POST(self):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    57
        try:
4015
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    58
            try:
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    59
                self.do_hgweb()
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    60
            except socket.error, inst:
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    61
                if inst[0] != errno.EPIPE:
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    62
                    raise
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    63
        except StandardError, inst:
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    64
            self._start_response("500 Internal Server Error", [])
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    65
            self._write("Internal Server Error")
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    66
            tb = "".join(traceback.format_exception(*sys.exc_info()))
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    67
            self.log_error("Exception happened during processing request '%s':\n%s",
769be3c57564 Handle exceptions in do_hgweb: Send "Internal Server Error", log traceback
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3836
diff changeset
    68
                           self.path, tb)
133
fb84d3e71042 added template support for some hgweb output, also, template files for
jake@edge2.net
parents: 132
diff changeset
    69
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    70
    def do_GET(self):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    71
        self.do_POST()
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
    72
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    73
    def do_hgweb(self):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    74
        path_info, query = _splitURI(self.path)
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    75
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    76
        env = {}
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    77
        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    78
        env['REQUEST_METHOD'] = self.command
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    79
        env['SERVER_NAME'] = self.server.server_name
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    80
        env['SERVER_PORT'] = str(self.server.server_port)
3263
3207e30bf468 hgweb: support for generating and parsing NWI URLs
Brendan Cully <brendan@kublai.com>
parents: 3130
diff changeset
    81
        env['REQUEST_URI'] = self.path
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    82
        env['PATH_INFO'] = path_info
4359
80d3f6f0d8e5 hg serve: don't do DNS lookups
Matt Mackall <mpm@selenic.com>
parents: 4245
diff changeset
    83
        env['REMOTE_HOST'] = self.client_address[0]
80d3f6f0d8e5 hg serve: don't do DNS lookups
Matt Mackall <mpm@selenic.com>
parents: 4245
diff changeset
    84
        env['REMOTE_ADDR'] = self.client_address[0]
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    85
        if query:
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    86
            env['QUERY_STRING'] = query
1579
85803ec2daab Remove tabs, and trailing whitespace from hgweb.py
Josef "Jeff" Sipek <jeffpc@optonline.net>
parents: 1575
diff changeset
    87
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    88
        if self.headers.typeheader is None:
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    89
            env['CONTENT_TYPE'] = self.headers.type
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    90
        else:
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    91
            env['CONTENT_TYPE'] = self.headers.typeheader
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    92
        length = self.headers.getheader('content-length')
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    93
        if length:
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
    94
            env['CONTENT_LENGTH'] = length
4633
ff7253a0d1da Cleanup of whitespace, indentation and line continuation.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4534
diff changeset
    95
        for header in [h for h in self.headers.keys()
2505
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
    96
                       if h not in ('content-type', 'content-length')]:
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
    97
            hkey = 'HTTP_' + header.replace('-', '_').upper()
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
    98
            hval = self.headers.getheader(header)
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
    99
            hval = hval.replace('\n', '').strip()
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
   100
            if hval:
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
   101
                env[hkey] = hval
01b856927970 Fix server to set up a more WSGI compliant environment.
Eric Hopper <hopper@omnifarious.org>
parents: 2434
diff changeset
   102
        env['SERVER_PROTOCOL'] = self.request_version
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   103
        env['wsgi.version'] = (1, 0)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   104
        env['wsgi.url_scheme'] = 'http'
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   105
        env['wsgi.input'] = self.rfile
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   106
        env['wsgi.errors'] = _error_logger(self)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   107
        env['wsgi.multithread'] = isinstance(self.server,
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   108
                                             SocketServer.ThreadingMixIn)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   109
        env['wsgi.multiprocess'] = isinstance(self.server,
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   110
                                              SocketServer.ForkingMixIn)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   111
        env['wsgi.run_once'] = 0
601
8865eb8ade99 Add globals to templater/fixup RSS
mpm@selenic.com
parents: 600
diff changeset
   112
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   113
        self.close_connection = True
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   114
        self.saved_status = None
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   115
        self.saved_headers = []
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   116
        self.sent_headers = False
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   117
        self.length = None
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   118
        req = self.server.reqmaker(env, self._start_response)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   119
        for data in req:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   120
            if data:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   121
                self._write(data)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   122
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   123
    def send_headers(self):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   124
        if not self.saved_status:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   125
            raise AssertionError("Sending headers before start_response() called")
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   126
        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
   127
        saved_status[0] = int(saved_status[0])
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   128
        self.send_response(*saved_status)
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   129
        should_close = True
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   130
        for h in self.saved_headers:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   131
            self.send_header(*h)
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   132
            if h[0].lower() == 'content-length':
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   133
                should_close = False
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   134
                self.length = int(h[1])
2582
276de216d2c5 Respect "Connection: close" headers sent by HTTP clients.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2508
diff changeset
   135
        # The value of the Connection header is a list of case-insensitive
276de216d2c5 Respect "Connection: close" headers sent by HTTP clients.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2508
diff changeset
   136
        # tokens separated by commas and optional whitespace.
2600
c4325f0a9b91 clean up trailing white space.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2582
diff changeset
   137
        if 'close' in [token.strip().lower() for token in
2582
276de216d2c5 Respect "Connection: close" headers sent by HTTP clients.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2508
diff changeset
   138
                       self.headers.get('connection', '').split(',')]:
276de216d2c5 Respect "Connection: close" headers sent by HTTP clients.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2508
diff changeset
   139
            should_close = True
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   140
        if should_close:
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   141
            self.send_header('Connection', 'close')
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   142
        self.close_connection = should_close
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   143
        self.end_headers()
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   144
        self.sent_headers = True
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   145
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   146
    def _start_response(self, http_status, headers, exc_info=None):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   147
        code, msg = http_status.split(None, 1)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   148
        code = int(code)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   149
        self.saved_status = http_status
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   150
        bad_headers = ('connection', 'transfer-encoding')
4633
ff7253a0d1da Cleanup of whitespace, indentation and line continuation.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4534
diff changeset
   151
        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
   152
                              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
   153
        return self._write
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   154
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   155
    def _write(self, data):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   156
        if not self.saved_status:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   157
            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
   158
        elif not self.sent_headers:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   159
            self.send_headers()
2508
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   160
        if self.length is not None:
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   161
            if len(data) > self.length:
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   162
                raise AssertionError("Content-length header sent, but more bytes than specified are being written.")
ab460a3f0e3a Put support for persistent connections back in.
Eric Hopper <hopper@omnifarious.org>
parents: 2507
diff changeset
   163
            self.length = self.length - len(data)
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   164
        self.wfile.write(data)
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents: 2505
diff changeset
   165
        self.wfile.flush()
136
0e8d60d2bb2b added annotate
jake@edge2.net
parents: 135
diff changeset
   166
2392
8238a3f039e6 Adjusting hgweb splitup to be a little cleaner.
Eric Hopper <hopper@omnifarious.org>
parents: 2391
diff changeset
   167
def create_server(ui, repo):
2121
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   168
    use_threads = True
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
   169
938
54b2a42e501e hgweb: add [web] section to hgrc
mpm@selenic.com
parents: 937
diff changeset
   170
    def openlog(opt, default):
54b2a42e501e hgweb: add [web] section to hgrc
mpm@selenic.com
parents: 937
diff changeset
   171
        if opt and opt != '-':
54b2a42e501e hgweb: add [web] section to hgrc
mpm@selenic.com
parents: 937
diff changeset
   172
            return open(opt, 'w')
54b2a42e501e hgweb: add [web] section to hgrc
mpm@selenic.com
parents: 937
diff changeset
   173
        return default
54b2a42e501e hgweb: add [web] section to hgrc
mpm@selenic.com
parents: 937
diff changeset
   174
2127
8a85dbbadddf Allow 'hg serve --webdir-conf foo' to be run outside a repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2124
diff changeset
   175
    address = ui.config("web", "address", "")
8a85dbbadddf Allow 'hg serve --webdir-conf foo' to be run outside a repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2124
diff changeset
   176
    port = int(ui.config("web", "port", 8000))
8a85dbbadddf Allow 'hg serve --webdir-conf foo' to be run outside a repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2124
diff changeset
   177
    use_ipv6 = ui.configbool("web", "ipv6")
8a85dbbadddf Allow 'hg serve --webdir-conf foo' to be run outside a repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2124
diff changeset
   178
    webdir_conf = ui.config("web", "webdir_conf")
8a85dbbadddf Allow 'hg serve --webdir-conf foo' to be run outside a repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2124
diff changeset
   179
    accesslog = openlog(ui.config("web", "accesslog", "-"), sys.stdout)
8a85dbbadddf Allow 'hg serve --webdir-conf foo' to be run outside a repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2124
diff changeset
   180
    errorlog = openlog(ui.config("web", "errorlog", "-"), sys.stderr)
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
   181
2121
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   182
    if use_threads:
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   183
        try:
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   184
            from threading import activeCount
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   185
        except ImportError:
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   186
            use_threads = False
938
54b2a42e501e hgweb: add [web] section to hgrc
mpm@selenic.com
parents: 937
diff changeset
   187
2121
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   188
    if use_threads:
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   189
        _mixin = SocketServer.ThreadingMixIn
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   190
    else:
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   191
        if hasattr(os, "fork"):
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   192
            _mixin = SocketServer.ForkingMixIn
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   193
        else:
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3628
diff changeset
   194
            class _mixin:
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3628
diff changeset
   195
                pass
2121
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   196
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   197
    class MercurialHTTPServer(object, _mixin, BaseHTTPServer.HTTPServer):
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4379
diff changeset
   198
4130
178007785be8 web/server: disable address reuse option for BaseHTTPServer on windows
Patrick Mezard <pmezard@gmail.com>
parents: 4091
diff changeset
   199
        # SO_REUSEADDR has broken semantics on windows
178007785be8 web/server: disable address reuse option for BaseHTTPServer on windows
Patrick Mezard <pmezard@gmail.com>
parents: 4091
diff changeset
   200
        if os.name == 'nt':
178007785be8 web/server: disable address reuse option for BaseHTTPServer on windows
Patrick Mezard <pmezard@gmail.com>
parents: 4091
diff changeset
   201
            allow_reuse_address = 0
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4379
diff changeset
   202
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   203
        def __init__(self, *args, **kargs):
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   204
            BaseHTTPServer.HTTPServer.__init__(self, *args, **kargs)
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   205
            self.accesslog = accesslog
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   206
            self.errorlog = errorlog
2650
56e98084e040 Make hgweb threads into daemon threads.
Brendan Cully <brendan@kublai.com>
parents: 2600
diff changeset
   207
            self.daemon_threads = True
4245
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   208
            def make_handler():
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   209
                if webdir_conf:
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   210
                    hgwebobj = hgwebdir(webdir_conf, ui)
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   211
                elif repo is not None:
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   212
                    hgwebobj = hgweb(hg.repository(repo.ui, repo.root))
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   213
                else:
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   214
                    raise hg.RepoError(_("There is no Mercurial repository here"
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   215
                                         " (.hg not found)"))
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   216
                return hgwebobj
bd46b83b9692 avoid wsgiapplication <-> MercurialHTTPServer circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4130
diff changeset
   217
            self.reqmaker = wsgiapplication(make_handler)
2355
eb08fb4d41e1 Splitting up hgweb so it's easier to change.
Eric Hopper <hopper@omnifarious.org>
parents: 2328
diff changeset
   218
4534
121999244123 hg serve: don't lookup user-supplied names/addresses
Matt Mackall <mpm@selenic.com>
parents: 4516
diff changeset
   219
            addr = address
121999244123 hg serve: don't lookup user-supplied names/addresses
Matt Mackall <mpm@selenic.com>
parents: 4516
diff changeset
   220
            if addr in ('', '::'):
3628
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   221
                addr = socket.gethostname()
4534
121999244123 hg serve: don't lookup user-supplied names/addresses
Matt Mackall <mpm@selenic.com>
parents: 4516
diff changeset
   222
3628
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   223
            self.addr, self.port = addr, port
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   224
2121
150cdd6c3c90 Added threading support to hg serve.
Alexander Schremmer <alex AT alexanderweb DOT de>
parents: 2119
diff changeset
   225
    class IPv6HTTPServer(MercurialHTTPServer):
881
16ce690c411d Fix problem with "hg serve" on systems not providing IPv6.
Bryan O'Sullivan <bos@serpentine.com>
parents: 858
diff changeset
   226
        address_family = getattr(socket, 'AF_INET6', None)
16ce690c411d Fix problem with "hg serve" on systems not providing IPv6.
Bryan O'Sullivan <bos@serpentine.com>
parents: 858
diff changeset
   227
16ce690c411d Fix problem with "hg serve" on systems not providing IPv6.
Bryan O'Sullivan <bos@serpentine.com>
parents: 858
diff changeset
   228
        def __init__(self, *args, **kwargs):
16ce690c411d Fix problem with "hg serve" on systems not providing IPv6.
Bryan O'Sullivan <bos@serpentine.com>
parents: 858
diff changeset
   229
            if self.address_family is None:
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
   230
                raise hg.RepoError(_('IPv6 not available on this system'))
2507
7e01da2bc7f3 Fix two small bugs that would've prevented the web interface and IPv6
Eric Hopper <hopper@omnifarious.org>
parents: 2506
diff changeset
   231
            super(IPv6HTTPServer, self).__init__(*args, **kwargs)
158
be7103467d2e Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents: 157
diff changeset
   232
3628
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   233
    try:
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   234
        if use_ipv6:
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   235
            return IPv6HTTPServer((address, port), _hgwebhandler)
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   236
        else:
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   237
            return MercurialHTTPServer((address, port), _hgwebhandler)
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   238
    except socket.error, inst:
dc3504af7722 hgweb: internalize some socket details
Matt Mackall <mpm@selenic.com>
parents: 3263
diff changeset
   239
        raise util.Abort(_('cannot start server: %s') % inst.args[1])