diff -r 2372284d9457 -r 687b865b95ad mercurial/hgweb/common.py --- a/mercurial/hgweb/common.py Sun Oct 06 09:45:02 2019 -0400 +++ b/mercurial/hgweb/common.py Sun Oct 06 09:48:39 2019 -0400 @@ -42,7 +42,7 @@ Can be overridden by extensions to provide more complex authorization schemes. """ - return userlist == ['*'] or username in userlist + return userlist == [b'*'] or username in userlist def checkauthz(hgweb, req, op): @@ -52,41 +52,41 @@ user = req.remoteuser - deny_read = hgweb.configlist('web', 'deny_read') + deny_read = hgweb.configlist(b'web', b'deny_read') if deny_read and (not user or ismember(hgweb.repo.ui, user, deny_read)): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') + raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized') - allow_read = hgweb.configlist('web', 'allow_read') + allow_read = hgweb.configlist(b'web', b'allow_read') if allow_read and (not ismember(hgweb.repo.ui, user, allow_read)): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') + raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized') - if op == 'pull' and not hgweb.allowpull: - raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') - elif op == 'pull' or op is None: # op is None for interface requests + if op == b'pull' and not hgweb.allowpull: + raise ErrorResponse(HTTP_UNAUTHORIZED, b'pull not authorized') + elif op == b'pull' or op is None: # op is None for interface requests return # Allow LFS uploading via PUT requests - if op == 'upload': - if req.method != 'PUT': - msg = 'upload requires PUT request' + if op == b'upload': + if req.method != b'PUT': + msg = b'upload requires PUT request' raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) # enforce that you can only push using POST requests - elif req.method != 'POST': - msg = 'push requires POST request' + elif req.method != b'POST': + msg = b'push requires POST request' raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) # require ssl by default for pushing, auth info cannot be sniffed # and replayed - if hgweb.configbool('web', 'push_ssl') and req.urlscheme != 'https': - raise ErrorResponse(HTTP_FORBIDDEN, 'ssl required') + if hgweb.configbool(b'web', b'push_ssl') and req.urlscheme != b'https': + raise ErrorResponse(HTTP_FORBIDDEN, b'ssl required') - deny = hgweb.configlist('web', 'deny_push') + deny = hgweb.configlist(b'web', b'deny_push') if deny and (not user or ismember(hgweb.repo.ui, user, deny)): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') + raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized') - allow = hgweb.configlist('web', 'allow-push') + allow = hgweb.configlist(b'web', b'allow-push') if not (allow and ismember(hgweb.repo.ui, user, allow)): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') + raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized') # Hooks for hgweb permission checks; extensions can add hooks here. @@ -128,11 +128,11 @@ def read(self, amt=-1): if not self.continued: self.continued = True - self._write('HTTP/1.1 100 Continue\r\n\r\n') + self._write(b'HTTP/1.1 100 Continue\r\n\r\n') return self.f.read(amt) def __getattr__(self, attr): - if attr in ('close', 'readline', 'readlines', '__iter__'): + if attr in (b'close', b'readline', b'readlines', b'__iter__'): return getattr(self.f, attr) raise AttributeError @@ -145,7 +145,7 @@ def statusmessage(code, message=None): - return '%d %s' % (code, message or _statusmessage(code)) + return b'%d %s' % (code, message or _statusmessage(code)) def get_stat(spath, fn): @@ -158,15 +158,15 @@ def get_mtime(spath): - return get_stat(spath, "00changelog.i")[stat.ST_MTIME] + return get_stat(spath, b"00changelog.i")[stat.ST_MTIME] def ispathsafe(path): """Determine if a path is safe to use for filesystem access.""" - parts = path.split('/') + parts = path.split(b'/') for part in parts: if ( - part in ('', pycompat.oscurdir, pycompat.ospardir) + part in (b'', pycompat.oscurdir, pycompat.ospardir) or pycompat.ossep in part or pycompat.osaltsep is not None and pycompat.osaltsep in part @@ -188,7 +188,7 @@ if not ispathsafe(fname): return - fpath = os.path.join(*fname.split('/')) + fpath = os.path.join(*fname.split(b'/')) if isinstance(directory, str): directory = [directory] for d in directory: @@ -200,14 +200,14 @@ ct = pycompat.sysbytes( mimetypes.guess_type(pycompat.fsdecode(path))[0] or r"text/plain" ) - with open(path, 'rb') as fh: + with open(path, b'rb') as fh: data = fh.read() - res.headers['Content-Type'] = ct + res.headers[b'Content-Type'] = ct res.setbodybytes(data) return res except TypeError: - raise ErrorResponse(HTTP_SERVER_ERROR, 'illegal filename') + raise ErrorResponse(HTTP_SERVER_ERROR, b'illegal filename') except OSError as err: if err.errno == errno.ENOENT: raise ErrorResponse(HTTP_NOT_FOUND) @@ -241,10 +241,10 @@ ui.username or $EMAIL as a fallback to display something useful. """ return ( - config("web", "contact") - or config("ui", "username") - or encoding.environ.get("EMAIL") - or "" + config(b"web", b"contact") + or config(b"ui", b"username") + or encoding.environ.get(b"EMAIL") + or b"" ) @@ -275,11 +275,11 @@ # Don't allow untrusted CSP setting since it be disable protections # from a trusted/global source. - csp = ui.config('web', 'csp', untrusted=False) + csp = ui.config(b'web', b'csp', untrusted=False) nonce = None - if csp and '%nonce%' in csp: - nonce = base64.urlsafe_b64encode(uuid.uuid4().bytes).rstrip('=') - csp = csp.replace('%nonce%', nonce) + if csp and b'%nonce%' in csp: + nonce = base64.urlsafe_b64encode(uuid.uuid4().bytes).rstrip(b'=') + csp = csp.replace(b'%nonce%', nonce) return csp, nonce