summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2020-11-04 15:57:00 +0100
committerLudovic Courtès <ludo@gnu.org>2020-11-04 16:02:53 +0100
commit5e7cf66fb35780f930ad0bc5fe21ac330df4411d (patch)
treeb4604b178b43e29e136635333a7716579f02dbab
parent95024494f31c3176bcd2238662e7b7868acc2882 (diff)
downloadguix-5e7cf66fb35780f930ad0bc5fe21ac330df4411d.tar.gz
publish: Do not path the empty string to 'query-path-info'.
Fixes <https://bugs.gnu.org/44442>.
Regression introduced in 2b2ab7796ac186d88060793b8873fc0e21462758.

* guix/scripts/publish.scm (render-nar/cached): Do not call
'bypass-cache?' when ITEM is the empty string.
* tests/publish.scm ("with cache, cache bypass, unmapped hash part"):
New test.
-rw-r--r--guix/scripts/publish.scm3
-rw-r--r--tests/publish.scm35
2 files changed, 37 insertions, 1 deletions
diff --git a/guix/scripts/publish.scm b/guix/scripts/publish.scm
index 9706b52844..e8faf379e2 100644
--- a/guix/scripts/publish.scm
+++ b/guix/scripts/publish.scm
@@ -681,7 +681,8 @@ return it; otherwise, return 404.  When TTL is true, use it as the
                   (item (and hash
                              (guard (c ((store-error? c) #f))
                                (hash-part->path store hash)))))
-             (and item (bypass-cache? store item)))
+             (and item (not (string-null? item))
+                  (bypass-cache? store item)))
            ;; Render STORE-ITEM live.  We reach this because STORE-ITEM is
            ;; being baked but clients are already asking for it.  Thus, we're
            ;; duplicating work, but doing so allows us to reduce delays.
diff --git a/tests/publish.scm b/tests/publish.scm
index 84aa6e5d73..e46e6256b7 100644
--- a/tests/publish.scm
+++ b/tests/publish.scm
@@ -622,6 +622,41 @@ References: ~%"
                           (stat:size (stat item)))
                        (response-code response))))))))))
 
+(test-equal "with cache, cache bypass, unmapped hash part"
+  200
+
+  ;; This test reproduces the bug described in <https://bugs.gnu.org/44442>:
+  ;; the daemon connection would be closed as a side effect of a nar request
+  ;; for a non-existing file name.
+  (call-with-temporary-directory
+   (lambda (cache)
+     (let ((thread (with-separate-output-ports
+                    (call-with-new-thread
+                     (lambda ()
+                       (guix-publish "--port=6787" "-C" "gzip"
+                                     (string-append "--cache=" cache)))))))
+       (wait-until-ready 6787)
+
+       (let* ((base     "http://localhost:6787/")
+              (item     (add-text-to-store %store "random" (random-text)))
+              (part     (store-path-hash-part item))
+              (narinfo  (string-append base part ".narinfo"))
+              (nar      (string-append base "nar/gzip/" (basename item)))
+              (cached   (string-append cache "/gzip/" (basename item)
+                                       ".narinfo")))
+         ;; The first response used to be 500 and to terminate the daemon
+         ;; connection as a side effect.
+         (and (= (response-code
+                  (http-get (string-append base "nar/gzip/"
+                                           (make-string 32 #\e)
+                                           "-does-not-exist")))
+                 404)
+              (= 200 (response-code (http-get nar)))
+              (= 200 (response-code (http-get narinfo)))
+              (begin
+                (wait-for-file cached)
+                (response-code (http-get nar)))))))))
+
 (test-equal "/log/NAME"
   `(200 #t application/x-bzip2)
   (let ((drv (run-with-store %store