mercurial/hgweb/hgweb_mod.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 22 Aug 2015 14:59:36 -0700
changeset 26134 e0a6908f066f
parent 26133 44ed220ef26f
child 26135 edfb4d3b9672
permissions -rw-r--r--
hgweb: establish class for holding per request context Currently, hgweb applications have many instance variables holding mutated state. This is somewhat problematic because multiple threads may race accessing or changing this state. This patch starts a series that will add more thread safety to hgweb applications. It will do this by moving mutated state out of hgweb and into per-request instances of the newly established "requestcontext" class. Our new class currently behaves like a proxy to hgweb instances. This should change once all state is captured in it instead of hgweb. The effectiveness of this proxy is demonstrated by passing instances of it - not hgweb instances/self - to various functions.
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
20034
1e5b38a919dd cleanup: move stdlib imports to their own import statement
Augie Fackler <raf@durin42.com>
parents: 19906
diff changeset
     9
import os, re
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
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
    12
from mercurial.i18n import _
13958
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13445
diff changeset
    13
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
    14
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
    15
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
    16
from request import wsgirequest
20034
1e5b38a919dd cleanup: move stdlib imports to their own import statement
Augie Fackler <raf@durin42.com>
parents: 19906
diff changeset
    17
import webcommands, protocol, webutil
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    18
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    19
perms = {
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    20
    'changegroup': 'pull',
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    21
    'changegroupsubset': 'pull',
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13571
diff changeset
    22
    'getbundle': 'pull',
11370
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
    23
    'stream_out': 'pull',
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
    24
    'listkeys': 'pull',
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    25
    'unbundle': 'push',
11370
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
    26
    'pushkey': 'push',
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    27
}
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
    28
25718
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
    29
## Files of interest
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
    30
# Used to check if the repository has changed looking at mtime and size of
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
    31
# theses files. This should probably be relocated a bit higher in core.
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
    32
foi = [('spath', '00changelog.i'),
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
    33
       ('spath', 'phaseroots'), # ! phase can change content at the same size
25719
c51a18609a7f hgweb: also refresh the repo on changes to the obsstore
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25718
diff changeset
    34
       ('spath', 'obsstore'),
25720
bd2e171d023b hgweb: also monitor change to bookmarks
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25719
diff changeset
    35
       ('path', 'bookmarks'), # ! bookmark can change content at the same size
25718
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
    36
      ]
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
    37
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    38
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
    39
    '''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
    40
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    41
    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
    42
    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
    43
    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
    44
    '''
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    45
    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
    46
        url = url[:-1]
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    47
    if prefix:
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    48
        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
    49
    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
    50
    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
    51
        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
    52
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    53
    breadcrumb = []
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    54
    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
    55
    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
    56
    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
    57
        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
    58
            break
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    59
        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
    60
        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
    61
    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
    62
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    63
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    64
class requestcontext(object):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    65
    """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
    66
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    67
    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
    68
    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
    69
    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
    70
    """
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    71
    def __init__(self, app):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    72
        object.__setattr__(self, 'app', app)
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    73
        object.__setattr__(self, 'repo', app.repo)
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    74
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    75
    # Proxy unknown reads and writes to the application instance
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    76
    # until everything is moved to us.
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    77
    def __getattr__(self, name):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    78
        return getattr(self.app, name)
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    79
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    80
    def __setattr__(self, name, value):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    81
        return setattr(self.app, name, value)
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    82
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1554
diff changeset
    83
class hgweb(object):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
    84
    """HTTP server for individual repositories.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
    85
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
    86
    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
    87
    repository.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
    88
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
    89
    Instances are typically used as WSGI applications.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
    90
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
    91
    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
    92
    be multiple active threads inside __call__.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
    93
    """
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
    94
    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
    95
        if isinstance(repo, str):
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
    96
            if baseui:
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
    97
                u = baseui.copy()
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
    98
            else:
12696
ef969e58a394 hgweb: another fix for the help termwidth bug
Matt Mackall <mpm@selenic.com>
parents: 12691
diff changeset
    99
                u = ui.ui()
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   100
            r = hg.repository(u, repo)
987
bfe12654764d hgweb: change startup argument processing
mpm@selenic.com
parents: 986
diff changeset
   101
        else:
