use Content-Digest header in HEAD requests instead of length (to track non-monotone changes);
authorFabian Huch <huch@in.tum.de>
Mon, 03 Jun 2024 19:21:22 +0200
changeset 80243 b2889dd54a2a
parent 80242 5cb9fd414e92
child 80244 885fc1e837ed
use Content-Digest header in HEAD requests instead of length (to track non-monotone changes);
src/Pure/General/http.scala
src/Pure/System/web_app.scala
--- a/src/Pure/General/http.scala	Mon Jun 03 20:56:41 2024 +0100
+++ b/src/Pure/General/http.scala	Mon Jun 03 19:21:22 2024 +0200
@@ -10,6 +10,7 @@
 import java.io.{File => JFile}
 import java.nio.file.Files
 import java.net.{InetSocketAddress, URI, HttpURLConnection}
+import java.util.HexFormat
 import com.sun.net.httpserver.{HttpExchange, HttpHandler, HttpServer}
 
 
@@ -222,7 +223,10 @@
 
     def write(http: HttpExchange, code: Int, is_head: Boolean = false): Unit = {
       http.getResponseHeaders.set("Content-Type", content_type)
-      http.getResponseHeaders.set("Content-Length", output.length.toString)
+      if (is_head) {
+        val encoded_digest = Base64.encode(HexFormat.of().parseHex(SHA1.digest(output).toString))
+        http.getResponseHeaders.set("Content-Digest", "sha=:" + encoded_digest + ":")
+      }
       http.sendResponseHeaders(code, if (is_head) -1 else output.length.toLong)
       if (!is_head) using(http.getResponseBody)(output.write_stream)
     }
--- a/src/Pure/System/web_app.scala	Mon Jun 03 20:56:41 2024 +0100
+++ b/src/Pure/System/web_app.scala	Mon Jun 03 19:21:22 2024 +0200
@@ -407,7 +407,7 @@
 var state = null;
 function heartbeat() {
   fetch(window.location, { method: "HEAD" }).then((http_res) => {
-    const new_state = http_res.headers.get("Content-Length")
+    const new_state = http_res.headers.get("Content-Digest")
     if (state === null) state = new_state
     if (http_res.status === 200 && state !== new_state) {
       state = new_state