annotate mercurial/hgweb/hgweb_mod.py @ 36518:7937850a523d

hgweb: make templater mostly compatible with log templates Prepares for gradually switching templatekw.showsuccsandmarkers() to new API. This was a PoC showing how to reuse templatekw functions in hgweb. We could remove rev, node, author, etc. from the commonentry() table, but we'll have to carefully remove all corresponding symbols from webcommands.*(). Otherwise, we would face the issue5612. Still templatekw.keywords aren't exported. Otherwise some tests would fail because the atom template expects {files} to be empty in filelog, but templatekw.showfiles() provides the {files} implementation.
author Yuya Nishihara <yuya@tcha.org>
date Fri, 22 Dec 2017 21:59:38 +0900
parents a87093e2805d
children 2442927cdd96
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 from .request import wsgirequest
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
26
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
27 from .. import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
28 encoding,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
29 error,
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
30 formatter,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
31 hg,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
32 hook,
29787
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
33 profiling,
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
34 pycompat,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
35 repoview,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
36 templatefilters,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
37 templater,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
38 ui as uimod,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
39 util,
35856
ef3a24a023ec wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35037
diff changeset
40 wireprotoserver,
27046
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
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
43 from . import (
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
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
49 perms = {
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
50 'changegroup': 'pull',
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
51 'changegroupsubset': 'pull',
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13571
diff changeset
52 'getbundle': 'pull',
11370
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
53 'stream_out': 'pull',
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
54 'listkeys': 'pull',
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
55 'unbundle': 'push',
11370
db3f6f0e4e7d pushkey: add http support
Matt Mackall <mpm@selenic.com>
parents: 10995
diff changeset
56 'pushkey': 'push',
6779
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
57 }
d3147b4e3e8a hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6777
diff changeset
58
30749
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
59 archivespecs = util.sortdict((
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
60 ('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
61 ('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
62 ('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
63 ))
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
64
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
65 def getstyle(req, configfn, templatepath):
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
66 fromreq = req.form.get('style', [None])[0]
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
67 styles = (
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
68 fromreq,
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
69 configfn('web', 'style'),
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
70 'paper',
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
71 )
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
72 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
73
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
74 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
75 '''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
76
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
77 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
78 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
79 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
80 '''
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
81 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
82 url = url[:-1]
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
83 if prefix:
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18429
diff changeset
84 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
85 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
86 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
87 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
88
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
89 breadcrumb = []
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
90 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
91 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
92 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
93 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
94 break
bebb05a7e249 hgweb: add a "URL breadcrumb" to the index and repository pages
Angel Ezquerra <angel.ezquerra at gmail.com>
parents: 16754
diff changeset
95 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
96 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
97 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
98
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
99 class requestcontext(object):
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
100 """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
101
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
102 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
103 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
104 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
105 """
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
106 def __init__(self, app, repo):
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
107 self.repo = repo
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
108 self.reponame = app.reponame
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
109
30749
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
110 self.archivespecs = archivespecs
e38e7ea21987 hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents: 30748
diff changeset
111
34590
95f4e5b1ec92 configitems: register the 'web.maxchanges' config
Boris Feld <boris.feld@octobus.net>
parents: 34589
diff changeset
112 self.maxchanges = self.configint('web', 'maxchanges')
34245
945c9816ec1d configitems: register the 'web.stripes' config
Boris Feld <boris.feld@octobus.net>
parents: 34239
diff changeset
113 self.stripecount = self.configint('web', 'stripes')
34588
0d9928a67254 configitems: register the 'web.maxshortchanges' config
Boris Feld <boris.feld@octobus.net>
parents: 34587
diff changeset
114 self.maxshortchanges = self.configint('web', 'maxshortchanges')
34589
883d06211973 configitems: register the 'web.maxfiles' config
Boris Feld <boris.feld@octobus.net>
parents: 34588
diff changeset
115 self.maxfiles = self.configint('web', 'maxfiles')
35037
da5d5ea7d696 config: rename allowpull to allow-pull
David Demelier <markand@malikania.fr>
parents: 34806
diff changeset
116 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
117
26163
84511b1d9724 hgweb: move templatepath to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26162
diff changeset
118 # 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
119 # 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
120 # 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
121 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
122
26164
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
123 # 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
124 # 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
125 # 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
126 # 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
127 # of the request.
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
128 self.websubtable = app.websubtable
26164
e037fd28c8bb hgweb: create websubtable on requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26163
diff changeset
129
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
130 self.csp, self.nonce = cspvalues(self.repo.ui)
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
131
26135
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
132 # 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
133 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
134 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
135 untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
136
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
137 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
138 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
139 untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
140
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
141 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
142 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
143 untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
144
33328
c8f212cb0c83 hgweb: use ui._unset to prevent a warning in configitems
David Demelier <demelier.david@gmail.com>
parents: 32788
diff changeset
145 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
146 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
147 untrusted=untrusted)
edfb4d3b9672 hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26134
diff changeset
148
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
149 def archivelist(self, nodeid):
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
150 allowed = self.configlist('web', 'allow_archive')
30748
319914d57b9e hgweb: use util.sortdict for archivespecs
Anton Shestakov <av6@dwimlabs.net>
parents: 30735
diff changeset
151 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
152 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
153 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
154
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
155 def templater(self, req):
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
156 # determine scheme, port and server name
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
157 # this is needed to create absolute urls
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 proto = req.env.get('wsgi.url_scheme')
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
160 if proto == 'https':
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
161 proto = 'https'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
162 default_port = '443'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
163 else:
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
164 proto = 'http'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
165 default_port = '80'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
166
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
167 port = req.env[r'SERVER_PORT']
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
168 port = port != default_port and (r':' + port) or r''
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
169 urlbase = r'%s://%s%s' % (proto, req.env[r'SERVER_NAME'], port)
34612
c2cb6be4212f configitems: register the 'web.logourl' config
Boris Feld <boris.feld@octobus.net>
parents: 34611
diff changeset
170 logourl = self.config('web', 'logourl')
34611
c879fc7bd71f configitems: register the 'web.logoimg' config
Boris Feld <boris.feld@octobus.net>
parents: 34605
diff changeset
171 logoimg = self.config('web', 'logoimg')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
172 staticurl = self.config('web', 'staticurl') or req.url + 'static/'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
173 if not staticurl.endswith('/'):
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
174 staticurl += '/'
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
175
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
176 # some functions for the templater
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
177
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
178 def motd(**map):
34587
b50c036494dc configitems: register the 'web.motd' config
Boris Feld <boris.feld@octobus.net>
parents: 34586
diff changeset
179 yield self.config('web', 'motd')
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
180
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
181 # figure out which style to use
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
182
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
183 vars = {}
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
184 styles, (style, mapfile) = getstyle(req, self.config,
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34245
diff changeset
185 self.templatepath)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
186 if style == styles[0]:
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
187 vars['style'] = style
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
188
34806
afd7fd950f6e hgweb: correct an earlier error of mine - `start` should be bytes
Augie Fackler <augie@google.com>
parents: 34740
diff changeset
189 start = '&' if req.url[-1] == r'?' else '?'
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
190 sessionvars = webutil.sessionvars(vars, start)
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
191
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
192 if not self.reponame:
34586
c364f3f73634 configitems: register the 'web.name' config
Boris Feld <boris.feld@octobus.net>
parents: 34584
diff changeset
193 self.reponame = (self.config('web', 'name', '')
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
194 or req.env.get('REPO_NAME')
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
195 or req.url.strip('/') or self.repo.root)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
196
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
197 def websubfilter(text):
27008
7f19f331ef59 hgweb: do not import templatefilters.revescape and websub as symbol
Yuya Nishihara <yuya@tcha.org>
parents: 27007
diff changeset
198 return templatefilters.websub(text, self.websubtable)
26183
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 # create the templater
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
201 # 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
202 defaults = {
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
203 'url': req.url,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
204 'logourl': logourl,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
205 'logoimg': logoimg,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
206 'staticurl': staticurl,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
207 'urlbase': urlbase,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
208 'repo': self.reponame,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
209 'encoding': encoding.encoding,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
210 'motd': motd,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
211 'sessionvars': sessionvars,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
212 'pathdef': makebreadcrumb(req.url),
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
213 'style': style,
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
214 'nonce': self.nonce,
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
215 }
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
216 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
217 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
218 filters={'websub': websubfilter},
36518
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
219 defaults=defaults,
7937850a523d hgweb: make templater mostly compatible with log templates
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
220 resources=tres)
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
221 return tmpl
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
222
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
223
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1554
diff changeset
224 class hgweb(object):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
225 """HTTP server for individual repositories.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
226
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
227 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
228 repository.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
229
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
230 Instances are typically used as WSGI applications.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
231
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
232 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
233 be multiple active threads inside __call__.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
234 """
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
235 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
236 if isinstance(repo, str):
10994
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
237 if baseui:
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
238 u = baseui.copy()
c12a57c1a67e hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents: 10905
diff changeset
239 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
240 u = uimod.ui.load()
20168
d4be314b2071 hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents: 19906
diff changeset
241 r = hg.repository(u, repo)
987
bfe12654764d hgweb: change startup argument processing
mpm@selenic.com
parents: 986
diff changeset
242 else:
22087
af62f0280a76 hgweb: avoid config object race with hgwebdir (issue4326)
Matt Mackall <mpm@selenic.com>
parents: 21759
diff changeset
243 # 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
244 r = repo
133
fb84d3e71042 added template support for some hgweb output, also, template files for
jake@edge2.net
parents: 132
diff changeset
245
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
246 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
247 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
248 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
249 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
250 # 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
251 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
252 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
253 # 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
254 # break some wsgi implementation.
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22578
diff changeset
255 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
256 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
257 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
258 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
259 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
260 self.reponame = name
3555
881064004fd0 use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3499
diff changeset
261
26218
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
262 def _webifyrepo(self, repo):
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
263 repo = getwebview(repo)
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
264 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
265 return repo
7d45ec47c0af hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26217
diff changeset
266
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
267 @contextlib.contextmanager
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
268 def _obtainrepo(self):
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
269 """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
270
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
271 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
272 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
273 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
274 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
275
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
276 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
277 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
278 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
279 """
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
280 if self._repos:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
281 cached = self._repos.pop()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
282 r, created = cached.fetch()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
283 else:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
284 cached = self._lastrepo.copy()
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
285 r, created = cached.fetch()
26240
2b1434e5eaa0 hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26226
diff changeset
286 if created:
2b1434e5eaa0 hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26226
diff changeset
287 r = self._webifyrepo(r)
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
288
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
289 self._lastrepo = cached
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
290 self.mtime = cached.mtime
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
291 try:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
292 yield r
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
293 finally:
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
294 self._repos.append(cached)
258
268bcb5a072a hgweb: watch changelog for changes
mpm@selenic.com
parents: 241
diff changeset
295
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
296 def run(self):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
297 """Start a server from CGI environment.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
298
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
299 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
300 method, if possible.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
301 """
30636
f1c9fafcbf46 py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
302 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
303 '').startswith("CGI/1."):
8663
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8390
diff changeset
304 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
305 "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
306 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
307
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
308 def __call__(self, env, respond):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
309 """Run the WSGI application.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
310
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
311 This may be called by multiple threads.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
312 """
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
313 req = wsgirequest(env, respond)
6784
18c429ea3a0e hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6781
diff changeset
314 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
315
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
316 def run_wsgi(self, req):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
317 """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
318
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
319 This is typically only called by Mercurial. External consumers
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25777
diff changeset
320 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
321 """
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
322 with self._obtainrepo() as repo:
32788
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
323 profile = repo.ui.configbool('profiling', 'enabled')
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
324 with profiling.profile(repo.ui, enabled=profile):
29787
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
325 for r in self._runwsgi(req, repo):
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28954
diff changeset
326 yield r
26220
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
327
a43328baa2ac hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26219
diff changeset
328 def _runwsgi(self, req, repo):
26219
ae33fff17c1e hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26218
diff changeset
329 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
330
26160
952e0564b46e hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26149
diff changeset
331 # 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
332 encoding.encoding = rctx.config('web', 'encoding')
26160
952e0564b46e hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26149
diff changeset
333 rctx.repo.ui.environ = req.env
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
334
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
335 if rctx.csp:
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
336 # 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
337 # replace it.
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
338 req.headers = [h for h in req.headers
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
339 if h[0] != 'Content-Security-Policy']
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
340 req.headers.append(('Content-Security-Policy', rctx.csp))
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
341
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
342 # work with CGI variables to create coherent structure
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
343 # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
344
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
345 req.url = req.env[r'SCRIPT_NAME']
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
346 if not req.url.endswith('/'):
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
347 req.url += '/'
32004
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 30766
diff changeset
348 if req.env.get('REPO_NAME'):
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
349 req.url += req.env[r'REPO_NAME'] + r'/'
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
350
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
351 if r'PATH_INFO' in req.env:
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
352 parts = req.env[r'PATH_INFO'].strip('/').split('/')
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
353 repo_parts = req.env.get(r'REPO_NAME', r'').split(r'/')
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
354 if parts[:len(repo_parts)] == repo_parts:
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
355 parts = parts[len(repo_parts):]
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
356 query = '/'.join(parts)
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
357 else:
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
358 query = req.env[r'QUERY_STRING'].partition(r'&')[0]
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
359 query = query.partition(r';')[0]
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
360
35984
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
361 # Route it to a wire protocol handler if it looks like a wire protocol
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
362 # request.
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
363 protohandler = wireprotoserver.parsehttprequest(rctx.repo, req, query)
35982
5a56bf4180ad wireproto: function for testing if wire protocol command is available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35857
diff changeset
364
35984
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
365 if protohandler:
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
366 cmd = protohandler['cmd']
13445
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
367 try:
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
368 if query:
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
369 raise ErrorResponse(HTTP_NOT_FOUND)
61a898576888 hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents: 12739
diff changeset
370 if cmd in perms:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
371 self.check_perm(rctx, req, perms[cmd])
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
372 except ErrorResponse as inst:
35986
98a00aa0288d wireprotoserver: move error response handling out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35985
diff changeset
373 return protohandler['handleerror'](inst)
8860
36654238c050 hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8859
diff changeset
374
35985
e69e65b2b4a9 hgweb: move call to protocol handler outside of try..except
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35984
diff changeset
375 return protohandler['dispatch']()
e69e65b2b4a9 hgweb: move call to protocol handler outside of try..except
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35984
diff changeset
376
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
377 # 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
378
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
379 args = query.split('/', 2)
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
380 if r'cmd' not in req.form and args and args[0]:
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
381 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
382 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
383 if style != -1:
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
384 req.form['style'] = [cmd[:style]]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
385 cmd = cmd[style + 1:]
5596
20b07b68a865 hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5595
diff changeset
386
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
387 # 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
388 if util.safehasattr(webcommands, cmd):
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
389 req.form[r'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
390
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
391 if cmd == 'static':
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
392 req.form['file'] = ['/'.join(args)]
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
393 else:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
394 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
395 node = args.pop(0).replace('%2F', '/')
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
396 req.form['node'] = [node]
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
397 if args:
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
398 req.form['file'] = args
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
399
9731
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
400 ua = req.env.get('HTTP_USER_AGENT', '')
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
401 if cmd == 'rev' and 'mercurial' in ua:
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
402 req.form['style'] = ['raw']
0e080d519d1b hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8860
diff changeset
403
7287
6e9fe4ff9c54 hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents: 7180
diff changeset
404 if cmd == 'archive':
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
405 fn = req.form['node'][0]
26136
6defc74f3066 hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26135
diff changeset
406 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
407 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
408 if fn.endswith(ext):
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
409 req.form['node'] = [fn[:-len(ext)]]
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
410 req.form['type'] = [type_]
35984
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
411 else:
cdc93fe1da77 wireprotoserver: move protocol parsing and dispatch out of hgweb
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
412 cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0])
5591
08887121a652 split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
413
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
414 # process the web interface request
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
415
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
416 try:
26183
bf1b24785f13 hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26167
diff changeset
417 tmpl = rctx.templater(req)
8859
580a79dde2a3 hgweb: web.encoding should override encoding.encoding (issue1183)
Matt Mackall <mpm@selenic.com>
parents: 8663
diff changeset
418 ctype = tmpl('mimetype', encoding=encoding.encoding)
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
419 ctype = templater.stringify(ctype)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
420
7562
b663b5563de7 hgweb: allow static content when deny_read denies access
Mark Edgington <edgimar@gmail.com>
parents: 7396
diff changeset
421 # 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
422 if cmd != 'static':
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
423 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
424
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
425 if cmd == '':
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
426 req.form[r'cmd'] = [tmpl.cache['default']]
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
427 cmd = req.form[r'cmd'][0]
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
428
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
429 # 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
430 # be a nonce.
34605
625202a44d88 configitems: register the 'web.cache' config
Boris Feld <boris.feld@octobus.net>
parents: 34602
diff changeset
431 if rctx.configbool('web', 'cache') and not rctx.nonce:
13966
a1c31c64bcd3 hgweb: support disabling page cache
Steven Stallion <sstallion@gmail.com>
parents: 13964
diff changeset
432 caching(self, req) # sets ETag header or raises NOT_MODIFIED
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
433 if cmd not in webcommands.__all__:
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
434 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
435 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
34704
c51380879054 hgweb: rewrite most obviously-native-strings to be native strings
Augie Fackler <augie@google.com>
parents: 34703
diff changeset
436 elif cmd == 'file' and r'raw' in req.form.get(r'style', []):
26217
0d0a0837895d hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26211
diff changeset
437 rctx.ctype = ctype
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
438 content = webcommands.rawfile(rctx, req, tmpl)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
439 else:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
440 content = getattr(webcommands, cmd)(rctx, req, tmpl)
6149
b023915aa1bc hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6142
diff changeset
441 req.respond(HTTP_OK, ctype)
5890
a0e20a5eba3c hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5889
diff changeset
442
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7348
diff changeset
443 return content
5600
9d900f7282e6 hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5599
diff changeset
444
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25565
diff changeset
445 except (error.LookupError, error.RepoLookupError) as err:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
446 req.respond(HTTP_NOT_FOUND, ctype)
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 35986
diff changeset
447 msg = pycompat.bytestr(err)
18855
50c922c1b514 hgweb: show correct error message for i18n environment
Takumi IINO <trot.thunder@gmail.com>
parents: 18522
diff changeset
448 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
449 not isinstance(err, error.ManifestLookupError)):
6368
2c370f08c486 hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6249
diff changeset
450 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
451 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
452 except (error.RepoError, error.RevlogError) as inst:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
453 req.respond(HTTP_SERVER_ERROR, ctype)
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 35986
diff changeset
454 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
455 except ErrorResponse as inst:
7740
176d3d681702 hgweb: pass ErrorResponses directly into req.respond()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
456 req.respond(inst, ctype)
12739
8dcd3203a261 hgweb: don't send a body or illegal headers during 304 response
Augie Fackler <durin42@gmail.com>
parents: 12696
diff changeset
457 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
458 # 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
459 return ['']
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 35986
diff changeset
460 return tmpl('error', error=pycompat.bytestr(inst))
5599
3de66c2a9734 hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5598
diff changeset
461
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
462 def check_perm(self, rctx, req, op):
22200
b27c3beaaf30 cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents: 22087
diff changeset
463 for permhook in permhooks:
26134
e0a6908f066f hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26133
diff changeset
464 permhook(rctx, req, op)
26208
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
465
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
466 def getwebview(repo):
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
467 """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
468 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
469 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
470 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
471 still excludes "hidden" one.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
472
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
473 See the repoview module for details.
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
474
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
475 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
476 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
477 # experimental config: web.view
bf2389b1f15e configitems: register the 'web.view' config
Boris Feld <boris.feld@octobus.net>
parents: 34515
diff changeset
478 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
479 if viewconfig == 'all':
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
480 return repo.unfiltered()
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
481 elif viewconfig in repoview.filtertable:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
482 return repo.filtered(viewconfig)
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
483 else:
c87566ac3c49 hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26207
diff changeset
484 return repo.filtered('served')