guix_mirror_bot pushed a commit to branch master
in repository guix.
commit 0c5108766ffbd3ae0e6801a9b05694362df789dd
Author: Ludovic Courtès <[email protected]>
AuthorDate: Tue Sep 8 15:20:52 2026 +0200
publish: Use chunked encoding when size is unknown.
* guix/scripts/publish.scm (render-nar): Add ‘Transfer-Encoding’ header.
(nar-compressed-port): Use ‘make-zlib-output-port’ instead of
‘make-gzip-output-port’.
(http-write)[chunk-size]: New variable.
In ‘application/x–nix-archive’ case, call ‘make-chunked-output-port’ instead
of ‘duplicate-port’.
* tests/publish.scm ("/nar/gzip/*"): Change to ‘call-with-zlib-input-port’.
("/nar/gzip/* is really gzip"): Adjust comment accordingly.
Fixes: guix/guix#10190
Reported-by: Vagrant Cascadian <[email protected]>
Suggested-by: Christopher Baines <[email protected]>
Signed-off-by: Ludovic Courtès <[email protected]>
Merges: #11131
---
guix/scripts/publish.scm | 20 +++++++++++++++-----
tests/publish.scm | 12 ++++++------
2 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/guix/scripts/publish.scm b/guix/scripts/publish.scm
index 6f213234e35..3f0087ff6c2 100644
--- a/guix/scripts/publish.scm
+++ b/guix/scripts/publish.scm
@@ -708,6 +708,11 @@ requested using POOL."
(if (valid-path? store store-path)
(values `((content-type . (application/x-nix-archive
(charset . "ISO-8859-1")))
+
+ ;; Since the size is unknown, 'Content-Length' cannot be
+ ;; provided so we have to fall back to chunked encoding.
+ (transfer-encoding . ((chunked)))
+
(x-nar-compression . ,compression))
;; XXX: We're not returning the actual contents, deferring
;; instead to 'http-write'. This is a hack to work around
@@ -897,9 +902,8 @@ EXP..."
according to COMPRESSION."
(match compression
(($ <compression> 'gzip level)
- ;; Note: We cannot used chunked encoding here because
- ;; 'make-gzip-output-port' wants a file port.
- (make-gzip-output-port port
+ (make-zlib-output-port port
+ #:format 'gzip
#:level level
#:buffer-size %default-buffer-size))
(($ <compression> 'lzip level)
@@ -950,6 +954,10 @@ blocking."
(force-output port)
(poll-set-add! (http-poll-set server) port *events*))
+ (define chunk-size
+ ;; Size in bytes of chunks for chunked transfer encoding.
+ (expt 2 17))
+
(define compression
(assoc-ref (response-headers response) 'x-nar-compression))
@@ -979,8 +987,10 @@ blocking."
;; returned port. This is needed for the
;; keep-alive mechanism.
(nar-compressed-port
- (duplicate-port
- (response-port response) "w+0b")
+ (make-chunked-output-port
+ (response-port response)
+ #:keep-alive? keep-alive?
+ #:buffering chunk-size)
compression))))
;; XXX: Given our ugly workaround for <http://bugs.gnu.org/21093>
;; in 'render-nar', BODY here is just the file name of the store
diff --git a/tests/publish.scm b/tests/publish.scm
index 91576abf139..47a60e7580e 100644
--- a/tests/publish.scm
+++ b/tests/publish.scm
@@ -1,7 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 David Thompson <[email protected]>
;;; Copyright © 2020 by Amar M. Singh <[email protected]>
-;;; Copyright © 2016-2022, 2024 Ludovic Courtès <[email protected]>
+;;; Copyright © 2016-2022, 2024, 2026 Ludovic Courtès <[email protected]>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -262,15 +262,15 @@ FileSize: ~a~%"
(let ((nar (http-get-port
(publish-uri
(string-append "/nar/gzip/" (basename %item))))))
- (call-with-gzip-input-port nar
- (cut restore-file <> temp)))
+ (call-with-zlib-input-port nar
+ (cut restore-file <> temp)
+ #:format 'gzip))
(call-with-input-file temp read-string))))
(test-equal "/nar/gzip/* is really gzip"
%gzip-magic-bytes
- ;; Since 'gzdopen' (aka. 'call-with-gzip-input-port') transparently reads
- ;; uncompressed gzip, the test above doesn't check whether it's actually
- ;; gzip. This is what this test does. See <https://bugs.gnu.org/30184>.
+ ;; Explicitly check whether it's actually gzip.
+ ;; See <https://bugs.gnu.org/30184>.
(let ((nar (http-get-port
(publish-uri
(string-append "/nar/gzip/" (basename %item))))))