Fix POST with streams to use chunked encoding, add http-put word
parent
c7c37f5f5c
commit
f160771123
|
@ -1,4 +1,4 @@
|
|||
! Copyright (C) 2005, 2008 Slava Pestov.
|
||||
! Copyright (C) 2005, 2009 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors assocs kernel math math.parser namespaces make
|
||||
sequences strings splitting calendar continuations accessors vectors
|
||||
|
@ -10,6 +10,12 @@ io.streams.duplex fry ascii urls urls.encoding present
|
|||
http http.parsers ;
|
||||
IN: http.client
|
||||
|
||||
ERROR: too-many-redirects ;
|
||||
|
||||
CONSTANT: max-redirects 10
|
||||
|
||||
<PRIVATE
|
||||
|
||||
: write-request-line ( request -- request )
|
||||
dup
|
||||
[ method>> write bl ]
|
||||
|
@ -21,17 +27,29 @@ IN: http.client
|
|||
[ host>> ] [ port>> ] bi dup "http" protocol-port =
|
||||
[ drop ] [ ":" swap number>string 3append ] if ;
|
||||
|
||||
: set-post-data-headers ( header post-data -- header )
|
||||
[
|
||||
data>> dup sequence?
|
||||
[ length "content-length" ]
|
||||
[ drop "chunked" "transfer-encoding" ] if
|
||||
pick set-at
|
||||
] [ content-type>> "content-type" pick set-at ] bi ;
|
||||
|
||||
: set-host-header ( request header -- request header )
|
||||
over url>> url-host "host" pick set-at ;
|
||||
|
||||
: set-cookie-header ( header cookies -- header )
|
||||
unparse-cookie "cookie" pick set-at ;
|
||||
|
||||
: write-request-header ( request -- request )
|
||||
dup header>> >hashtable
|
||||
over url>> host>> [ over url>> url-host "host" pick set-at ] when
|
||||
over post-data>> [
|
||||
[ data>> length "content-length" pick set-at ]
|
||||
[ content-type>> "content-type" pick set-at ]
|
||||
bi
|
||||
] when*
|
||||
over cookies>> [ unparse-cookie "cookie" pick set-at ] unless-empty
|
||||
over url>> host>> [ set-host-header ] when
|
||||
over post-data>> [ set-post-data-headers ] when*
|
||||
over cookies>> [ set-cookie-header ] unless-empty
|
||||
write-header ;
|
||||
|
||||
PRIVATE>
|
||||
|
||||
GENERIC: >post-data ( object -- post-data )
|
||||
|
||||
M: f >post-data ;
|
||||
|
@ -51,6 +69,8 @@ M: object >post-data
|
|||
"application/octet-stream" <post-data>
|
||||
swap >>data ;
|
||||
|
||||
<PRIVATE
|
||||
|
||||
: normalize-post-data ( request -- request )
|
||||
dup post-data>> [
|
||||
dup params>> [
|
||||
|
@ -62,11 +82,18 @@ M: object >post-data
|
|||
[ >post-data ] change-post-data
|
||||
normalize-post-data ;
|
||||
|
||||
: write-chunk ( chunk -- )
|
||||
[ length >hex ";\r\n" append ascii encode write ] [ write ] bi ;
|
||||
|
||||
: write-chunked ( stream -- )
|
||||
[ [ write-chunk ] each-block ] with-input-stream
|
||||
"0;\r\n" ascii encode write ;
|
||||
|
||||
: write-post-data ( request -- request )
|
||||
dup method>> { "POST" "PUT" } member? [
|
||||
dup post-data>> data>> dup sequence?
|
||||
[ write ] [ output-stream get stream-copy ] if
|
||||
] when ;
|
||||
[ write ] [ write-chunked ] if
|
||||
] when ;
|
||||
|
||||
: write-request ( request -- )
|
||||
unparse-post-data
|
||||
|
@ -95,12 +122,6 @@ M: object >post-data
|
|||
read-response-line
|
||||
read-response-header ;
|
||||
|
||||
: max-redirects 10 ;
|
||||
|
||||
ERROR: too-many-redirects ;
|
||||
|
||||
<PRIVATE
|
||||
|
||||
DEFER: (with-http-request)
|
||||
|
||||
SYMBOL: redirects
|
||||
|
@ -130,15 +151,10 @@ SYMBOL: redirects
|
|||
read-crlf B{ } assert= read-chunked
|
||||
] if ; inline recursive
|
||||
|
||||
: read-unchunked ( quot: ( chunk -- ) -- )
|
||||
8192 read-partial dup [
|
||||
[ swap call ] [ drop read-unchunked ] 2bi
|
||||
] [ 2drop ] if ; inline recursive
|
||||
|
||||
: read-response-body ( quot response -- )
|
||||
binary decode-input
|
||||
"transfer-encoding" header "chunked" =
|
||||
[ read-chunked ] [ read-unchunked ] if ; inline
|
||||
[ read-chunked ] [ each-block ] if ; inline
|
||||
|
||||
: <request-socket> ( -- stream )
|
||||
request get url>> url-addr ascii <client> drop
|
||||
|
@ -166,6 +182,11 @@ SYMBOL: redirects
|
|||
[ do-redirect ] [ nip ] if
|
||||
] with-variable ; inline recursive
|
||||
|
||||
: <client-request> ( url method -- request )
|
||||
<request>
|
||||
swap >>method
|
||||
swap >url ensure-port >>url ; inline
|
||||
|
||||
PRIVATE>
|
||||
|
||||
: success? ( code -- ? ) 200 299 between? ;
|
||||
|
@ -183,9 +204,7 @@ ERROR: download-failed response ;
|
|||
over content-charset>> decode ;
|
||||
|
||||
: <get-request> ( url -- request )
|
||||
<request>
|
||||
"GET" >>method
|
||||
swap >url ensure-port >>url ;
|
||||
"GET" <client-request> ;
|
||||
|
||||
: http-get ( url -- response data )
|
||||
<get-request> http-request ;
|
||||
|
@ -203,14 +222,19 @@ ERROR: download-failed response ;
|
|||
dup download-name download-to ;
|
||||
|
||||
: <post-request> ( post-data url -- request )
|
||||
<request>
|
||||
"POST" >>method
|
||||
swap >url ensure-port >>url
|
||||
"POST" <client-request>
|
||||
swap >>post-data ;
|
||||
|
||||
: http-post ( post-data url -- response data )
|
||||
<post-request> http-request ;
|
||||
|
||||
: <put-request> ( post-data url -- request )
|
||||
"PUT" <client-request>
|
||||
swap >>post-data ;
|
||||
|
||||
: http-put ( post-data url -- response data )
|
||||
<put-request> http-request ;
|
||||
|
||||
USING: vocabs vocabs.loader ;
|
||||
|
||||
"debugger" vocab [ "http.client.debugger" require ] when
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
USING: http http.server http.client tools.test multiline
|
||||
USING: http http.server http.client http.client.private tools.test multiline
|
||||
io.streams.string io.encodings.utf8 io.encodings.8-bit
|
||||
io.encodings.binary io.encodings.string kernel arrays splitting
|
||||
sequences assocs io.sockets db db.sqlite continuations urls
|
||||
|
|
|
@ -55,7 +55,7 @@ IN: http.server.cgi
|
|||
binary encode-output
|
||||
_ output-stream get swap <cgi-process> binary <process-stream> [
|
||||
post-request? [ request get post-data>> data>> write flush ] when
|
||||
input-stream get swap (stream-copy)
|
||||
'[ _ write ] each-block
|
||||
] with-stream
|
||||
] >>body ;
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@ html.elements
|
|||
html.streams ;
|
||||
IN: http.server
|
||||
|
||||
\ parse-cookie DEBUG add-input-logging
|
||||
|
||||
: check-absolute ( url -- url )
|
||||
dup path>> "/" head? [ "Bad request: URL" throw ] unless ; inline
|
||||
|
||||
|
|
Loading…
Reference in New Issue