From mboxrd@z Thu Jan 1 00:00:00 1970 From: ludo@gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) Subject: Re: cannot fetch narinfo with HTTP pipelining Date: Wed, 08 Apr 2015 12:02:38 +0200 Message-ID: <87a8yj0wg1.fsf@gnu.org> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:38627) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yfmoq-0002tj-5g for guix-devel@gnu.org; Wed, 08 Apr 2015 06:02:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yfmok-0001w6-IG for guix-devel@gnu.org; Wed, 08 Apr 2015 06:02:48 -0400 Received: from fencepost.gnu.org ([2001:4830:134:3::e]:43871) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yfmok-0001w2-Et for guix-devel@gnu.org; Wed, 08 Apr 2015 06:02:42 -0400 In-Reply-To: (Ricardo Wurmus's message of "Wed, 8 Apr 2015 11:02:24 +0200") List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: Ricardo Wurmus Cc: Guix-devel --=-=-= Content-Type: text/plain Ricardo Wurmus skribis: > The numbers in the `bad-response' error message differ for different > operations. In all cases the first number (here 403) is larger than the > second (here 15). The second number is the reported content length. That rings a bell. Could you try this patch? --=-=-= Content-Type: text/x-patch Content-Disposition: inline diff --git a/guix/http-client.scm b/guix/http-client.scm index 051fcee..abd9e64 100644 --- a/guix/http-client.scm +++ b/guix/http-client.scm @@ -135,6 +135,47 @@ closed it will also close PORT, unless the KEEP-ALIVE? is true." (when (module-variable %web-http 'read-chunk-body) (module-set! %web-http 'make-chunked-input-port make-chunked-input-port)) + (define (make-delimited-input-port port len keep-alive?) + "Return an input port that reads from PORT, and makes sure that +exactly LEN bytes are available from PORT. Closing the returned port +closes PORT, unless KEEP-ALIVE? is true." + (define bytes-read 0) + + (define (fail) + ((@@ (web response) bad-response) + "EOF while reading response body: ~a bytes of ~a" + bytes-read len)) + + (define (read! bv start count) + ;; Read at most LEN bytes in total. HTTP/1.1 doesn't say what to do + ;; when a server provides more than the Content-Length, but it seems + ;; wise to just stop reading at LEN. + (let ((count (min count (- len bytes-read)))) + (let loop ((ret (get-bytevector-n! port bv start count))) + (cond ((eof-object? ret) + (if (= bytes-read len) + 0 ; EOF + (fail))) + ((and (zero? ret) (> count 0)) + ;; Do not return zero since zero means EOF, so try again. + (loop (get-bytevector-n! port bv start count))) + (else + (set! bytes-read (+ bytes-read ret)) + ret))))) + + (define close + (and (not keep-alive?) + (lambda () + (close port)))) + + (make-custom-binary-input-port "delimited input port" read! #f #f close)) + + (unless (guile-version>? "2.0.9") + ;; Guile <= 2.0.9 had a bug whereby 'response-body-port' would read more + ;; than what 'content-length' says. See Guile commit 802a25b. + (module-set! (resolve-interface '(web response)) + 'make-delimited-input-port make-delimited-input-port)) + (define (read-response-body* r) "Reads the response body from @var{r}, as a bytevector. Returns @code{#f} if there was no response body." --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Anyone using Guile < 2.0.11 is welcome to test this and report success or failure! Thanks, Ludo=E2=80=99. --=-=-=--