mercurial/hgweb/hgweb_mod.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 10 Mar 2018 12:11:26 -0800
changeset 36864 4e06e8336634
parent 36863 1a1972b1a1ff
child 36865 3d60a22e27f5
permissions -rw-r--r--
hgweb: set variables in qsparams We currently mutate wsgireq.form in a few places. Since it is independent from req.qsparams, we will need to make changes on req.qsparams as well before consumers can use qsparams. So let's do that. Eventually, we'll delete wsgireq.form and all references to it. Differential Revision: https://phab.mercurial-scm.org/D2780
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,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    17
    HTTP_NOT_FOUND,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    18
    HTTP_NOT_MODIFIED,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    19
    HTTP_OK,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    20
    HTTP_SERVER_ERROR,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    21
    caching,
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
    22
    cspvalues,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    23
    permhooks,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    24
)
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    25
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    26
from .. import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    27
    encoding,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    28
    error,
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
    29
    formatter,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    30
    hg,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    31
    hook,
29787
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
    32
    profiling,
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    33
    pycompat,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    34
    repoview,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    35
    templatefilters,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    36
    templater,
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
30749
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    49
archivespecs = util.sortdict((
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    50
    ('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
    51
    ('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
    52
    ('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
    53
))
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    54
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    55
def getstyle(req, configfn, templatepath):
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    56
    styles = (
36863
1a1972b1a1ff hgweb: use our new request object for "style" parameter
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36861
diff changeset
    57
        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
    58
        configfn('web', 'style'),
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    59
        'paper',
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    60
    )
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
    61
    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
    62
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    63
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
    64
    '''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
    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
    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
    67
    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
    68
    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
    69
    '''
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    70
    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
    71
        url = url[:-1]
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    72
    if prefix:
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
    73
        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
    74
    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
    75
    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
    76
        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
    77
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    78
    breadcrumb = []
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    79
    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
    80
    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
    81
    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
    82
        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
    83
            break
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
    84
        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
    85
        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
    86
    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
    87
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    88
class requestcontext(object):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    89
    """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
    90
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    91
    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
    92
    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
    93
    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
    94
    """
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
    95
    def __init__(self, app, repo):
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
    96
        self.repo = repo
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
    97
        self.reponame = app.reponame
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
    98
30749
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
    99
        self.archivespecs = archivespecs
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
   100
34590
95f4e5b1ec92 configitems: register the 'web.maxchanges' config
Boris Feld <boris.feld@octobus.net>
parents: 34589
diff changeset
   101
        self.maxchanges = self.configint('web', 'maxchanges')
34245
945c9816ec1d configitems: register the 'web.stripes' config
Boris Feld <boris.feld@octobus.net>
parents: 34239
diff changeset
   102
        self.stripecount = self.configint('web', 'stripes')
34588
0d9928a67254 configitems: register the 'web.maxshortchanges' config
Boris Feld <boris.feld@octobus.net>
parents: 34587
diff changeset
   103
        self.maxshortchanges = self.configint('web', 'maxshortchanges')
34589
883d06211973 configitems: register the 'web.maxfiles' config
Boris Feld <boris.feld@octobus.net>
parents: 34588
diff changeset
   104
        self.maxfiles = self.configint('web', 'maxfiles')
35037
da5d5ea7d696 config: rename allowpull to allow-pull
David Demelier <markand@malikania.fr>
parents: 34806
diff changeset
   105
        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
   106
26163
84511b1d9724 hgweb: move templatepath to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26162
diff changeset
   107
        # 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
   108
        # 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
   109
        # 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
   110
        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
   111
26164
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
   112
        # 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
   113
        # 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
   114
        # 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
   115
        # 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
   116
        # of the request.
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
   117
        self.websubtable = app.websubtable
26164
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
   118
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   119
        self.csp, self.nonce = cspvalues(self.repo.ui)
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   120
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   121
    # 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
   122
    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
   123
        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
   124
                                   untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   125
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   126
    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
   127
        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
   128
                                       untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   129
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   130
    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
   131
        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
   132
                                      untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
   133
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
   134
    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
   135
        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
   136
                                       untrusted=untrusted)
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):
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
   139
        allowed = self.configlist('web', 'allow_archive')
30748
319914d57b9e hgweb: use util.sortdict for archivespecs
Anton Shestakov <av6@dwimlabs.net>
parents: 30735
diff changeset
   140
        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
   141
            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
   142
                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
   143
36807
1e2194e0ef62 hgweb: use computed base URL from parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36806
diff changeset
   144
    def templater(self, wsgireq, req):
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   145
        # determine scheme, port and server name
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   146
        # 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
   147
        logourl = self.config('web', 'logourl')
34611
c879fc7bd71f configitems: register the 'web.logoimg' config
Boris Feld <boris.feld@octobus.net>
parents: 34605
diff changeset
   148
        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
   149
        staticurl = (self.config('web', 'staticurl')
36808
0031e972ded2 hgweb: use the parsed application path directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36807
diff changeset
   150
                     or req.apppath + '/static/')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   151
        if not staticurl.endswith('/'):
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   152
            staticurl += '/'
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
        # some functions for the templater
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   155
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   156
        def motd(**map):
34587
b50c036494dc configitems: register the 'web.motd' config
Boris Feld <boris.feld@octobus.net>
parents: 34586
diff changeset
   157
            yield self.config('web', 'motd')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   158
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   159
        # figure out which style to use
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   160
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   161
        vars = {}
36863
1a1972b1a1ff hgweb: use our new request object for "style" parameter
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36861
diff changeset
   162
        styles, (style, mapfile) = getstyle(wsgireq.req, self.config,
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
   163
                                            self.templatepath)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   164
        if style == styles[0]:
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   165
            vars['style'] = style
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   166
36805
ec46415ed826 hgweb: always use "?" when writing session vars
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36804
diff changeset
   167
        sessionvars = webutil.sessionvars(vars, '?')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   168
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   169
        if not self.reponame:
34586
c364f3f73634 configitems: register the 'web.name' config
Boris Feld <boris.feld@octobus.net>
parents: 34584
diff changeset
   170
            self.reponame = (self.config('web', 'name', '')
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   171
                             or wsgireq.env.get('REPO_NAME')
36808
0031e972ded2 hgweb: use the parsed application path directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36807
diff changeset
   172
                             or req.apppath or self.repo.root)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   173
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 = {
36808
0031e972ded2 hgweb: use the parsed application path directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36807
diff changeset
   180
            'url': req.apppath + '/',
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   181
            'logourl': logourl,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   182
            'logoimg': logoimg,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   183
            'staticurl': staticurl,
36807
1e2194e0ef62 hgweb: use computed base URL from parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36806
diff changeset
   184
            'urlbase': req.advertisedbaseurl,
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   185
            'repo': self.reponame,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   186
            'encoding': encoding.encoding,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   187
            'motd': motd,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   188
            'sessionvars': sessionvars,
36808
0031e972ded2 hgweb: use the parsed application path directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36807
diff changeset
   189
            '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
   190
            'style': style,
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   191
            'nonce': self.nonce,
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   192
        }
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   193
        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
   194
        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
   195
                                               filters={'websub': websubfilter},
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   196
                                               defaults=defaults,
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
   197
                                               resources=tres)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   198
        return tmpl
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   199
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
   200
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1554
diff changeset
   201
