in eden/scm/edenscm/mercurial/hgweb/hgweb_mod.py [0:0]
def _runwsgi(self, req, repo):
rctx = requestcontext(self, repo)
# This state is global across all threads.
encoding.encoding = rctx.config("web", "encoding")
rctx.repo.ui.environ = req.env
if rctx.csp:
# hgwebdir may have added CSP header. Since we generate our own,
# replace it.
req.headers = [h for h in req.headers if h[0] != "Content-Security-Policy"]
req.headers.append(("Content-Security-Policy", rctx.csp))
# work with CGI variables to create coherent structure
# use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
req.url = req.env[r"SCRIPT_NAME"]
if not req.url.endswith("/"):
req.url += "/"
if req.env.get("REPO_NAME"):
req.url += req.env[r"REPO_NAME"] + r"/"
if r"PATH_INFO" in req.env:
parts = req.env[r"PATH_INFO"].strip("/").split("/")
repo_parts = req.env.get(r"REPO_NAME", r"").split(r"/")
if parts[: len(repo_parts)] == repo_parts:
parts = parts[len(repo_parts) :]
query = "/".join(parts)
else:
query = req.env[r"QUERY_STRING"].partition(r"&")[0]
query = query.partition(r";")[0]
# process this if it's a protocol request
# protocol bits don't need to create any URLs
# and the clients always use the old URL structure
cmd = req.form.get(r"cmd", [r""])[0]
if protocol.iscmd(cmd):
try:
if query:
raise ErrorResponse(HTTP_NOT_FOUND)
if cmd in perms:
self.check_perm(rctx, req, perms[cmd])
return protocol.call(rctx.repo, req, cmd)
except ErrorResponse as inst:
# A client that sends unbundle without 100-continue will
# break if we respond early.
if (
cmd == "unbundle"
and (req.env.get("HTTP_EXPECT", "").lower() != "100-continue")
or req.env.get("X-HgHttp2", "")
):
req.drain()
else:
req.headers.append((r"Connection", r"Close"))
req.respond(inst, protocol.HGTYPE, body="0\n%s\n" % inst)
return ""
# translate user-visible url structure to internal structure
args = query.split("/", 2)
if r"cmd" not in req.form and args and args[0]:
cmd = args.pop(0)
style = cmd.rfind("-")
if style != -1:
req.form["style"] = [cmd[:style]]
cmd = cmd[style + 1 :]
# avoid accepting e.g. style parameter as command
if util.safehasattr(webcommands, cmd):
req.form[r"cmd"] = [cmd]
if cmd == "static":
req.form["file"] = ["/".join(args)]
else:
if args and args[0]:
node = args.pop(0).replace("%2F", "/")
req.form["node"] = [node]
if args:
req.form["file"] = args
ua = req.env.get("HTTP_USER_AGENT", "")
if cmd == "rev" and "mercurial" in ua:
req.form["style"] = ["raw"]
if cmd == "archive":
fn = req.form["node"][0]
for type_, spec in pycompat.iteritems(rctx.archivespecs):
ext = spec[2]
if fn.endswith(ext):
req.form["node"] = [fn[: -len(ext)]]
req.form["type"] = [type_]
# process the web interface request
try:
tmpl = rctx.templater(req)
ctype = tmpl("mimetype", encoding=encoding.encoding)
ctype = templater.stringify(ctype)
# check read permissions non-static content
if cmd != "static":
self.check_perm(rctx, req, None)
if cmd == "":
req.form[r"cmd"] = [tmpl.cache["default"]]
cmd = req.form[r"cmd"][0]
# Don't enable caching if using a CSP nonce because then it wouldn't
# be a nonce.
if rctx.configbool("web", "cache") and not rctx.nonce:
caching(self, req) # sets ETag header or raises NOT_MODIFIED
if cmd not in webcommands.__all__:
msg = "no such method: %s" % cmd
raise ErrorResponse(HTTP_BAD_REQUEST, msg)
elif cmd == "file" and r"raw" in req.form.get(r"style", []):
rctx.ctype = ctype
content = webcommands.rawfile(rctx, req, tmpl)
else:
content = getattr(webcommands, cmd)(rctx, req, tmpl)
req.respond(HTTP_OK, ctype)
return content
except (error.LookupError, error.RepoLookupError) as err:
req.respond(HTTP_NOT_FOUND, ctype)
msg = str(err)
if util.safehasattr(err, "name") and not isinstance(
err, error.ManifestLookupError
):
msg = "revision not found: %s" % err.name
return tmpl("error", error=msg)
except (error.RepoError, error.RevlogError) as inst:
req.respond(HTTP_SERVER_ERROR, ctype)
return tmpl("error", error=str(inst))
except ErrorResponse as inst:
req.respond(inst, ctype)
if inst.code == HTTP_NOT_MODIFIED:
# Not allowed to return a body on a 304
return [""]
return tmpl("error", error=str(inst))