mercurial/hgweb/hgweb_mod.py
author Yuya Nishihara <yuya@tcha.org>
Fri, 16 Mar 2018 21:24:12 +0900
changeset 36989 de117f579431
parent 36920 6ff6e1d6b5b8
child 37019 c97b936d8bb5
permissions -rw-r--r--
templater: factor out helper that renders named template as string This is quite common in non-web templating, and **kwargs expansion is annoying because of the unicode-ness of Python3.
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
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
     9
from __future__ import absolute_import
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    10
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
    11
import contextlib
26162
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26161
diff changeset
    12
import os
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    13
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    14
from .common import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    15
    ErrorResponse,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    16
    HTTP_BAD_REQUEST,
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
    17
    cspvalues,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    18
    permhooks,
36879
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
    19
    statusmessage,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    20
)
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    21
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    22
from .. import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    23
    encoding,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    24
    error,
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
    25
    formatter,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    26
    hg,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    27
    hook,
29787
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
    28
    profiling,
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    29
    pycompat,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    30
    repoview,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    31
    templatefilters,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    32
    templater,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    33
    ui as uimod,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    34
    util,
35856
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35037
diff changeset
    35
    wireprotoserver,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    36
)
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    37
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    38
from . import (
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
    39
    request as requestmod,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    40
    webcommands,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    41
    webutil,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    42
    wsgicgi,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    43
)
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    44
30749
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    45
archivespecs = util.sortdict((
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    46
    ('zip', ('application/zip', 'zip', '.zip', None)),
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    47
    ('gz', ('application/x-gzip', 'tgz', '.tar.gz', None)),
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    48
    ('bz2', ('application/x-bzip2', 'tbz2', '.tar.bz2', None)),
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    49
))
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    50
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    51
def getstyle(req, configfn, templatepath):
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    52
    styles = (
36863
1a1972b1a1ff hgweb: use our new request object for "style" parameter
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36861
diff changeset
    53
        req.qsparams.get('style', None),
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    54
        configfn('web', 'style'),
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    55
        'paper',
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    56
    )
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    57
    return styles, templater.stylemap(styles, templatepath)
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    58
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    59
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
    60
    '''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
    61
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    62
    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
    63
    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
    64
    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
    65
    '''
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    66
    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
    67
        url = url[:-1]
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    68
    if prefix:
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    69
        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
    70
    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
    71
    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
    72
        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
    73
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    74
    breadcrumb = []
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    75
    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
    76
    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
    77
    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
    78
        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
    79
            break
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    80
        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
    81
        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
    82
    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
    83
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    84
class requestcontext(object):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    85
    """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
    86
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    87
    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
    88
    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
    89
    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
    90
    """
36870
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
    91
    def __init__(self, app, repo, req, res):
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
    92
        self.repo = repo
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    93
        self.reponame = app.reponame
36870
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
    94
        self.req = req
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
    95
        self.res = res
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    96
30749
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    97
        self.archivespecs = archivespecs
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    98
34590
95f4e5b1ec92 configitems: register the 'web.maxchanges' config
Boris Feld <boris.feld@octobus.net>
parents: 34589
diff changeset
    99
        self.maxchanges = self.configint('web', 'maxchanges')
34245
945c9816ec1d configitems: register the 'web.stripes' config
Boris Feld <boris.feld@octobus.net>
parents: 34239
diff changeset
   100
        self.stripecount = self.configint('web', 'stripes')
34588
0d9928a67254 configitems: register the 'web.maxshortchanges' config
Boris Feld <boris.feld@octobus.net>
parents: 34587
diff changeset
   101
        self.maxshortchanges = self.configint('web', 'maxshortchanges')
34589
883d06211973 configitems: register the 'web.maxfiles' config
Boris Feld <boris.feld@octobus.net>
parents: 34588
diff changeset
   102
        self.maxfiles = self.configint('web', 'maxfiles')