22087
af62f0280a76 hgweb: avoid config object race with hgwebdir (issue4326)
Matt Mackall <mpm@selenic.com>
parents: 21759
diff changeset
   102
            # 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
   103
            r = repo
133
fb84d3e71042 added template support for some hgweb output, also, template files for
jake@edge2.net
parents: 132
diff changeset
   104
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   105
        r = self._getview(r)
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
   106
        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
   107
        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
   108
        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
   109
        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
   110
        # 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
   111
        # break some wsgi implementation.
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   112
        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
   113
        r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   114
        self.repo = r
5833
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 5779
diff changeset
   115
        hook.redirect(True)
22577
a111e460318a hgweb: refresh hgweb.repo on phase change (issue4061)
Anton Shestakov <engored@ya.ru>
parents: 22506
diff changeset
   116
        self.repostate = ((-1, -1), (-1, -1))
258
268bcb5a072a hgweb: watch changelog for changes
mpm@selenic.com
parents: 241
diff changeset
   117
        self.mtime = -1
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
   118
        self.reponame = name
1078
33f40d0c6124 Various cleanups for tarball support
mpm@selenic.com
parents: 1077
diff changeset
   119
        self.archives = 'zip', 'gz', 'bz2'
2666
ebf033bc8eb2 hgweb: Configurable zebra stripes
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 2622
diff changeset
   120
        self.stripecount = 1
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   121
        # a repo owner may set web.templates in .hg/hgrc to get any file
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   122
        # readable by the user running the CGI script
7966
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   123
        self.templatepath = self.config('web', 'templates')
18627
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   124
        self.websubtable = self.loadwebsub()
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   125
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   126
    # The CGI scripts are often run by a user different from the repo owner.
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   127
    # Trust the settings from the .hg/hgrc files by default.
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   128
    def config(self, section, name, default=None, untrusted=True):
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   129
        return self.repo.ui.config(section, name, default,
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   130
                                   untrusted=untrusted)
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   131
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   132
    def configbool(self, section, name, default=False, untrusted=True):
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   133
        return self.repo.ui.configbool(section, name, default,
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   134
                                       untrusted=untrusted)
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   135
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   136
    def configlist(self, section, name, default=None, untrusted=True):
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   137
        return self.repo.ui.configlist(section, name, default,
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   138
                                       untrusted=untrusted)
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
   139
18522
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
   140
    def _getview(self, repo):
25565
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   141
        """The 'web.view' config controls changeset filter to hgweb. Possible
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   142
        values are ``served``, ``visible`` and ``all``. Default is ``served``.
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   143
        The ``served`` filter only shows changesets that can be pulled from the
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   144
        hgweb instance.  The``visible`` filter includes secret changesets but
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   145
        still excludes "hidden" one.
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   146
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   147
        See the repoview module for details.
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   148
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   149
        The option has been around undocumented since Mercurial 2.5, but no
be4dc0007b8d hgweb: add some in-code documentation for 'web.view'
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 25488
diff changeset
   150
        user ever asked about it. So we better keep it undocumented for now."""
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   151
        viewconfig = repo.ui.config('web', 'view', 'served',
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   152
                                    untrusted=True)
18522
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
   153
        if viewconfig == 'all':
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
   154
            return repo.unfiltered()
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
   155
        elif viewconfig in repoview.filtertable:
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
   156
            return repo.filtered(viewconfig)
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
   157
        else:
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
   158
            return repo.filtered('served')
36549fa712da hgweb: add a `web.view` to control filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18521
diff changeset
   159
26133
44ed220ef26f hgweb: don't make request optional
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26132
diff changeset
   160
    def refresh(self, request):
25718
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
   161
        repostate = []
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
   162
        # file of interrests mtime and size
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
   163
        for meth, fname in foi:
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
   164
            prefix = getattr(self.repo, meth)
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
   165
            st = get_stat(prefix, fname)
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
   166
            repostate.append((st.st_mtime, st.st_size))
2e32f0897bcf hgweb: use an extensible list of files to check for refresh
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25717
diff changeset
   167
        repostate = tuple(repostate)
