1 USING: accessors assocs continuations http http.client http.client.private
2 http.server http.server.requests io.streams.limited io.streams.string kernel
3 math math.parser multiline namespaces peg sequences splitting tools.test urls ;
4 IN: http.server.requests.tests
6 : normalize-nl ( str -- str' )
9 : request>string ( request -- string )
10 [ write-request ] with-string-writer ;
12 : string>request ( str -- request )
13 [ request-limit get limited-input read-request ] with-string-reader ;
17 "foo=bar" "localhost" <post-request> request>string string>request
18 [ post-data>> data>> ] [ header>> "content-length" of ] bi
22 "" "localhost" <post-request> request>string string>request
23 [ post-data>> data>> ] [ header>> "content-length" of ] bi
26 ! Incorrect content-length works fine
27 { H{ { "foo" "bar" } } } [
28 { { "foo" "bar" } } "localhost" <post-request> request>string
29 "7" "190" replace string>request post-data>> params>>
32 { H{ { "name" "John Smith" } } } [
33 { { "name" "John Smith" } } "localhost" <post-request> request>string
34 string>request post-data>> params>>
38 STRING: test-multipart/form-data
41 Accept-Encoding: gzip, deflate
42 Connection: keep-alive
44 Content-Type: multipart/form-data; boundary=768de80194d942619886d23f1337aa15
46 User-Agent: HTTPie/0.9.0-dev
48 --768de80194d942619886d23f1337aa15
49 Content-Disposition: form-data; name="text"; filename="upload.txt"
52 --768de80194d942619886d23f1337aa15--
58 { "content-disposition"
59 "form-data; name=\"text\"; filename=\"upload.txt\"" }
62 test-multipart/form-data normalize-nl string>request
63 post-data>> params>> "text" of [ filename>> ] [ headers>> ] bi
67 ! If the incoming request is not valid, read-request should throw an
69 STRING: test-multipart/form-data-missing-boundary
72 Accept-Encoding: gzip, deflate
73 Connection: keep-alive
75 Content-Type: multipart/form-data; abcd
77 User-Agent: HTTPie/0.9.0-dev
79 --768de80194d942619886d23f1337aa15
80 Content-Disposition: form-data; name="text"; filename="upload.txt"
83 --768de80194d942619886d23f1337aa15--
86 [ test-multipart/form-data-missing-boundary string>request ]
87 [ no-boundary? ] must-fail-with
89 ! Relative urls are invalid.
90 [ "GET foo HTTP/1.1" string>request ] [ path>> "foo" = ] must-fail-with
93 [ "" string>request ] [ parse-error>> parse-error? ] must-fail-with
95 ! Missing content-length is probably not ok. It's plausible
96 ! transfer-length could replace it, but we don't handle it atm anyway.
98 { { "foo" "bar" } } "localhost" <post-request> request>string
99 "content-length" "foo" replace string>request
100 ] [ content-length-missing? ] must-fail-with
102 ! Non-numeric content-length is ofc crap.
104 { { "foo" "bar" } } "localhost" <post-request> request>string
105 "7" "i am not a number!" replace string>request
107 [ invalid-content-length? ]
108 [ content-length>> "i am not a number!" = ] bi and
111 ! Negative is it too.
113 { { "foo" "bar" } } "localhost" <post-request> request>string
114 "7" "-1234" replace string>request
116 [ invalid-content-length? ]
117 [ content-length>> -1234 = ] bi and
122 { { "foo" "bar" } } "localhost" <post-request> request>string
123 "7" upload-limit get 1 + number>string replace string>request
125 [ invalid-content-length? ]
126 [ content-length>> upload-limit get 1 + = ] bi and
130 ! RFC 2616: Section 4.1
131 ! In the interest of robustness, servers SHOULD ignore any empty
132 ! line(s) received where a Request-Line is expected. In other words, if
133 ! the server is reading the protocol stream at the beginning of a
134 ! message and receives a CRLF first, it should ignore the CRLF.
145 "\r\n\r\n\r\nGET / HTTP/1.0\r\n\r\n"
146 [ read-request ] with-string-reader
149 ! RFC 2616: Section 19.3
150 ! The line terminator for message-header fields is the sequence CRLF.
151 ! However, we recommend that applications, when parsing such headers,
152 ! recognize a single LF as a line terminator and ignore the leading CR.
157 "host: 127.0.0.1:55532"
158 "user-agent: Factor http.client"
159 } [ "\n" join ] [ "\r\n" join ] bi
160 [ [ read-request ] with-string-reader ] same?