35037
da5d5ea7d696 config: rename allowpull to allow-pull
David Demelier <markand@malikania.fr>
parents: 34806
diff changeset
   103
        self.allowpull = self.configbool('web', 'allow-pull')
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   104
26163
84511b1d9724 hgweb: move templatepath to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26162
diff changeset
   105
        # 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
   106
        # 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
   107
        # 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
   108
        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
   109
26164
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
   110
        # 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
   111
        # 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
   112
        # 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
   113
        # 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
   114
        # of the request.
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
   115
        self.websubtable = app.websubtable
26164
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
   116
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   117
        self.csp, self.nonce = cspvalues(self.repo.ui)
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   118
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   119
    # Trust the settings from the .hg/hgrc files by default.
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   120
    def config(self, section, name, default=uimod._unset, untrusted=True):
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   121
        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
   122
                                   untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   123
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   124
    def configbool(self, section, name, default=uimod._unset, untrusted=True):
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   125
        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
   126
                                       untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   127
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   128
    def configint(self, section, name, default=uimod._unset, untrusted=True):
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   129
        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
   130
                                      untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   131
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   132
    def configlist(self, section, name, default=uimod._unset, untrusted=True):
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   133
        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
   134
                                       untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   135
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   136
    def archivelist(self, nodeid):
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   137
        allowed = self.configlist('web', 'allow_archive')
30748
319914d57b9e hgweb: use util.sortdict for archivespecs
Anton Shestakov <av6@dwimlabs.net>
parents: 30735
diff changeset
   138
        for typ, spec in self.archivespecs.iteritems():
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   139
            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
   140
                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
   141
36868
8ddb5c354906 hgweb: expose repo name on parsedrequest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36866
diff changeset
   142
    def templater(self, req):
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   143
        # determine scheme, port and server name
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   144
        # this is needed to create absolute urls
34612
c2cb6be4212f configitems: register the 'web.logourl' config
Boris Feld <boris.feld@octobus.net>
parents: 34611
diff changeset
   145
        logourl = self.config('web', 'logourl')
34611
c879fc7bd71f configitems: register the 'web.logoimg' config
Boris Feld <boris.feld@octobus.net>
parents: 34605
diff changeset
   146
        logoimg = self.config('web', 'logoimg')
36802
7fc80c982656 hgweb: ensure all wsgi environment values are str
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36801
diff changeset
   147
        staticurl = (self.config('web', 'staticurl')
36808
0031e972ded2 hgweb: use the parsed application path directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36807
diff changeset
   148
                     or req.apppath + '/static/')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   149
        if not staticurl.endswith('/'):
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   150
            staticurl += '/'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   151
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   152
        # some functions for the templater
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
        def motd(**map):
34587
b50c036494dc configitems: register the 'web.motd' config
Boris Feld <boris.feld@octobus.net>
parents: 34586
diff changeset
   155
            yield self.config('web', 'motd')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   156
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   157
        # figure out which style to use
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
        vars = {}
36868
8ddb5c354906 hgweb: expose repo name on parsedrequest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36866
diff changeset
   160
        styles, (style, mapfile) = getstyle(req, self.config,
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
   161
                                            self.templatepath)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   162
        if style == styles[0]:
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   163
            vars['style'] = style
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   164
36805
ec46415ed826 hgweb: always use "?" when writing session vars
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36804
diff changeset
   165
        sessionvars = webutil.sessionvars(vars, '?')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   166
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   167
        if not self.reponame:
34586
c364f3f73634 configitems: register the 'web.name' config
Boris Feld <boris.feld@octobus.net>
parents: 34584
diff changeset
   168
            self.reponame = (self.config('web', 'name', '')
36868
8ddb5c354906 hgweb: expose repo name on parsedrequest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36866
diff changeset
   169
                             or req.reponame
8ddb5c354906 hgweb: expose repo name on parsedrequest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36866
diff changeset
   170
                             or req.apppath
8ddb5c354906 hgweb: expose repo name on parsedrequest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36866
diff changeset
   171
                             or self.repo.root)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   172
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   173
        def websubfilter(text):