22577
a111e460318a hgweb: refresh hgweb.repo on phase change (issue4061)
Anton Shestakov <engored@ya.ru>
parents: 22506
diff changeset
   168
        # we need to compare file size in addition to mtime to catch
a111e460318a hgweb: refresh hgweb.repo on phase change (issue4061)
Anton Shestakov <engored@ya.ru>
parents: 22506
diff changeset
   169
        # changes made less than a second ago
a111e460318a hgweb: refresh hgweb.repo on phase change (issue4061)
Anton Shestakov <engored@ya.ru>
parents: 22506
diff changeset
   170
        if repostate != self.repostate:
22223
c39d404f0eb0 hgweb: refresh repository using URL not path (issue4323)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22200
diff changeset
   171
            r = hg.repository(self.repo.baseui, self.repo.url())
18826
35fb2ef52a39 hgweb: do not pass on repo.ui when recreating a repo
Simon Heimberg <simohe@besonet.ch>
parents: 18629
diff changeset
   172
            self.repo = self._getview(r)
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   173
            self.maxchanges = int(self.config("web", "maxchanges", 10))
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   174
            self.stripecount = int(self.config("web", "stripes", 1))
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 14999
diff changeset
   175
            self.maxshortchanges = int(self.config("web", "maxshortchanges",
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 14999
diff changeset
   176
                                                   60))
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   177
            self.maxfiles = int(self.config("web", "maxfiles", 10))
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   178
            self.allowpull = self.configbool("web", "allowpull", True)
8859
580a79dde2a3 hgweb: web.encoding should override encoding.encoding (issue1183)
Matt Mackall <mpm@selenic.com>
parents: 8663
diff changeset
   179
            encoding.encoding = self.config("web", "encoding",
580a79dde2a3 hgweb: web.encoding should override encoding.encoding (issue1183)
Matt Mackall <mpm@selenic.com>
parents: 8663
diff changeset
   180
                                            encoding.encoding)
21759
bd3360c63bb3 hgweb: avoid initialization race (issue4280)
Matt Mackall <mpm@selenic.com>
parents: 20790
diff changeset
   181
            # update these last to avoid threads seeing empty settings
22577
a111e460318a hgweb: refresh hgweb.repo on phase change (issue4061)
Anton Shestakov <engored@ya.ru>
parents: 22506
diff changeset
   182
            self.repostate = repostate
a111e460318a hgweb: refresh hgweb.repo on phase change (issue4061)
Anton Shestakov <engored@ya.ru>
parents: 22506
diff changeset
   183
            # mtime is needed for ETag
21759
bd3360c63bb3 hgweb: avoid initialization race (issue4280)
Matt Mackall <mpm@selenic.com>
parents: 20790
diff changeset
   184
            self.mtime = st.st_mtime
26133
44ed220ef26f hgweb: don't make request optional
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26132
diff changeset
   185
44ed220ef26f hgweb: don't make request optional
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26132
diff changeset
   186
        self.repo.ui.environ = request.env
258
268bcb5a072a hgweb: watch changelog for changes
mpm@selenic.com
parents: 241
diff changeset
   187
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   188
    def run(self):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   189
        """Start a server from CGI environment.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   190
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   191
        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
   192
        method, if possible.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   193
        """
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   194
        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
   195
            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
   196
                               "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
   197
        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
   198
        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
   199
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   200
    def __call__(self, env, respond):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   201
        """Run the WSGI application.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   202
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   203
        This may be called by multiple threads.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   204
        """
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   205
        req = wsgirequest(env, respond)
6784
18c429ea3a0e hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6781
diff changeset
   206
        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
   207
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   208
    def run_wsgi(self, req):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   209
        """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
   210
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   211
        This is typically only called by Mercurial. External consumers
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   212
        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
   213
        """
9887
38170eeed18c ui: add environ property to access os.environ or wsgirequest.environ
Sune Foldager <cryo@cyanite.org>
parents: 9842
diff changeset
   214
        self.refresh(req)
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   215
        rctx = requestcontext(self)
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   216
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   217
        # 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
   218
        # 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
   219
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   220
        req.url = req.env['SCRIPT_NAME']
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   221
        if not req.url.endswith('/'):
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   222
            req.url += '/'
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5890
diff changeset
   223
        if 'REPO_NAME' in req.env:
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   224
            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
   225
