[...]
Hello!
I'll land a similar change in Guile's (web client) module afterwards
if there are no objections.
Ludo'.
diff --git a/guix/build/download.scm b/guix/build/download.scm
index 41583e8143..de094890b3 100644
--- a/guix/build/download.scm
+++ b/guix/build/download.scm
@@ -245,6 +245,54 @@ (define (print-tls-certificate-error port key args
default-printer)
(set-exception-printer! 'tls-certificate-error
print-tls-certificate-error)
+(define (wrap-record-port-for-gnutls<3.7.7 record port)
+ "Return a port that wraps RECORD to ensure that closing it also closes PORT,
+the actual socket port, and its file descriptor. Make sure it does not
+introduce extra buffering (custom ports are buffered by default as of Guile
+3.0.5).
+
+This wrapper is unnecessary with GnuTLS >= 3.7.7, which can automatically
+close SESSION's file descriptor when RECORD is closed."
+ (define (read! bv start count)
+ (define read
+ (catch 'gnutls-error
+ (lambda ()
+ (get-bytevector-n! record bv start count))
+ (lambda (key err proc . rest)
+ ;; When responding to "Connection: close" requests, some servers
+ ;; close the connection abruptly after sending the response body,
+ ;; without doing a proper TLS connection termination. Treat it as
+ ;; EOF. This is fixed in GnuTLS 3.7.7.
+ (if (eq? err error/premature-termination)
+ the-eof-object
+ (apply throw key err proc rest)))))