summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2012-11-28 22:50:26 +0100
committerLudovic Courtès <ludo@gnu.org>2012-11-28 22:50:26 +0100
commit91e693a8e8a9d6d7841b189171829ed1c91a01d1 (patch)
tree8463d799fa94c8112cbcbf3eab672785a87000af
parent75d6c59fc25cdcc02f19b626961d46a96bb33234 (diff)
downloadguile-91e693a8e8a9d6d7841b189171829ed1c91a01d1.tar.gz
web: Add `http-get*'.
* module/web/client.scm (http-get*): New procedure. * doc/ref/web.texi (Web Client): Document it.
-rw-r--r--doc/ref/web.texi7
-rw-r--r--module/web/client.scm25
2 files changed, 31 insertions, 1 deletions
diff --git a/doc/ref/web.texi b/doc/ref/web.texi
index 3b53ccdd6..e892453e3 100644
--- a/doc/ref/web.texi
+++ b/doc/ref/web.texi
@@ -1400,6 +1400,13 @@ response will be decoded to string, if it is a textual content-type.
Otherwise it will be returned as a bytevector.
@end deffn
+@deffn {Scheme Procedure} http-get* uri [#:port=(open-socket-for-uri uri)] [#:version='(1 . 1)] [#:keep-alive?=#f] [#:extra-headers='()] [#:decode-body?=#t]
+Like @code{http-get}, but return an input port from which to read. When
+@var{decode-body?} is true, as is the default, the returned port has its
+encoding set appropriately if the data at @var{uri} is textual. Closing the
+returned port closes @var{port}, unless @var{keep-alive?} is true.
+@end deffn
+
@code{http-get} is useful for making one-off requests to web sites. If
you are writing a web spider or some other client that needs to handle a
number of requests in parallel, it's better to build an event-driven URL
diff --git a/module/web/client.scm b/module/web/client.scm
index d9dff0322..df0a74900 100644
--- a/module/web/client.scm
+++ b/module/web/client.scm
@@ -39,7 +39,8 @@
#:use-module (web response)
#:use-module (web uri)
#:export (open-socket-for-uri
- http-get))
+ http-get
+ http-get*))
(define (open-socket-for-uri uri)
"Return an open input/output port for a connection to URI."
@@ -135,3 +136,25 @@ Otherwise it will be returned as a bytevector."
(if decode-body?
(decode-response-body res body)
body)))))
+
+(define* (http-get* uri #:key (port (open-socket-for-uri uri))
+ (version '(1 . 1)) (keep-alive? #f) (extra-headers '())
+ (decode-body? #t))
+ "Like ‘http-get’, but return an input port from which to read. When
+DECODE-BODY? is true, as is the default, the returned port has its
+encoding set appropriately if the data at URI is textual. Closing the
+returned port closes PORT, unless KEEP-ALIVE? is true."
+ (let ((req (build-request uri #:version version
+ #:headers (if keep-alive?
+ extra-headers
+ (cons '(connection close)
+ extra-headers)))))
+ (write-request req port)
+ (force-output port)
+ (unless keep-alive?
+ (shutdown port 1))
+ (let* ((res (read-response port))
+ (body (response-body-port res
+ #:keep-alive? keep-alive?
+ #:decode? decode-body?)))
+ (values res body))))