6459
8189e03adb44 hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   226
        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
   227
            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
   228
            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
   229
            if parts[:len(repo_parts)] == repo_parts:
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   230
                parts = parts[len(repo_parts):]
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   231
            query = '/'.join(parts)
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   232
        else:
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   233
            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
   234
            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
   235
8860
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   236
        # 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
   237
        # 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
   238
        # 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
   239
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   240
        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
   241
        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
   242
            try:
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
   243
                if query:
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
   244
                    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
   245
                if cmd in perms:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   246
                    self.check_perm(rctx, req, perms[cmd])
13445
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
   247
                return protocol.call(self.repo, req, cmd)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   248
            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
   249
                # 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
   250
                # 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
   251
                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
   252
                    (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
   253
                                 '').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
   254
                    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
   255
                    req.drain()
19488
60e060f4faa9 hgweb: force connection close on early response
Augie Fackler <raf@durin42.com>
parents: 18858
diff changeset
   256
                else:
60e060f4faa9 hgweb: force connection close on early response
Augie Fackler <raf@durin42.com>
parents: 18858
diff changeset
   257
                    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
   258
                req.respond(inst, protocol.HGTYPE,
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18258
diff changeset
   259
                            body='0\n%s\n' % inst.message)
e33b9b92a200 hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents: 18258
diff changeset
   260
                return ''
8860
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
   261
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   262
        # 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
   263
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   264
        args = query.split('/', 2)
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   265
        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
   266
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   267
            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
   268
            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
   269
            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
   270
                req.form['style'] = [cmd[:style]]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   271
                cmd = cmd[style + 1:]
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   272
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   273
            # 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
   274
            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
   275
                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
   276
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   277
            if cmd == 'static':
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   278
                req.form['file'] = ['/'.join(args)]
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   279
            else:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   280
                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
   281
                    node = args.pop(0).replace('%2F', '/')
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   282
                    req.form['node'] = [node]
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   283
                if args:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   284
                    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
   285
9731
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
   286
            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
   287
            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
   288
                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
   289
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   290
            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
   291
                fn = req.form['node'][0]
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   292
                for type_, spec in self.archive_specs.iteritems():
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   293
                    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
   294
                    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
   295
                        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
   296
                        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
   297
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   298
        # process the web interface request
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   299
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   300
        try:
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   301
            tmpl = self.templater(req)
8859
580a79dde2a3 hgweb: web.encoding should override encoding.encoding (issue1183)
Matt Mackall <mpm@selenic.com>
parents: 8663
diff changeset
   302
            ctype = tmpl('mimetype', encoding=encoding.encoding)
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   303
            ctype = templater.stringify(ctype)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   304
7562
b663b5563de7 hgweb: allow static content when deny_read denies access
Mark Edgington <edgimar@gmail.com>
parents: 7396
diff changeset
   305
            # 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
   306
            if cmd != 'static':
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   307
                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
   308
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   309
            if cmd == '':
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   310
                req.form['cmd'] = [tmpl.cache['default']]
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   311
                cmd = req.form['cmd'][0]
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
   312
13966
a1c31c64bcd3 hgweb: support disabling page cache
Steven Stallion <sstallion@gmail.com>
parents: 13964
diff changeset
   313
            if self.configbool('web', 'cache', True):
a1c31c64bcd3 hgweb: support disabling page cache
Steven Stallion <sstallion@gmail.com>
parents: 13964
diff changeset
   314
                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
   315
            if cmd not in webcommands.__all__:
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
   316
                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
   317
                raise ErrorResponse(HTTP_BAD_REQUEST, msg)
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   318
            elif cmd == 'file' and 'raw' in req.form.get('style', []):
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   319
                self.ctype = ctype
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   320
                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
   321
            else:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   322
                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
   323
                req.respond(HTTP_OK, ctype)
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
   324
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
   325
            return content
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   326
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   327
        except (error.LookupError, error.RepoLookupError) as err:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   328
            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
   329
            msg = str(err)
