Using guile's web client

2012-03-14 Thread Chris Vine
Hi,

I have been playing around with guile-2.0.5's high-level web modules.
In order to see if I understood them, I tried about the simplest thing
I could think of: a GET request to checkip.dyndns.com to obtain my IP
address.

The following code works correctly provided I leave the commented out
code commented out:

(use-modules
 (web uri)
 (web response)
 (rnrs bytevectors)
 (web client))

((lambda()
   (let ((uri (build-uri 'http
 #:host "checkip.dyndns.com"
 #:port 80
 #:path "/")))
 (display uri)
 (newline)
 (let ((r (http-get uri #:keep-alive? #t)))
   (if r
   (begin
 (display r)(newline)
;;   (display (read-response-body r))(newline)
 )
   (begin
 (display "Can't obtain response body")
 (newline)))

It outputs:

#< scheme: http userinfo: #f host: "checkip.dyndns.com" port: 80 path: "/" 
query: #f fragment: #f>
#< version: (1 . 1) code: 200 reason-phrase: "OK" headers: 
((content-type text/html) (server . "DynDNS-CheckIP/1.0") (connection close) 
(cache-control no-cache) (pragma no-cache) (content-length . 105)) port: 
#>

The contents of the response object mirrors the response obtained by
node.js with the equivalent code written in javascript, including the
content length, so the response object appears to be correct.  However,
if I try to obtain the response body by uncommenting the call to
read-response-body, I get an error:

Backtrace:
In ice-9/boot-9.scm:
 149: 10 [catch #t # ...]
 157: 9 [#]
In unknown file:
   ?: 8 [catch-closure]
In ice-9/boot-9.scm:
  63: 7 [call-with-prompt prompt0 ...]
In ice-9/eval.scm:
 407: 6 [eval # #]
In ice-9/boot-9.scm:
2111: 5 [save-module-excursion #]
3653: 4 [#]
In unknown file:
   ?: 3 [load-compiled/vm 
"/home/chris/.cache/guile/ccache/2.0-LE-4-2.0/home/chris/src/scheme/my-ip-test.scm.go"]
In /home/chris/src/scheme/my-ip-test.scm:
  18: 2 [#]
In web/response.scm:
 223: 1 [read-response-body #]
In unknown file:
   ?: 0 [bytevector-length #]

ERROR: In procedure bytevector-length:
ERROR: In procedure scm_c_bytevector_length: Wrong type argument in position 1 
(expecting bytevector): #

The error is in the procedure call to read-response-body.  Is this a
bug in guile-2, or am I doing something wrong?

Chris



Re: Using guile's web client

2012-03-14 Thread Ian Price
Chris Vine  writes:

> ((lambda()
>(let ((uri (build-uri 'http
>  #:host "checkip.dyndns.com"
>  #:port 80
>  #:path "/")))
>  (display uri)
>  (newline)
>  (let ((r (http-get uri #:keep-alive? #t)))
^^ there's your problem
>(if r
>(begin
>  (display r)(newline)
> ;;   (display (read-response-body r))(newline)
>  )
>(begin
>  (display "Can't obtain response body")
>  (newline)))
snip.

>
> The error is in the procedure call to read-response-body.  Is this a
> bug in guile-2, or am I doing something wrong?
It's actually debatable whether or not this is your fault :). http-get
returns 2 values: the response and the body. When you call
read-response-body on the port, you are trying to read information that
has already been read, and so it is coming up with an (eof-object)
rather than the body. However, I notice that the manual doesn't actually
say that it returns two values, so that'll need to be fixed.

The correct way to write this code snippet is to use call-with-values
(or sugar such as receive or let-values), instead of let.

(let ((uri (build-uri 'http
  #:host "checkip.dyndns.com"
  #:port 80
  #:path "/")))
  (call-with-values
  (lambda ()
(http-get uri #:keep-alive? #t))
(lambda (request body)
  ...)))

the request should (I think) always be a request object, so you don't
need to check it with if. Though, the body may be #f, so it's worth
checking that.


-- 
Ian Price

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



Re: Using guile's web client

2012-03-14 Thread Nala Ginrut
I'm afraid it's a real bug.
read-response-body didn't check  before it call bytevector-length.
But actually, all the data has already been read. When it encounters ,
it should return the body immediately. The bug is, it checks
bytevector-length first which cause (bytevector-length ).
I didn't realize this bug before, because I read the body by block which
always constrains the bytevector length within the range of content-length.

But I'm not going to send a patch for this bug. Because I've sent another
patch to rewrite the whole read-response-body which get rid of this bug
already. And it will return the received body data when any error or break
happens. The old one didn't do this job.
Here is the thread:
http://lists.gnu.org/archive/html/guile-devel/2012-03/msg00116.html
What do you think?

Regard.

On Thu, Mar 15, 2012 at 8:05 AM, Chris Vine wrote:

> Hi,
>
> I have been playing around with guile-2.0.5's high-level web modules.
> In order to see if I understood them, I tried about the simplest thing
> I could think of: a GET request to checkip.dyndns.com to obtain my IP
> address.
>
> The following code works correctly provided I leave the commented out
> code commented out:
>
> (use-modules
>  (web uri)
>  (web response)
>  (rnrs bytevectors)
>  (web client))
>
> ((lambda()
>   (let ((uri (build-uri 'http
> #:host "checkip.dyndns.com"
> #:port 80
> #:path "/")))
> (display uri)
> (newline)
> (let ((r (http-get uri #:keep-alive? #t)))
>   (if r
>   (begin
> (display r)(newline)
> ;;   (display (read-response-body r))(newline)
> )
>   (begin
> (display "Can't obtain response body")
> (newline)))
>
> It outputs:
>
> #< scheme: http userinfo: #f host: "checkip.dyndns.com" port: 80
> path: "/" query: #f fragment: #f>
> #< version: (1 . 1) code: 200 reason-phrase: "OK" headers:
> ((content-type text/html) (server . "DynDNS-CheckIP/1.0") (connection
> close) (cache-control no-cache) (pragma no-cache) (content-length . 105))
> port: #>
>
> The contents of the response object mirrors the response obtained by
> node.js with the equivalent code written in javascript, including the
> content length, so the response object appears to be correct.  However,
> if I try to obtain the response body by uncommenting the call to
> read-response-body, I get an error:
>
> Backtrace:
> In ice-9/boot-9.scm:
>  149: 10 [catch #t # ...]
>  157: 9 [#]
> In unknown file:
>   ?: 8 [catch-closure]
> In ice-9/boot-9.scm:
>  63: 7 [call-with-prompt prompt0 ...]
> In ice-9/eval.scm:
>  407: 6 [eval # #]
> In ice-9/boot-9.scm:
> 2111: 5 [save-module-excursion # ice-9/boot-9.scm:3646:3 ()>]
> 3653: 4 [#]
> In unknown file:
>   ?: 3 [load-compiled/vm
> "/home/chris/.cache/guile/ccache/2.0-LE-4-2.0/home/chris/src/scheme/my-ip-test.scm.go"]
> In /home/chris/src/scheme/my-ip-test.scm:
>  18: 2 [#]
> In web/response.scm:
>  223: 1 [read-response-body #]
> In unknown file:
>   ?: 0 [bytevector-length #]
>
> ERROR: In procedure bytevector-length:
> ERROR: In procedure scm_c_bytevector_length: Wrong type argument in
> position 1 (expecting bytevector): #
>
> The error is in the procedure call to read-response-body.  Is this a
> bug in guile-2, or am I doing something wrong?
>
> Chris
>
>


Re: Using guile's web client

2012-03-14 Thread Ian Price
Nala Ginrut  writes:

> I'm afraid it's a real bug.
No, it's not. See my response to him. :)

-- 
Ian Price

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



Re: Using guile's web client

2012-03-14 Thread Nala Ginrut
I must say NO to NO.
You may try http-get directly in this situation and see if it returns. No
matter how you handle the values, it never return because of the error I
mentioned.

On Thu, Mar 15, 2012 at 10:11 AM, Ian Price wrote:

> Nala Ginrut  writes:
>
> > I'm afraid it's a real bug.
> No, it's not. See my response to him. :)
>
> --
> Ian Price
>
> "Programming is like pinball. The reward for doing it well is
> the opportunity to do it again" - from "The Wizardy Compiled"
>


Re: Using guile's web client

2012-03-14 Thread Nala Ginrut
To clarify, he used wrong usage of http-get is another issue need to be
noticed.

On Thu, Mar 15, 2012 at 11:55 AM, Nala Ginrut  wrote:

> I must say NO to NO.
> You may try http-get directly in this situation and see if it returns. No
> matter how you handle the values, it never return because of the error I
> mentioned.
>
>
> On Thu, Mar 15, 2012 at 10:11 AM, Ian Price wrote:
>
>> Nala Ginrut  writes:
>>
>> > I'm afraid it's a real bug.
>> No, it's not. See my response to him. :)
>>
>> --
>> Ian Price
>>
>> "Programming is like pinball. The reward for doing it well is
>> the opportunity to do it again" - from "The Wizardy Compiled"
>>
>
>