author | Denis Laxalde <denis.laxalde@logilab.fr> |
Tue, 17 Jan 2017 17:25:48 +0100 | |
changeset 31082 | abb92b3d370e |
parent 30766 | d7bf7d2bd5ab |
child 32004 | bd3cb917761a |
permissions | -rw-r--r-- |
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 | 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 | 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 | 7 |
# GNU General Public License version 2 or any later version. |
131 | 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, |
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, |
27046
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
33 |
repoview, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
34 |
templatefilters, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
35 |
templater, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
36 |
ui as uimod, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
37 |
util, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
38 |
) |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
39 |
|
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
40 |
from . import ( |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
41 |
protocol, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
42 |
webcommands, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
43 |
webutil, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
44 |
wsgicgi, |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27045
diff
changeset
|
45 |
) |
138 | 46 |
|
6779
d3147b4e3e8a
hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6777
diff
changeset
|
47 |
perms = { |
d3147b4e3e8a
hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6777
diff
changeset
|
48 |
'changegroup': 'pull', |
d3147b4e3e8a
hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6777
diff
changeset
|
49 |
'changegroupsubset': 'pull', |
13741
b51bf961b3cb
wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13571
diff
changeset
|
50 |
'getbundle': 'pull', |
11370 | 51 |
'stream_out': 'pull', |
52 |
'listkeys': 'pull', |
|
6779
d3147b4e3e8a
hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6777
diff
changeset
|
53 |
'unbundle': 'push', |
11370 | 54 |
'pushkey': 'push', |
6779
d3147b4e3e8a
hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6777
diff
changeset
|
55 |
} |
d3147b4e3e8a
hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6777
diff
changeset
|
56 |
|
30749
e38e7ea21987
hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents:
30748
diff
changeset
|
57 |
archivespecs = util.sortdict(( |
e38e7ea21987
hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents:
30748
diff
changeset
|
58 |
('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
|
59 |
('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
|
60 |
('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
|
61 |
)) |
e38e7ea21987
hgweb: use archivespecs for links on repo index page too
Anton Shestakov <av6@dwimlabs.net>
parents:
30748
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 |
|
26217
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
101 |
self.maxchanges = self.configint('web', 'maxchanges', 10) |
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
102 |
self.stripecount = self.configint('web', 'stripes', 1) |
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
103 |
self.maxshortchanges = self.configint('web', 'maxshortchanges', 60) |
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
104 |
self.maxfiles = self.configint('web', 'maxfiles', 10) |
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
105 |
self.allowpull = self.configbool('web', 'allowpull', True) |
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. |
edfb4d3b9672
hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26134
diff
changeset
|
122 |
def config(self, section, name, default=None, untrusted=True): |
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 |
|
edfb4d3b9672
hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26134
diff
changeset
|
126 |
def configbool(self, section, name, default=False, untrusted=True): |
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 |
|
edfb4d3b9672
hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26134
diff
changeset
|
130 |
def configint(self, section, name, default=None, untrusted=True): |
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 |
|
edfb4d3b9672
hgweb: move some config options to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26134
diff
changeset
|
134 |
def configlist(self, section, name, default=None, untrusted=True): |
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 |
|
26183
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
144 |
def templater(self, req): |
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 |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
147 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
148 |
proto = req.env.get('wsgi.url_scheme') |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
149 |
if proto == 'https': |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
150 |
proto = 'https' |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
151 |
default_port = '443' |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
152 |
else: |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
153 |
proto = 'http' |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
154 |
default_port = '80' |
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 |
port = req.env['SERVER_PORT'] |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
157 |
port = port != default_port and (':' + port) or '' |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
158 |
urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port) |
26421
4b0fc75f9403
urls: bulk-change primary website URLs
Matt Mackall <mpm@selenic.com>
parents:
26294
diff
changeset
|
159 |
logourl = self.config('web', 'logourl', 'https://mercurial-scm.org/') |
26183
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
160 |
logoimg = self.config('web', 'logoimg', 'hglogo.png') |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
161 |
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
|
162 |
if not staticurl.endswith('/'): |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
163 |
staticurl += '/' |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
164 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
165 |
# some functions for the templater |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
166 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
167 |
def motd(**map): |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
168 |
yield self.config('web', 'motd', '') |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
169 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
170 |
# figure out which style to use |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
171 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
172 |
vars = {} |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
173 |
styles = ( |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
174 |
req.form.get('style', [None])[0], |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
175 |
self.config('web', 'style'), |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
176 |
'paper', |
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 |
style, mapfile = templater.stylemap(styles, self.templatepath) |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
179 |
if style == styles[0]: |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
180 |
vars['style'] = style |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
181 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
182 |
start = req.url[-1] == '?' and '&' or '?' |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
183 |
sessionvars = webutil.sessionvars(vars, start) |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
184 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
185 |
if not self.reponame: |
26217
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
186 |
self.reponame = (self.config('web', 'name') |
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
187 |
or req.env.get('REPO_NAME') |
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
188 |
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
|
189 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
190 |
def websubfilter(text): |
27008
7f19f331ef59
hgweb: do not import templatefilters.revescape and websub as symbol
Yuya Nishihara <yuya@tcha.org>
parents:
27007
diff
changeset
|
191 |
return templatefilters.websub(text, self.websubtable) |
26183
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
192 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
193 |
# create the templater |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
194 |
|
28954
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
195 |
defaults = { |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
196 |
'url': req.url, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
197 |
'logourl': logourl, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
198 |
'logoimg': logoimg, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
199 |
'staticurl': staticurl, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
200 |
'urlbase': urlbase, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
201 |
'repo': self.reponame, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
202 |
'encoding': encoding.encoding, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
203 |
'motd': motd, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
204 |
'sessionvars': sessionvars, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
205 |
'pathdef': makebreadcrumb(req.url), |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
206 |
'style': style, |
30766
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
207 |
'nonce': self.nonce, |
28954
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
208 |
} |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
209 |
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
|
210 |
filters={'websub': websubfilter}, |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
27046
diff
changeset
|
211 |
defaults=defaults) |
26183
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
212 |
return tmpl |
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
213 |
|
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
214 |
|
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1554
diff
changeset
|
215 |
class hgweb(object): |
26132
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
216 |
"""HTTP server for individual repositories. |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
217 |
|
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
218 |
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
|
219 |
repository. |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
220 |
|
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
221 |
Instances are typically used as WSGI applications. |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
222 |
|
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
223 |
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
|
224 |
be multiple active threads inside __call__. |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
225 |
""" |
10994
c12a57c1a67e
hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents:
10905
diff
changeset
|
226 |
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
|
227 |
if isinstance(repo, str): |
10994
c12a57c1a67e
hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents:
10905
diff
changeset
|
228 |
if baseui: |
c12a57c1a67e
hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents:
10905
diff
changeset
|
229 |
u = baseui.copy() |
c12a57c1a67e
hgweb: add baseui to hgweb entrypoint
Matt Mackall <mpm@selenic.com>
parents:
10905
diff
changeset
|
230 |
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
|
231 |
u = uimod.ui.load() |
20168
d4be314b2071
hgweb: avoid initialization race (issue3953)
Matt Mackall <mpm@selenic.com>
parents:
19906
diff
changeset
|
232 |
r = hg.repository(u, repo) |
987 | 233 |
else: |
22087
af62f0280a76
hgweb: avoid config object race with hgwebdir (issue4326)
Matt Mackall <mpm@selenic.com>
parents:
21759
diff
changeset
|
234 |
# 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
|
235 |
r = repo |
133
fb84d3e71042
added template support for some hgweb output, also, template files for
jake@edge2.net
parents:
132
diff
changeset
|
236 |
|
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
|
237 |
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
|
238 |
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
|
239 |
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
|
240 |
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
|
241 |
# 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
|
242 |
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
|
243 |
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
|
244 |
# 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
|
245 |
# break some wsgi implementation. |
89ce95f907bd
hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22578
diff
changeset
|
246 |
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
|
247 |
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
|
248 |
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
|
249 |
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
|
250 |
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
|
251 |
self.reponame = name |
3555
881064004fd0
use untrusted settings in hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3499
diff
changeset
|
252 |
|
26218
7d45ec47c0af
hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26217
diff
changeset
|
253 |
def _webifyrepo(self, repo): |
7d45ec47c0af
hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26217
diff
changeset
|
254 |
repo = getwebview(repo) |
7d45ec47c0af
hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26217
diff
changeset
|
255 |
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
|
256 |
return repo |
7d45ec47c0af
hgweb: create function to perform actions on new repo
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26217
diff
changeset
|
257 |
|
26220
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
258 |
@contextlib.contextmanager |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
259 |
def _obtainrepo(self): |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
260 |
"""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
|
261 |
|
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
262 |
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
|
263 |
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
|
264 |
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
|
265 |
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
|
266 |
|
26220
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
267 |
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
|
268 |
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
|
269 |
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
|
270 |
""" |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
271 |
if self._repos: |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
272 |
cached = self._repos.pop() |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
273 |
r, created = cached.fetch() |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
274 |
else: |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
275 |
cached = self._lastrepo.copy() |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
276 |
r, created = cached.fetch() |
26240
2b1434e5eaa0
hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26226
diff
changeset
|
277 |
if created: |
2b1434e5eaa0
hg: always create new localrepository instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26226
diff
changeset
|
278 |
r = self._webifyrepo(r) |
26220
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 |
self._lastrepo = cached |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
281 |
self.mtime = cached.mtime |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
282 |
try: |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
283 |
yield r |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
284 |
finally: |
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
285 |
self._repos.append(cached) |
258 | 286 |
|
5591
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
287 |
def run(self): |
26132
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
288 |
"""Start a server from CGI environment. |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
289 |
|
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
290 |
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
|
291 |
method, if possible. |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
292 |
""" |
30636
f1c9fafcbf46
py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30559
diff
changeset
|
293 |
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
|
294 |
'').startswith("CGI/1."): |
8663
45f626a39def
wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents:
8390
diff
changeset
|
295 |
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
|
296 |
"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
|
297 |
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
|
298 |
|
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
299 |
def __call__(self, env, respond): |
26132
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
300 |
"""Run the WSGI application. |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
301 |
|
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
302 |
This may be called by multiple threads. |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
303 |
""" |
5591
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
304 |
req = wsgirequest(env, respond) |
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6781
diff
changeset
|
305 |
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
|
306 |
|
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
307 |
def run_wsgi(self, req): |
26132
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
308 |
"""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
|
309 |
|
26132
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
310 |
This is typically only called by Mercurial. External consumers |
9df8c729e2e7
hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25777
diff
changeset
|
311 |
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
|
312 |
""" |
26220
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
313 |
with self._obtainrepo() as repo: |
29787
80df04266a16
hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28954
diff
changeset
|
314 |
with profiling.maybeprofile(repo.ui): |
80df04266a16
hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28954
diff
changeset
|
315 |
for r in self._runwsgi(req, repo): |
80df04266a16
hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28954
diff
changeset
|
316 |
yield r |
26220
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
317 |
|
a43328baa2ac
hgweb: use separate repo instances per thread
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26219
diff
changeset
|
318 |
def _runwsgi(self, req, repo): |
26219
ae33fff17c1e
hg: establish a cache for localrepository instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26218
diff
changeset
|
319 |
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
|
320 |
|
26160
952e0564b46e
hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26149
diff
changeset
|
321 |
# This state is global across all threads. |
952e0564b46e
hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26149
diff
changeset
|
322 |
encoding.encoding = rctx.config('web', 'encoding', encoding.encoding) |
952e0564b46e
hgweb: move additional state setting outside of refresh
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26149
diff
changeset
|
323 |
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
|
324 |
|
30766
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
325 |
if rctx.csp: |
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
326 |
# 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
|
327 |
# replace it. |
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
328 |
req.headers = [h for h in req.headers |
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
329 |
if h[0] != 'Content-Security-Policy'] |
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
330 |
req.headers.append(('Content-Security-Policy', rctx.csp)) |
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
331 |
|
5596
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
332 |
# 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
|
333 |
# 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
|
334 |
|
5596
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
335 |
req.url = req.env['SCRIPT_NAME'] |
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
336 |
if not req.url.endswith('/'): |
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
337 |
req.url += '/' |
5915
d0576d065993
Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents:
5890
diff
changeset
|
338 |
if 'REPO_NAME' in req.env: |
5596
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
339 |
req.url += req.env['REPO_NAME'] + '/' |
5591
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
340 |
|
6459
8189e03adb44
hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6379
diff
changeset
|
341 |
if 'PATH_INFO' in req.env: |
8189e03adb44
hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6379
diff
changeset
|
342 |
parts = req.env['PATH_INFO'].strip('/').split('/') |
5596
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
343 |
repo_parts = req.env.get('REPO_NAME', '').split('/') |
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
344 |
if parts[:len(repo_parts)] == repo_parts: |
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
345 |
parts = parts[len(repo_parts):] |
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
346 |
query = '/'.join(parts) |
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
347 |
else: |
26846
7c1b4840c2cd
hgweb: replace some str.split() calls by str.partition() or str.rpartition()
Anton Shestakov <av6@dwimlabs.net>
parents:
26421
diff
changeset
|
348 |
query = req.env['QUERY_STRING'].partition('&')[0] |
7c1b4840c2cd
hgweb: replace some str.split() calls by str.partition() or str.rpartition()
Anton Shestakov <av6@dwimlabs.net>
parents:
26421
diff
changeset
|
349 |
query = query.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
|
350 |
|
8860
36654238c050
hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8859
diff
changeset
|
351 |
# process this if it's a protocol request |
36654238c050
hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8859
diff
changeset
|
352 |
# protocol bits don't need to create any URLs |
36654238c050
hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8859
diff
changeset
|
353 |
# and the clients always use the old URL structure |
36654238c050
hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8859
diff
changeset
|
354 |
|
36654238c050
hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8859
diff
changeset
|
355 |
cmd = req.form.get('cmd', [''])[0] |
11595
368cd5325348
protocol: move hgweb protocol support back into protocol.py
Matt Mackall <mpm@selenic.com>
parents:
11593
diff
changeset
|
356 |
if protocol.iscmd(cmd): |
13445
61a898576888
hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents:
12739
diff
changeset
|
357 |
try: |
61a898576888
hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents:
12739
diff
changeset
|
358 |
if query: |
61a898576888
hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents:
12739
diff
changeset
|
359 |
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
|
360 |
if cmd in perms: |
26134
e0a6908f066f
hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26133
diff
changeset
|
361 |
self.check_perm(rctx, req, perms[cmd]) |
26209
7917746c9a67
hgweb: don't access self.repo during request processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26208
diff
changeset
|
362 |
return protocol.call(rctx.repo, req, cmd) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25565
diff
changeset
|
363 |
except ErrorResponse as inst: |
13571
84bd3fd63afc
hgweb_mod: respond right away if the client specified 100-continue support
Augie Fackler <durin42@gmail.com>
parents:
13445
diff
changeset
|
364 |
# A client that sends unbundle without 100-continue will |
84bd3fd63afc
hgweb_mod: respond right away if the client specified 100-continue support
Augie Fackler <durin42@gmail.com>
parents:
13445
diff
changeset
|
365 |
# break if we respond early. |
84bd3fd63afc
hgweb_mod: respond right away if the client specified 100-continue support
Augie Fackler <durin42@gmail.com>
parents:
13445
diff
changeset
|
366 |
if (cmd == 'unbundle' and |
14991
4f39610996fa
http2: send an extra header to signal a non-broken client
Augie Fackler <durin42@gmail.com>
parents:
13966
diff
changeset
|
367 |
(req.env.get('HTTP_EXPECT', |
4f39610996fa
http2: send an extra header to signal a non-broken client
Augie Fackler <durin42@gmail.com>
parents:
13966
diff
changeset
|
368 |
'').lower() != '100-continue') or |
4f39610996fa
http2: send an extra header to signal a non-broken client
Augie Fackler <durin42@gmail.com>
parents:
13966
diff
changeset
|
369 |
req.env.get('X-HgHttp2', '')): |
13445
61a898576888
hgweb: handle invalid requests with both form data and querystring
Mads Kiilerich <mads@kiilerich.com>
parents:
12739
diff
changeset
|
370 |
req.drain() |
19488
60e060f4faa9
hgweb: force connection close on early response
Augie Fackler <raf@durin42.com>
parents:
18858
diff
changeset
|
371 |
else: |
60e060f4faa9
hgweb: force connection close on early response
Augie Fackler <raf@durin42.com>
parents:
18858
diff
changeset
|
372 |
req.headers.append(('Connection', 'Close')) |
18352
e33b9b92a200
hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents:
18258
diff
changeset
|
373 |
req.respond(inst, protocol.HGTYPE, |
26200 | 374 |
body='0\n%s\n' % inst) |
18352
e33b9b92a200
hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents:
18258
diff
changeset
|
375 |
return '' |
8860
36654238c050
hgweb: deny cloning a subpath of a repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8859
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) |
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
380 |
if 'cmd' not in req.form and args and args[0]: |
5591
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
381 |
|
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
382 |
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
|
383 |
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
|
384 |
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
|
385 |
req.form['style'] = [cmd[:style]] |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
386 |
cmd = cmd[style + 1:] |
5596
20b07b68a865
hgweb: get rid of some nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5595
diff
changeset
|
387 |
|
5591
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
388 |
# 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
|
389 |
if util.safehasattr(webcommands, cmd): |
5591
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
390 |
req.form['cmd'] = [cmd] |
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
391 |
|
7287
6e9fe4ff9c54
hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents:
7180
diff
changeset
|
392 |
if cmd == 'static': |
6e9fe4ff9c54
hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents:
7180
diff
changeset
|
393 |
req.form['file'] = ['/'.join(args)] |
6e9fe4ff9c54
hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents:
7180
diff
changeset
|
394 |
else: |
6e9fe4ff9c54
hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents:
7180
diff
changeset
|
395 |
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
|
396 |
node = args.pop(0).replace('%2F', '/') |
7287
6e9fe4ff9c54
hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents:
7180
diff
changeset
|
397 |
req.form['node'] = [node] |
6e9fe4ff9c54
hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents:
7180
diff
changeset
|
398 |
if args: |
6e9fe4ff9c54
hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents:
7180
diff
changeset
|
399 |
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
|
400 |
|
9731
0e080d519d1b
hgweb: treat rev as raw-rev if user agent is hg
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8860
diff
changeset
|
401 |
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
|
402 |
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
|
403 |
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
|
404 |
|
7287
6e9fe4ff9c54
hgweb: handle subdirectories within static directory
Brendan Cully <brendan@kublai.com>
parents:
7180
diff
changeset
|
405 |
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
|
406 |
fn = req.form['node'][0] |
26136
6defc74f3066
hgweb: move archive related attributes to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26135
diff
changeset
|
407 |
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
|
408 |
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
|
409 |
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
|
410 |
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
|
411 |
req.form['type'] = [type_] |
08887121a652
split out hgweb commands into a separate file, move some code around
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5579
diff
changeset
|
412 |
|
6149
b023915aa1bc
hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6142
diff
changeset
|
413 |
# process the web interface request |
5599
3de66c2a9734
hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5598
diff
changeset
|
414 |
|
3de66c2a9734
hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5598
diff
changeset
|
415 |
try: |
26183
bf1b24785f13
hgweb: move templater instantiation to requestcontext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26167
diff
changeset
|
416 |
tmpl = rctx.templater(req) |
8859
580a79dde2a3
hgweb: web.encoding should override encoding.encoding (issue1183)
Matt Mackall <mpm@selenic.com>
parents:
8663
diff
changeset
|
417 |
ctype = tmpl('mimetype', encoding=encoding.encoding) |
6391
a1007f7b9b7b
Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6379
diff
changeset
|
418 |
ctype = templater.stringify(ctype) |
6149
b023915aa1bc
hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6142
diff
changeset
|
419 |
|
7562
b663b5563de7
hgweb: allow static content when deny_read denies access
Mark Edgington <edgimar@gmail.com>
parents:
7396
diff
changeset
|
420 |
# 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
|
421 |
if cmd != 'static': |
26134
e0a6908f066f
hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26133
diff
changeset
|
422 |
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
|
423 |
|
6149
b023915aa1bc
hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6142
diff
changeset
|
424 |
if cmd == '': |
b023915aa1bc
hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6142
diff
changeset
|
425 |
req.form['cmd'] = [tmpl.cache['default']] |
b023915aa1bc
hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6142
diff
changeset
|
426 |
cmd = req.form['cmd'][0] |
5890
a0e20a5eba3c
hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5889
diff
changeset
|
427 |
|
30766
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
428 |
# 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
|
429 |
# be a nonce. |
d7bf7d2bd5ab
hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30749
diff
changeset
|
430 |
if rctx.configbool('web', 'cache', True) and not rctx.nonce: |
13966
a1c31c64bcd3
hgweb: support disabling page cache
Steven Stallion <sstallion@gmail.com>
parents:
13964
diff
changeset
|
431 |
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
|
432 |
if cmd not in webcommands.__all__: |
6368
2c370f08c486
hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6249
diff
changeset
|
433 |
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
|
434 |
raise ErrorResponse(HTTP_BAD_REQUEST, msg) |
b023915aa1bc
hgweb: separate protocol calls from interface calls (issue996)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6142
diff
changeset
|
435 |
elif cmd == 'file' and 'raw' in req.form.get('style', []): |
26217
0d0a0837895d
hgweb: remove proxy to hgweb instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26211
diff
changeset
|
436 |
rctx.ctype = ctype |
26134
e0a6908f066f
hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26133
diff
changeset
|
437 |
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
|
438 |
else: |
26134
e0a6908f066f
hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26133
diff
changeset
|
439 |
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
|
440 |
req.respond(HTTP_OK, ctype) |
5890
a0e20a5eba3c
hgweb: fast path for sending raw files
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5889
diff
changeset
|
441 |
|
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7348
diff
changeset
|
442 |
return content |
5600
9d900f7282e6
hgweb: explicitly pass around the templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5599
diff
changeset
|
443 |
|
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25565
diff
changeset
|
444 |
except (error.LookupError, error.RepoLookupError) as err: |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5976
diff
changeset
|
445 |
req.respond(HTTP_NOT_FOUND, ctype) |
6374
31a01e3d99cc
hgweb: fix breakage in python < 2.5 introduced in 2c370f08c486
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6368
diff
changeset
|
446 |
msg = str(err) |
18855
50c922c1b514
hgweb: show correct error message for i18n environment
Takumi IINO <trot.thunder@gmail.com>
parents:
18522
diff
changeset
|
447 |
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
|
448 |
not isinstance(err, error.ManifestLookupError)): |
6368
2c370f08c486
hgweb: better error messages
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6249
diff
changeset
|
449 |
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
|
450 |
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
|
451 |
except (error.RepoError, error.RevlogError) as inst: |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5976
diff
changeset
|
452 |
req.respond(HTTP_SERVER_ERROR, ctype) |
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7348
diff
changeset
|
453 |
return tmpl('error', error=str(inst)) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25565
diff
changeset
|
454 |
except ErrorResponse as inst: |
7740
176d3d681702
hgweb: pass ErrorResponses directly into req.respond()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7637
diff
changeset
|
455 |
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
|
456 |
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
|
457 |
# 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
|
458 |
return [''] |
26200 | 459 |
return tmpl('error', error=str(inst)) |
5599
3de66c2a9734
hgweb: split out templater definition
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5598
diff
changeset
|
460 |
|
26134
e0a6908f066f
hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26133
diff
changeset
|
461 |
def check_perm(self, rctx, req, op): |
22200
b27c3beaaf30
cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents:
22087
diff
changeset
|
462 |
for permhook in permhooks: |
26134
e0a6908f066f
hgweb: establish class for holding per request context
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26133
diff
changeset
|
463 |
permhook(rctx, req, op) |
26208
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
464 |
|
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
465 |
def getwebview(repo): |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
466 |
"""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
|
467 |
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
|
468 |
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
|
469 |
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
|
470 |
still excludes "hidden" one. |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
471 |
|
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
472 |
See the repoview module for details. |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
473 |
|
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
474 |
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
|
475 |
user ever asked about it. So we better keep it undocumented for now.""" |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
476 |
viewconfig = repo.ui.config('web', 'view', 'served', |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
477 |
untrusted=True) |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
478 |
if viewconfig == 'all': |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
479 |
return repo.unfiltered() |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
480 |
elif viewconfig in repoview.filtertable: |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
481 |
return repo.filtered(viewconfig) |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
482 |
else: |
c87566ac3c49
hgweb: extract _getview to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26207
diff
changeset
|
483 |
return repo.filtered('served') |