27008
7f19f331ef59 hgweb: do not import templatefilters.revescape and websub as symbol
Yuya Nishihara <yuya@tcha.org>
parents: 27007
diff changeset
   174
            return templatefilters.websub(text, self.websubtable)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   175
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   176
        # create the templater
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   177
        # TODO: export all keywords: defaults = templatekw.keywords.copy()
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   178
        defaults = {
36808
0031e972ded2 hgweb: use the parsed application path directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36807
diff changeset
   179
            'url': req.apppath + '/',
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   180
            'logourl': logourl,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   181
            'logoimg': logoimg,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   182
            'staticurl': staticurl,
36807
1e2194e0ef62 hgweb: use computed base URL from parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36806
diff changeset
   183
            'urlbase': req.advertisedbaseurl,
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   184
            'repo': self.reponame,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   185
            'encoding': encoding.encoding,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   186
            'motd': motd,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   187
            'sessionvars': sessionvars,
36808
0031e972ded2 hgweb: use the parsed application path directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36807
diff changeset
   188
            'pathdef': makebreadcrumb(req.apppath),
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   189
            'style': style,
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   190
            'nonce': self.nonce,
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   191
        }
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   192
        tres = formatter.templateresources(self.repo.ui, self.repo)
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   193
        tmpl = templater.templater.frommapfile(mapfile,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   194
                                               filters={'websub': websubfilter},
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   195
                                               defaults=defaults,
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   196
                                               resources=tres)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   197
        return tmpl
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   198
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   199
    def sendtemplate(self, name, **kwargs):
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   200
        """Helper function to send a response generated from a template."""
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   201
        self.res.setbodygen(self.tmpl(name, **kwargs))
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   202
        return self.res.sendresponse()
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   203
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1554
diff changeset
   204
class hgweb(object):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   205
    """HTTP server for individual repositories.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   206
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   207
    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
   208
    repository.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   209
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   210
    Instances are typically used as WSGI applications.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   211
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   212
    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
   213
    be multiple active threads inside __call__.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   214
    """
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   215
    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
   216
        if isinstance(repo, str):
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   217
            if baseui:
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   218
                u = baseui.copy()
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   219
            else:
30559
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 29787
diff changeset
   220
                u = uimod.ui.load()
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   221
            r = hg.repository(u, repo)
987
bfe12654764d hgweb: change startup argument processing
mpm@selenic.com
parents: 986
diff changeset
   222
        else:
22087
af62f0280a76 hgweb: avoid config object race with hgwebdir (issue4326)
Matt Mackall <mpm@selenic.com>
parents: 21759
diff changeset
   223
            # 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
   224
            r = repo
133
fb84d3e71042 added template support for some hgweb output, also, template files for
jake@edge2.net
parents: 132
diff changeset
   225
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
   226
        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
   227
        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
   228
        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
   229
        r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
26294
1ffc61c4e32e hgweb: overwrite cwd to resolve file patterns relative to repo (issue4568)
Yuya Nishihara <yuya@tcha.org>
parents: 26247
diff changeset
   230
        # resolve file patterns relative to repo root
1ffc61c4e32e hgweb: overwrite cwd to resolve file patterns relative to repo (issue4568)
Yuya Nishihara <yuya@tcha.org>
parents: 26247
diff changeset
   231
        r.ui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
1ffc61c4e32e hgweb: overwrite cwd to resolve file patterns relative to repo (issue4568)
Yuya Nishihara <yuya@tcha.org>
parents: 26247
diff changeset
   232
        r.baseui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
25488
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   233
        # 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
   234
        # break some wsgi implementation.
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   235
        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
   236
        r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   237
        self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))]
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   238
        self._lastrepo = self._repos[0]
