factor/extra/http/client/client.factor

96 lines
2.7 KiB
Factor
Raw Normal View History

! Copyright (C) 2005, 2008 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: assocs http kernel math math.parser namespaces sequences
2008-02-09 22:34:42 -05:00
io io.sockets io.streams.string io.files io.timeouts strings
2008-03-07 16:52:41 -05:00
splitting calendar continuations accessors vectors io.encodings.latin1
io.encodings.binary ;
2007-09-20 18:09:08 -04:00
IN: http.client
2008-02-25 15:53:18 -05:00
: parse-url ( url -- resource host port )
"http://" ?head [ "Only http:// supported" throw ] unless
2008-01-14 20:49:13 -05:00
"/" split1 [ "/" swap append ] [ "/" ] if*
2008-02-25 15:53:18 -05:00
swap parse-host ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
<PRIVATE
2008-01-14 20:49:13 -05:00
2008-02-25 15:53:18 -05:00
: store-path ( request path -- request )
"?" split1 >r >>path r> dup [ query>assoc ] when >>query ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
! This is all pretty complex because it needs to handle
! HTTP redirects, which might be absolute or relative
: request-with-url ( url request -- request )
clone dup "request" set
swap parse-url >r >r store-path r> >>host r> >>port ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
DEFER: (http-request)
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
: absolute-redirect ( url -- request )
"request" get request-with-url ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
: relative-redirect ( path -- request )
"request" get swap store-path ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
: do-redirect ( response -- response stream )
dup response-code 300 399 between? [
2008-02-29 01:57:38 -05:00
header>> "location" swap at
2008-02-25 15:53:18 -05:00
dup "http://" head? [
absolute-redirect
] [
relative-redirect
] if "GET" >>method (http-request)
] [
stdio get
] if ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
: (http-request) ( request -- response stream )
2008-03-07 16:52:41 -05:00
dup host>> over port>> <inet> latin1 <client> stdio set
2008-02-29 01:57:38 -05:00
dup "r" set-global write-request flush read-response
2008-02-25 15:53:18 -05:00
do-redirect ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
PRIVATE>
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
: http-request ( url request -- response stream )
[
request-with-url
[
(http-request)
1 minutes over set-timeout
] [ ] [ stdio get dispose ] cleanup
] with-scope ;
2008-02-25 15:53:18 -05:00
: <get-request> ( -- request )
2008-02-29 01:57:38 -05:00
<request> "GET" >>method ;
2008-02-25 15:53:18 -05:00
: http-get-stream ( url -- response stream )
<get-request> http-request ;
2007-09-20 18:09:08 -04:00
: success? ( code -- ? ) 200 = ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
: check-response ( response stream -- stream )
swap code>> success?
[ dispose "HTTP download failed" throw ] unless ;
: http-get ( url -- string )
http-get-stream check-response contents ;
: download-name ( url -- name )
file-name "?" split1 drop "/" ?tail drop ;
: download-to ( url file -- )
2007-09-20 18:09:08 -04:00
#! Downloads the contents of a URL to a file.
2008-02-25 15:53:18 -05:00
swap http-get-stream check-response
[ swap binary <file-writer> stream-copy ] with-disposal ;
: download ( url -- )
dup download-name download-to ;
2007-09-20 18:09:08 -04:00
2008-02-25 15:53:18 -05:00
: <post-request> ( content-type content -- request )
2008-02-29 01:57:38 -05:00
<request>
2008-02-25 15:53:18 -05:00
"POST" >>method
swap >>post-data
swap >>post-data-type ;
: http-post ( content-type content url -- response string )
#! The content is URL encoded for you.
-rot url-encode <post-request> http-request contents ;