mercurial/hgweb/hgweb_mod.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 22 Aug 2015 18:54:34 -0700
changeset 26219 ae33fff17c1e
parent 26218 7d45ec47c0af
child 26220 a43328baa2ac
permissions -rw-r--r--
hg: establish a cache for localrepository instances hgweb contained code for determining whether a cached localrepository instance was up to date. This code was way too low-level to be in hgweb. This functionality has been moved to a new "cachedlocalrepo" class in hg.py. The code has been changed slightly to facilitate use inside a class. hgweb has been refactored to use the new API. As part of this refactor, hgweb.repo no longer exists! We're very close to using a distinct repo instance per thread. The new cache records state when it is created. This intelligence prevents an extra localrepository from being created on the first hgweb request. This is why some redundant output from test-extension.t has gone away.
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: 2361
diff changeset
     1
# hgweb/hgweb_mod.py - Web interface for a repository.
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: 4539
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: 8191
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: 9842
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
26162
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26161
diff changeset
     9
import os
18522
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
    10
from mercurial import ui, hg, hook, error, encoding, templater, util, repoview
18627
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
    11
from mercurial.templatefilters import websub
13958
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13445
diff changeset
    12
from common import get_stat, ErrorResponse, permhooks, caching
12739
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
    13
from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
    14
from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR
5566
d74fc8dec2b4 Less indirection in the WSGI web interface. This simplifies some code, and makes it more compliant with WSGI.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5565
diff changeset
    15
from request import wsgirequest
20034
1e5b38a919dd cleanup: move stdlib imports to their own import statement
Augie Fackler <raf@durin42.com>
parents: 19906
diff changeset
    16
import webcommands, protocol, webutil
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    17
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    18
perms = {
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    19
    'changegroup': 'pull',
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    20
    'changegroupsubset': 'pull',
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13571
diff changeset
    21
    'getbundle': 'pull',
11370
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
    22
    'stream_out': 'pull',
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
    23
    'listkeys': 'pull',
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    24
    'unbundle': 'push',
11370
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
    25
    'pushkey': 'push',
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    26
}
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    27
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    28
def makebreadcrumb(url, prefix=''):
18258
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    29
    '''Return a 'URL breadcrumb' list
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    30
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    31
    A 'URL breadcrumb' is a list of URL-name pairs,
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    32
    corresponding to each of the path items on a URL.
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    33
    This can be used to create path navigation entries.
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    34
    '''
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    35
    if url.endswith('/'):
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    36
        url = url[:-1]
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    37
    if prefix:
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    38
        url = '/' + prefix + url
18258
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    39
    relpath = url
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    40
    if relpath.startswith('/'):
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    41
        relpath = relpath[1:]
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    42
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    43
    breadcrumb = []
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    44
    urlel = url
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    45
    pathitems = [''] + relpath.split('/')
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    46
    for pathel in reversed(pathitems):
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    47
        if not pathel or not urlel:
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    48
            break
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    49
        breadcrumb.append({'url': urlel, 'name': pathel})
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    50
        urlel = os.path.dirname(urlel)
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    51
    return reversed(breadcrumb)
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    52
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    53
class requestcontext(object):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    54
    """Holds state/context for an individual request.
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    55
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    56
    Servers can be multi-threaded. Holding state on the WSGI application
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    57
    is prone to race conditions. Instances of this class exist to hold
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    58
    mutable and race-free state for requests.
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    59
    """
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
    60
    def __init__(self, app, repo):
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
    61
        self.repo = repo
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    62
        self.reponame = app.reponame
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    63
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    64
        self.archives = ('zip', 'gz', 'bz2')
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
    65
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    66
        self.maxchanges = self.configint('web', 'maxchanges', 10)
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    67
        self.stripecount = self.configint('web', 'stripes', 1)
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    68
        self.maxshortchanges = self.configint('web', 'maxshortchanges', 60)
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    69
        self.maxfiles = self.configint('web', 'maxfiles', 10)
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    70
        self.allowpull = self.configbool('web', 'allowpull', True)
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    71
26163
84511b1d9724 hgweb: move templatepath to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26162
diff changeset
    72
        # we use untrusted=False to prevent a repo owner from using