5833
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 5779
diff changeset
   239
        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
   240
        self.reponame = name
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   241
26218
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   242
    def _webifyrepo(self, repo):
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   243
        repo = getwebview(repo)
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   244
        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
   245
        return repo
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   246
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   247
    @contextlib.contextmanager
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   248
    def _obtainrepo(self):
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   249
        """Obtain a repo unique to the caller.
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   250
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   251
        Internally we maintain a stack of cachedlocalrepo instances
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   252
        to be handed out. If one is available, we pop it and return it,
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   253
        ensuring it is up to date in the process. If one is not available,
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   254
        we clone the most recently used repo instance and return it.
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   255
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   256
        It is currently possible for the stack to grow without bounds
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   257
        if the server allows infinite threads. However, servers should
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   258
        have a thread limit, thus establishing our limit.
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   259
        """
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   260
        if self._repos:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   261
            cached = self._repos.pop()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   262
            r, created = cached.fetch()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   263
        else:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   264
            cached = self._lastrepo.copy()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   265
            r, created = cached.fetch()
26240
2b1434e5eaa0 hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26226
diff changeset
   266
        if created:
2b1434e5eaa0 hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26226
diff changeset
   267
            r = self._webifyrepo(r)
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   268
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   269
        self._lastrepo = cached
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   270
        self.mtime = cached.mtime
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   271
        try:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   272
            yield r
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   273
        finally:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   274
            self._repos.append(cached)
258
268bcb5a072a hgweb: watch changelog for changes
mpm@selenic.com
parents: 241
diff changeset
   275
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   276
    def run(self):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   277
        """Start a server from CGI environment.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   278
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   279
        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
   280
        method, if possible.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   281
        """
30636
f1c9fafcbf46 py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
   282
        if not encoding.environ.get('GATEWAY_INTERFACE',
f1c9fafcbf46 py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
   283
                                    '').startswith("CGI/1."):
8663
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8390
diff changeset
   284
            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
   285
                               "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
   286
        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
   287
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   288
    def __call__(self, env, respond):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   289
        """Run the WSGI application.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   290
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   291
        This may be called by multiple threads.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   292
        """
36911
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   293
        req = requestmod.parserequestfromenv(env)
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   294
        res = requestmod.wsgiresponse(req, respond)
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   295
36911
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   296
        return self.run_wsgi(req, res)
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   297
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   298
    def run_wsgi(self, req, res):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   299
        """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
   300
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   301
        This is typically only called by Mercurial. External consumers
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   302
        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
   303
        """
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   304
        with self._obtainrepo() as repo:
32788
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
   305
            profile = repo.ui.configbool('profiling', 'enabled')
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
   306
            with profiling.profile(repo.ui, enabled=profile):
36911
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   307
                for r in self._runwsgi(req, res, repo):
29787
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
   308
                    yield r
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   309
36911
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   310
    def _runwsgi(self, req, res, repo):
36870
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
   311
        rctx = requestcontext(self, repo, req, res)
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   312
26160
952e0564b46e hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26149
diff changeset
   313
        # This state is global across all threads.
34239
344fd1fe237b configitems: register the 'web.encoding' config
Boris Feld <boris.feld@octobus.net>
parents: 33328
diff changeset
   314
        encoding.encoding = rctx.config('web', 'encoding')
36909
84110a1d0f7d hgweb: store the raw WSGI environment dict
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   315
        rctx.repo.ui.environ = req.rawenv
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   316
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   317
        if rctx.csp:
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   318
            # hgwebdir may have added CSP header. Since we generate our own,
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   319
            # replace it.
