summaryrefslogtreecommitdiff
path: root/doc/invocations-http-server
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2025-04-24 11:51:32 +0200
committerKlaus Aehlig <klaus.aehlig@huawei.com>2025-04-24 12:03:09 +0200
commit5615498846307cb8f08e5485e5091cda7969d502 (patch)
tree9d22a6a8e51170f53d9941abe333c21d329ee2cb /doc/invocations-http-server
parent52002f63955ec211d1b1508eb5b9f9dd195d5ebf (diff)
downloadjustbuild-5615498846307cb8f08e5485e5091cda7969d502.tar.gz
Invocation server: support download of all blobs
For many text files it is useful to read them directly in the browser. However, many files that are better analysed by machines (like large repository configurations) also come as plain-text files. Therefore, always offer to download a file currently being viewed. Use the URL scheme in such a way that the name to download the file as can be specified; in this way, we are prepared if we decide to also log the artifacts to be built and offer those to be downloaded.
Diffstat (limited to 'doc/invocations-http-server')
-rwxr-xr-xdoc/invocations-http-server/server.py18
-rw-r--r--doc/invocations-http-server/templates/blob.html2
2 files changed, 17 insertions, 3 deletions
diff --git a/doc/invocations-http-server/server.py b/doc/invocations-http-server/server.py
index 940e03a1..68955841 100755
--- a/doc/invocations-http-server/server.py
+++ b/doc/invocations-http-server/server.py
@@ -36,6 +36,9 @@ class HashIdentifierConverter(werkzeug.routing.BaseConverter):
class InvocationIdentifierConverter(werkzeug.routing.BaseConverter):
regex = '[-:_a-zA-Z0-9]{1,200}'
+class FileIdentifierConverter(werkzeug.routing.BaseConverter):
+ regex = '[-:_.a-zA-Z0-9]{3,200}'
+
class InvocationServer:
def __init__(self, logsdir, *,
just_mr = None,
@@ -59,6 +62,9 @@ class InvocationServer:
rule("/blob/<hashidentifier:blob>",
methods=("GET",),
endpoint="get_blob"),
+ rule("/blob/<hashidentifier:blob>/<fileidentifier:name>",
+ methods=("GET",),
+ endpoint="get_blob_as"),
rule("/tree/<hashidentifier:tree>",
methods=("GET",),
endpoint="get_tree"),
@@ -68,6 +74,7 @@ class InvocationServer:
], converters=dict(
invocationidentifier=InvocationIdentifierConverter,
hashidentifier=HashIdentifierConverter,
+ fileidentifier=FileIdentifierConverter,
))
@Request.application
@@ -132,7 +139,7 @@ class InvocationServer:
pass
return self.render("failure.html", params)
- def do_get_blob(self, blob):
+ def do_get_blob(self, blob, *, download_as=None):
cmd = self.just_mr + ["install-cas", "--remember", blob]
blob_data = subprocess.run(cmd,
stdout=subprocess.PIPE,
@@ -142,17 +149,22 @@ class InvocationServer:
try:
blob_content = blob_data.stdout.decode('utf-8')
except:
- # Not utf-8, so return as binary file
+ # Not utf-8, so return as binary file to download separately
+ download_as = download_as or blob
+ if download_as:
response = Response()
response.content_type = "application/octet-stream"
response.data = blob_data.stdout
response.headers['Content-Disposition'] = \
- "attachement; filename=%s" %(blob,)
+ "attachement; filename=%s" %(download_as,)
return response
return self.render("blob.html",
{"name": blob,
"data": blob_content})
+ def do_get_blob_as(self, blob, name):
+ return self.do_get_blob(blob, download_as=name)
+
def do_get_tree(self, tree):
cmd = self.just_mr + ["install-cas", "%s::t" % (tree,)]
tree_data = subprocess.run(cmd,
diff --git a/doc/invocations-http-server/templates/blob.html b/doc/invocations-http-server/templates/blob.html
index 2a64d064..d88368fe 100644
--- a/doc/invocations-http-server/templates/blob.html
+++ b/doc/invocations-http-server/templates/blob.html
@@ -6,5 +6,7 @@ Blob {{ name | e }}
{% block content %}
<h1>Blob {{ name | e }}</h1>
+<a href="/blob/{{ name | e }}/{{ name | e}}">download</a>
+
<pre>{{ data | e}}</pre>
{% endblock %}