[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
05/14: http-client: Add error handling to http-multiple-get.
From: |
guix-commits |
Subject: |
05/14: http-client: Add error handling to http-multiple-get. |
Date: |
Mon, 22 Feb 2021 15:44:45 -0500 (EST) |
cbaines pushed a commit to branch master
in repository guix.
commit 205833b72c5517915a47a50dbe28e7024dc74e57
Author: Christopher Baines <mail@cbaines.net>
AuthorDate: Thu Jan 7 19:40:43 2021 +0000
http-client: Add error handling to http-multiple-get.
Making sure to close the port if it looks to be unusable. This closing of
the
port will allow for caching connections, without caching broken connections,
as the cache can avoid handing out closed ports.
* guix/http-client.scm (http-multiple-get): Try to catch exceptions that
happen if the port is unusable, this is a adaptation of code within the
(guix
scripts substitute) module.
---
guix/http-client.scm | 74 +++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 56 insertions(+), 18 deletions(-)
diff --git a/guix/http-client.scm b/guix/http-client.scm
index 7ead493..3aba3b2 100644
--- a/guix/http-client.scm
+++ b/guix/http-client.scm
@@ -38,6 +38,7 @@
#:use-module (guix utils)
#:use-module (guix base64)
#:autoload (gcrypt hash) (sha256)
+ #:autoload (gnutls) (error/invalid-session)
#:use-module ((guix build utils)
#:select (mkdir-p dump-port))
#:use-module ((guix build download)
@@ -180,10 +181,25 @@ returning."
;; Inherit the HTTP proxying property from P.
(set-http-proxy-port?! buffer (http-proxy-port? p))
- (for-each (cut write-request <> buffer)
- batch)
- (put-bytevector p (get))
- (force-output p))
+ (catch #t
+ (lambda ()
+ (for-each (cut write-request <> buffer)
+ batch)
+ (put-bytevector p (get))
+ (force-output p))
+ (lambda (key . args)
+ ;; If PORT becomes unusable, open a fresh connection and
+ ;; retry.
+ (if (or (and (eq? key 'system-error)
+ (= EPIPE (system-error-errno `(,key ,@args))))
+ (and (eq? key 'gnutls-error)
+ (eq? (first args) error/invalid-session)))
+ (begin
+ (close-port p) ; close the broken port
+ (connect #f
+ requests
+ result))
+ (apply throw key args)))))
;; Now start processing responses.
(let loop ((sent batch)
@@ -199,20 +215,42 @@ returning."
(remainder
(connect p remainder result))))
((head tail ...)
- (let* ((resp (read-response p))
- (body (response-body-port resp))
- (result (proc head resp body result)))
- ;; The server can choose to stop responding at any time, in which
- ;; case we have to try again. Check whether that is the case.
- ;; Note that even upon "Connection: close", we can read from BODY.
- (match (assq 'connection (response-headers resp))
- (('connection 'close)
- (close-port p)
- (connect #f ;try again
- (drop requests (+ 1 processed))
- result))
- (_
- (loop tail (+ 1 processed) result)))))))))) ;keep going
+ (catch #t
+ (lambda ()
+ (let* ((resp (read-response p))
+ (body (response-body-port resp))
+ (result (proc head resp body result)))
+ ;; The server can choose to stop responding at any time,
+ ;; in which case we have to try again. Check whether
+ ;; that is the case. Note that even upon "Connection:
+ ;; close", we can read from BODY.
+ (match (assq 'connection (response-headers resp))
+ (('connection 'close)
+ (close-port p)
+ (connect #f ;try again
+ (drop requests (+ 1 processed))
+ result))
+ (_
+ (loop tail (+ 1 processed) result))))) ;keep going
+ (lambda (key . args)
+ ;; If PORT was cached and the server closed the connection
+ ;; in the meantime, we get EPIPE. In that case, open a
+ ;; fresh connection and retry. We might also get
+ ;; 'bad-response or a similar exception from (web response)
+ ;; later on, once we've sent the request, or a
+ ;; ERROR/INVALID-SESSION from GnuTLS.
+ (if (or (and (eq? key 'system-error)
+ (= EPIPE (system-error-errno `(,key ,@args))))
+ (and (eq? key 'gnutls-error)
+ (eq? (first args) error/invalid-session))
+ (memq key
+ '(bad-response bad-header bad-header-component)))
+ (begin
+ (close-port p)
+ (connect #f ; try again
+ (drop requests (+ 1 processed))
+ result))
+ (apply throw key args))))))))))
;;;
- branch master updated (f1f6e49 -> 20c08a8), guix-commits, 2021/02/22
- 01/14: substitute: Remove buffer handling from fetch., guix-commits, 2021/02/22
- 02/14: substitute: Remove connection handling from fetch., guix-commits, 2021/02/22
- 03/14: substitute: Remove redundant let block from fetch., guix-commits, 2021/02/22
- 04/14: guix: Move http-multiple-get to (guix http-client)., guix-commits, 2021/02/22
- 05/14: http-client: Add error handling to http-multiple-get.,
guix-commits <=
- 06/14: substitute: open-connection-for-uri/maybe add #:verify-certificate?., guix-commits, 2021/02/22
- 10/14: substitute: Remove now redundant connection caching helpers., guix-commits, 2021/02/22
- 08/14: http-client: Accept #:open-connection in http-fetch., guix-commits, 2021/02/22
- 07/14: substitute: Stop using call-with-cached-connection in fetch-narinfos., guix-commits, 2021/02/22
- 09/14: substitute: Change connection cache handling in process-substitution., guix-commits, 2021/02/22
- 13/14: substitute: Remove fetch-narinfos use open-connection-for-uri/maybe., guix-commits, 2021/02/22
- 11/14: substitute: Remove redundant fetch arguments., guix-commits, 2021/02/22
- 12/14: substitute: Inline fetch in to process-substitutes., guix-commits, 2021/02/22
- 14/14: substitute: Rework connection error handling., guix-commits, 2021/02/22