Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/hgweb/hgweb_mod.py @ 43077:687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Done with
python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py')
black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**')
# skip-blame mass-reformatting only
Differential Revision: https://phab.mercurial-scm.org/D6972
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:48:39 -0400 |
parents | 2372284d9457 |
children | c59eb1560c44 |
comparison
equal
deleted
inserted
replaced
43076:2372284d9457 | 43077:687b865b95ad |
---|---|
46 ) | 46 ) |
47 | 47 |
48 | 48 |
49 def getstyle(req, configfn, templatepath): | 49 def getstyle(req, configfn, templatepath): |
50 styles = ( | 50 styles = ( |
51 req.qsparams.get('style', None), | 51 req.qsparams.get(b'style', None), |
52 configfn('web', 'style'), | 52 configfn(b'web', b'style'), |
53 'paper', | 53 b'paper', |
54 ) | 54 ) |
55 return styles, templater.stylemap(styles, templatepath) | 55 return styles, templater.stylemap(styles, templatepath) |
56 | 56 |
57 | 57 |
58 def makebreadcrumb(url, prefix=''): | 58 def makebreadcrumb(url, prefix=b''): |
59 '''Return a 'URL breadcrumb' list | 59 '''Return a 'URL breadcrumb' list |
60 | 60 |
61 A 'URL breadcrumb' is a list of URL-name pairs, | 61 A 'URL breadcrumb' is a list of URL-name pairs, |
62 corresponding to each of the path items on a URL. | 62 corresponding to each of the path items on a URL. |
63 This can be used to create path navigation entries. | 63 This can be used to create path navigation entries. |
64 ''' | 64 ''' |
65 if url.endswith('/'): | 65 if url.endswith(b'/'): |
66 url = url[:-1] | 66 url = url[:-1] |
67 if prefix: | 67 if prefix: |
68 url = '/' + prefix + url | 68 url = b'/' + prefix + url |
69 relpath = url | 69 relpath = url |
70 if relpath.startswith('/'): | 70 if relpath.startswith(b'/'): |
71 relpath = relpath[1:] | 71 relpath = relpath[1:] |
72 | 72 |
73 breadcrumb = [] | 73 breadcrumb = [] |
74 urlel = url | 74 urlel = url |
75 pathitems = [''] + relpath.split('/') | 75 pathitems = [b''] + relpath.split(b'/') |
76 for pathel in reversed(pathitems): | 76 for pathel in reversed(pathitems): |
77 if not pathel or not urlel: | 77 if not pathel or not urlel: |
78 break | 78 break |
79 breadcrumb.append({'url': urlel, 'name': pathel}) | 79 breadcrumb.append({b'url': urlel, b'name': pathel}) |
80 urlel = os.path.dirname(urlel) | 80 urlel = os.path.dirname(urlel) |
81 return templateutil.mappinglist(reversed(breadcrumb)) | 81 return templateutil.mappinglist(reversed(breadcrumb)) |
82 | 82 |
83 | 83 |
84 class requestcontext(object): | 84 class requestcontext(object): |
93 self.repo = repo | 93 self.repo = repo |
94 self.reponame = app.reponame | 94 self.reponame = app.reponame |
95 self.req = req | 95 self.req = req |
96 self.res = res | 96 self.res = res |
97 | 97 |
98 self.maxchanges = self.configint('web', 'maxchanges') | 98 self.maxchanges = self.configint(b'web', b'maxchanges') |
99 self.stripecount = self.configint('web', 'stripes') | 99 self.stripecount = self.configint(b'web', b'stripes') |
100 self.maxshortchanges = self.configint('web', 'maxshortchanges') | 100 self.maxshortchanges = self.configint(b'web', b'maxshortchanges') |
101 self.maxfiles = self.configint('web', 'maxfiles') | 101 self.maxfiles = self.configint(b'web', b'maxfiles') |
102 self.allowpull = self.configbool('web', 'allow-pull') | 102 self.allowpull = self.configbool(b'web', b'allow-pull') |
103 | 103 |
104 # we use untrusted=False to prevent a repo owner from using | 104 # we use untrusted=False to prevent a repo owner from using |
105 # web.templates in .hg/hgrc to get access to any file readable | 105 # web.templates in .hg/hgrc to get access to any file readable |
106 # by the user running the CGI script | 106 # by the user running the CGI script |
107 self.templatepath = self.config('web', 'templates', untrusted=False) | 107 self.templatepath = self.config(b'web', b'templates', untrusted=False) |
108 | 108 |
109 # This object is more expensive to build than simple config values. | 109 # This object is more expensive to build than simple config values. |
110 # It is shared across requests. The app will replace the object | 110 # It is shared across requests. The app will replace the object |
111 # if it is updated. Since this is a reference and nothing should | 111 # if it is updated. Since this is a reference and nothing should |
112 # modify the underlying object, it should be constant for the lifetime | 112 # modify the underlying object, it should be constant for the lifetime |
138 return webutil.archivelist(self.repo.ui, nodeid) | 138 return webutil.archivelist(self.repo.ui, nodeid) |
139 | 139 |
140 def templater(self, req): | 140 def templater(self, req): |
141 # determine scheme, port and server name | 141 # determine scheme, port and server name |
142 # this is needed to create absolute urls | 142 # this is needed to create absolute urls |
143 logourl = self.config('web', 'logourl') | 143 logourl = self.config(b'web', b'logourl') |
144 logoimg = self.config('web', 'logoimg') | 144 logoimg = self.config(b'web', b'logoimg') |
145 staticurl = ( | 145 staticurl = ( |
146 self.config('web', 'staticurl') | 146 self.config(b'web', b'staticurl') |
147 or req.apppath.rstrip('/') + '/static/' | 147 or req.apppath.rstrip(b'/') + b'/static/' |
148 ) | 148 ) |
149 if not staticurl.endswith('/'): | 149 if not staticurl.endswith(b'/'): |
150 staticurl += '/' | 150 staticurl += b'/' |
151 | 151 |
152 # figure out which style to use | 152 # figure out which style to use |
153 | 153 |
154 vars = {} | 154 vars = {} |
155 styles, (style, mapfile) = getstyle(req, self.config, self.templatepath) | 155 styles, (style, mapfile) = getstyle(req, self.config, self.templatepath) |
156 if style == styles[0]: | 156 if style == styles[0]: |
157 vars['style'] = style | 157 vars[b'style'] = style |
158 | 158 |
159 sessionvars = webutil.sessionvars(vars, '?') | 159 sessionvars = webutil.sessionvars(vars, b'?') |
160 | 160 |
161 if not self.reponame: | 161 if not self.reponame: |
162 self.reponame = ( | 162 self.reponame = ( |
163 self.config('web', 'name', '') | 163 self.config(b'web', b'name', b'') |
164 or req.reponame | 164 or req.reponame |
165 or req.apppath | 165 or req.apppath |
166 or self.repo.root | 166 or self.repo.root |
167 ) | 167 ) |
168 | 168 |
169 filters = {} | 169 filters = {} |
170 templatefilter = registrar.templatefilter(filters) | 170 templatefilter = registrar.templatefilter(filters) |
171 | 171 |
172 @templatefilter('websub', intype=bytes) | 172 @templatefilter(b'websub', intype=bytes) |
173 def websubfilter(text): | 173 def websubfilter(text): |
174 return templatefilters.websub(text, self.websubtable) | 174 return templatefilters.websub(text, self.websubtable) |
175 | 175 |
176 # create the templater | 176 # create the templater |
177 # TODO: export all keywords: defaults = templatekw.keywords.copy() | 177 # TODO: export all keywords: defaults = templatekw.keywords.copy() |
178 defaults = { | 178 defaults = { |
179 'url': req.apppath + '/', | 179 b'url': req.apppath + b'/', |
180 'logourl': logourl, | 180 b'logourl': logourl, |
181 'logoimg': logoimg, | 181 b'logoimg': logoimg, |
182 'staticurl': staticurl, | 182 b'staticurl': staticurl, |
183 'urlbase': req.advertisedbaseurl, | 183 b'urlbase': req.advertisedbaseurl, |
184 'repo': self.reponame, | 184 b'repo': self.reponame, |
185 'encoding': encoding.encoding, | 185 b'encoding': encoding.encoding, |
186 'sessionvars': sessionvars, | 186 b'sessionvars': sessionvars, |
187 'pathdef': makebreadcrumb(req.apppath), | 187 b'pathdef': makebreadcrumb(req.apppath), |
188 'style': style, | 188 b'style': style, |
189 'nonce': self.nonce, | 189 b'nonce': self.nonce, |
190 } | 190 } |
191 templatekeyword = registrar.templatekeyword(defaults) | 191 templatekeyword = registrar.templatekeyword(defaults) |
192 | 192 |
193 @templatekeyword('motd', requires=()) | 193 @templatekeyword(b'motd', requires=()) |
194 def motd(context, mapping): | 194 def motd(context, mapping): |
195 yield self.config('web', 'motd') | 195 yield self.config(b'web', b'motd') |
196 | 196 |
197 tres = formatter.templateresources(self.repo.ui, self.repo) | 197 tres = formatter.templateresources(self.repo.ui, self.repo) |
198 tmpl = templater.templater.frommapfile( | 198 tmpl = templater.templater.frommapfile( |
199 mapfile, filters=filters, defaults=defaults, resources=tres | 199 mapfile, filters=filters, defaults=defaults, resources=tres |
200 ) | 200 ) |
230 r = hg.repository(u, repo) | 230 r = hg.repository(u, repo) |
231 else: | 231 else: |
232 # we trust caller to give us a private copy | 232 # we trust caller to give us a private copy |
233 r = repo | 233 r = repo |
234 | 234 |
235 r.ui.setconfig('ui', 'report_untrusted', 'off', 'hgweb') | 235 r.ui.setconfig(b'ui', b'report_untrusted', b'off', b'hgweb') |
236 r.baseui.setconfig('ui', 'report_untrusted', 'off', 'hgweb') | 236 r.baseui.setconfig(b'ui', b'report_untrusted', b'off', b'hgweb') |
237 r.ui.setconfig('ui', 'nontty', 'true', 'hgweb') | 237 r.ui.setconfig(b'ui', b'nontty', b'true', b'hgweb') |
238 r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb') | 238 r.baseui.setconfig(b'ui', b'nontty', b'true', b'hgweb') |
239 # resolve file patterns relative to repo root | 239 # resolve file patterns relative to repo root |
240 r.ui.setconfig('ui', 'forcecwd', r.root, 'hgweb') | 240 r.ui.setconfig(b'ui', b'forcecwd', r.root, b'hgweb') |
241 r.baseui.setconfig('ui', 'forcecwd', r.root, 'hgweb') | 241 r.baseui.setconfig(b'ui', b'forcecwd', r.root, b'hgweb') |
242 # it's unlikely that we can replace signal handlers in WSGI server, | 242 # it's unlikely that we can replace signal handlers in WSGI server, |
243 # and mod_wsgi issues a big warning. a plain hgweb process (with no | 243 # and mod_wsgi issues a big warning. a plain hgweb process (with no |
244 # threading) could replace signal handlers, but we don't bother | 244 # threading) could replace signal handlers, but we don't bother |
245 # conditionally enabling it. | 245 # conditionally enabling it. |
246 r.ui.setconfig('ui', 'signal-safe-lock', 'false', 'hgweb') | 246 r.ui.setconfig(b'ui', b'signal-safe-lock', b'false', b'hgweb') |
247 r.baseui.setconfig('ui', 'signal-safe-lock', 'false', 'hgweb') | 247 r.baseui.setconfig(b'ui', b'signal-safe-lock', b'false', b'hgweb') |
248 # displaying bundling progress bar while serving feel wrong and may | 248 # displaying bundling progress bar while serving feel wrong and may |
249 # break some wsgi implementation. | 249 # break some wsgi implementation. |
250 r.ui.setconfig('progress', 'disable', 'true', 'hgweb') | 250 r.ui.setconfig(b'progress', b'disable', b'true', b'hgweb') |
251 r.baseui.setconfig('progress', 'disable', 'true', 'hgweb') | 251 r.baseui.setconfig(b'progress', b'disable', b'true', b'hgweb') |
252 self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))] | 252 self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))] |
253 self._lastrepo = self._repos[0] | 253 self._lastrepo = self._repos[0] |
254 hook.redirect(True) | 254 hook.redirect(True) |
255 self.reponame = name | 255 self.reponame = name |
256 | 256 |
292 """Start a server from CGI environment. | 292 """Start a server from CGI environment. |
293 | 293 |
294 Modern servers should be using WSGI and should avoid this | 294 Modern servers should be using WSGI and should avoid this |
295 method, if possible. | 295 method, if possible. |
296 """ | 296 """ |
297 if not encoding.environ.get('GATEWAY_INTERFACE', '').startswith( | 297 if not encoding.environ.get(b'GATEWAY_INTERFACE', b'').startswith( |
298 "CGI/1." | 298 b"CGI/1." |
299 ): | 299 ): |
300 raise RuntimeError( | 300 raise RuntimeError( |
301 "This function is only intended to be " | 301 b"This function is only intended to be " |
302 "called while running as a CGI script." | 302 b"called while running as a CGI script." |
303 ) | 303 ) |
304 wsgicgi.launch(self) | 304 wsgicgi.launch(self) |
305 | 305 |
306 def __call__(self, env, respond): | 306 def __call__(self, env, respond): |
307 """Run the WSGI application. | 307 """Run the WSGI application. |
318 | 318 |
319 This is typically only called by Mercurial. External consumers | 319 This is typically only called by Mercurial. External consumers |
320 should be using instances of this class as the WSGI application. | 320 should be using instances of this class as the WSGI application. |
321 """ | 321 """ |
322 with self._obtainrepo() as repo: | 322 with self._obtainrepo() as repo: |
323 profile = repo.ui.configbool('profiling', 'enabled') | 323 profile = repo.ui.configbool(b'profiling', b'enabled') |
324 with profiling.profile(repo.ui, enabled=profile): | 324 with profiling.profile(repo.ui, enabled=profile): |
325 for r in self._runwsgi(req, res, repo): | 325 for r in self._runwsgi(req, res, repo): |
326 yield r | 326 yield r |
327 | 327 |
328 def _runwsgi(self, req, res, repo): | 328 def _runwsgi(self, req, res, repo): |
329 rctx = requestcontext(self, repo, req, res) | 329 rctx = requestcontext(self, repo, req, res) |
330 | 330 |
331 # This state is global across all threads. | 331 # This state is global across all threads. |
332 encoding.encoding = rctx.config('web', 'encoding') | 332 encoding.encoding = rctx.config(b'web', b'encoding') |
333 rctx.repo.ui.environ = req.rawenv | 333 rctx.repo.ui.environ = req.rawenv |
334 | 334 |
335 if rctx.csp: | 335 if rctx.csp: |
336 # hgwebdir may have added CSP header. Since we generate our own, | 336 # hgwebdir may have added CSP header. Since we generate our own, |
337 # replace it. | 337 # replace it. |
338 res.headers['Content-Security-Policy'] = rctx.csp | 338 res.headers[b'Content-Security-Policy'] = rctx.csp |
339 | 339 |
340 # /api/* is reserved for various API implementations. Dispatch | 340 # /api/* is reserved for various API implementations. Dispatch |
341 # accordingly. But URL paths can conflict with subrepos and virtual | 341 # accordingly. But URL paths can conflict with subrepos and virtual |
342 # repos in hgwebdir. So until we have a workaround for this, only | 342 # repos in hgwebdir. So until we have a workaround for this, only |
343 # expose the URLs if the feature is enabled. | 343 # expose the URLs if the feature is enabled. |
344 apienabled = rctx.repo.ui.configbool('experimental', 'web.apiserver') | 344 apienabled = rctx.repo.ui.configbool(b'experimental', b'web.apiserver') |
345 if apienabled and req.dispatchparts and req.dispatchparts[0] == b'api': | 345 if apienabled and req.dispatchparts and req.dispatchparts[0] == b'api': |
346 wireprotoserver.handlewsgiapirequest( | 346 wireprotoserver.handlewsgiapirequest( |
347 rctx, req, res, self.check_perm | 347 rctx, req, res, self.check_perm |
348 ) | 348 ) |
349 return res.sendresponse() | 349 return res.sendresponse() |
359 # If PATH_INFO is present (signaled by ``req.dispatchpath`` having | 359 # If PATH_INFO is present (signaled by ``req.dispatchpath`` having |
360 # a value), we use it. Otherwise fall back to the query string. | 360 # a value), we use it. Otherwise fall back to the query string. |
361 if req.dispatchpath is not None: | 361 if req.dispatchpath is not None: |
362 query = req.dispatchpath | 362 query = req.dispatchpath |
363 else: | 363 else: |
364 query = req.querystring.partition('&')[0].partition(';')[0] | 364 query = req.querystring.partition(b'&')[0].partition(b';')[0] |
365 | 365 |
366 # translate user-visible url structure to internal structure | 366 # translate user-visible url structure to internal structure |
367 | 367 |
368 args = query.split('/', 2) | 368 args = query.split(b'/', 2) |
369 if 'cmd' not in req.qsparams and args and args[0]: | 369 if b'cmd' not in req.qsparams and args and args[0]: |
370 cmd = args.pop(0) | 370 cmd = args.pop(0) |
371 style = cmd.rfind('-') | 371 style = cmd.rfind(b'-') |
372 if style != -1: | 372 if style != -1: |
373 req.qsparams['style'] = cmd[:style] | 373 req.qsparams[b'style'] = cmd[:style] |
374 cmd = cmd[style + 1 :] | 374 cmd = cmd[style + 1 :] |
375 | 375 |
376 # avoid accepting e.g. style parameter as command | 376 # avoid accepting e.g. style parameter as command |
377 if util.safehasattr(webcommands, cmd): | 377 if util.safehasattr(webcommands, cmd): |
378 req.qsparams['cmd'] = cmd | 378 req.qsparams[b'cmd'] = cmd |
379 | 379 |
380 if cmd == 'static': | 380 if cmd == b'static': |
381 req.qsparams['file'] = '/'.join(args) | 381 req.qsparams[b'file'] = b'/'.join(args) |
382 else: | 382 else: |
383 if args and args[0]: | 383 if args and args[0]: |
384 node = args.pop(0).replace('%2F', '/') | 384 node = args.pop(0).replace(b'%2F', b'/') |
385 req.qsparams['node'] = node | 385 req.qsparams[b'node'] = node |
386 if args: | 386 if args: |
387 if 'file' in req.qsparams: | 387 if b'file' in req.qsparams: |
388 del req.qsparams['file'] | 388 del req.qsparams[b'file'] |
389 for a in args: | 389 for a in args: |
390 req.qsparams.add('file', a) | 390 req.qsparams.add(b'file', a) |
391 | 391 |
392 ua = req.headers.get('User-Agent', '') | 392 ua = req.headers.get(b'User-Agent', b'') |
393 if cmd == 'rev' and 'mercurial' in ua: | 393 if cmd == b'rev' and b'mercurial' in ua: |
394 req.qsparams['style'] = 'raw' | 394 req.qsparams[b'style'] = b'raw' |
395 | 395 |
396 if cmd == 'archive': | 396 if cmd == b'archive': |
397 fn = req.qsparams['node'] | 397 fn = req.qsparams[b'node'] |
398 for type_, spec in webutil.archivespecs.iteritems(): | 398 for type_, spec in webutil.archivespecs.iteritems(): |
399 ext = spec[2] | 399 ext = spec[2] |
400 if fn.endswith(ext): | 400 if fn.endswith(ext): |
401 req.qsparams['node'] = fn[: -len(ext)] | 401 req.qsparams[b'node'] = fn[: -len(ext)] |
402 req.qsparams['type'] = type_ | 402 req.qsparams[b'type'] = type_ |
403 else: | 403 else: |
404 cmd = req.qsparams.get('cmd', '') | 404 cmd = req.qsparams.get(b'cmd', b'') |
405 | 405 |
406 # process the web interface request | 406 # process the web interface request |
407 | 407 |
408 try: | 408 try: |
409 rctx.tmpl = rctx.templater(req) | 409 rctx.tmpl = rctx.templater(req) |
410 ctype = rctx.tmpl.render( | 410 ctype = rctx.tmpl.render( |
411 'mimetype', {'encoding': encoding.encoding} | 411 b'mimetype', {b'encoding': encoding.encoding} |
412 ) | 412 ) |
413 | 413 |
414 # check read permissions non-static content | 414 # check read permissions non-static content |
415 if cmd != 'static': | 415 if cmd != b'static': |
416 self.check_perm(rctx, req, None) | 416 self.check_perm(rctx, req, None) |
417 | 417 |
418 if cmd == '': | 418 if cmd == b'': |
419 req.qsparams['cmd'] = rctx.tmpl.render('default', {}) | 419 req.qsparams[b'cmd'] = rctx.tmpl.render(b'default', {}) |
420 cmd = req.qsparams['cmd'] | 420 cmd = req.qsparams[b'cmd'] |
421 | 421 |
422 # Don't enable caching if using a CSP nonce because then it wouldn't | 422 # Don't enable caching if using a CSP nonce because then it wouldn't |
423 # be a nonce. | 423 # be a nonce. |
424 if rctx.configbool('web', 'cache') and not rctx.nonce: | 424 if rctx.configbool(b'web', b'cache') and not rctx.nonce: |
425 tag = 'W/"%d"' % self.mtime | 425 tag = b'W/"%d"' % self.mtime |
426 if req.headers.get('If-None-Match') == tag: | 426 if req.headers.get(b'If-None-Match') == tag: |
427 res.status = '304 Not Modified' | 427 res.status = b'304 Not Modified' |
428 # Content-Type may be defined globally. It isn't valid on a | 428 # Content-Type may be defined globally. It isn't valid on a |
429 # 304, so discard it. | 429 # 304, so discard it. |
430 try: | 430 try: |
431 del res.headers[b'Content-Type'] | 431 del res.headers[b'Content-Type'] |
432 except KeyError: | 432 except KeyError: |
433 pass | 433 pass |
434 # Response body not allowed on 304. | 434 # Response body not allowed on 304. |
435 res.setbodybytes('') | 435 res.setbodybytes(b'') |
436 return res.sendresponse() | 436 return res.sendresponse() |
437 | 437 |
438 res.headers['ETag'] = tag | 438 res.headers[b'ETag'] = tag |
439 | 439 |
440 if cmd not in webcommands.__all__: | 440 if cmd not in webcommands.__all__: |
441 msg = 'no such method: %s' % cmd | 441 msg = b'no such method: %s' % cmd |
442 raise ErrorResponse(HTTP_BAD_REQUEST, msg) | 442 raise ErrorResponse(HTTP_BAD_REQUEST, msg) |
443 else: | 443 else: |
444 # Set some globals appropriate for web handlers. Commands can | 444 # Set some globals appropriate for web handlers. Commands can |
445 # override easily enough. | 445 # override easily enough. |
446 res.status = '200 Script output follows' | 446 res.status = b'200 Script output follows' |
447 res.headers['Content-Type'] = ctype | 447 res.headers[b'Content-Type'] = ctype |
448 return getattr(webcommands, cmd)(rctx) | 448 return getattr(webcommands, cmd)(rctx) |
449 | 449 |
450 except (error.LookupError, error.RepoLookupError) as err: | 450 except (error.LookupError, error.RepoLookupError) as err: |
451 msg = pycompat.bytestr(err) | 451 msg = pycompat.bytestr(err) |
452 if util.safehasattr(err, 'name') and not isinstance( | 452 if util.safehasattr(err, b'name') and not isinstance( |
453 err, error.ManifestLookupError | 453 err, error.ManifestLookupError |
454 ): | 454 ): |
455 msg = 'revision not found: %s' % err.name | 455 msg = b'revision not found: %s' % err.name |
456 | 456 |
457 res.status = '404 Not Found' | 457 res.status = b'404 Not Found' |
458 res.headers['Content-Type'] = ctype | 458 res.headers[b'Content-Type'] = ctype |
459 return rctx.sendtemplate('error', error=msg) | 459 return rctx.sendtemplate(b'error', error=msg) |
460 except (error.RepoError, error.StorageError) as e: | 460 except (error.RepoError, error.StorageError) as e: |
461 res.status = '500 Internal Server Error' | 461 res.status = b'500 Internal Server Error' |
462 res.headers['Content-Type'] = ctype | 462 res.headers[b'Content-Type'] = ctype |
463 return rctx.sendtemplate('error', error=pycompat.bytestr(e)) | 463 return rctx.sendtemplate(b'error', error=pycompat.bytestr(e)) |
464 except error.Abort as e: | 464 except error.Abort as e: |
465 res.status = '403 Forbidden' | 465 res.status = b'403 Forbidden' |
466 res.headers['Content-Type'] = ctype | 466 res.headers[b'Content-Type'] = ctype |
467 return rctx.sendtemplate('error', error=pycompat.bytestr(e)) | 467 return rctx.sendtemplate(b'error', error=pycompat.bytestr(e)) |
468 except ErrorResponse as e: | 468 except ErrorResponse as e: |
469 for k, v in e.headers: | 469 for k, v in e.headers: |
470 res.headers[k] = v | 470 res.headers[k] = v |
471 res.status = statusmessage(e.code, pycompat.bytestr(e)) | 471 res.status = statusmessage(e.code, pycompat.bytestr(e)) |
472 res.headers['Content-Type'] = ctype | 472 res.headers[b'Content-Type'] = ctype |
473 return rctx.sendtemplate('error', error=pycompat.bytestr(e)) | 473 return rctx.sendtemplate(b'error', error=pycompat.bytestr(e)) |
474 | 474 |
475 def check_perm(self, rctx, req, op): | 475 def check_perm(self, rctx, req, op): |
476 for permhook in permhooks: | 476 for permhook in permhooks: |
477 permhook(rctx, req, op) | 477 permhook(rctx, req, op) |
478 | 478 |
487 See the repoview module for details. | 487 See the repoview module for details. |
488 | 488 |
489 The option has been around undocumented since Mercurial 2.5, but no | 489 The option has been around undocumented since Mercurial 2.5, but no |
490 user ever asked about it. So we better keep it undocumented for now.""" | 490 user ever asked about it. So we better keep it undocumented for now.""" |
491 # experimental config: web.view | 491 # experimental config: web.view |
492 viewconfig = repo.ui.config('web', 'view', untrusted=True) | 492 viewconfig = repo.ui.config(b'web', b'view', untrusted=True) |
493 if viewconfig == 'all': | 493 if viewconfig == b'all': |
494 return repo.unfiltered() | 494 return repo.unfiltered() |
495 elif viewconfig in repoview.filtertable: | 495 elif viewconfig in repoview.filtertable: |
496 return repo.filtered(viewconfig) | 496 return repo.filtered(viewconfig) |
497 else: | 497 else: |
498 return repo.filtered('served') | 498 return repo.filtered(b'served') |