Subject: Re: bug#15227: Possible bug in (web server)

From: Ian Price <[email-masked]>
Date: Fri, 13 Sep 2013 14:36:04 +0100

Shane Celis <[email-masked]> writes:

> ;; GNU/Linux bug
> ;; ------------
> ;; 
> ;; Info
> ;; ----
> ;;
> ;; $ uname -a
> ;; Linux debian 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1 i686 GNU/Linux
> ;;
> ;; $ guile --version
> ;; guile (GNU Guile) 2.0.9 [...]
> ;;
> ;; $ bash ./build-aux/config.guess
> ;; i686-pc-linux-gnu
> ;;
> ;; $ ./config.status --config
> ;;
> ;; Running
> ;; -------
> ;;
> ;; $ ./guile-web-server-osx-bug.scm server 
> ;; Web server replied 'Hello World! 0'.
> ;;
> ;; ---
> ;;
> ;; $ ./guile-web-server-osx-bug.scm client
> ;; Getting http://gnu.org... response #<<response> [...]
> ;;
> ;; Getting http://fsf.org... response #<<response> [...]
> ;;
> ;; Getting http://localhost:8080...SIGALRM called; timedout.
> ;;
> ;; If I try to connect to http://localhost:8080 through a web browser,
> ;; it works fine; so it seems like the (web client) is not working on
> ;; GNU/Linux and the (web server) is not working on Mac OS X.
> ;; 
If I run the client under strace I get

read(13, "HTTP/1.1 200 OK\r\nContent-Length: 15\r\nContent-Type: text/plain;charset=utf-8\r\n\r\nHello World! 22", 4096) = 94
read(13, 0xa1ec000, 4096)               = ? ERESTARTSYS (To be restarted if SA_RESTART is set)

so even though we've read all the data that's needed, we're still making
another call to read and blocking.

One problem was that read-response-body was making a call to
get-bytevector-all, but even after changing it to

(define (read-response-body r)
  "Reads the response body from R, as a bytevector.  Returns
‘#f’ if there was no response body."
  (let ((body (and=> (response-body-port r #:decode? #f)
                     (lambda (p)
                       (cond ((response-content-length r) =>
                              (lambda (n)
                                (get-bytevector-n p n)))
                             (else (get-bytevector-all p)))))))
    ;; Reading a body of length 0 will result in get-bytevector-all
    ;; returning the EOF object.
    (if (eof-object? body)
        #vu8()
        body)))

I'm still seeing the same behaviour. (I did check and the
get-bytevector-n case is definitely being ran)

So, I'm guessing the problem lies in the C code for handling ports,
and/or for handling sockets.

No idea why it doesn't happen on web calls but only localhost.

Aside:
The above change to read-response-body has not been committed. I'm
undecided as to whether or not read-response-body should handle checking
the size of the content body. Currently it doesn't, but we have separate
code for doing that in (web client), so maybe not. But it might be an
idea to document that read-response-body may return less bytes than the
content length.

-- 
Ian Price -- shift-reset.com

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"