Using guile's web client
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
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
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
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
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
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" >> > >