84511b1d9724 hgweb: move templatepath to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26162
diff changeset
    73
        # web.templates in .hg/hgrc to get access to any file readable
84511b1d9724 hgweb: move templatepath to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26162
diff changeset
    74
        # by the user running the CGI script
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    75
        self.templatepath = self.config('web', 'templates', untrusted=False)
26163
84511b1d9724 hgweb: move templatepath to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26162
diff changeset
    76
26164
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
    77
        # This object is more expensive to build than simple config values.
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
    78
        # It is shared across requests. The app will replace the object
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
    79
        # if it is updated. Since this is a reference and nothing should
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
    80
        # modify the underlying object, it should be constant for the lifetime
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
    81
        # of the request.
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    82
        self.websubtable = app.websubtable
26164
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
    83
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    84
    # Trust the settings from the .hg/hgrc files by default.
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    85
    def config(self, section, name, default=None, untrusted=True):
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    86
        return self.repo.ui.config(section, name, default,
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    87
                                   untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    88
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    89
    def configbool(self, section, name, default=False, untrusted=True):
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    90
        return self.repo.ui.configbool(section, name, default,
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    91
                                       untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    92
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    93
    def configint(self, section, name, default=None, untrusted=True):
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    94
        return self.repo.ui.configint(section, name, default,
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    95
                                      untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    96
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    97
    def configlist(self, section, name, default=None, untrusted=True):
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    98
        return self.repo.ui.configlist(section, name, default,
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
    99
                                       untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   100
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   101
    archivespecs = {
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   102
        'bz2': ('application/x-bzip2', 'tbz2', '.tar.bz2', None),
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   103
        'gz': ('application/x-gzip', 'tgz', '.tar.gz', None),
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   104
        'zip': ('application/zip', 'zip', '.zip', None),
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   105
    }
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   106
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   107
    def archivelist(self, nodeid):
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   108
        allowed = self.configlist('web', 'allow_archive')
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   109
        for typ, spec in self.archivespecs.iteritems():
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   110
            if typ in allowed or self.configbool('web', 'allow%s' % typ):
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   111
                yield {'type': typ, 'extension': spec[2], 'node': nodeid}
18258
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
   112
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   113
    def templater(self, req):
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   114
        # determine scheme, port and server name
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   115
        # this is needed to create absolute urls
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   116
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   117
        proto = req.env.get('wsgi.url_scheme')
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   118
        if proto == 'https':
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   119
            proto = 'https'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   120
            default_port = '443'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   121
        else:
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   122
            proto = 'http'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   123
            default_port = '80'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   124
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   125
        port = req.env['SERVER_PORT']
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   126
        port = port != default_port and (':' + port) or ''
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   127
        urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   128
        logourl = self.config('web', 'logourl', 'http://mercurial.selenic.com/')
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   129
        logoimg = self.config('web', 'logoimg', 'hglogo.png')
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   130
        staticurl = self.config('web', 'staticurl') or req.url + 'static/'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   131
        if not staticurl.endswith('/'):
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   132
            staticurl += '/'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   133
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   134
        # some functions for the templater
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   135
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   136
        def motd(**map):
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   137
            yield self.config('web', 'motd', '')
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   138
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   139
        # figure out which style to use
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   140
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   141
        vars = {}
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   142
        styles = (
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   143
            req.form.get('style', [None])[0],
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   144
            self.config('web', 'style'),
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   145
            'paper',
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   146
        )
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   147
        style, mapfile = templater.stylemap(styles, self.templatepath)
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   148
        if style == styles[0]:
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   149
            vars['style'] = style
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   150
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   151
        start = req.url[-1] == '?' and '&' or '?'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   152
        sessionvars = webutil.sessionvars(vars, start)
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   153
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   154
        if not self.reponame:
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
   155
            self.reponame = (self.config('web', 'name')
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
   156
                             or req.env.get('REPO_NAME')
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
   157
                             or req.url.strip('/') or self.repo.root)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   158
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   159
        def websubfilter(text):
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   160
            return websub(text, self.websubtable)
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   161
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   162
        # create the templater
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   163
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   164
        tmpl = templater.templater(mapfile,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   165
                                   filters={'websub': websubfilter},
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   166
                                   defaults={'url': req.url,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   167
                                             'logourl': logourl,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   168
                                             'logoimg': logoimg,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   169
                                             'staticurl': staticurl,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   170
                                             'urlbase': urlbase,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   171
                                             'repo': self.reponame,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   172
                                             'encoding': encoding.encoding,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   173
                                             'motd': motd,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   174
                                             'sessionvars': sessionvars,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   175
                                             'pathdef': makebreadcrumb(req.url),
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   176
                                             'style': style,
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   177
                                            })
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   178
        return tmpl
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   179
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   180
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1554
diff changeset
   181
class hgweb(object):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   182
    """HTTP server for individual repositories.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   183
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   184
    Instances of this class serve HTTP responses for a particular
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   185
    repository.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   186
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   187
    Instances are typically used as WSGI applications.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   188
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   189
    Some servers are multi-threaded. On these servers, there may
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   190
    be multiple active threads inside __call__.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   191
    """
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   192
    def __init__(self, repo, name=None, baseui=None):
4874
d9e385a7a806 Use isinstance instead of type == type
Christian Ebert <blacktrash@gmx.net>
parents: 4872
diff changeset
   193
        if isinstance(repo, str):
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   194
            if baseui:
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   195
                u = baseui.copy()
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   196
            else:
12696
ef969e58a394 hgweb: another fix for the help termwidth bug
Matt Mackall <mpm@selenic.com>
parents: 12691
diff changeset
   197
                u = ui.ui()
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   198
            r = hg.repository(u, repo)
987
bfe12654764d hgweb: change startup argument processing
mpm@selenic.com
parents: 986
diff changeset
   199
        else:
22087
af62f0280a76 hgweb: avoid config object race with hgwebdir (issue4326)
Matt Mackall <mpm@selenic.com>
parents: 21759
diff changeset
   200
            # we trust caller to give us a private copy
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   201
            r = repo
133
fb84d3e71042 added template support for some hgweb output, also, template files for
jake@edge2.net
parents: 132
diff changeset
   202
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20253
diff changeset
   203
        r.ui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20253
diff changeset
   204
        r.baseui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20253
diff changeset
   205
        r.ui.setconfig('ui', 'nontty', 'true', 'hgweb')
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20253
diff changeset
   206
        r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
25488
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   207
        # displaying bundling progress bar while serving feel wrong and may
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   208
        # break some wsgi implementation.
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   209
        r.ui.setconfig('progress', 'disable', 'true', 'hgweb')
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   210
        r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   211
        self._repo = hg.cachedlocalrepo(self._webifyrepo(r))
5833
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 5779
diff changeset
   212
        hook.redirect(True)
1172
3f30a5e7e15b Use path relative to document root as reponame if published via a web server.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1170
diff changeset
   213
        self.reponame = name
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   214
26218
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   215
    def _webifyrepo(self, repo):
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   216
        repo = getwebview(repo)
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   217
        self.websubtable = webutil.getwebsubs(repo)
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   218
        return repo
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   219
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   220
    def _getrepo(self):
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   221
        r, created = self._repo.fetch()
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   222
        if created:
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   223
            r = self._webifyrepo(r)
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   224
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   225
        self.mtime = self._repo.mtime
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   226
        return r
258
268bcb5a072a hgweb: watch changelog for changes
mpm@selenic.com
parents: 241
diff changeset
   227
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   228
    def run(self):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   229
        """Start a server from CGI environment.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   230
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   231
        Modern servers should be using WSGI and should avoid this
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   232
        method, if possible.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   233
        """
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   234
        if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
8663
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8390
diff changeset
   235
            raise RuntimeError("This function is only intended to be "
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8390
diff changeset
   236
                               "called while running as a CGI script.")
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   237
        import mercurial.hgweb.wsgicgi as wsgicgi
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   238
        wsgicgi.launch(self)
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   239
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   240
    def __call__(self, env, respond):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   241
        """Run the WSGI application.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   242
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   243
        This may be called by multiple threads.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   244
        """
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   245
        req = wsgirequest(env, respond)
6784
18c429ea3a0e hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6781
diff changeset
   246
        return self.run_wsgi(req)
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   247
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   248
    def run_wsgi(self, req):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   249
        """Internal method to run the WSGI application.
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   250
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   251
        This is typically only called by Mercurial. External consumers
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   252
        should be using instances of this class as the WSGI application.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   253
        """
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   254
        repo = self._getrepo()
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   255
        rctx = requestcontext(self, repo)
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   256
26160
952e0564b46e hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26149
diff changeset
   257
        # This state is global across all threads.
952e0564b46e hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26149
diff changeset
   258
        encoding.encoding = rctx.config('web', 'encoding', encoding.encoding)
952e0564b46e hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26149
diff changeset
   259
        rctx.repo.ui.environ = req.env
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   260
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   261
        # work with CGI variables to create coherent structure
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   262
        # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   263
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   264
        req.url = req.env['SCRIPT_NAME']
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   265
        if not req.url.endswith('/'):
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   266
            req.url += '/'
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5890
diff changeset
   267
        if 'REPO_NAME' in req.env:
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   268
            req.url += req.env['REPO_NAME'] + '/'
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   269
6459
8189e03adb44 hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   270
        if 'PATH_INFO' in req.env:
8189e03adb44 hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   271
            parts = req.env['PATH_INFO'].strip('/').split('/')
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   272
            repo_parts = req.env.get('REPO_NAME', '').split('/')
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   273
            if parts[:len(repo_parts)] == repo_parts:
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   274
                parts = parts[len(repo_parts):]
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   275
            query = '/'.join(parts)
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   276
        else:
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   277
            query = req.env['QUERY_STRING'].split('&', 1)[0]
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   278
            query = query.split(';', 1)[0]
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   279
8860
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   280
        # process this if it's a protocol request
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   281
        # protocol bits don't need to create any URLs
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   282
        # and the clients always use the old URL structure
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   283
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   284
        cmd = req.form.get('cmd', [''])[0]
11595
368cd5325348 protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   285
        if protocol.iscmd(cmd):
13445
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
   286
            try:
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
   287
                if query:
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
   288
                    raise ErrorResponse(HTTP_NOT_FOUND)
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
   289
                if cmd in perms:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   290
                    self.check_perm(rctx, req, perms[cmd])
26209
7917746c9a67 hgweb: don't access self.repo during request processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26208
diff changeset
   291
                return protocol.call(rctx.repo, req, cmd)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   292
            except ErrorResponse as inst:
13571
84bd3fd63afc hgweb_mod: respond right away if the client specified 100-continue support
Augie Fackler <durin42@gmail.com>
parents: 13445
diff changeset
   293
                # A client that sends unbundle without 100-continue will
84bd3fd63afc hgweb_mod: respond right away if the client specified 100-continue support
Augie Fackler <durin42@gmail.com>
parents: 13445
diff changeset
   294
                # break if we respond early.
84bd3fd63afc hgweb_mod: respond right away if the client specified 100-continue support
Augie Fackler <durin42@gmail.com>
parents: 13445
diff changeset
   295
                if (cmd == 'unbundle' and
14991
4f39610996fa http2: send an extra header to signal a non-broken client
Augie Fackler <durin42@gmail.com>
parents: 13966
diff changeset
   296
                    (req.env.get('HTTP_EXPECT',
4f39610996fa http2: send an extra header to signal a non-broken client
Augie Fackler <durin42@gmail.com>
parents: 13966
diff changeset
   297
                                 '').lower() != '100-continue') or
4f39610996fa http2: send an extra header to signal a non-broken client
Augie Fackler <durin42@gmail.com>
parents: 13966
diff changeset
   298
                    req.env.get('X-HgHttp2', '')):
13445
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
   299
                    req.drain()
19488
60e060f4faa9 hgweb: force connection close on early response
Augie Fackler <raf@durin42.com>
parents: 18858
diff changeset
   300
                else:
60e060f4faa9 hgweb: force connection close on early response
Augie Fackler <raf@durin42.com>
parents: 18858
diff changeset
   301
                    req.headers.append(('Connection', 'Close'))
18352
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18258
diff changeset
   302
                req.respond(inst, protocol.HGTYPE,
26200
461e7b700fdf hgweb: remove ErrorResponse.message
timeless@mozdev.org
parents: 26183
diff changeset
   303
                            body='0\n%s\n' % inst)
18352
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18258
diff changeset
   304
                return ''
8860
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   305
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   306
        # translate user-visible url structure to internal structure
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   307
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   308
        args = query.split('/', 2)
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   309
        if 'cmd' not in req.form and args and args[0]:
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   310
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   311
            cmd = args.pop(0)
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   312
            style = cmd.rfind('-')
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   313
            if style != -1:
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   314
                req.form['style'] = [cmd[:style]]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   315
                cmd = cmd[style + 1:]
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   316
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   317
            # avoid accepting e.g. style parameter as command
14953
6ee6ecf1ee89 hgweb_mod: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14913
diff changeset
   318
            if util.safehasattr(webcommands, cmd):
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   319
                req.form['cmd'] = [cmd]
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   320
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   321
            if cmd == 'static':
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   322
                req.form['file'] = ['/'.join(args)]
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   323
            else:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   324
                if args and args[0]:
25777
1c2a8db33b8f hgweb: allow symbolic revisions with forward slashes in urls
Anton Shestakov <av6@dwimlabs.net>
parents: 25720
diff changeset
   325
                    node = args.pop(0).replace('%2F', '/')
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   326
                    req.form['node'] = [node]
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   327
                if args:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   328
                    req.form['file'] = args
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   329
9731
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
   330
            ua = req.env.get('HTTP_USER_AGENT', '')
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
   331
            if cmd == 'rev' and 'mercurial' in ua:
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
   332
                req.form['style'] = ['raw']
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
   333
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   334
            if cmd == 'archive':
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   335
                fn = req.form['node'][0]
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   336
                for type_, spec in rctx.archivespecs.iteritems():
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   337
                    ext = spec[2]
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   338
                    if fn.endswith(ext):
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   339
                        req.form['node'] = [fn[:-len(ext)]]
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   340
                        req.form['type'] = [type_]
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   341
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   342
        # process the web interface request
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   343
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   344
        try:
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   345
            tmpl = rctx.templater(req)
8859
580a79dde2a3 hgweb: web.encoding should override encoding.encoding (issue1183)
Matt Mackall <mpm@selenic.com>
parents: 8663
diff changeset
   346
            ctype = tmpl('mimetype', encoding=encoding.encoding)
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   347
            ctype = templater.stringify(ctype)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   348
7562
b663b5563de7 hgweb: allow static content when deny_read denies access
Mark Edgington <edgimar@gmail.com>
parents: 7396
diff changeset
   349
            # check read permissions non-static content
b663b5563de7 hgweb: allow static content when deny_read denies access
Mark Edgington <edgimar@gmail.com>
parents: 7396
diff changeset
   350
            if cmd != 'static':
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   351
                self.check_perm(rctx, req, None)
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7311
diff changeset
   352
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   353
            if cmd == '':
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   354
                req.form['cmd'] = [tmpl.cache['default']]
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   355
                cmd = req.form['cmd'][0]
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
   356
26161
16d54bbdbf89 hgweb: remove hgweb.configbool
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26160
diff changeset
   357
            if rctx.configbool('web', 'cache', True):
13966
a1c31c64bcd3 hgweb: support disabling page cache
Steven Stallion <sstallion@gmail.com>
parents: 13964
diff changeset
   358
                caching(self, req) # sets ETag header or raises NOT_MODIFIED
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   359
            if cmd not in webcommands.__all__:
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
   360
                msg = 'no such method: %s' % cmd
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   361
                raise ErrorResponse(HTTP_BAD_REQUEST, msg)
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   362
            elif cmd == 'file' and 'raw' in req.form.get('style', []):
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
   363
                rctx.ctype = ctype
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   364
                content = webcommands.rawfile(rctx, req, tmpl)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   365
            else:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   366
                content = getattr(webcommands, cmd)(rctx, req, tmpl)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   367
                req.respond(HTTP_OK, ctype)
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
   368
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
   369
            return content
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   370
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   371
        except (error.LookupError, error.RepoLookupError) as err:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   372
            req.respond(HTTP_NOT_FOUND, ctype)
6374
31a01e3d99cc hgweb: fix breakage in python < 2.5 introduced in 2c370f08c486
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6368
diff changeset
   373
            msg = str(err)
18855
50c922c1b514 hgweb: show correct error message for i18n environment
Takumi IINO <trot.thunder@gmail.com>
parents: 18522
diff changeset
   374
            if (util.safehasattr(err, 'name') and
50c922c1b514 hgweb: show correct error message for i18n environment
Takumi IINO <trot.thunder@gmail.com>
parents: 18522
diff changeset
   375
                not isinstance(err,  error.ManifestLookupError)):
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
   376
                msg = 'revision not found: %s' % err.name
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
   377
            return tmpl('error', error=msg)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   378
        except (error.RepoError, error.RevlogError) as inst:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   379
            req.respond(HTTP_SERVER_ERROR, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
   380
            return tmpl('error', error=str(inst))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   381
        except ErrorResponse as inst:
7740
176d3d681702 hgweb: pass ErrorResponses directly into req.respond()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   382
            req.respond(inst, ctype)
12739
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
   383
            if inst.code == HTTP_NOT_MODIFIED:
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
   384
                # Not allowed to return a body on a 304
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
   385
                return ['']
26200
461e7b700fdf hgweb: remove ErrorResponse.message
timeless@mozdev.org
parents: 26183
diff changeset
   386
            return tmpl('error', error=str(inst))
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   387
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   388
    def check_perm(self, rctx, req, op):
22200
b27c3beaaf30 cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents: 22087
diff changeset
   389
        for permhook in permhooks:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   390
            permhook(rctx, req, op)
26208
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   391
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   392
def getwebview(repo):
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   393
    """The 'web.view' config controls changeset filter to hgweb. Possible
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   394
    values are ``served``, ``visible`` and ``all``. Default is ``served``.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   395
    The ``served`` filter only shows changesets that can be pulled from the
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   396
    hgweb instance.  The``visible`` filter includes secret changesets but
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   397
    still excludes "hidden" one.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   398
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   399
    See the repoview module for details.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   400
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   401
    The option has been around undocumented since Mercurial 2.5, but no
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   402
    user ever asked about it. So we better keep it undocumented for now."""
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   403
    viewconfig = repo.ui.config('web', 'view', 'served',
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   404
                                untrusted=True)
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   405
    if viewconfig == 'all':
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   406
        return repo.unfiltered()
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   407
    elif viewconfig in repoview.filtertable:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   408
        return repo.filtered(viewconfig)
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   409
    else:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   410
        return repo.filtered('served')
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   411