36861
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36856
diff changeset
   320
            res.headers['Content-Security-Policy'] = rctx.csp
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   321
36861
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36856
diff changeset
   322
        handled = wireprotoserver.handlewsgirequest(
36877
02bea04b4c54 hgweb: transition permissions hooks to modern request type (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36876
diff changeset
   323
            rctx, req, res, self.check_perm)
36812
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36811
diff changeset
   324
        if handled:
36861
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36856
diff changeset
   325
            return res.sendresponse()
36812
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36811
diff changeset
   326
36898
d0b0fedbfb53 hgweb: change how dispatch path is reported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36887
diff changeset
   327
        # Old implementations of hgweb supported dispatching the request via
d0b0fedbfb53 hgweb: change how dispatch path is reported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36887
diff changeset
   328
        # the initial query string parameter instead of using PATH_INFO.
d0b0fedbfb53 hgweb: change how dispatch path is reported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36887
diff changeset
   329
        # If PATH_INFO is present (signaled by ``req.dispatchpath`` having
d0b0fedbfb53 hgweb: change how dispatch path is reported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36887
diff changeset
   330
        # a value), we use it. Otherwise fall back to the query string.
d0b0fedbfb53 hgweb: change how dispatch path is reported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36887
diff changeset
   331
        if req.dispatchpath is not None:
36811
cfb9ef24968c hgweb: use parsed request to construct query parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36810
diff changeset
   332
            query = req.dispatchpath
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   333
        else:
36811
cfb9ef24968c hgweb: use parsed request to construct query parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36810
diff changeset
   334
            query = req.querystring.partition('&')[0].partition(';')[0]
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   335
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   336
        # 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
   337
36811
cfb9ef24968c hgweb: use parsed request to construct query parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36810
diff changeset
   338
        args = query.split('/', 2)
36865
3d60a22e27f5 hgweb: perform all parameter lookup via qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36864
diff changeset
   339
        if 'cmd' not in req.qsparams 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
   340
            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
   341
            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
   342
            if style != -1:
36863
1a1972b1a1ff hgweb: use our new request object for "style" parameter
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36861
diff changeset
   343
                req.qsparams['style'] = cmd[:style]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   344
                cmd = cmd[style + 1:]
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   345
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   346
            # 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
   347
            if util.safehasattr(webcommands, cmd):
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   348
                req.qsparams['cmd'] = cmd
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   349
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   350
            if cmd == 'static':
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   351
                req.qsparams['file'] = '/'.join(args)
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   352
            else:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   353
                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
   354
                    node = args.pop(0).replace('%2F', '/')
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   355
                    req.qsparams['node'] = node
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   356
                if args:
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   357
                    if 'file' in req.qsparams:
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   358
                        del req.qsparams['file']
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   359
                    for a in args:
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   360
                        req.qsparams.add('file', a)
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   361
36814
f9078c6caeb6 hgweb: parse and store HTTP request headers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36812
diff changeset
   362
            ua = req.headers.get('User-Agent', '')
9731
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
   363
            if cmd == 'rev' and 'mercurial' in ua:
36863
1a1972b1a1ff hgweb: use our new request object for "style" parameter
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36861
diff changeset
   364
                req.qsparams['style'] = 'raw'
9731
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
   365
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   366
            if cmd == 'archive':
36865
3d60a22e27f5 hgweb: perform all parameter lookup via qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36864
diff changeset
   367
                fn = req.qsparams['node']
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   368
                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
   369
                    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
   370
                    if fn.endswith(ext):
36865
3d60a22e27f5 hgweb: perform all parameter lookup via qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36864
diff changeset
   371
                        req.qsparams['node'] = fn[:-len(ext)]
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   372
                        req.qsparams['type'] = type_
35984
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
   373
        else:
36865
3d60a22e27f5 hgweb: perform all parameter lookup via qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36864
diff changeset
   374
            cmd = req.qsparams.get('cmd', '')
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   375
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   376
        # process the web interface request
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   377
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   378
        try:
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   379
            rctx.tmpl = rctx.templater(req)
36989
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
   380
            ctype = rctx.tmpl.render('mimetype',
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
   381
                                     {'encoding': encoding.encoding})
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   382
7562
b663b5563de7 hgweb: allow static content when deny_read denies access
Mark Edgington <edgimar@gmail.com>
parents: 7396
diff changeset
   383
            # 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
   384
            if cmd != 'static':
36877
02bea04b4c54 hgweb: transition permissions hooks to modern request type (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36876
diff changeset
   385
                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
   386
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   387
            if cmd == '':
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   388
                req.qsparams['cmd'] = rctx.tmpl.cache['default']
36865
3d60a22e27f5 hgweb: perform all parameter lookup via qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36864
diff changeset
   389
                cmd = req.qsparams['cmd']
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
   390
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   391
            # Don't enable caching if using a CSP nonce because then it wouldn't
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   392
            # be a nonce.
34605
625202a44d88 configitems: register the 'web.cache' config
Boris Feld <boris.feld@octobus.net>
parents: 34602
diff changeset
   393
            if rctx.configbool('web', 'cache') and not rctx.nonce:
36869
7ad6a275316f hgweb: inline caching() and port to modern mechanisms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   394
                tag = 'W/"%d"' % self.mtime
7ad6a275316f hgweb: inline caching() and port to modern mechanisms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   395
                if req.headers.get('If-None-Match') == tag:
36878
ccb70a77f746 hgweb: refactor 304 handling code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36877
diff changeset
   396
                    res.status = '304 Not Modified'
ccb70a77f746 hgweb: refactor 304 handling code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36877
diff changeset
   397
                    # Response body not allowed on 304.
ccb70a77f746 hgweb: refactor 304 handling code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36877
diff changeset
   398
                    res.setbodybytes('')
ccb70a77f746 hgweb: refactor 304 handling code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36877
diff changeset
   399
                    return res.sendresponse()
36869
7ad6a275316f hgweb: inline caching() and port to modern mechanisms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   400
7ad6a275316f hgweb: inline caching() and port to modern mechanisms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   401
                res.headers['ETag'] = tag
7ad6a275316f hgweb: inline caching() and port to modern mechanisms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   402
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   403
            if cmd not in webcommands.__all__:
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
   404
                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
   405
                raise ErrorResponse(HTTP_BAD_REQUEST, msg)
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   406
            else:
36870
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
   407
                # Set some globals appropriate for web handlers. Commands can
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
   408
                # override easily enough.
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
   409
                res.status = '200 Script output follows'
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
   410
                res.headers['Content-Type'] = ctype
36887
4daa22071d5d hgweb: stop passing req and tmpl into @webcommand functions (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36883
diff changeset
   411
                return getattr(webcommands, cmd)(rctx)
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   412
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   413
        except (error.LookupError, error.RepoLookupError) as err:
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 35986
diff changeset
   414
            msg = pycompat.bytestr(err)
18855
50c922c1b514 hgweb: show correct error message for i18n environment
Takumi IINO <trot.thunder@gmail.com>
parents: 18522
diff changeset
   415
            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
   416
                not isinstance(err,  error.ManifestLookupError)):
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
   417
                msg = 'revision not found: %s' % err.name
36879
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   418
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   419
            res.status = '404 Not Found'
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   420
            res.headers['Content-Type'] = ctype
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   421
            return rctx.sendtemplate('error', error=msg)
36879
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   422
        except (error.RepoError, error.RevlogError) as e:
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   423
            res.status = '500 Internal Server Error'
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   424
            res.headers['Content-Type'] = ctype
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   425
            return rctx.sendtemplate('error', error=pycompat.bytestr(e))
36879
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   426
        except ErrorResponse as e:
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   427
            res.status = statusmessage(e.code, pycompat.bytestr(e))
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   428
            res.headers['Content-Type'] = ctype
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   429
            return rctx.sendtemplate('error', error=pycompat.bytestr(e))
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   430
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   431
    def check_perm(self, rctx, req, op):
22200
b27c3beaaf30 cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents: 22087
diff changeset
   432
        for permhook in permhooks:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   433
            permhook(rctx, req, op)
26208
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   434
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   435
def getwebview(repo):
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   436
    """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
   437
    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
   438
    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
   439
    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
   440
    still excludes "hidden" one.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   441
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   442
    See the repoview module for details.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   443
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   444
    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
   445
    user ever asked about it. So we better keep it undocumented for now."""
34584
bf2389b1f15e configitems: register the 'web.view' config
Boris Feld <boris.feld@octobus.net>
parents: 34515
diff changeset
   446
    # experimental config: web.view
bf2389b1f15e configitems: register the 'web.view' config
Boris Feld <boris.feld@octobus.net>
parents: 34515
diff changeset
   447
    viewconfig = repo.ui.config('web', 'view', untrusted=True)
26208
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   448
    if viewconfig == 'all':
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   449
        return repo.unfiltered()
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   450
    elif viewconfig in repoview.filtertable:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   451
        return repo.filtered(viewconfig)
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   452
    else:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   453
        return repo.filtered('served')