class hgweb(object):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   202
    """HTTP server for individual repositories.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   203
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   204
    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
   205
    repository.
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 are typically used as WSGI applications.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   208
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   209
    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
   210
    be multiple active threads inside __call__.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   211
    """
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   212
    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
   213
        if isinstance(repo, str):
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   214
            if baseui:
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   215
                u = baseui.copy()
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
   216
            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
   217
                u = uimod.ui.load()
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
   218
            r = hg.repository(u, repo)
987
bfe12654764d hgweb: change startup argument processing
mpm@selenic.com
parents: 986
diff changeset
   219
        else:
22087
af62f0280a76 hgweb: avoid config object race with hgwebdir (issue4326)
Matt Mackall <mpm@selenic.com>
parents: 21759
diff changeset
   220
            # 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
   221
            r = repo
133
fb84d3e71042 added template support for some hgweb output, also, template files for
jake@edge2.net
parents: 132
diff changeset
   222
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
   223
        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
   224
        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
   225
        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
   226
        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
   227
        # 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
   228
        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
   229
        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
   230
        # 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
   231
        # break some wsgi implementation.
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
   232
        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
   233
        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
   234
        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
   235
        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
   236
        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
   237
        self.reponame = name
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
   238
26218
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   239
    def _webifyrepo(self, repo):
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   240
        repo = getwebview(repo)
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   241
        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
   242
        return repo
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
   243
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   244
    @contextlib.contextmanager
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   245
    def _obtainrepo(self):
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   246
        """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
   247
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   248
        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
   249
        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
   250
        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
   251
        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
   252
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   253
        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
   254
        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
   255
        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
   256
        """
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   257
        if self._repos:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   258
            cached = self._repos.pop()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   259
            r, created = cached.fetch()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   260
        else:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   261
            cached = self._lastrepo.copy()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   262
            r, created = cached.fetch()
