Mercurial > hg
annotate mercurial/hgweb/common.py @ 30014:d34cf260d15b
wireproto: rename argument to groupchunks()
groupchunks() is a generic "turn a file object into a generator"
function. It isn't limited to changegroups. Rename the argument
and update the docstring to reflect this.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sun, 25 Sep 2016 12:20:31 -0700 |
parents | 075146e85bb6 |
children | bb77654dc7ae |
rev | line source |
---|---|
2391
d351a3be3371
Fixing up comment headers for split up code.
Eric Hopper <hopper@omnifarious.org>
parents:
2356
diff
changeset
|
1 # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod |
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> |
2859 | 4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
131 | 5 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7966
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:
27044
diff
changeset
|
9 from __future__ import absolute_import |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27044
diff
changeset
|
10 |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27044
diff
changeset
|
11 import errno |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27044
diff
changeset
|
12 import mimetypes |
37fcfe52c68c
hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
27044
diff
changeset
|
13 import os |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
14 |
29566
075146e85bb6
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29491
diff
changeset
|
15 from .. import util |
075146e85bb6
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29491
diff
changeset
|
16 |
075146e85bb6
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29491
diff
changeset
|
17 httpserver = util.httpserver |
075146e85bb6
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29491
diff
changeset
|
18 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
19 HTTP_OK = 200 |
12183
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
20 HTTP_NOT_MODIFIED = 304 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
21 HTTP_BAD_REQUEST = 400 |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6924
diff
changeset
|
22 HTTP_UNAUTHORIZED = 401 |
7029
b84d27386285
hgweb: Respond with HTTP 403 for disabled archive types instead of 404
Rocco Rutte <pdmef@gmx.net>
parents:
6926
diff
changeset
|
23 HTTP_FORBIDDEN = 403 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
24 HTTP_NOT_FOUND = 404 |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6924
diff
changeset
|
25 HTTP_METHOD_NOT_ALLOWED = 405 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
26 HTTP_SERVER_ERROR = 500 |
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
27 |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
28 |
19032
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
29 def ismember(ui, username, userlist): |
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
30 """Check if username is a member of userlist. |
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
31 |
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
32 If userlist has a single '*' member, all users are considered members. |
19951
d51c4d85ec23
spelling: random spell checker fixes
Mads Kiilerich <madski@unity3d.com>
parents:
19032
diff
changeset
|
33 Can be overridden by extensions to provide more complex authorization |
19032
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
34 schemes. |
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
35 """ |
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
36 return userlist == ['*'] or username in userlist |
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
37 |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
38 def checkauthz(hgweb, req, op): |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
39 '''Check permission for operation based on request data (including |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
40 authentication info). Return if op allowed, else raise an ErrorResponse |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
41 exception.''' |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
42 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
43 user = req.env.get('REMOTE_USER') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
44 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
45 deny_read = hgweb.configlist('web', 'deny_read') |
19032
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
46 if deny_read and (not user or ismember(hgweb.repo.ui, user, deny_read)): |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
47 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
48 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
49 allow_read = hgweb.configlist('web', 'allow_read') |
19032
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
50 if allow_read and (not ismember(hgweb.repo.ui, user, allow_read)): |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
51 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
52 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
53 if op == 'pull' and not hgweb.allowpull: |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
54 raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
55 elif op == 'pull' or op is None: # op is None for interface requests |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
56 return |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
57 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
58 # enforce that you can only push using POST requests |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
59 if req.env['REQUEST_METHOD'] != 'POST': |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
60 msg = 'push requires POST request' |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
61 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
62 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
63 # require ssl by default for pushing, auth info cannot be sniffed |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
64 # and replayed |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
65 scheme = req.env.get('wsgi.url_scheme') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
66 if hgweb.configbool('web', 'push_ssl', True) and scheme != 'https': |
17456
59a168019255
hgweb: respond 403 forbidden for ssl required error
Yuya Nishihara <yuya@tcha.org>
parents:
16687
diff
changeset
|
67 raise ErrorResponse(HTTP_FORBIDDEN, 'ssl required') |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
68 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
69 deny = hgweb.configlist('web', 'deny_push') |
19032
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
70 if deny and (not user or ismember(hgweb.repo.ui, user, deny)): |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
71 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
72 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
73 allow = hgweb.configlist('web', 'allow_push') |
19032
7d31f2e42a8a
hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
18645
diff
changeset
|
74 if not (allow and ismember(hgweb.repo.ui, user, allow)): |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
75 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
76 |
14058
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
77 # Hooks for hgweb permission checks; extensions can add hooks here. |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
78 # Each hook is invoked like this: hook(hgweb, request, operation), |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
79 # where operation is either read, pull or push. Hooks should either |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
80 # raise an ErrorResponse exception, or just return. |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
81 # |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
82 # It is possible to do both authentication and authorization through |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
83 # this. |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
84 permhooks = [checkauthz] |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
85 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
86 |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
87 class ErrorResponse(Exception): |
7741
a3d7f99c23c0
hgweb: support custom http headers in ErrorResponse
Sune Foldager <cryo@cyanite.org>
parents:
7310
diff
changeset
|
88 def __init__(self, code, message=None, headers=[]): |
13444
75f5f312df5f
hgweb: give ErrorResponse a descriptive string/Exception representation
Mads Kiilerich <mads@kiilerich.com>
parents:
13400
diff
changeset
|
89 if message is None: |
75f5f312df5f
hgweb: give ErrorResponse a descriptive string/Exception representation
Mads Kiilerich <mads@kiilerich.com>
parents:
13400
diff
changeset
|
90 message = _statusmessage(code) |
26200 | 91 Exception.__init__(self, message) |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
92 self.code = code |
7741
a3d7f99c23c0
hgweb: support custom http headers in ErrorResponse
Sune Foldager <cryo@cyanite.org>
parents:
7310
diff
changeset
|
93 self.headers = headers |
5563
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
94 |
13570
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
95 class continuereader(object): |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
96 def __init__(self, f, write): |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
97 self.f = f |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
98 self._write = write |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
99 self.continued = False |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
100 |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
101 def read(self, amt=-1): |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
102 if not self.continued: |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
103 self.continued = True |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
104 self._write('HTTP/1.1 100 Continue\r\n\r\n') |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
105 return self.f.read(amt) |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
106 |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
107 def __getattr__(self, attr): |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
108 if attr in ('close', 'readline', 'readlines', '__iter__'): |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
109 return getattr(self.f, attr) |
16687
e34106fa0dc3
cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents:
14058
diff
changeset
|
110 raise AttributeError |
5563
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
111 |
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
112 def _statusmessage(code): |
29566
075146e85bb6
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29491
diff
changeset
|
113 responses = httpserver.basehttprequesthandler.responses |
5563
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
114 return responses.get(code, ('Error', 'Unknown error'))[0] |
5760
0145f9afb0e7
Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5563
diff
changeset
|
115 |
9694
8269fe2d48f6
hgweb: send proper error messages to the client
Sune Foldager <cryo@cyanite.org>
parents:
9031
diff
changeset
|
116 def statusmessage(code, message=None): |
8269fe2d48f6
hgweb: send proper error messages to the client
Sune Foldager <cryo@cyanite.org>
parents:
9031
diff
changeset
|
117 return '%d %s' % (code, message or _statusmessage(code)) |
131 | 118 |
25717
46e2c57026bc
hgweb: drop the default argument for get_stat
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25660
diff
changeset
|
119 def get_stat(spath, fn): |
46e2c57026bc
hgweb: drop the default argument for get_stat
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25660
diff
changeset
|
120 """stat fn if it exists, spath otherwise""" |
22577
a111e460318a
hgweb: refresh hgweb.repo on phase change (issue4061)
Anton Shestakov <engored@ya.ru>
parents:
19951
diff
changeset
|
121 cl_path = os.path.join(spath, fn) |
3853
c0b449154a90
switch to the .hg/store layout, fix the tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3276
diff
changeset
|
122 if os.path.exists(cl_path): |
13958
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
123 return os.stat(cl_path) |
1418
68f81ba07b2a
Make hgweb work when the repository is empty (no 00changelog.i)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1416
diff
changeset
|
124 else: |
13958
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
125 return os.stat(spath) |
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
126 |
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
127 def get_mtime(spath): |
25717
46e2c57026bc
hgweb: drop the default argument for get_stat
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25660
diff
changeset
|
128 return get_stat(spath, "00changelog.i").st_mtime |
1418
68f81ba07b2a
Make hgweb work when the repository is empty (no 00changelog.i)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1416
diff
changeset
|
129 |
2514
419c42223bee
Really fix http headers for web UI and issue 254.
Eric Hopper <hopper@omnifarious.org>
parents:
2391
diff
changeset
|
130 def staticfile(directory, fname, req): |
5930
c301f15c965a
send conservatively capitalized HTTP headers
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5779
diff
changeset
|
131 """return a file inside directory with guessed Content-Type header |
1825
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
132 |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
133 fname always uses '/' as directory separator and isn't allowed to |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
134 contain unusual path components. |
5930
c301f15c965a
send conservatively capitalized HTTP headers
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5779
diff
changeset
|
135 Content-Type is guessed using the mimetypes module. |
1825
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
136 Return an empty string if fname is illegal or file not found. |
1793
83c6d8355909
Allow serving static files from hgwebdir to fix CSS and favicon.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1792
diff
changeset
|
137 |
1825
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
138 """ |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
139 parts = fname.split('/') |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
140 for part in parts: |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
141 if (part in ('', os.curdir, os.pardir) or |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
142 os.sep in part or os.altsep is not None and os.altsep in part): |
18645
76ff3a715cf2
hgweb: simplify internal staticfile return codes
Mads Kiilerich <mads@kiilerich.com>
parents:
18352
diff
changeset
|
143 return |
7288
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
144 fpath = os.path.join(*parts) |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
145 if isinstance(directory, str): |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
146 directory = [directory] |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
147 for d in directory: |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
148 path = os.path.join(d, fpath) |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
149 if os.path.exists(path): |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
150 break |
1793
83c6d8355909
Allow serving static files from hgwebdir to fix CSS and favicon.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1792
diff
changeset
|
151 try: |
1825
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
152 os.stat(path) |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
153 ct = mimetypes.guess_type(path)[0] or "text/plain" |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12183
diff
changeset
|
154 fp = open(path, 'rb') |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12183
diff
changeset
|
155 data = fp.read() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12183
diff
changeset
|
156 fp.close() |
18352
e33b9b92a200
hgweb: pass the actual response body to request.response, not just the length
Mads Kiilerich <mads@kiilerich.com>
parents:
17456
diff
changeset
|
157 req.respond(HTTP_OK, ct, body=data) |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
158 except TypeError: |
8761
0289f384e1e5
Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents:
8225
diff
changeset
|
159 raise ErrorResponse(HTTP_SERVER_ERROR, 'illegal filename') |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
22577
diff
changeset
|
160 except OSError as err: |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
161 if err.errno == errno.ENOENT: |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
162 raise ErrorResponse(HTTP_NOT_FOUND) |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
163 else: |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
164 raise ErrorResponse(HTTP_SERVER_ERROR, err.strerror) |
3276
db9d2a624521
hgweb: Search templates in templatepath/style/map, too, using a common function.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3244
diff
changeset
|
165 |
4462
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
166 def paritygen(stripecount, offset=0): |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
167 """count parity of horizontal stripes for easier reading""" |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
168 if stripecount and offset: |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
169 # account for offset, e.g. due to building the list in reverse |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
170 count = (stripecount + offset) % stripecount |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
171 parity = (stripecount + offset) / stripecount & 1 |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
172 else: |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
173 count = 0 |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
174 parity = 0 |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
175 while True: |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
176 yield parity |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
177 count += 1 |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
178 if stripecount and count >= stripecount: |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
179 parity = 1 - parity |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
180 count = 0 |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
181 |
5779
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
182 def get_contact(config): |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
183 """Return repo contact information or empty string. |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
184 |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
185 web.contact is the primary source, but if that is not set, try |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
186 ui.username or $EMAIL as a fallback to display something useful. |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
187 """ |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
188 return (config("web", "contact") or |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
189 config("ui", "username") or |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
190 os.environ.get("EMAIL") or "") |
12183
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
191 |
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
192 def caching(web, req): |
29491
7f0498bd284e
hgweb: emit a valid, weak ETag
Anton Shestakov <av6@dwimlabs.net>
parents:
27046
diff
changeset
|
193 tag = 'W/"%s"' % web.mtime |
12183
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
194 if req.env.get('HTTP_IF_NONE_MATCH') == tag: |
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
195 raise ErrorResponse(HTTP_NOT_MODIFIED) |
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
196 req.headers.append(('ETag', tag)) |