mercurial/hgweb/hgweb_mod.py
changeset 34704 c51380879054
parent 34703 d1fccbd50fcd
child 34740 b2601c5977a4
equal deleted inserted replaced
34703:d1fccbd50fcd 34704:c51380879054
   163             default_port = '443'
   163             default_port = '443'
   164         else:
   164         else:
   165             proto = 'http'
   165             proto = 'http'
   166             default_port = '80'
   166             default_port = '80'
   167 
   167 
   168         port = req.env['SERVER_PORT']
   168         port = req.env[r'SERVER_PORT']
   169         port = port != default_port and (':' + port) or ''
   169         port = port != default_port and (r':' + port) or r''
   170         urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
   170         urlbase = r'%s://%s%s' % (proto, req.env[r'SERVER_NAME'], port)
   171         logourl = self.config('web', 'logourl')
   171         logourl = self.config('web', 'logourl')
   172         logoimg = self.config('web', 'logoimg')
   172         logoimg = self.config('web', 'logoimg')
   173         staticurl = self.config('web', 'staticurl') or req.url + 'static/'
   173         staticurl = self.config('web', 'staticurl') or req.url + 'static/'
   174         if not staticurl.endswith('/'):
   174         if not staticurl.endswith('/'):
   175             staticurl += '/'
   175             staticurl += '/'
   339             req.headers.append(('Content-Security-Policy', rctx.csp))
   339             req.headers.append(('Content-Security-Policy', rctx.csp))
   340 
   340 
   341         # work with CGI variables to create coherent structure
   341         # work with CGI variables to create coherent structure
   342         # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
   342         # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
   343 
   343 
   344         req.url = req.env['SCRIPT_NAME']
   344         req.url = req.env[r'SCRIPT_NAME']
   345         if not req.url.endswith('/'):
   345         if not req.url.endswith('/'):
   346             req.url += '/'
   346             req.url += '/'
   347         if req.env.get('REPO_NAME'):
   347         if req.env.get('REPO_NAME'):
   348             req.url += req.env['REPO_NAME'] + '/'
   348             req.url += req.env[r'REPO_NAME'] + r'/'
   349 
   349 
   350         if 'PATH_INFO' in req.env:
   350         if r'PATH_INFO' in req.env:
   351             parts = req.env['PATH_INFO'].strip('/').split('/')
   351             parts = req.env[r'PATH_INFO'].strip('/').split('/')
   352             repo_parts = req.env.get('REPO_NAME', '').split('/')
   352             repo_parts = req.env.get(r'REPO_NAME', r'').split(r'/')
   353             if parts[:len(repo_parts)] == repo_parts:
   353             if parts[:len(repo_parts)] == repo_parts:
   354                 parts = parts[len(repo_parts):]
   354                 parts = parts[len(repo_parts):]
   355             query = '/'.join(parts)
   355             query = '/'.join(parts)
   356         else:
   356         else:
   357             query = req.env['QUERY_STRING'].partition('&')[0]
   357             query = req.env[r'QUERY_STRING'].partition(r'&')[0]
   358             query = query.partition(';')[0]
   358             query = query.partition(r';')[0]
   359 
   359 
   360         # process this if it's a protocol request
   360         # process this if it's a protocol request
   361         # protocol bits don't need to create any URLs
   361         # protocol bits don't need to create any URLs
   362         # and the clients always use the old URL structure
   362         # and the clients always use the old URL structure
   363 
   363 
   364         cmd = req.form.get('cmd', [''])[0]
   364         cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0])
   365         if protocol.iscmd(cmd):
   365         if protocol.iscmd(cmd):
   366             try:
   366             try:
   367                 if query:
   367                 if query:
   368                     raise ErrorResponse(HTTP_NOT_FOUND)
   368                     raise ErrorResponse(HTTP_NOT_FOUND)
   369                 if cmd in perms:
   369                 if cmd in perms:
   384                 return ''
   384                 return ''
   385 
   385 
   386         # translate user-visible url structure to internal structure
   386         # translate user-visible url structure to internal structure
   387 
   387 
   388         args = query.split('/', 2)
   388         args = query.split('/', 2)
   389         if 'cmd' not in req.form and args and args[0]:
   389         if r'cmd' not in req.form and args and args[0]:
   390 
       
   391             cmd = args.pop(0)
   390             cmd = args.pop(0)
   392             style = cmd.rfind('-')
   391             style = cmd.rfind('-')
   393             if style != -1:
   392             if style != -1:
   394                 req.form['style'] = [cmd[:style]]
   393                 req.form['style'] = [cmd[:style]]
   395                 cmd = cmd[style + 1:]
   394                 cmd = cmd[style + 1:]
   396 
   395 
   397             # avoid accepting e.g. style parameter as command
   396             # avoid accepting e.g. style parameter as command
   398             if util.safehasattr(webcommands, cmd):
   397             if util.safehasattr(webcommands, cmd):
   399                 req.form['cmd'] = [cmd]
   398                 req.form[r'cmd'] = [cmd]
   400 
   399 
   401             if cmd == 'static':
   400             if cmd == 'static':
   402                 req.form['file'] = ['/'.join(args)]
   401                 req.form['file'] = ['/'.join(args)]
   403             else:
   402             else:
   404                 if args and args[0]:
   403                 if args and args[0]:
   429             # check read permissions non-static content
   428             # check read permissions non-static content
   430             if cmd != 'static':
   429             if cmd != 'static':
   431                 self.check_perm(rctx, req, None)
   430                 self.check_perm(rctx, req, None)
   432 
   431 
   433             if cmd == '':
   432             if cmd == '':
   434                 req.form['cmd'] = [tmpl.cache['default']]
   433                 req.form[r'cmd'] = [tmpl.cache['default']]
   435                 cmd = req.form['cmd'][0]
   434                 cmd = req.form[r'cmd'][0]
   436 
   435 
   437             # Don't enable caching if using a CSP nonce because then it wouldn't
   436             # Don't enable caching if using a CSP nonce because then it wouldn't
   438             # be a nonce.
   437             # be a nonce.
   439             if rctx.configbool('web', 'cache') and not rctx.nonce:
   438             if rctx.configbool('web', 'cache') and not rctx.nonce:
   440                 caching(self, req) # sets ETag header or raises NOT_MODIFIED
   439                 caching(self, req) # sets ETag header or raises NOT_MODIFIED
   441             if cmd not in webcommands.__all__:
   440             if cmd not in webcommands.__all__:
   442                 msg = 'no such method: %s' % cmd
   441                 msg = 'no such method: %s' % cmd
   443                 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
   442                 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
   444             elif cmd == 'file' and 'raw' in req.form.get('style', []):
   443             elif cmd == 'file' and r'raw' in req.form.get(r'style', []):
   445                 rctx.ctype = ctype
   444                 rctx.ctype = ctype
   446                 content = webcommands.rawfile(rctx, req, tmpl)
   445                 content = webcommands.rawfile(rctx, req, tmpl)
   447             else:
   446             else:
   448                 content = getattr(webcommands, cmd)(rctx, req, tmpl)
   447                 content = getattr(webcommands, cmd)(rctx, req, tmpl)
   449                 req.respond(HTTP_OK, ctype)
   448                 req.respond(HTTP_OK, ctype)