26240
2b1434e5eaa0 hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26226
diff changeset
   263
        if created:
2b1434e5eaa0 hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26226
diff changeset
   264
            r = self._webifyrepo(r)
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   265
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   266
        self._lastrepo = cached
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   267
        self.mtime = cached.mtime
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   268
        try:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   269
            yield r
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   270
        finally:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   271
            self._repos.append(cached)
258
268bcb5a072a hgweb: watch changelog for changes
mpm@selenic.com
parents: 241
diff changeset
   272
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   273
    def run(self):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   274
        """Start a server from CGI environment.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   275
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   276
        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
   277
        method, if possible.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   278
        """
30636
f1c9fafcbf46 py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
   279
        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
   280
                                    '').startswith("CGI/1."):
8663
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8390
diff changeset
   281
            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
   282
                               "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
   283
        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
   284
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   285
    def __call__(self, env, respond):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   286
        """Run the WSGI application.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   287
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   288
        This may be called by multiple threads.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   289
        """
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   290
        req = requestmod.wsgirequest(env, respond)
6784
18c429ea3a0e hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6781
diff changeset
   291
        return self.run_wsgi(req)
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   292
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   293
    def run_wsgi(self, wsgireq):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   294
        """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
   295
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   296
        This is typically only called by Mercurial. External consumers
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
   297
        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
   298
        """
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   299
        with self._obtainrepo() as repo:
32788
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
   300
            profile = repo.ui.configbool('profiling', 'enabled')
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
   301
            with profiling.profile(repo.ui, enabled=profile):
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   302
                for r in self._runwsgi(wsgireq, repo):
29787
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
   303
                    yield r
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
   304
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   305
    def _runwsgi(self, wsgireq, repo):
36856
1f7d9024674c hgweb: make parsedrequest part of wsgirequest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36814
diff changeset
   306
        req = wsgireq.req
36861
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36856
diff changeset
   307
        res = wsgireq.res
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
   308
        rctx = requestcontext(self, repo)
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   309
26160
952e0564b46e hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26149
diff changeset
   310
        # 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
   311
        encoding.encoding = rctx.config('web', 'encoding')
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   312
        rctx.repo.ui.environ = wsgireq.env
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   313
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   314
        if rctx.csp:
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   315
            # 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
   316
            # replace it.
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   317
            wsgireq.headers = [h for h in wsgireq.headers
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   318
                               if h[0] != 'Content-Security-Policy']
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   319
            wsgireq.headers.append(('Content-Security-Policy', rctx.csp))
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(
a88d68dc3ee8 hgweb: create dedicated type for WSGI responses
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36856
diff changeset
   323
            rctx, wsgireq, 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
36811
cfb9ef24968c hgweb: use parsed request to construct query parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36810
diff changeset
   327
        if req.havepathinfo:
cfb9ef24968c hgweb: use parsed request to construct query parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36810
diff changeset
   328
            query = req.dispatchpath
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   329
        else:
36811
cfb9ef24968c hgweb: use parsed request to construct query parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36810
diff changeset
   330
            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
   331
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   332
        # 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
   333
36811
cfb9ef24968c hgweb: use parsed request to construct query parameters
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36810
diff changeset
   334
        args = query.split('/', 2)
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   335
        if 'cmd' not in wsgireq.form and args and args[0]:
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   336
            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
   337
            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
   338
            if style != -1:
36863
1a1972b1a1ff hgweb: use our new request object for "style" parameter
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36861
diff changeset
   339
                req.qsparams['style'] = cmd[:style]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   340
                cmd = cmd[style + 1:]
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
   341
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   342
            # 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
   343
            if util.safehasattr(webcommands, cmd):
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   344
                wsgireq.form['cmd'] = [cmd]
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   345
                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
   346
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   347
            if cmd == 'static':
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   348
                wsgireq.form['file'] = ['/'.join(args)]
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   349
                req.qsparams['file'] = '/'.join(args)
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   350
            else:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   351
                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
   352
                    node = args.pop(0).replace('%2F', '/')
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   353
                    wsgireq.form['node'] = [node]
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   354
                    req.qsparams['node'] = node
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
   355
                if args:
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   356
                    wsgireq.form['file'] = 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':
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   367
                fn = wsgireq.form['node'][0]
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):
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   371
                        wsgireq.form['node'] = [fn[:-len(ext)]]
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   372
                        req.qsparams['node'] = fn[:-len(next)]
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   373
                        wsgireq.form['type'] = [type_]
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   374
                        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
   375
        else:
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   376
            cmd = wsgireq.form.get('cmd', [''])[0]
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
   377
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   378
        # process the web interface request
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   379
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   380
        try:
