1 ! Copyright (C) 2005, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: assocs http kernel math math.parser namespaces sequences
4 io io.sockets io.streams.string io.files io.timeouts strings
5 splitting calendar continuations accessors vectors math.order
12 fry debugger summary ascii urls present ;
17 ERROR: too-many-redirects ;
19 M: too-many-redirects summary
21 [ "Redirection limit of " % max-redirects # " exceeded" % ] "" make ;
29 : redirect-url ( request url -- request )
30 '[ , >url ensure-port derive-url ensure-port ] change-url ;
32 : do-redirect ( response data -- response data )
33 over code>> 300 399 between? [
36 redirects get max-redirects < [
38 swap "location" header redirect-url
39 "GET" >>method (http-request)
47 : read-chunk-size ( -- n )
48 read-crlf ";" split1 drop [ blank? ] right-trim
49 hex> [ "Bad chunk size" throw ] unless* ;
52 read-chunk-size dup zero?
53 [ drop ] [ read % read-crlf B{ } assert= read-chunks ] if ;
55 : read-response-body ( response -- response data )
56 dup "transfer-encoding" header "chunked" = [
58 [ read-chunks ] B{ } make
59 over content-charset>> decode
61 dup content-charset>> decode-input
62 input-stream get contents
65 : (http-request) ( request -- response data )
67 dup url>> url-addr ascii [
76 : success? ( code -- ? ) 200 = ;
78 ERROR: download-failed response body ;
80 M: download-failed error.
81 "HTTP download failed:" print nl
82 [ response>> write-response-line nl drop ]
86 : check-response ( response data -- response data )
87 over code>> success? [ download-failed ] unless ;
89 : http-request ( request -- response data )
90 (http-request) check-response ;
92 : <get-request> ( url -- request )
95 swap >url ensure-port >>url ;
97 : http-get ( url -- response data )
98 <get-request> http-request ;
100 : download-name ( url -- name )
101 present file-name "?" split1 drop "/" ?tail drop ;
103 : download-to ( url file -- )
104 #! Downloads the contents of a URL to a file.
106 [ content-charset>> ] [ '[ , write ] ] bi*
109 : download ( url -- )
110 dup download-name download-to ;
112 : <post-request> ( post-data url -- request )
115 swap >url ensure-port >>url
118 : http-post ( post-data url -- response data )
119 <post-request> http-request ;