18855
50c922c1b514 hgweb: show correct error message for i18n environment
Takumi IINO <trot.thunder@gmail.com>
parents: 18522
diff changeset
   330
            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
   331
                not isinstance(err,  error.ManifestLookupError)):
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
   332
                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
   333
            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
   334
        except (error.RepoError, error.RevlogError) as inst:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   335
            req.respond(HTTP_SERVER_ERROR, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
   336
            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
   337
        except ErrorResponse as inst:
7740
176d3d681702 hgweb: pass ErrorResponses directly into req.respond()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   338
            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
   339
            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
   340
                # 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
   341
                return ['']
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
   342
            return tmpl('error', error=inst.message)
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   343
18627
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   344
    def loadwebsub(self):
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   345
        websubtable = []
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   346
        websubdefs = self.repo.ui.configitems('websub')
18629
013fcd112f13 extensions: obsolete and remove interhg extension
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18627
diff changeset
   347
        # we must maintain interhg backwards compatibility
013fcd112f13 extensions: obsolete and remove interhg extension
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18627
diff changeset
   348
        websubdefs += self.repo.ui.configitems('interhg')
18627
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   349
        for key, pattern in websubdefs:
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   350
            # grab the delimiter from the character after the "s"
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   351
            unesc = pattern[1]
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   352
            delim = re.escape(unesc)
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   353
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   354
            # identify portions of the pattern, taking care to avoid escaped
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   355
            # delimiters. the replace format and flags are optional, but
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   356
            # delimiters are required.
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   357
            match = re.match(
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   358
                r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$'
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   359
                % (delim, delim, delim), pattern)
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   360
            if not match:
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   361
                self.repo.ui.warn(_("websub: invalid pattern for %s: %s\n")
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   362
                                  % (key, pattern))
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   363
                continue
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   364
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   365
            # we need to unescape the delimiter for regexp and format
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   366
            delim_re = re.compile(r'(?<!\\)\\%s' % delim)
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   367
            regexp = delim_re.sub(unesc, match.group(1))
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   368
            format = delim_re.sub(unesc, match.group(2))
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   369
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   370
            # the pattern allows for 6 regexp flags, so set them if necessary
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   371
            flagin = match.group(3)
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   372
            flags = 0
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   373
            if flagin:
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   374
                for flag in flagin.upper():
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   375
                    flags |= re.__dict__[flag]
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   376
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   377
            try:
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   378
                regexp = re.compile(regexp, flags)
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   379
                websubtable.append((regexp, format))
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   380
            except re.error:
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   381
                self.repo.ui.warn(_("websub: invalid regexp for %s: %s\n")
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   382
                                  % (key, regexp))
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   383
        return websubtable
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   384
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   385
    def templater(self, req):
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   386
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   387
        # determine scheme, port and server name
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   388
        # this is needed to create absolute urls
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   389
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   390
        proto = req.env.get('wsgi.url_scheme')
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   391
        if proto == 'https':
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   392
            proto = 'https'
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   393
            default_port = "443"
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   394
        else:
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   395
            proto = 'http'
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   396
            default_port = "80"
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   397
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   398
        port = req.env["SERVER_PORT"]
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   399
        port = port != default_port and (":" + port) or ""
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   400
        urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
13964
616ad3f6fd33 hgweb: support alternate logo url
Steven Stallion <sstallion@gmail.com>
parents: 13959
diff changeset
   401
        logourl = self.config("web", "logourl", "http://mercurial.selenic.com/")
14913
44382887d012 hgweb: add a "web/logoimg" setting to customize the web logo image
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 13966
diff changeset
   402
        logoimg = self.config("web", "logoimg", "hglogo.png")
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   403
        staticurl = self.config("web", "staticurl") or req.url + 'static/'
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   404
        if not staticurl.endswith('/'):
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   405
            staticurl += '/'
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   406
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   407
        # some functions for the templater
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   408
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   409
        def motd(**map):
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   410
            yield self.config("web", "motd", "")
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   411
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   412
        # figure out which style to use
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   413
7345
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7336
diff changeset
   414
        vars = {}
9842
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9731
diff changeset
   415
        styles = (
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9731
diff changeset
   416
            req.form.get('style', [None])[0],
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9731
diff changeset
   417
            self.config('web', 'style'),
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9731
diff changeset
   418
            'paper',
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9731
diff changeset
   419
        )
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9731
diff changeset
   420
        style, mapfile = templater.stylemap(styles, self.templatepath)
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9731
diff changeset
   421
        if style == styles[0]:
7345
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7336
diff changeset
   422
            vars['style'] = style
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7336
diff changeset
   423
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7336
diff changeset
   424
        start = req.url[-1] == '?' and '&' or '?'
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7336
diff changeset
   425
        sessionvars = webutil.sessionvars(vars, start)
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   426
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   427
        if not self.reponame:
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   428
            self.reponame = (self.config("web", "name")
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   429
                             or req.env.get('REPO_NAME')
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   430
                             or req.url.strip('/') or self.repo.root)
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   431
18627
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   432
        def websubfilter(text):
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   433
            return websub(text, self.websubtable)
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   434
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   435
        # create the templater
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   436
8360
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8225
diff changeset
   437
        tmpl = templater.templater(mapfile,
18627
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18522
diff changeset
   438
                                   filters={"websub": websubfilter},
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   439
                                   defaults={"url": req.url,
13964
616ad3f6fd33 hgweb: support alternate logo url
Steven Stallion <sstallion@gmail.com>
parents: 13959
diff changeset
   440
                                             "logourl": logourl,
14913
44382887d012 hgweb: add a "web/logoimg" setting to customize the web logo image
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 13966
diff changeset
   441
                                             "logoimg": logoimg,
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   442
                                             "staticurl": staticurl,
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   443
                                             "urlbase": urlbase,
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   444
                                             "repo": self.reponame,
19906
1dba26575dba hgweb: remove now unnecessary explicit header() and footer()
Alexander Plavin <alexander@plav.in>
parents: 19488
diff changeset
   445
                                             "encoding": encoding.encoding,
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   446
                                             "motd": motd,
18258
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
   447
                                             "sessionvars": sessionvars,
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
   448
                                             "pathdef": makebreadcrumb(req.url),
20253
43cfad930d38 hgweb: avoid invalid infinity scroll request when overwritten web.style
Takumi IINO <trot.thunder@gmail.com>
parents: 20169
diff changeset
   449
                                             "style": style,
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   450
                                            })
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   451
        return tmpl
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   452
1498
78590fb4a82b hgweb: Added archive download buttons to manifest page.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1473
diff changeset
   453
    def archivelist(self, nodeid):
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   454
        allowed = self.configlist("web", "allow_archive")
3260
1f1af9b273e8 hgweb: accept NewWebInterface URLs
Brendan Cully <brendan@kublai.com>
parents: 3231
diff changeset
   455
        for i, spec in self.archive_specs.iteritems():
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   456
            if i in allowed or self.configbool("web", "allow" + i):
3260
1f1af9b273e8 hgweb: accept NewWebInterface URLs
Brendan Cully <brendan@kublai.com>
parents: 3231
diff changeset
   457
                yield {"type" : i, "extension" : spec[2], "node" : nodeid}
1498
78590fb4a82b hgweb: Added archive download buttons to manifest page.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1473
diff changeset
   458
2113
633d733e7b11 make hgweb use new archival module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2103
diff changeset
   459
    archive_specs = {
12570
a72c5ff1260c Correct Content-Type header values for archive downloads.
Ry4an Brase <ry4an-hg@ry4an.org>
parents: 11370
diff changeset
   460
        'bz2': ('application/x-bzip2', 'tbz2', '.tar.bz2', None),
a72c5ff1260c Correct Content-Type header values for archive downloads.
Ry4an Brase <ry4an-hg@ry4an.org>
parents: 11370
diff changeset
   461
        'gz': ('application/x-gzip', 'tgz', '.tar.gz', None),
2113
633d733e7b11 make hgweb use new archival module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2103
diff changeset
   462
        'zip': ('application/zip', 'zip', '.zip', None),
633d733e7b11 make hgweb use new archival module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2103
diff changeset
   463
        }
1076
01db658cc78a tarball support v0.3
Wojciech Milkowski <wmilkowski@interia.pl>
parents: 1073
diff changeset
   464
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   465
    def check_perm(self, rctx, req, op):
22200
b27c3beaaf30 cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents: 22087
diff changeset
   466
        for permhook in permhooks:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   467
            permhook(rctx, req, op)