mercurial/hgweb/hgweb_mod.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 28 Feb 2020 10:30:18 -0800
changeset 44409 f935b680860d
parent 43106 d783f945a701
child 45307 ba50c8a95e2b
permissions -rw-r--r--
commit: error out on unresolved files even if commit would be empty Differential Revision: https://phab.mercurial-scm.org/D8195
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
)
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
    21
from ..pycompat import getattr
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    22
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    23
from .. import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    24
    encoding,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    25
    error,
40728
2cd5f1fac788 hgweb: load globally-enabled extensions explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 39777
diff changeset
    26
    extensions,
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
    27
    formatter,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    28
    hg,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    29
    hook,
29787
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
    30
    profiling,
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    31
    pycompat,
37221
307ee8883975 hgweb: use registrar to declare "websub" template filter
Yuya Nishihara <yuya@tcha.org>
parents: 37093
diff changeset
    32
    registrar,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    33
    repoview,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    34
    templatefilters,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    35
    templater,
37509
cb7b275c0cd0 hgweb: wrap {pathdef} with mappinglist
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
    36
    templateutil,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    37
    ui as uimod,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    38
    util,
35856
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35037
diff changeset
    39
    wireprotoserver,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    40
)
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    41
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    42
from . import (
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
    43
    request as requestmod,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    44
    webcommands,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    45
    webutil,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    46
    wsgicgi,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    47
)
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    48
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
    49
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    50
def getstyle(req, configfn, templatepath):
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    51
    styles = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    52
        req.qsparams.get(b'style', None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    53
        configfn(b'web', b'style'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    54
        b'paper',
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    55
    )
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    56
    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
    57
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
    58
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    59
def makebreadcrumb(url, prefix=b''):
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
    '''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    66
    if url.endswith(b'/'):
18258
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:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    69
        url = b'/' + 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
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    71
    if relpath.startswith(b'/'):
18258
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
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    76
    pathitems = [b''] + relpath.split(b'/')
18258
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
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    80
        breadcrumb.append({b'url': urlel, b'name': pathel})
18258
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)
37509
cb7b275c0cd0 hgweb: wrap {pathdef} with mappinglist
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
    82
    return templateutil.mappinglist(reversed(breadcrumb))
18258
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    83
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
    84
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    85
class requestcontext(object):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    86
    """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
    87
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    88
    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
    89
    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
    90
    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
    91
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
    92
36870
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
    93
    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
    94
        self.repo = repo
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    95
        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
    96
        self.req = req
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
    97
        self.res = res
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    98
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    99
        self.maxchanges = self.configint(b'web', b'maxchanges')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   100
        self.stripecount = self.configint(b'web', b'stripes')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   101
        self.maxshortchanges = self.configint(b'web', b'maxshortchanges')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   102
        self.maxfiles = self.configint(b'web', b'maxfiles')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   103
        self.allowpull = self.configbool(b'web', b'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
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   108
        self.templatepath = self.config(b'web', b'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):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   121
        return self.repo.ui.config(section, name, default, untrusted=untrusted)
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   122
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   123
    def configbool(self, section, name, default=uimod._unset, untrusted=True):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   124
        return self.repo.ui.configbool(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   125
            section, name, default, untrusted=untrusted
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   126
        )
26135
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):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   129
        return self.repo.ui.configint(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   130
            section, name, default, untrusted=untrusted
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   131
        )
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   132
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   133
    def configlist(self, section, name, default=uimod._unset, untrusted=True):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   134
        return self.repo.ui.configlist(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   135
            section, name, default, untrusted=untrusted
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   136
        )
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   137
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   138
    def archivelist(self, nodeid):
37514
034a422aeaff hgweb: forward archivelist() of hgweb to webutil
Yuya Nishihara <yuya@tcha.org>
parents: 37512
diff changeset
   139
        return webutil.archivelist(self.repo.ui, 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
   140
36868
8ddb5c354906 hgweb: expose repo name on parsedrequest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36866
diff changeset
   141
    def templater(self, req):
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   142
        # determine scheme, port and server name
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   143
        # this is needed to create absolute urls
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   144
        logourl = self.config(b'web', b'logourl')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   145
        logoimg = self.config(b'web', b'logoimg')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   146
        staticurl = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   147
            self.config(b'web', b'staticurl')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   148
            or req.apppath.rstrip(b'/') + b'/static/'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   149
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   150
        if not staticurl.endswith(b'/'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   151
            staticurl += b'/'
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   152
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   153
        # figure out which style to use
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   154
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   155
        vars = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   156
        styles, (style, mapfile) = getstyle(req, self.config, self.templatepath)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   157
        if style == styles[0]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   158
            vars[b'style'] = style
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   159
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   160
        sessionvars = webutil.sessionvars(vars, b'?')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   161
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   162
        if not self.reponame:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   163
            self.reponame = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   164
                self.config(b'web', b'name', b'')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   165
                or req.reponame
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   166
                or req.apppath
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   167
                or self.repo.root
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   168
            )
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   169
37221
307ee8883975 hgweb: use registrar to declare "websub" template filter
Yuya Nishihara <yuya@tcha.org>
parents: 37093
diff changeset
   170
        filters = {}
307ee8883975 hgweb: use registrar to declare "websub" template filter
Yuya Nishihara <yuya@tcha.org>
parents: 37093
diff changeset
   171
        templatefilter = registrar.templatefilter(filters)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   172
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   173
        @templatefilter(b'websub', intype=bytes)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   174
        def websubfilter(text):
27008
7f19f331ef59 hgweb: do not import templatefilters.revescape and websub as symbol
Yuya Nishihara <yuya@tcha.org>
parents: 27007
diff changeset
   175
            return templatefilters.websub(text, self.websubtable)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   176
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   177
        # create the templater
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   178
        # 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
   179
        defaults = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   180
            b'url': req.apppath + b'/',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   181
            b'logourl': logourl,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   182
            b'logoimg': logoimg,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   183
            b'staticurl': staticurl,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   184
            b'urlbase': req.advertisedbaseurl,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   185
            b'repo': self.reponame,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   186
            b'encoding': encoding.encoding,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   187
            b'sessionvars': sessionvars,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   188
            b'pathdef': makebreadcrumb(req.apppath),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   189
            b'style': style,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   190
            b'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
        }
38928
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   192
        templatekeyword = registrar.templatekeyword(defaults)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   193
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   194
        @templatekeyword(b'motd', requires=())
38928
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   195
        def motd(context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   196
            yield self.config(b'web', b'motd')
38928
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   197
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   198
        tres = formatter.templateresources(self.repo.ui, self.repo)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   199
        tmpl = templater.templater.frommapfile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   200
            mapfile, filters=filters, defaults=defaults, resources=tres
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   201
        )
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   202
        return tmpl
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   203
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   204
    def sendtemplate(self, name, **kwargs):
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   205
        """Helper function to send a response generated from a template."""
37019
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   206
        kwargs = pycompat.byteskwargs(kwargs)
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   207
        self.res.setbodygen(self.tmpl.generate(name, kwargs))
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   208
        return self.res.sendresponse()
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   209
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   210
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1554
diff changeset
   211
class hgweb(object):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   212
    """HTTP server for individual repositories.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   213
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   214
    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
   215
    repository.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   216
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   217
    Instances are typically used as WSGI applications.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   218
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   219
    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
   220
    be multiple active threads inside __call__.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   221
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   222
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   223
    def __init__(self, repo, name=None, baseui=None):
37746
b29f490eb904 hgweb_mod: inform hgweb class about paths actually being bytes
Augie Fackler <augie@google.com>
parents: 37514
diff changeset
   224
        if isinstance(repo, bytes):
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   225
            if baseui:
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   226
                u = baseui.copy()
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   227
            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
   228
                u = uimod.ui.load()
40728
2cd5f1fac788 hgweb: load globally-enabled extensions explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 39777
diff changeset
   229
                extensions.loadall(u)
40729
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40728
diff changeset
   230
                extensions.populateui(u)
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   231
            r = hg.repository(u, repo)
987
bfe12654764d hgweb: change startup argument processing
mpm@selenic.com
parents: 986
diff changeset
   232
        else:
22087
af62f0280a76 hgweb: avoid config object race with hgwebdir (issue4326)
Matt Mackall <mpm@selenic.com>
parents: 21759
diff changeset
   233
            # 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
   234
            r = repo
133
fb84d3e71042 added template support for some hgweb output, also, template files for
jake@edge2.net
parents: 132
diff changeset
   235
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   236
        r.ui.setconfig(b'ui', b'report_untrusted', b'off', b'hgweb')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   237
        r.baseui.setconfig(b'ui', b'report_untrusted', b'off', b'hgweb')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   238
        r.ui.setconfig(b'ui', b'nontty', b'true', b'hgweb')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   239
        r.baseui.setconfig(b'ui', b'nontty', b'true', b'hgweb')
26294
1ffc61c4e32e hgweb: overwrite cwd to resolve file patterns relative to repo (issue4568)
Yuya Nishihara <yuya@tcha.org>
parents: 26247
diff changeset
   240
        # resolve file patterns relative to repo root
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   241
        r.ui.setconfig(b'ui', b'forcecwd', r.root, b'hgweb')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   242
        r.baseui.setconfig(b'ui', b'forcecwd', r.root, b'hgweb')
38039
5b831053d9b6 hgweb: do not try to replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37827
diff changeset
   243
        # it's unlikely that we can replace signal handlers in WSGI server,
5b831053d9b6 hgweb: do not try to replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37827
diff changeset
   244
        # and mod_wsgi issues a big warning. a plain hgweb process (with no
5b831053d9b6 hgweb: do not try to replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37827
diff changeset
   245
        # threading) could replace signal handlers, but we don't bother
5b831053d9b6 hgweb: do not try to replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37827
diff changeset
   246
        # conditionally enabling it.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   247
        r.ui.setconfig(b'ui', b'signal-safe-lock', b'false', b'hgweb')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   248
        r.baseui.setconfig(b'ui', b'signal-safe-lock', b'false', b'hgweb')
25488
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   249
        # 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
   250
        # break some wsgi implementation.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   251
        r.ui.setconfig(b'progress', b'disable', b'true', b'hgweb')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   252
        r.baseui.setconfig(b'progress', b'disable', b'true', b'hgweb')
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   253
        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
   254
        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
   255
        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
   256
        self.reponame = name
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   257
26218
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   258
    def _webifyrepo(self, repo):
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   259
        repo = getwebview(repo)
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   260
        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
   261
        return repo
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   262
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   263
    @contextlib.contextmanager
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   264
    def _obtainrepo(self):
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   265
        """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
   266
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   267
        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
   268
        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
   269
        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
   270
        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
   271
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   272
        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
   273
        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
   274
        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
   275
        """
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   276
        if self._repos:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   277
            cached = self._repos.pop()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   278
            r, created = cached.fetch()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   279
        else:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   280
            cached = self._lastrepo.copy()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   281
            r, created = cached.fetch()
26240
2b1434e5eaa0 hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26226
diff changeset
   282
        if created:
2b1434e5eaa0 hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26226
diff changeset
   283
            r = self._webifyrepo(r)
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   284
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   285
        self._lastrepo = cached
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   286
        self.mtime = cached.mtime
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   287
        try:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   288
            yield r
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   289
        finally:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   290
            self._repos.append(cached)
258
268bcb5a072a hgweb: watch changelog for changes
mpm@selenic.com
parents: 241
diff changeset
   291
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   292
    def run(self):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   293
        """Start a server from CGI environment.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   294
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   295
        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
   296
        method, if possible.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   297
        """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   298
        if not encoding.environ.get(b'GATEWAY_INTERFACE', b'').startswith(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   299
            b"CGI/1."
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   300
        ):
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   301
            raise RuntimeError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   302
                b"This function is only intended to be "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   303
                b"called while running as a CGI script."
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   304
            )
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   305
        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
   306
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   307
    def __call__(self, env, respond):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   308
        """Run the WSGI application.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   309
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   310
        This may be called by multiple threads.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   311
        """
36911
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   312
        req = requestmod.parserequestfromenv(env)
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   313
        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
   314
36911
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   315
        return self.run_wsgi(req, res)
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   316
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   317
    def run_wsgi(self, req, res):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   318
        """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
   319
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   320
        This is typically only called by Mercurial. External consumers
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   321
        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
   322
        """
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   323
        with self._obtainrepo() as repo:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   324
            profile = repo.ui.configbool(b'profiling', b'enabled')
32788
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
   325
            with profiling.profile(repo.ui, enabled=profile):
36911
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   326
                for r in self._runwsgi(req, res, repo):
29787
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
   327
                    yield r
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   328
36911
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   329
    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
   330
        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
   331
26160
952e0564b46e hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26149
diff changeset
   332
        # This state is global across all threads.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   333
        encoding.encoding = rctx.config(b'web', b'encoding')
36909
84110a1d0f7d hgweb: store the raw WSGI environment dict
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   334
        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
   335
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   336
        if rctx.csp:
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   337
            # 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
   338
            # replace it.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   339
            res.headers[b'Content-Security-Policy'] = rctx.csp
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   340
37046
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37020
diff changeset
   341
        # /api/* is reserved for various API implementations. Dispatch
37093
db114320df7e hgweb: don't responsd to api requests unless feature is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
   342
        # accordingly. But URL paths can conflict with subrepos and virtual
db114320df7e hgweb: don't responsd to api requests unless feature is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
   343
        # repos in hgwebdir. So until we have a workaround for this, only
db114320df7e hgweb: don't responsd to api requests unless feature is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
   344
        # expose the URLs if the feature is enabled.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   345
        apienabled = rctx.repo.ui.configbool(b'experimental', b'web.apiserver')
37093
db114320df7e hgweb: don't responsd to api requests unless feature is enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37046
diff changeset
   346
        if apienabled and req.dispatchparts and req.dispatchparts[0] == b'api':
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   347
            wireprotoserver.handlewsgiapirequest(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   348
                rctx, req, res, self.check_perm
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   349
            )
37046
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37020
diff changeset
   350
            return res.sendresponse()
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37020
diff changeset
   351
36861
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36856
diff changeset
   352
        handled = wireprotoserver.handlewsgirequest(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   353
            rctx, req, res, self.check_perm
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   354
        )
36812
158d4ecc03c8 wireprotoserver: move all wire protocol handling logic out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36811
diff changeset
   355
        if handled:
36861
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36856
diff changeset
   356
            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
   357
36898
d0b0fedbfb53 hgweb: change how dispatch path is reported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36887
diff changeset
   358
        # 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
   359
        # 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
   360
        # 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
   361
        # 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
   362
        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
   363
            query = req.dispatchpath
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   364
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   365
            query = req.querystring.partition(b'&')[0].partition(b';')[0]
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   366
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   367
        # 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
   368
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   369
        args = query.split(b'/', 2)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   370
        if b'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
   371
            cmd = args.pop(0)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   372
            style = cmd.rfind(b'-')
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   373
            if style != -1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   374
                req.qsparams[b'style'] = cmd[:style]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   375
                cmd = cmd[style + 1 :]
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   376
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   377
            # 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
   378
            if util.safehasattr(webcommands, cmd):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   379
                req.qsparams[b'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
   380
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   381
            if cmd == b'static':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   382
                req.qsparams[b'file'] = b'/'.join(args)
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   383
            else:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   384
                if args and args[0]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   385
                    node = args.pop(0).replace(b'%2F', b'/')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   386
                    req.qsparams[b'node'] = node
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   387
                if args:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   388
                    if b'file' in req.qsparams:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   389
                        del req.qsparams[b'file']
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   390
                    for a in args:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   391
                        req.qsparams.add(b'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
   392
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   393
            ua = req.headers.get(b'User-Agent', b'')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   394
            if cmd == b'rev' and b'mercurial' in ua:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   395
                req.qsparams[b'style'] = b'raw'
9731
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
   396
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   397
            if cmd == b'archive':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   398
                fn = req.qsparams[b'node']
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43089
diff changeset
   399
                for type_, spec in pycompat.iteritems(webutil.archivespecs):
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   400
                    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
   401
                    if fn.endswith(ext):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   402
                        req.qsparams[b'node'] = fn[: -len(ext)]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   403
                        req.qsparams[b'type'] = type_
35984
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
   404
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   405
            cmd = req.qsparams.get(b'cmd', b'')
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   406
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   407
        # process the web interface request
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   408
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   409
        try:
36883
061635d4221c hgweb: add a sendtemplate() helper function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36881
diff changeset
   410
            rctx.tmpl = rctx.templater(req)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   411
            ctype = rctx.tmpl.render(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   412
                b'mimetype', {b'encoding': encoding.encoding}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   413
            )
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   414
7562
b663b5563de7 hgweb: allow static content when deny_read denies access
Mark Edgington <edgimar@gmail.com>
parents: 7396
diff changeset
   415
            # check read permissions non-static content
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   416
            if cmd != b'static':
36877
02bea04b4c54 hgweb: transition permissions hooks to modern request type (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36876
diff changeset
   417
                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
   418
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   419
            if cmd == b'':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   420
                req.qsparams[b'cmd'] = rctx.tmpl.render(b'default', {})
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   421
                cmd = req.qsparams[b'cmd']
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
   422
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   423
            # 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
   424
            # be a nonce.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   425
            if rctx.configbool(b'web', b'cache') and not rctx.nonce:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   426
                tag = b'W/"%d"' % self.mtime
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   427
                if req.headers.get(b'If-None-Match') == tag:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   428
                    res.status = b'304 Not Modified'
37827
11ee9bf24791 hgweb: discard Content-Type header for 304 responses (issue5844)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37746
diff changeset
   429
                    # Content-Type may be defined globally. It isn't valid on a
11ee9bf24791 hgweb: discard Content-Type header for 304 responses (issue5844)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37746
diff changeset
   430
                    # 304, so discard it.
11ee9bf24791 hgweb: discard Content-Type header for 304 responses (issue5844)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37746
diff changeset
   431
                    try:
11ee9bf24791 hgweb: discard Content-Type header for 304 responses (issue5844)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37746
diff changeset
   432
                        del res.headers[b'Content-Type']
11ee9bf24791 hgweb: discard Content-Type header for 304 responses (issue5844)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37746
diff changeset
   433
                    except KeyError:
11ee9bf24791 hgweb: discard Content-Type header for 304 responses (issue5844)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37746
diff changeset
   434
                        pass
36878
ccb70a77f746 hgweb: refactor 304 handling code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36877
diff changeset
   435
                    # Response body not allowed on 304.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   436
                    res.setbodybytes(b'')
36878
ccb70a77f746 hgweb: refactor 304 handling code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36877
diff changeset
   437
                    return res.sendresponse()
36869
7ad6a275316f hgweb: inline caching() and port to modern mechanisms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   438
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   439
                res.headers[b'ETag'] = tag
36869
7ad6a275316f hgweb: inline caching() and port to modern mechanisms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36868
diff changeset
   440
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   441
            if cmd not in webcommands.__all__:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   442
                msg = b'no such method: %s' % cmd
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   443
                raise ErrorResponse(HTTP_BAD_REQUEST, msg)
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   444
            else:
36870
1f42d621f090 hgweb: support using new response object for web commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
   445
                # 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
   446
                # override easily enough.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   447
                res.status = b'200 Script output follows'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   448
                res.headers[b'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
   449
                return getattr(webcommands, cmd)(rctx)
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   450
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   451
        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
   452
            msg = pycompat.bytestr(err)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   453
            if util.safehasattr(err, b'name') and not isinstance(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   454
                err, error.ManifestLookupError
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   455
            ):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   456
                msg = b'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
   457
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   458
            res.status = b'404 Not Found'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   459
            res.headers[b'Content-Type'] = ctype
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   460
            return rctx.sendtemplate(b'error', error=msg)
39777
b63dee7bd0d9 global: replace most uses of RevlogError with StorageError (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39470
diff changeset
   461
        except (error.RepoError, error.StorageError) as e:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   462
            res.status = b'500 Internal Server Error'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   463
            res.headers[b'Content-Type'] = ctype
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   464
            return rctx.sendtemplate(b'error', error=pycompat.bytestr(e))
39470
17ca967e9fca hgweb: map Abort to 403 error to report inaccessible path for example
Yuya Nishihara <yuya@tcha.org>
parents: 38928
diff changeset
   465
        except error.Abort as e:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   466
            res.status = b'403 Forbidden'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   467
            res.headers[b'Content-Type'] = ctype
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   468
            return rctx.sendtemplate(b'error', error=pycompat.bytestr(e))
36879
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   469
        except ErrorResponse as e:
38307
519b46a8f4d2 hgweb: propagate http headers from ErrorResponse for web interface commands
Sune Foldager <cryo@cyanite.org>
parents: 38039
diff changeset
   470
            for k, v in e.headers:
519b46a8f4d2 hgweb: propagate http headers from ErrorResponse for web interface commands
Sune Foldager <cryo@cyanite.org>
parents: 38039
diff changeset
   471
                res.headers[k] = v
36879
9675147aec06 hgweb: send errors using new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36878
diff changeset
   472
            res.status = statusmessage(e.code, pycompat.bytestr(e))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   473
            res.headers[b'Content-Type'] = ctype
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   474
            return rctx.sendtemplate(b'error', error=pycompat.bytestr(e))
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   475
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   476
    def check_perm(self, rctx, req, op):
22200
b27c3beaaf30 cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents: 22087
diff changeset
   477
        for permhook in permhooks:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   478
            permhook(rctx, req, op)
26208
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   479
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40729
diff changeset
   480
26208
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   481
def getwebview(repo):
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   482
    """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
   483
    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
   484
    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
   485
    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
   486
    still excludes "hidden" one.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   487
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   488
    See the repoview module for details.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   489
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   490
    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
   491
    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
   492
    # experimental config: web.view
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   493
    viewconfig = repo.ui.config(b'web', b'view', untrusted=True)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   494
    if viewconfig == b'all':
26208
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   495
        return repo.unfiltered()
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   496
    elif viewconfig in repoview.filtertable:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   497
        return repo.filtered(viewconfig)
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   498
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   499
        return repo.filtered(b'served')