annotate mercurial/hgweb/common.py @ 45737:b3e8d8e4a40d

hook: ignore EPIPE when flushing stdout/stderr This fixes the bug described in the parent commit. test-transaction-rollback-on-sigpipe.t is updated to show the new behavior. Differential Revision: https://phab.mercurial-scm.org/D9152
author Mitchell Plamann <mplamann@janestreet.com>
date Mon, 05 Oct 2020 17:18:39 -0400
parents f0735f2ce542
children 89a2afe31e82
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2391
d351a3be3371 Fixing up comment headers for split up code.
Eric Hopper <hopper@omnifarious.org>
parents: 2356
diff changeset
1 # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
2 #
238
3b92f8fe47ae hgweb.py: kill #! line, clean up copyright notice
mpm@selenic.com
parents: 222
diff changeset
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2514
diff changeset
4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
5 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7966
diff changeset
6 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9694
diff changeset
7 # GNU General Public License version 2 or any later version.
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
8
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
9 from __future__ import absolute_import
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
10
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
11 import base64
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
12 import errno
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
13 import mimetypes
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
14 import os
36781
ffa3026d4196 cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime
Augie Fackler <augie@google.com>
parents: 36648
diff changeset
15 import stat
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
16
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
17 from ..pycompat import (
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
18 getattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
19 open,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
20 )
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
21 from .. import (
30636
f1c9fafcbf46 py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30625
diff changeset
22 encoding,
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
23 pycompat,
45378
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
24 templater,
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
25 util,
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
26 )
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29491
diff changeset
27
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29491
diff changeset
28 httpserver = util.httpserver
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29491
diff changeset
29
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
30 HTTP_OK = 200
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
31 HTTP_CREATED = 201
12183
f64b416b0ac8 hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10264
diff changeset
32 HTTP_NOT_MODIFIED = 304
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
33 HTTP_BAD_REQUEST = 400
6926
57b954d8d003 hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6924
diff changeset
34 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
35 HTTP_FORBIDDEN = 403
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
36 HTTP_NOT_FOUND = 404
6926
57b954d8d003 hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6924
diff changeset
37 HTTP_METHOD_NOT_ALLOWED = 405
37693
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37149
diff changeset
38 HTTP_NOT_ACCEPTABLE = 406
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37149
diff changeset
39 HTTP_UNSUPPORTED_MEDIA_TYPE = 415
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
40 HTTP_SERVER_ERROR = 500
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
41
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
42
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
43 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
44 """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
45
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
46 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
47 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
48 schemes.
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
49 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
50 return userlist == [b'*'] or username in userlist
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
51
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
52
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
53 def checkauthz(hgweb, req, op):
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
54 '''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
55 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
56 exception.'''
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
57
36877
02bea04b4c54 hgweb: transition permissions hooks to modern request type (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36873
diff changeset
58 user = req.remoteuser
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
59
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
60 deny_read = hgweb.configlist(b'web', b'deny_read')
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
61 if deny_read and (not user or ismember(hgweb.repo.ui, user, deny_read)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
62 raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
63
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
64 allow_read = hgweb.configlist(b'web', b'allow_read')
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
65 if allow_read and (not ismember(hgweb.repo.ui, user, allow_read)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
66 raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
67
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
68 if op == b'pull' and not hgweb.allowpull:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
69 raise ErrorResponse(HTTP_UNAUTHORIZED, b'pull not authorized')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
70 elif op == b'pull' or op is None: # op is None for interface requests
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
71 return
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
72
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 36877
diff changeset
73 # Allow LFS uploading via PUT requests
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
74 if op == b'upload':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
75 if req.method != b'PUT':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
76 msg = b'upload requires PUT request'
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 36877
diff changeset
77 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
78 # enforce that you can only push using POST requests
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
79 elif req.method != b'POST':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
80 msg = b'push requires POST request'
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
81 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
82
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
83 # 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
84 # and replayed
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
85 if hgweb.configbool(b'web', b'push_ssl') and req.urlscheme != b'https':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
86 raise ErrorResponse(HTTP_FORBIDDEN, b'ssl required')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
87
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
88 deny = hgweb.configlist(b'web', b'deny_push')
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
89 if deny and (not user or ismember(hgweb.repo.ui, user, deny)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
90 raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
91
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
92 allow = hgweb.configlist(b'web', b'allow-push')
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
93 if not (allow and ismember(hgweb.repo.ui, user, allow)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
94 raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
95
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
96
14058
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
97 # 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
98 # Each hook is invoked like this: hook(hgweb, request, operation),
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 36877
diff changeset
99 # where operation is either read, pull, push or upload. Hooks should either
14058
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
100 # raise an ErrorResponse exception, or just return.
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
101 #
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
102 # 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
103 # this.
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
104 permhooks = [checkauthz]
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
105
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
106
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
107 class ErrorResponse(Exception):
31390
7dafa8d0e006 hgweb: don't use mutable default argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30766
diff changeset
108 def __init__(self, code, message=None, headers=None):
13444
75f5f312df5f hgweb: give ErrorResponse a descriptive string/Exception representation
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
109 if message is None:
75f5f312df5f hgweb: give ErrorResponse a descriptive string/Exception representation
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
110 message = _statusmessage(code)
36429
f8ea6988a5fb hgweb: pass exception message to builtin Exception ctor as sysstr
Augie Fackler <augie@google.com>
parents: 36397
diff changeset
111 Exception.__init__(self, pycompat.sysstr(message))
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
112 self.code = code
31435
2daeab02b4b1 hgweb: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31390
diff changeset
113 if headers is None:
2daeab02b4b1 hgweb: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31390
diff changeset
114 headers = []
2daeab02b4b1 hgweb: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31390
diff changeset
115 self.headers = headers
42922
8d9322b6e687 hgweb: add a `message` attribute to `hgweb.common.ErrorResponse`
Connor Sheehan <sheehan@mozilla.com>
parents: 40211
diff changeset
116 self.message = message
5563
d61fea133f2d hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents: 5561
diff changeset
117
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
118
13570
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
119 class continuereader(object):
36853
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
120 """File object wrapper to handle HTTP 100-continue.
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
121
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
122 This is used by servers so they automatically handle Expect: 100-continue
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
123 request headers. On first read of the request body, the 100 Continue
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
124 response is sent. This should trigger the client into actually sending
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
125 the request body.
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
126 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
127
13570
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
128 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
129 self.f = f
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
130 self._write = write
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
131 self.continued = False
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
132
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
133 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
134 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
135 self.continued = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
136 self._write(b'HTTP/1.1 100 Continue\r\n\r\n')
13570
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
137 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
138
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
139 def __getattr__(self, attr):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
140 if attr in (b'close', b'readline', b'readlines', b'__iter__'):
13570
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
141 return getattr(self.f, attr)
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 14058
diff changeset
142 raise AttributeError
5563
d61fea133f2d hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents: 5561
diff changeset
143
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
144
5563
d61fea133f2d hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents: 5561
diff changeset
145 def _statusmessage(code):
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29491
diff changeset
146 responses = httpserver.basehttprequesthandler.responses
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
147 return pycompat.bytesurl(responses.get(code, ('Error', 'Unknown error'))[0])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
148
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5563
diff changeset
149
9694
8269fe2d48f6 hgweb: send proper error messages to the client
Sune Foldager <cryo@cyanite.org>
parents: 9031
diff changeset
150 def statusmessage(code, message=None):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
151 return b'%d %s' % (code, message or _statusmessage(code))
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
152
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
153
25717
46e2c57026bc hgweb: drop the default argument for get_stat
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25660
diff changeset
154 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
155 """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
156 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
157 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
158 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
159 else:
13958
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13444
diff changeset
160 return os.stat(spath)
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13444
diff changeset
161
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
162
13958
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13444
diff changeset
163 def get_mtime(spath):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
164 return get_stat(spath, b"00changelog.i")[stat.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
165
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
166
31790
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
167 def ispathsafe(path):
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
168 """Determine if a path is safe to use for filesystem access."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
169 parts = path.split(b'/')
31790
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
170 for part in parts:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
171 if (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
172 part in (b'', pycompat.oscurdir, pycompat.ospardir)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
173 or pycompat.ossep in part
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
174 or pycompat.osaltsep is not None
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
175 and pycompat.osaltsep in part
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
176 ):
31790
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
177 return False
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
178
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
179 return True
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
180
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
181
45378
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
182 def staticfile(templatepath, directory, fname, res):
5930
c301f15c965a send conservatively capitalized HTTP headers
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5779
diff changeset
183 """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
184
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
185 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
186 contain unusual path components.
5930
c301f15c965a send conservatively capitalized HTTP headers
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5779
diff changeset
187 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
188 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
189
1825
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
190 """
31790
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
191 if not ispathsafe(fname):
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
192 return
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
193
45378
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
194 if not directory:
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
195 tp = templatepath or templater.templatedir()
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
196 if tp is not None:
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
197 directory = os.path.join(tp, b'static')
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
198
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
199 fpath = os.path.join(*fname.split(b'/'))
45380
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
200 ct = pycompat.sysbytes(
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
201 mimetypes.guess_type(pycompat.fsdecode(fpath))[0] or r"text/plain"
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
202 )
45306
9a5c4875a88c hgweb: simplify staticfile() now that we always pass it a single directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 43793
diff changeset
203 path = os.path.join(directory, fpath)
1793
83c6d8355909 Allow serving static files from hgwebdir to fix CSS and favicon.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1792
diff changeset
204 try:
1825
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
205 os.stat(path)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
206 with open(path, b'rb') as fh:
31789
161a87ed456e hgweb: use context manager for file I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31435
diff changeset
207 data = fh.read()
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
208 except TypeError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
209 raise ErrorResponse(HTTP_SERVER_ERROR, b'illegal filename')
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22577
diff changeset
210 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
211 if err.errno == errno.ENOENT:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
212 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
213 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
214 raise ErrorResponse(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
215 HTTP_SERVER_ERROR, encoding.strtolocal(err.strerror)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
216 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
217
45380
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
218 res.headers[b'Content-Type'] = ct
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
219 res.setbodybytes(data)
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
220 return res
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
221
3276
db9d2a624521 hgweb: Search templates in templatepath/style/map, too, using a common function.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3244
diff changeset
222
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
223 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
224 """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
225 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
226 # 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
227 count = (stripecount + offset) % stripecount
36397
7a3590e67868 py3: use '//' for integer division in hgweb/common.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36296
diff changeset
228 parity = (stripecount + offset) // stripecount & 1
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
229 else:
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
230 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
231 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
232 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
233 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
234 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
235 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
236 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
237 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
238
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
239
5779
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
240 def get_contact(config):
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
241 """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
242
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
243 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
244 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
245 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
246 return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
247 config(b"web", b"contact")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
248 or config(b"ui", b"username")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
249 or encoding.environ.get(b"EMAIL")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
250 or b""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
251 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
252
12183
f64b416b0ac8 hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10264
diff changeset
253
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
254 def cspvalues(ui):
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
255 """Obtain the Content-Security-Policy header and nonce value.
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
256
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
257 Returns a 2-tuple of the CSP header value and the nonce value.
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
258
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
259 First value is ``None`` if CSP isn't enabled. Second value is ``None``
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
260 if CSP isn't enabled or if the CSP header doesn't need a nonce.
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
261 """
34643
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
262 # Without demandimport, "import uuid" could have an immediate side-effect
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
263 # running "ldconfig" on Linux trying to find libuuid.
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
264 # With Python <= 2.7.12, that "ldconfig" is run via a shell and the shell
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
265 # may pollute the terminal with:
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
266 #
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
267 # shell-init: error retrieving current directory: getcwd: cannot access
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
268 # parent directories: No such file or directory
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
269 #
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
270 # Python >= 2.7.13 has fixed it by running "ldconfig" directly without a
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
271 # shell (hg changeset a09ae70f3489).
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
272 #
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
273 # Moved "import uuid" from here so it's executed after we know we have
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
274 # a sane cwd (i.e. after dispatch.py cwd check).
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
275 #
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
276 # We can move it back once we no longer need Python <= 2.7.12 support.
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
277 import uuid
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
278
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
279 # Don't allow untrusted CSP setting since it be disable protections
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
280 # from a trusted/global source.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
281 csp = ui.config(b'web', b'csp', untrusted=False)
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
282 nonce = None
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
283
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
284 if csp and b'%nonce%' in csp:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
285 nonce = base64.urlsafe_b64encode(uuid.uuid4().bytes).rstrip(b'=')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
286 csp = csp.replace(b'%nonce%', nonce)
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
287
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
288 return csp, nonce