Mercurial > hg
annotate mercurial/hgweb/common.py @ 17613:aafc521668d8
rebase: properly handle --collapse when creating obsolescence marker
In collapse mode, that content of state is not suitable to compute obsolescence
markers. We explicitly pass the resulting revision instead and use it as the
successors for all elements of the rebased set.
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Tue, 18 Sep 2012 23:42:27 +0200 |
parents | 59a168019255 |
children | e33b9b92a200 |
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 |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
9 import errno, mimetypes, os |
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
10 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
11 HTTP_OK = 200 |
12183
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
12 HTTP_NOT_MODIFIED = 304 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
13 HTTP_BAD_REQUEST = 400 |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6924
diff
changeset
|
14 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
|
15 HTTP_FORBIDDEN = 403 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
16 HTTP_NOT_FOUND = 404 |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6924
diff
changeset
|
17 HTTP_METHOD_NOT_ALLOWED = 405 |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
18 HTTP_SERVER_ERROR = 500 |
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
19 |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
20 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
21 def checkauthz(hgweb, req, op): |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
22 '''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
|
23 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
|
24 exception.''' |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
25 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
26 user = req.env.get('REMOTE_USER') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
27 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
28 deny_read = hgweb.configlist('web', 'deny_read') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
29 if deny_read and (not user or deny_read == ['*'] or user in deny_read): |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
30 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
|
31 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
32 allow_read = hgweb.configlist('web', 'allow_read') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
33 result = (not allow_read) or (allow_read == ['*']) |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
34 if not (result or user in allow_read): |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
35 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
|
36 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
37 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
|
38 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
|
39 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
|
40 return |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
41 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
42 # 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
|
43 if req.env['REQUEST_METHOD'] != 'POST': |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
44 msg = 'push requires POST request' |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
45 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
|
46 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
47 # 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
|
48 # and replayed |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
49 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
|
50 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
|
51 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
|
52 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
53 deny = hgweb.configlist('web', 'deny_push') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
54 if deny and (not user or deny == ['*'] or user in deny): |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
55 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
|
56 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
57 allow = hgweb.configlist('web', 'allow_push') |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
58 result = allow and (allow == ['*'] or user in allow) |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
59 if not result: |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
60 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
|
61 |
14058
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
62 # 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
|
63 # 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
|
64 # 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
|
65 # raise an ErrorResponse exception, or just return. |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
66 # |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
67 # 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
|
68 # this. |
3233b39d756f
hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents:
13959
diff
changeset
|
69 permhooks = [checkauthz] |
9910
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
70 |
6f92997dbdca
hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents:
9694
diff
changeset
|
71 |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
72 class ErrorResponse(Exception): |
7741
a3d7f99c23c0
hgweb: support custom http headers in ErrorResponse
Sune Foldager <cryo@cyanite.org>
parents:
7310
diff
changeset
|
73 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
|
74 if message is None: |
75f5f312df5f
hgweb: give ErrorResponse a descriptive string/Exception representation
Mads Kiilerich <mads@kiilerich.com>
parents:
13400
diff
changeset
|
75 message = _statusmessage(code) |
13640
19f8629ea107
hgweb: drop use of super() for Exception base class
Matt Mackall <mpm@selenic.com>
parents:
13599
diff
changeset
|
76 Exception.__init__(self) |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
77 self.code = code |
13444
75f5f312df5f
hgweb: give ErrorResponse a descriptive string/Exception representation
Mads Kiilerich <mads@kiilerich.com>
parents:
13400
diff
changeset
|
78 self.message = message |
7741
a3d7f99c23c0
hgweb: support custom http headers in ErrorResponse
Sune Foldager <cryo@cyanite.org>
parents:
7310
diff
changeset
|
79 self.headers = headers |
13599
0bef8f69c078
don't depend on features of Exception as much
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
13570
diff
changeset
|
80 def __str__(self): |
0bef8f69c078
don't depend on features of Exception as much
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
13570
diff
changeset
|
81 return self.message |
5563
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
82 |
13570
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
83 class continuereader(object): |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
84 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
|
85 self.f = f |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
86 self._write = write |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
87 self.continued = False |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
88 |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
89 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
|
90 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
|
91 self.continued = True |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
92 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
|
93 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
|
94 |
617a87cb7eb2
hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents:
13444
diff
changeset
|
95 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
|
96 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
|
97 return getattr(self.f, attr) |
16687
e34106fa0dc3
cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents:
14058
diff
changeset
|
98 raise AttributeError |
5563
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
99 |
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
100 def _statusmessage(code): |
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
101 from BaseHTTPServer import BaseHTTPRequestHandler |
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
102 responses = BaseHTTPRequestHandler.responses |
d61fea133f2d
hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents:
5561
diff
changeset
|
103 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
|
104 |
9694
8269fe2d48f6
hgweb: send proper error messages to the client
Sune Foldager <cryo@cyanite.org>
parents:
9031
diff
changeset
|
105 def statusmessage(code, message=None): |
8269fe2d48f6
hgweb: send proper error messages to the client
Sune Foldager <cryo@cyanite.org>
parents:
9031
diff
changeset
|
106 return '%d %s' % (code, message or _statusmessage(code)) |
131 | 107 |
13958
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
108 def get_stat(spath): |
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
109 """stat changelog if it exists, spath otherwise""" |
10078
97c75ad3b1a0
hgweb: Make get_mtime use repository to find store path.
Brendan Cully <brendan@kublai.com>
parents:
9910
diff
changeset
|
110 cl_path = os.path.join(spath, "00changelog.i") |
3853
c0b449154a90
switch to the .hg/store layout, fix the tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3276
diff
changeset
|
111 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
|
112 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
|
113 else: |
13958
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
114 return os.stat(spath) |
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
115 |
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
116 def get_mtime(spath): |
71f51cc71652
hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents:
13444
diff
changeset
|
117 return get_stat(spath).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
|
118 |
2514
419c42223bee
Really fix http headers for web UI and issue 254.
Eric Hopper <hopper@omnifarious.org>
parents:
2391
diff
changeset
|
119 def staticfile(directory, fname, req): |
5930
c301f15c965a
send conservatively capitalized HTTP headers
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5779
diff
changeset
|
120 """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
|
121 |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
122 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
|
123 contain unusual path components. |
5930
c301f15c965a
send conservatively capitalized HTTP headers
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5779
diff
changeset
|
124 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
|
125 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
|
126 |
1825
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
127 """ |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
128 parts = fname.split('/') |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
129 for part in parts: |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
130 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
|
131 os.sep in part or os.altsep is not None and os.altsep in part): |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
132 return "" |
7288
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
133 fpath = os.path.join(*parts) |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
134 if isinstance(directory, str): |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
135 directory = [directory] |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
136 for d in directory: |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
137 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
|
138 if os.path.exists(path): |
9c399c53469d
Allow per-file shadowing of static directory in templatepath
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
139 break |
1793
83c6d8355909
Allow serving static files from hgwebdir to fix CSS and favicon.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1792
diff
changeset
|
140 try: |
1825
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
141 os.stat(path) |
a9343f9d7365
Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1796
diff
changeset
|
142 ct = mimetypes.guess_type(path)[0] or "text/plain" |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
143 req.respond(HTTP_OK, ct, length = os.path.getsize(path)) |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12183
diff
changeset
|
144 fp = open(path, 'rb') |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12183
diff
changeset
|
145 data = fp.read() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12183
diff
changeset
|
146 fp.close() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12183
diff
changeset
|
147 return data |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
148 except TypeError: |
8761
0289f384e1e5
Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents:
8225
diff
changeset
|
149 raise ErrorResponse(HTTP_SERVER_ERROR, 'illegal filename') |
5561
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
150 except OSError, err: |
22713dce19f6
hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents:
4462
diff
changeset
|
151 if err.errno == errno.ENOENT: |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
152 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
|
153 else: |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5930
diff
changeset
|
154 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
|
155 |
4462
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
156 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
|
157 """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
|
158 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
|
159 # 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
|
160 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
|
161 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
|
162 else: |
12e4d9524951
hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4038
diff
changeset
|
163 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
|
164 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
|
165 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
|
166 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
|
167 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
|
168 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
|
169 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
|
170 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
|
171 |
5779
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
172 def get_contact(config): |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
173 """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
|
174 |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
175 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
|
176 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
|
177 """ |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
178 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
|
179 config("ui", "username") or |
e9f68860d5ed
Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5760
diff
changeset
|
180 os.environ.get("EMAIL") or "") |
12183
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
181 |
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
182 def caching(web, req): |
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
183 tag = str(web.mtime) |
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
184 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
|
185 raise ErrorResponse(HTTP_NOT_MODIFIED) |
f64b416b0ac8
hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10264
diff
changeset
|
186 req.headers.append(('ETag', tag)) |