36807
1e2194e0ef62 hgweb: use computed base URL from parsed request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36806
diff changeset
   381
            tmpl = rctx.templater(wsgireq, req)
8859
580a79dde2a3 hgweb: web.encoding should override encoding.encoding (issue1183)
Matt Mackall <mpm@selenic.com>
parents: 8663
diff changeset
   382
            ctype = tmpl('mimetype', encoding=encoding.encoding)
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   383
            ctype = templater.stringify(ctype)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   384
7562
b663b5563de7 hgweb: allow static content when deny_read denies access
Mark Edgington <edgimar@gmail.com>
parents: 7396
diff changeset
   385
            # 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
   386
            if cmd != 'static':
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   387
                self.check_perm(rctx, wsgireq, None)
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7311
diff changeset
   388
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   389
            if cmd == '':
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   390
                wsgireq.form['cmd'] = [tmpl.cache['default']]
36864
4e06e8336634 hgweb: set variables in qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36863
diff changeset
   391
                req.qsparams['cmd'] = tmpl.cache['default']
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   392
                cmd = wsgireq.form['cmd'][0]
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
   393
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   394
            # 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
   395
            # be a nonce.
34605
625202a44d88 configitems: register the 'web.cache' config
Boris Feld <boris.feld@octobus.net>
parents: 34602
diff changeset
   396
            if rctx.configbool('web', 'cache') and not rctx.nonce:
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   397
                caching(self, wsgireq) # sets ETag header or raises NOT_MODIFIED
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   398
            if cmd not in webcommands.__all__:
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
   399
                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
   400
                raise ErrorResponse(HTTP_BAD_REQUEST, msg)
36863
1a1972b1a1ff hgweb: use our new request object for "style" parameter
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36861
diff changeset
   401
            elif cmd == 'file' and req.qsparams.get('style') == 'raw':
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
   402
                rctx.ctype = ctype
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   403
                content = webcommands.rawfile(rctx, wsgireq, tmpl)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
   404
            else:
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   405
                content = getattr(webcommands, cmd)(rctx, wsgireq, tmpl)
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   406
                wsgireq.respond(HTTP_OK, ctype)
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
   407
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
   408
            return content
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
   409
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   410
        except (error.LookupError, error.RepoLookupError) as err:
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   411
            wsgireq.respond(HTTP_NOT_FOUND, ctype)
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 35986
diff changeset
   412
            msg = pycompat.bytestr(err)
18855
50c922c1b514 hgweb: show correct error message for i18n environment
Takumi IINO <trot.thunder@gmail.com>
parents: 18522
diff changeset
   413
            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
   414
                not isinstance(err,  error.ManifestLookupError)):
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
   415
                msg = 'revision not found: %s' % err.name
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
   416
            return tmpl('error', error=msg)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   417
        except (error.RepoError, error.RevlogError) as inst:
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   418
            wsgireq.respond(HTTP_SERVER_ERROR, ctype)
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 35986
diff changeset
   419
            return tmpl('error', error=pycompat.bytestr(inst))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
   420
        except ErrorResponse as inst:
36804
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36802
diff changeset
   421
            wsgireq.respond(inst, ctype)
12739
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
   422
            if inst.code == HTTP_NOT_MODIFIED:
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
   423
                # Not allowed to return a body on a 304
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
   424
                return ['']
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 35986
diff changeset
   425
            return tmpl('error', error=pycompat.bytestr(inst))
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
   426
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   427
    def check_perm(self, rctx, req, op):
22200
b27c3beaaf30 cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents: 22087
diff changeset
   428
        for permhook in permhooks:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
   429
            permhook(rctx, req, op)
26208
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   430
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   431
def getwebview(repo):
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   432
    """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
   433
    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
   434
    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
   435
    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
   436
    still excludes "hidden" one.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   437
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   438
    See the repoview module for details.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   439
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   440
    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
   441
    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
   442
    # experimental config: web.view
bf2389b1f15e configitems: register the 'web.view' config
Boris Feld <boris.feld@octobus.net>
parents: 34515
diff changeset
   443
    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
   444
    if viewconfig == 'all':
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   445
        return repo.unfiltered()
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   446
    elif viewconfig in repoview.filtertable:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   447
        return repo.filtered(viewconfig)
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   448
    else:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
   449
        return repo.filtered('served')