2 require 'test/test_helper'
7 class HttpParserNgTest < Test::Unit::TestCase
10 @parser = HttpParser.new
13 def test_identity_step_headers
15 str = "PUT / HTTP/1.1\r\n"
16 assert ! @parser.headers(req, str)
17 str << "Content-Length: 123\r\n"
18 assert ! @parser.headers(req, str)
20 assert_equal req.object_id, @parser.headers(req, str).object_id
21 assert_equal '123', req['CONTENT_LENGTH']
22 assert_equal 0, str.size
25 def test_identity_oneshot_header
27 str = "PUT / HTTP/1.1\r\nContent-Length: 123\r\n\r\n"
28 assert_equal req.object_id, @parser.headers(req, str).object_id
29 assert_equal '123', req['CONTENT_LENGTH']
30 assert_equal 0, str.size
33 def test_identity_oneshot_header_with_body
34 body = ('a' * 123).freeze
36 str = "PUT / HTTP/1.1\r\n" \
37 "Content-Length: #{body.length}\r\n" \
39 assert_equal req.object_id, @parser.headers(req, str).object_id
40 assert_equal '123', req['CONTENT_LENGTH']
41 assert_equal 123, str.size
42 assert_equal body, str
44 assert_nil @parser.read_body(tmp, str)
45 assert_equal 0, str.size
46 assert_equal tmp, body
47 assert_equal "", @parser.read_body(tmp, str)
50 def test_identity_oneshot_header_with_body_partial
51 str = "PUT / HTTP/1.1\r\nContent-Length: 123\r\n\r\na"
52 assert_equal Hash, @parser.headers({}, str).class
53 assert_equal 1, str.size
56 assert_nil @parser.read_body(tmp, str)
60 rv = @parser.read_body(tmp, str)
61 assert_equal 122, tmp.size
64 assert_equal str.object_id, @parser.read_body(tmp, str).object_id
67 def test_identity_oneshot_header_with_body_slop
68 str = "PUT / HTTP/1.1\r\nContent-Length: 1\r\n\r\naG"
69 assert_equal Hash, @parser.headers({}, str).class
70 assert_equal 2, str.size
71 assert_equal 'aG', str
73 assert_nil @parser.read_body(tmp, str)
75 assert_equal "G", @parser.read_body(tmp, str)
76 assert_equal 1, tmp.size
81 str = "PUT / HTTP/1.1\r\ntransfer-Encoding: chunked\r\n\r\n"
83 assert_equal req, @parser.headers(req, str)
84 assert_equal 0, str.size
86 assert_nil @parser.read_body(tmp, "6")
87 assert_equal 0, tmp.size
88 assert_nil @parser.read_body(tmp, rv = "\r\n")
89 assert_equal 0, rv.size
90 assert_equal 0, tmp.size
92 assert_nil @parser.read_body(tmp, "..")
93 assert_equal "..", tmp
94 assert_nil @parser.read_body(tmp, "abcd\r\n0\r\n")
95 assert_equal "abcd", tmp
97 assert_equal rv.object_id, @parser.read_body(tmp, rv).object_id
98 assert_equal "PUT", rv
102 str = "PUT / HTTP/1.1\r\ntransfer-Encoding: chunked\r\n\r\n"
104 assert_equal req, @parser.headers(req, str)
105 assert_equal 0, str.size
107 assert_nil @parser.read_body(tmp, "6")
108 assert_equal 0, tmp.size
109 assert_nil @parser.read_body(tmp, rv = "\r\n")
111 assert_equal 0, tmp.size
113 assert_nil @parser.read_body(tmp, "..")
114 assert_equal 2, tmp.size
115 assert_equal "..", tmp
116 assert_nil @parser.read_body(tmp, "abcd\r\n1")
117 assert_equal "abcd", tmp
118 assert_nil @parser.read_body(tmp, "\r")
120 assert_nil @parser.read_body(tmp, "\n")
122 assert_nil @parser.read_body(tmp, "z")
123 assert_equal "z", tmp
124 assert_nil @parser.read_body(tmp, "\r\n")
125 assert_nil @parser.read_body(tmp, "0")
126 assert_nil @parser.read_body(tmp, "\r")
127 rv = @parser.read_body(tmp, buf = "\nGET")
128 assert_equal "GET", rv
129 assert_equal buf.object_id, rv.object_id
133 str = "PUT / HTTP/1.1\r\ntransfer-Encoding: chunked\r\n\r\n" \
136 assert_equal req, @parser.headers(req, str)
138 assert_nil @parser.read_body(tmp, str)
141 assert_nil @parser.read_body(tmp, str)
144 assert_nil @parser.read_body(tmp, str)
146 assert ! @parser.body_eof?
147 assert_equal "", @parser.read_body(tmp, "\r\n0\r\n")
148 assert @parser.body_eof?
151 def test_two_chunks_oneshot
152 str = "PUT / HTTP/1.1\r\ntransfer-Encoding: chunked\r\n\r\n" \
153 "1\r\na\r\n2\r\n..\r\n0\r\n"
155 assert_equal req, @parser.headers(req, str)
157 assert_nil @parser.read_body(tmp, str)
158 assert_equal 'a..', tmp
159 rv = @parser.read_body(tmp, str)
160 assert_equal rv.object_id, str.object_id
164 str = "PUT / HTTP/1.1\r\n" \
165 "Trailer: Content-MD5\r\n" \
166 "transfer-Encoding: chunked\r\n\r\n" \
167 "1\r\na\r\n2\r\n..\r\n0\r\n"
169 assert_equal req, @parser.headers(req, str)
170 assert_equal 'Content-MD5', req['HTTP_TRAILER']
171 assert_nil req['HTTP_CONTENT_MD5']
173 assert_nil @parser.read_body(tmp, str)
174 assert_equal 'a..', tmp
175 md5_b64 = [ Digest::MD5.digest(tmp) ].pack('m').strip.freeze
176 rv = @parser.read_body(tmp, str)
177 assert_equal rv.object_id, str.object_id
179 md5_hdr = "Content-MD5: #{md5_b64}\r\n".freeze
181 assert_nil @parser.trailers(req, str)
182 assert_equal md5_b64, req['HTTP_CONTENT_MD5']
183 assert_equal "CONTENT_MD5: #{md5_b64}\r\n", str
184 assert_nil @parser.trailers(req, str << "\r")
185 assert_equal req, @parser.trailers(req, str << "\nGET / ")
186 assert_equal "GET / ", str
190 str = "PUT / HTTP/1.1\r\n" \
191 "transfer-Encoding: chunked\r\n\r\n" \
192 "#{HttpParser::CHUNK_MAX.to_s(16)}\r\na\r\n2\r\n..\r\n0\r\n"
194 assert_equal req, @parser.headers(req, str)
195 assert_nil @parser.content_length
196 assert_nothing_raised { @parser.read_body('', str) }
200 n = HttpParser::LENGTH_MAX
201 str = "PUT / HTTP/1.1\r\nContent-Length: #{n}\r\n\r\n"
203 assert_nothing_raised { @parser.headers(req, str) }
204 assert_equal n, req['CONTENT_LENGTH'].to_i
207 def test_overflow_chunk
208 n = HttpParser::CHUNK_MAX + 1
209 str = "PUT / HTTP/1.1\r\n" \
210 "transfer-Encoding: chunked\r\n\r\n" \
211 "#{n.to_s(16)}\r\na\r\n2\r\n..\r\n0\r\n"
213 assert_equal req, @parser.headers(req, str)
214 assert_nil @parser.content_length
215 assert_raise(HttpParserError) { @parser.read_body('', str) }
218 def test_overflow_content_length
219 n = HttpParser::LENGTH_MAX + 1
220 str = "PUT / HTTP/1.1\r\nContent-Length: #{n}\r\n\r\n"
221 assert_raise(HttpParserError) { @parser.headers({}, str) }
225 str = "PUT / HTTP/1.1\r\n" \
226 "transfer-Encoding: chunked\r\n\r\n" \
227 "#zzz\r\na\r\n2\r\n..\r\n0\r\n"
229 assert_equal req, @parser.headers(req, str)
230 assert_nil @parser.content_length
231 assert_raise(HttpParserError) { @parser.read_body('', str) }
234 def test_bad_content_length
235 str = "PUT / HTTP/1.1\r\nContent-Length: 7ff\r\n\r\n"
236 assert_raise(HttpParserError) { @parser.headers({}, str) }
239 def test_bad_trailers
240 str = "PUT / HTTP/1.1\r\n" \
241 "Trailer: Transfer-Encoding\r\n" \
242 "transfer-Encoding: chunked\r\n\r\n" \
243 "1\r\na\r\n2\r\n..\r\n0\r\n"
245 assert_equal req, @parser.headers(req, str)
246 assert_equal 'Transfer-Encoding', req['HTTP_TRAILER']
248 assert_nil @parser.read_body(tmp, str)
249 assert_equal 'a..', tmp
251 str << "Transfer-Encoding: identity\r\n\r\n"
252 assert_raise(HttpParserError) { @parser.trailers(req, str) }