OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_stream_parser.h" | 5 #include "net/http/http_stream_parser.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 | 92 |
93 // The payload is one byte larger the output buffer size. | 93 // The payload is one byte larger the output buffer size. |
94 const std::string kPayload(kMaxPayloadSize + 1, '\xff'); | 94 const std::string kPayload(kMaxPayloadSize + 1, '\xff'); |
95 const int num_bytes_written = | 95 const int num_bytes_written = |
96 HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output)); | 96 HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output)); |
97 ASSERT_EQ(ERR_INVALID_ARGUMENT, num_bytes_written); | 97 ASSERT_EQ(ERR_INVALID_ARGUMENT, num_bytes_written); |
98 } | 98 } |
99 | 99 |
100 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_NoBody) { | 100 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_NoBody) { |
101 // Shouldn't be merged if upload data is non-existent. | 101 // Shouldn't be merged if upload data is non-existent. |
102 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( | 102 ASSERT_FALSE( |
103 "some header", NULL)); | 103 HttpStreamParser::ShouldMergeRequestHeadersAndBody("some header", NULL)); |
104 } | 104 } |
105 | 105 |
106 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_EmptyBody) { | 106 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_EmptyBody) { |
107 ScopedVector<UploadElementReader> element_readers; | 107 ScopedVector<UploadElementReader> element_readers; |
108 scoped_ptr<UploadDataStream> body( | 108 scoped_ptr<UploadDataStream> body( |
109 new UploadDataStream(element_readers.Pass(), 0)); | 109 new UploadDataStream(element_readers.Pass(), 0)); |
110 ASSERT_EQ(OK, body->Init(CompletionCallback())); | 110 ASSERT_EQ(OK, body->Init(CompletionCallback())); |
111 // Shouldn't be merged if upload data is empty. | 111 // Shouldn't be merged if upload data is empty. |
112 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( | 112 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody("some header", |
113 "some header", body.get())); | 113 body.get())); |
114 } | 114 } |
115 | 115 |
116 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_ChunkedBody) { | 116 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_ChunkedBody) { |
117 const std::string payload = "123"; | 117 const std::string payload = "123"; |
118 scoped_ptr<UploadDataStream> body( | 118 scoped_ptr<UploadDataStream> body( |
119 new UploadDataStream(UploadDataStream::CHUNKED, 0)); | 119 new UploadDataStream(UploadDataStream::CHUNKED, 0)); |
120 body->AppendChunk(payload.data(), payload.size(), true); | 120 body->AppendChunk(payload.data(), payload.size(), true); |
121 ASSERT_EQ(OK, body->Init(CompletionCallback())); | 121 ASSERT_EQ(OK, body->Init(CompletionCallback())); |
122 // Shouldn't be merged if upload data carries chunked data. | 122 // Shouldn't be merged if upload data carries chunked data. |
123 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( | 123 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody("some header", |
124 "some header", body.get())); | 124 body.get())); |
125 } | 125 } |
126 | 126 |
127 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_FileBody) { | 127 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_FileBody) { |
128 { | 128 { |
129 ScopedVector<UploadElementReader> element_readers; | 129 ScopedVector<UploadElementReader> element_readers; |
130 | 130 |
131 // Create an empty temporary file. | 131 // Create an empty temporary file. |
132 base::ScopedTempDir temp_dir; | 132 base::ScopedTempDir temp_dir; |
133 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 133 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
134 base::FilePath temp_file_path; | 134 base::FilePath temp_file_path; |
135 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), | 135 ASSERT_TRUE( |
136 &temp_file_path)); | 136 base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file_path)); |
137 | 137 |
138 element_readers.push_back( | 138 element_readers.push_back( |
139 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | 139 new UploadFileElementReader(base::MessageLoopProxy::current().get(), |
140 temp_file_path, | 140 temp_file_path, |
141 0, | 141 0, |
142 0, | 142 0, |
143 base::Time())); | 143 base::Time())); |
144 | 144 |
145 scoped_ptr<UploadDataStream> body( | 145 scoped_ptr<UploadDataStream> body( |
146 new UploadDataStream(element_readers.Pass(), 0)); | 146 new UploadDataStream(element_readers.Pass(), 0)); |
147 TestCompletionCallback callback; | 147 TestCompletionCallback callback; |
148 ASSERT_EQ(ERR_IO_PENDING, body->Init(callback.callback())); | 148 ASSERT_EQ(ERR_IO_PENDING, body->Init(callback.callback())); |
149 ASSERT_EQ(OK, callback.WaitForResult()); | 149 ASSERT_EQ(OK, callback.WaitForResult()); |
150 // Shouldn't be merged if upload data carries a file, as it's not in-memory. | 150 // Shouldn't be merged if upload data carries a file, as it's not in-memory. |
151 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( | 151 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( |
152 "some header", body.get())); | 152 "some header", body.get())); |
153 } | 153 } |
154 // UploadFileElementReaders may post clean-up tasks on destruction. | 154 // UploadFileElementReaders may post clean-up tasks on destruction. |
155 base::RunLoop().RunUntilIdle(); | 155 base::RunLoop().RunUntilIdle(); |
156 } | 156 } |
157 | 157 |
158 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_SmallBodyInMemory) { | 158 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_SmallBodyInMemory) { |
159 ScopedVector<UploadElementReader> element_readers; | 159 ScopedVector<UploadElementReader> element_readers; |
160 const std::string payload = "123"; | 160 const std::string payload = "123"; |
161 element_readers.push_back(new UploadBytesElementReader( | 161 element_readers.push_back( |
162 payload.data(), payload.size())); | 162 new UploadBytesElementReader(payload.data(), payload.size())); |
163 | 163 |
164 scoped_ptr<UploadDataStream> body( | 164 scoped_ptr<UploadDataStream> body( |
165 new UploadDataStream(element_readers.Pass(), 0)); | 165 new UploadDataStream(element_readers.Pass(), 0)); |
166 ASSERT_EQ(OK, body->Init(CompletionCallback())); | 166 ASSERT_EQ(OK, body->Init(CompletionCallback())); |
167 // Yes, should be merged if the in-memory body is small here. | 167 // Yes, should be merged if the in-memory body is small here. |
168 ASSERT_TRUE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( | 168 ASSERT_TRUE(HttpStreamParser::ShouldMergeRequestHeadersAndBody("some header", |
169 "some header", body.get())); | 169 body.get())); |
170 } | 170 } |
171 | 171 |
172 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_LargeBodyInMemory) { | 172 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_LargeBodyInMemory) { |
173 ScopedVector<UploadElementReader> element_readers; | 173 ScopedVector<UploadElementReader> element_readers; |
174 const std::string payload(10000, 'a'); // 'a' x 10000. | 174 const std::string payload(10000, 'a'); // 'a' x 10000. |
175 element_readers.push_back(new UploadBytesElementReader( | 175 element_readers.push_back( |
176 payload.data(), payload.size())); | 176 new UploadBytesElementReader(payload.data(), payload.size())); |
177 | 177 |
178 scoped_ptr<UploadDataStream> body( | 178 scoped_ptr<UploadDataStream> body( |
179 new UploadDataStream(element_readers.Pass(), 0)); | 179 new UploadDataStream(element_readers.Pass(), 0)); |
180 ASSERT_EQ(OK, body->Init(CompletionCallback())); | 180 ASSERT_EQ(OK, body->Init(CompletionCallback())); |
181 // Shouldn't be merged if the in-memory body is large here. | 181 // Shouldn't be merged if the in-memory body is large here. |
182 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( | 182 ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody("some header", |
183 "some header", body.get())); | 183 body.get())); |
184 } | 184 } |
185 | 185 |
186 // Test to ensure the HttpStreamParser state machine does not get confused | 186 // Test to ensure the HttpStreamParser state machine does not get confused |
187 // when sending a request with a chunked body, where chunks become available | 187 // when sending a request with a chunked body, where chunks become available |
188 // asynchronously, over a socket where writes may also complete | 188 // asynchronously, over a socket where writes may also complete |
189 // asynchronously. | 189 // asynchronously. |
190 // This is a regression test for http://crbug.com/132243 | 190 // This is a regression test for http://crbug.com/132243 |
191 TEST(HttpStreamParser, AsyncChunkAndAsyncSocket) { | 191 TEST(HttpStreamParser, AsyncChunkAndAsyncSocket) { |
192 // The chunks that will be written in the request, as reflected in the | 192 // The chunks that will be written in the request, as reflected in the |
193 // MockWrites below. | 193 // MockWrites below. |
194 static const char kChunk1[] = "Chunk 1"; | 194 static const char kChunk1[] = "Chunk 1"; |
195 static const char kChunk2[] = "Chunky 2"; | 195 static const char kChunk2[] = "Chunky 2"; |
196 static const char kChunk3[] = "Test 3"; | 196 static const char kChunk3[] = "Test 3"; |
197 | 197 |
198 MockWrite writes[] = { | 198 MockWrite writes[] = { |
199 MockWrite(ASYNC, 0, | 199 MockWrite(ASYNC, |
200 "GET /one.html HTTP/1.1\r\n" | 200 0, |
201 "Host: localhost\r\n" | 201 "GET /one.html HTTP/1.1\r\n" |
202 "Transfer-Encoding: chunked\r\n" | 202 "Host: localhost\r\n" |
203 "Connection: keep-alive\r\n\r\n"), | 203 "Transfer-Encoding: chunked\r\n" |
204 MockWrite(ASYNC, 1, "7\r\nChunk 1\r\n"), | 204 "Connection: keep-alive\r\n\r\n"), |
205 MockWrite(ASYNC, 2, "8\r\nChunky 2\r\n"), | 205 MockWrite(ASYNC, 1, "7\r\nChunk 1\r\n"), |
206 MockWrite(ASYNC, 3, "6\r\nTest 3\r\n"), | 206 MockWrite(ASYNC, 2, "8\r\nChunky 2\r\n"), |
207 MockWrite(ASYNC, 4, "0\r\n\r\n"), | 207 MockWrite(ASYNC, 3, "6\r\nTest 3\r\n"), MockWrite(ASYNC, 4, "0\r\n\r\n"), |
208 }; | 208 }; |
209 | 209 |
210 // The size of the response body, as reflected in the Content-Length of the | 210 // The size of the response body, as reflected in the Content-Length of the |
211 // MockRead below. | 211 // MockRead below. |
212 static const int kBodySize = 8; | 212 static const int kBodySize = 8; |
213 | 213 |
214 MockRead reads[] = { | 214 MockRead reads[] = { |
215 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"), | 215 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"), |
216 MockRead(ASYNC, 6, "Content-Length: 8\r\n\r\n"), | 216 MockRead(ASYNC, 6, "Content-Length: 8\r\n\r\n"), |
217 MockRead(ASYNC, 7, "one.html"), | 217 MockRead(ASYNC, 7, "one.html"), MockRead(SYNCHRONOUS, 0, 8), // EOF |
218 MockRead(SYNCHRONOUS, 0, 8), // EOF | |
219 }; | 218 }; |
220 | 219 |
221 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); | 220 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); |
222 upload_stream.AppendChunk(kChunk1, arraysize(kChunk1) - 1, false); | 221 upload_stream.AppendChunk(kChunk1, arraysize(kChunk1) - 1, false); |
223 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); | 222 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); |
224 | 223 |
225 DeterministicSocketData data(reads, arraysize(reads), | 224 DeterministicSocketData data( |
226 writes, arraysize(writes)); | 225 reads, arraysize(reads), writes, arraysize(writes)); |
227 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 226 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
228 | 227 |
229 scoped_ptr<DeterministicMockTCPClientSocket> transport( | 228 scoped_ptr<DeterministicMockTCPClientSocket> transport( |
230 new DeterministicMockTCPClientSocket(NULL, &data)); | 229 new DeterministicMockTCPClientSocket(NULL, &data)); |
231 data.set_delegate(transport->AsWeakPtr()); | 230 data.set_delegate(transport->AsWeakPtr()); |
232 | 231 |
233 TestCompletionCallback callback; | 232 TestCompletionCallback callback; |
234 int rv = transport->Connect(callback.callback()); | 233 int rv = transport->Connect(callback.callback()); |
235 rv = callback.GetResult(rv); | 234 rv = callback.GetResult(rv); |
236 ASSERT_EQ(OK, rv); | 235 ASSERT_EQ(OK, rv); |
(...skipping 12 matching lines...) Expand all Loading... |
249 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); | 248 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); |
250 | 249 |
251 HttpRequestHeaders request_headers; | 250 HttpRequestHeaders request_headers; |
252 request_headers.SetHeader("Host", "localhost"); | 251 request_headers.SetHeader("Host", "localhost"); |
253 request_headers.SetHeader("Transfer-Encoding", "chunked"); | 252 request_headers.SetHeader("Transfer-Encoding", "chunked"); |
254 request_headers.SetHeader("Connection", "keep-alive"); | 253 request_headers.SetHeader("Connection", "keep-alive"); |
255 | 254 |
256 HttpResponseInfo response_info; | 255 HttpResponseInfo response_info; |
257 // This will attempt to Write() the initial request and headers, which will | 256 // This will attempt to Write() the initial request and headers, which will |
258 // complete asynchronously. | 257 // complete asynchronously. |
259 rv = parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers, | 258 rv = parser.SendRequest("GET /one.html HTTP/1.1\r\n", |
260 &response_info, callback.callback()); | 259 request_headers, |
| 260 &response_info, |
| 261 callback.callback()); |
261 ASSERT_EQ(ERR_IO_PENDING, rv); | 262 ASSERT_EQ(ERR_IO_PENDING, rv); |
262 | 263 |
263 // Complete the initial request write. Additionally, this should enqueue the | 264 // Complete the initial request write. Additionally, this should enqueue the |
264 // first chunk. | 265 // first chunk. |
265 data.RunFor(1); | 266 data.RunFor(1); |
266 ASSERT_FALSE(callback.have_result()); | 267 ASSERT_FALSE(callback.have_result()); |
267 | 268 |
268 // Now append another chunk (while the first write is still pending), which | 269 // Now append another chunk (while the first write is still pending), which |
269 // should not confuse the state machine. | 270 // should not confuse the state machine. |
270 upload_stream.AppendChunk(kChunk2, arraysize(kChunk2) - 1, false); | 271 upload_stream.AppendChunk(kChunk2, arraysize(kChunk2) - 1, false); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 ASSERT_EQ(ERR_IO_PENDING, rv); | 318 ASSERT_EQ(ERR_IO_PENDING, rv); |
318 data.RunFor(1); | 319 data.RunFor(1); |
319 | 320 |
320 ASSERT_TRUE(callback.have_result()); | 321 ASSERT_TRUE(callback.have_result()); |
321 rv = callback.WaitForResult(); | 322 rv = callback.WaitForResult(); |
322 ASSERT_EQ(kBodySize, rv); | 323 ASSERT_EQ(kBodySize, rv); |
323 } | 324 } |
324 | 325 |
325 TEST(HttpStreamParser, TruncatedHeaders) { | 326 TEST(HttpStreamParser, TruncatedHeaders) { |
326 MockRead truncated_status_reads[] = { | 327 MockRead truncated_status_reads[] = { |
327 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 20"), | 328 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 20"), |
328 MockRead(SYNCHRONOUS, 0, 2), // EOF | 329 MockRead(SYNCHRONOUS, 0, 2), // EOF |
329 }; | 330 }; |
330 | 331 |
331 MockRead truncated_after_status_reads[] = { | 332 MockRead truncated_after_status_reads[] = { |
332 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\n"), | 333 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\n"), |
333 MockRead(SYNCHRONOUS, 0, 2), // EOF | 334 MockRead(SYNCHRONOUS, 0, 2), // EOF |
334 }; | 335 }; |
335 | 336 |
336 MockRead truncated_in_header_reads[] = { | 337 MockRead truncated_in_header_reads[] = { |
337 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\nHead"), | 338 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\nHead"), |
338 MockRead(SYNCHRONOUS, 0, 2), // EOF | 339 MockRead(SYNCHRONOUS, 0, 2), // EOF |
339 }; | 340 }; |
340 | 341 |
341 MockRead truncated_after_header_reads[] = { | 342 MockRead truncated_after_header_reads[] = { |
342 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\nHeader: foo\r\n"), | 343 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\nHeader: foo\r\n"), |
343 MockRead(SYNCHRONOUS, 0, 2), // EOF | 344 MockRead(SYNCHRONOUS, 0, 2), // EOF |
344 }; | 345 }; |
345 | 346 |
346 MockRead truncated_after_final_newline_reads[] = { | 347 MockRead truncated_after_final_newline_reads[] = { |
347 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\nHeader: foo\r\n\r"), | 348 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\nHeader: foo\r\n\r"), |
348 MockRead(SYNCHRONOUS, 0, 2), // EOF | 349 MockRead(SYNCHRONOUS, 0, 2), // EOF |
349 }; | 350 }; |
350 | 351 |
351 MockRead not_truncated_reads[] = { | 352 MockRead not_truncated_reads[] = { |
352 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\nHeader: foo\r\n\r\n"), | 353 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Ok\r\nHeader: foo\r\n\r\n"), |
353 MockRead(SYNCHRONOUS, 0, 2), // EOF | 354 MockRead(SYNCHRONOUS, 0, 2), // EOF |
354 }; | 355 }; |
355 | 356 |
356 MockRead* reads[] = { | 357 MockRead* reads[] = { |
357 truncated_status_reads, | 358 truncated_status_reads, truncated_after_status_reads, |
358 truncated_after_status_reads, | 359 truncated_in_header_reads, truncated_after_header_reads, |
359 truncated_in_header_reads, | 360 truncated_after_final_newline_reads, not_truncated_reads, |
360 truncated_after_header_reads, | |
361 truncated_after_final_newline_reads, | |
362 not_truncated_reads, | |
363 }; | 361 }; |
364 | 362 |
365 MockWrite writes[] = { | 363 MockWrite writes[] = { |
366 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"), | 364 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"), |
367 }; | 365 }; |
368 | 366 |
369 enum { | 367 enum { |
370 HTTP = 0, | 368 HTTP = 0, |
371 HTTPS, | 369 HTTPS, |
372 NUM_PROTOCOLS, | 370 NUM_PROTOCOLS, |
373 }; | 371 }; |
374 | 372 |
375 for (size_t protocol = 0; protocol < NUM_PROTOCOLS; protocol++) { | 373 for (size_t protocol = 0; protocol < NUM_PROTOCOLS; protocol++) { |
376 SCOPED_TRACE(protocol); | 374 SCOPED_TRACE(protocol); |
(...skipping 24 matching lines...) Expand all Loading... |
401 request_info.url = GURL("https://localhost"); | 399 request_info.url = GURL("https://localhost"); |
402 } | 400 } |
403 request_info.load_flags = LOAD_NORMAL; | 401 request_info.load_flags = LOAD_NORMAL; |
404 | 402 |
405 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); | 403 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
406 HttpStreamParser parser( | 404 HttpStreamParser parser( |
407 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); | 405 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); |
408 | 406 |
409 HttpRequestHeaders request_headers; | 407 HttpRequestHeaders request_headers; |
410 HttpResponseInfo response_info; | 408 HttpResponseInfo response_info; |
411 rv = parser.SendRequest("GET / HTTP/1.1\r\n", request_headers, | 409 rv = parser.SendRequest("GET / HTTP/1.1\r\n", |
412 &response_info, callback.callback()); | 410 request_headers, |
| 411 &response_info, |
| 412 callback.callback()); |
413 ASSERT_EQ(OK, rv); | 413 ASSERT_EQ(OK, rv); |
414 | 414 |
415 rv = parser.ReadResponseHeaders(callback.callback()); | 415 rv = parser.ReadResponseHeaders(callback.callback()); |
416 if (i == arraysize(reads) - 1) { | 416 if (i == arraysize(reads) - 1) { |
417 EXPECT_EQ(OK, rv); | 417 EXPECT_EQ(OK, rv); |
418 EXPECT_TRUE(response_info.headers.get()); | 418 EXPECT_TRUE(response_info.headers.get()); |
419 } else { | 419 } else { |
420 if (protocol == HTTP) { | 420 if (protocol == HTTP) { |
421 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); | 421 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); |
422 EXPECT_TRUE(response_info.headers.get()); | 422 EXPECT_TRUE(response_info.headers.get()); |
423 } else { | 423 } else { |
424 EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, rv); | 424 EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, rv); |
425 EXPECT_FALSE(response_info.headers.get()); | 425 EXPECT_FALSE(response_info.headers.get()); |
426 } | 426 } |
427 } | 427 } |
428 } | 428 } |
429 } | 429 } |
430 } | 430 } |
431 | 431 |
432 // Confirm that on 101 response, the headers are parsed but the data that | 432 // Confirm that on 101 response, the headers are parsed but the data that |
433 // follows remains in the buffer. | 433 // follows remains in the buffer. |
434 TEST(HttpStreamParser, Websocket101Response) { | 434 TEST(HttpStreamParser, Websocket101Response) { |
435 MockRead reads[] = { | 435 MockRead reads[] = { |
436 MockRead(SYNCHRONOUS, 1, | 436 MockRead(SYNCHRONOUS, |
437 "HTTP/1.1 101 Switching Protocols\r\n" | 437 1, |
438 "Upgrade: websocket\r\n" | 438 "HTTP/1.1 101 Switching Protocols\r\n" |
439 "Connection: Upgrade\r\n" | 439 "Upgrade: websocket\r\n" |
440 "\r\n" | 440 "Connection: Upgrade\r\n" |
441 "a fake websocket frame"), | 441 "\r\n" |
| 442 "a fake websocket frame"), |
442 }; | 443 }; |
443 | 444 |
444 MockWrite writes[] = { | 445 MockWrite writes[] = { |
445 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"), | 446 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"), |
446 }; | 447 }; |
447 | 448 |
448 DeterministicSocketData data(reads, arraysize(reads), | 449 DeterministicSocketData data( |
449 writes, arraysize(writes)); | 450 reads, arraysize(reads), writes, arraysize(writes)); |
450 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 451 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
451 data.SetStop(2); | 452 data.SetStop(2); |
452 | 453 |
453 scoped_ptr<DeterministicMockTCPClientSocket> transport( | 454 scoped_ptr<DeterministicMockTCPClientSocket> transport( |
454 new DeterministicMockTCPClientSocket(NULL, &data)); | 455 new DeterministicMockTCPClientSocket(NULL, &data)); |
455 data.set_delegate(transport->AsWeakPtr()); | 456 data.set_delegate(transport->AsWeakPtr()); |
456 | 457 |
457 TestCompletionCallback callback; | 458 TestCompletionCallback callback; |
458 int rv = transport->Connect(callback.callback()); | 459 int rv = transport->Connect(callback.callback()); |
459 rv = callback.GetResult(rv); | 460 rv = callback.GetResult(rv); |
460 ASSERT_EQ(OK, rv); | 461 ASSERT_EQ(OK, rv); |
461 | 462 |
462 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle); | 463 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle); |
463 socket_handle->SetSocket(transport.PassAs<StreamSocket>()); | 464 socket_handle->SetSocket(transport.PassAs<StreamSocket>()); |
464 | 465 |
465 HttpRequestInfo request_info; | 466 HttpRequestInfo request_info; |
466 request_info.method = "GET"; | 467 request_info.method = "GET"; |
467 request_info.url = GURL("http://localhost"); | 468 request_info.url = GURL("http://localhost"); |
468 request_info.load_flags = LOAD_NORMAL; | 469 request_info.load_flags = LOAD_NORMAL; |
469 | 470 |
470 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); | 471 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
471 HttpStreamParser parser( | 472 HttpStreamParser parser( |
472 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); | 473 socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog()); |
473 | 474 |
474 HttpRequestHeaders request_headers; | 475 HttpRequestHeaders request_headers; |
475 HttpResponseInfo response_info; | 476 HttpResponseInfo response_info; |
476 rv = parser.SendRequest("GET / HTTP/1.1\r\n", request_headers, | 477 rv = parser.SendRequest("GET / HTTP/1.1\r\n", |
477 &response_info, callback.callback()); | 478 request_headers, |
| 479 &response_info, |
| 480 callback.callback()); |
478 ASSERT_EQ(OK, rv); | 481 ASSERT_EQ(OK, rv); |
479 | 482 |
480 rv = parser.ReadResponseHeaders(callback.callback()); | 483 rv = parser.ReadResponseHeaders(callback.callback()); |
481 EXPECT_EQ(OK, rv); | 484 EXPECT_EQ(OK, rv); |
482 ASSERT_TRUE(response_info.headers.get()); | 485 ASSERT_TRUE(response_info.headers.get()); |
483 EXPECT_EQ(101, response_info.headers->response_code()); | 486 EXPECT_EQ(101, response_info.headers->response_code()); |
484 EXPECT_TRUE(response_info.headers->HasHeaderValue("Connection", "Upgrade")); | 487 EXPECT_TRUE(response_info.headers->HasHeaderValue("Connection", "Upgrade")); |
485 EXPECT_TRUE(response_info.headers->HasHeaderValue("Upgrade", "websocket")); | 488 EXPECT_TRUE(response_info.headers->HasHeaderValue("Upgrade", "websocket")); |
486 EXPECT_EQ(read_buffer->capacity(), read_buffer->offset()); | 489 EXPECT_EQ(read_buffer->capacity(), read_buffer->offset()); |
487 EXPECT_EQ("a fake websocket frame", | 490 EXPECT_EQ( |
488 base::StringPiece(read_buffer->StartOfBuffer(), | 491 "a fake websocket frame", |
489 read_buffer->capacity())); | 492 base::StringPiece(read_buffer->StartOfBuffer(), read_buffer->capacity())); |
490 } | 493 } |
491 | 494 |
492 // Helper class for constructing HttpStreamParser and running GET requests. | 495 // Helper class for constructing HttpStreamParser and running GET requests. |
493 class SimpleGetRunner { | 496 class SimpleGetRunner { |
494 public: | 497 public: |
495 SimpleGetRunner() : read_buffer_(new GrowableIOBuffer), sequence_number_(0) { | 498 SimpleGetRunner() : read_buffer_(new GrowableIOBuffer), sequence_number_(0) { |
496 writes_.push_back(MockWrite( | 499 writes_.push_back( |
497 SYNCHRONOUS, sequence_number_++, "GET / HTTP/1.1\r\n\r\n")); | 500 MockWrite(SYNCHRONOUS, sequence_number_++, "GET / HTTP/1.1\r\n\r\n")); |
498 } | 501 } |
499 | 502 |
500 HttpStreamParser* parser() { return parser_.get(); } | 503 HttpStreamParser* parser() { return parser_.get(); } |
501 GrowableIOBuffer* read_buffer() { return read_buffer_.get(); } | 504 GrowableIOBuffer* read_buffer() { return read_buffer_.get(); } |
502 HttpResponseInfo* response_info() { return &response_info_; } | 505 HttpResponseInfo* response_info() { return &response_info_; } |
503 | 506 |
504 void AddInitialData(const std::string& data) { | 507 void AddInitialData(const std::string& data) { |
505 int offset = read_buffer_->offset(); | 508 int offset = read_buffer_->offset(); |
506 int size = data.size(); | 509 int size = data.size(); |
507 read_buffer_->SetCapacity(offset + size); | 510 read_buffer_->SetCapacity(offset + size); |
(...skipping 24 matching lines...) Expand all Loading... |
532 | 535 |
533 socket_handle_->SetSocket(transport_.PassAs<StreamSocket>()); | 536 socket_handle_->SetSocket(transport_.PassAs<StreamSocket>()); |
534 | 537 |
535 request_info_.method = "GET"; | 538 request_info_.method = "GET"; |
536 request_info_.url = GURL("http://localhost"); | 539 request_info_.url = GURL("http://localhost"); |
537 request_info_.load_flags = LOAD_NORMAL; | 540 request_info_.load_flags = LOAD_NORMAL; |
538 | 541 |
539 parser_.reset(new HttpStreamParser( | 542 parser_.reset(new HttpStreamParser( |
540 socket_handle_.get(), &request_info_, read_buffer(), BoundNetLog())); | 543 socket_handle_.get(), &request_info_, read_buffer(), BoundNetLog())); |
541 | 544 |
542 rv = parser_->SendRequest("GET / HTTP/1.1\r\n", request_headers_, | 545 rv = parser_->SendRequest("GET / HTTP/1.1\r\n", |
543 &response_info_, callback.callback()); | 546 request_headers_, |
| 547 &response_info_, |
| 548 callback.callback()); |
544 ASSERT_EQ(OK, rv); | 549 ASSERT_EQ(OK, rv); |
545 } | 550 } |
546 | 551 |
547 void ReadHeaders() { | 552 void ReadHeaders() { |
548 TestCompletionCallback callback; | 553 TestCompletionCallback callback; |
549 EXPECT_EQ(OK, parser_->ReadResponseHeaders(callback.callback())); | 554 EXPECT_EQ(OK, parser_->ReadResponseHeaders(callback.callback())); |
550 } | 555 } |
551 | 556 |
552 void ReadBody(int user_buf_len, int* read_lengths) { | 557 void ReadBody(int user_buf_len, int* read_lengths) { |
553 TestCompletionCallback callback; | 558 TestCompletionCallback callback; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 EXPECT_EQ(0, get_runner.parser()->received_bytes()); | 593 EXPECT_EQ(0, get_runner.parser()->received_bytes()); |
589 int response_size = response.size(); | 594 int response_size = response.size(); |
590 int read_lengths[] = {response_size, 0}; | 595 int read_lengths[] = {response_size, 0}; |
591 get_runner.ReadBody(response_size, read_lengths); | 596 get_runner.ReadBody(response_size, read_lengths); |
592 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); | 597 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); |
593 } | 598 } |
594 | 599 |
595 // Test basic case where there is no keep-alive or extra data from the socket, | 600 // Test basic case where there is no keep-alive or extra data from the socket, |
596 // and the entire response is received in a single read. | 601 // and the entire response is received in a single read. |
597 TEST(HttpStreamParser, ReceivedBytesNormal) { | 602 TEST(HttpStreamParser, ReceivedBytesNormal) { |
598 std::string headers = "HTTP/1.1 200 OK\r\n" | 603 std::string headers = |
| 604 "HTTP/1.1 200 OK\r\n" |
599 "Content-Length: 7\r\n\r\n"; | 605 "Content-Length: 7\r\n\r\n"; |
600 std::string body = "content"; | 606 std::string body = "content"; |
601 std::string response = headers + body; | 607 std::string response = headers + body; |
602 | 608 |
603 SimpleGetRunner get_runner; | 609 SimpleGetRunner get_runner; |
604 get_runner.AddRead(response); | 610 get_runner.AddRead(response); |
605 get_runner.SetupParserAndSendRequest(); | 611 get_runner.SetupParserAndSendRequest(); |
606 get_runner.ReadHeaders(); | 612 get_runner.ReadHeaders(); |
607 int64 headers_size = headers.size(); | 613 int64 headers_size = headers.size(); |
608 EXPECT_EQ(headers_size, get_runner.parser()->received_bytes()); | 614 EXPECT_EQ(headers_size, get_runner.parser()->received_bytes()); |
609 int body_size = body.size(); | 615 int body_size = body.size(); |
610 int read_lengths[] = {body_size, 0}; | 616 int read_lengths[] = {body_size, 0}; |
611 get_runner.ReadBody(body_size, read_lengths); | 617 get_runner.ReadBody(body_size, read_lengths); |
612 int64 response_size = response.size(); | 618 int64 response_size = response.size(); |
613 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); | 619 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); |
614 } | 620 } |
615 | 621 |
616 // Test that bytes that represent "next" response are not counted | 622 // Test that bytes that represent "next" response are not counted |
617 // as current response "received_bytes". | 623 // as current response "received_bytes". |
618 TEST(HttpStreamParser, ReceivedBytesExcludesNextResponse) { | 624 TEST(HttpStreamParser, ReceivedBytesExcludesNextResponse) { |
619 std::string headers = "HTTP/1.1 200 OK\r\n" | 625 std::string headers = |
| 626 "HTTP/1.1 200 OK\r\n" |
620 "Content-Length: 8\r\n\r\n"; | 627 "Content-Length: 8\r\n\r\n"; |
621 std::string body = "content8"; | 628 std::string body = "content8"; |
622 std::string response = headers + body; | 629 std::string response = headers + body; |
623 std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO"; | 630 std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO"; |
624 std::string data = response + next_response; | 631 std::string data = response + next_response; |
625 | 632 |
626 SimpleGetRunner get_runner; | 633 SimpleGetRunner get_runner; |
627 get_runner.AddRead(data); | 634 get_runner.AddRead(data); |
628 get_runner.SetupParserAndSendRequest(); | 635 get_runner.SetupParserAndSendRequest(); |
629 get_runner.ReadHeaders(); | 636 get_runner.ReadHeaders(); |
(...skipping 10 matching lines...) Expand all Loading... |
640 } | 647 } |
641 | 648 |
642 // Test that "received_bytes" calculation works fine when last read | 649 // Test that "received_bytes" calculation works fine when last read |
643 // contains more data than requested by user. | 650 // contains more data than requested by user. |
644 // We send data in two reads: | 651 // We send data in two reads: |
645 // 1) Headers + beginning of response | 652 // 1) Headers + beginning of response |
646 // 2) remaining part of response + next response start | 653 // 2) remaining part of response + next response start |
647 // We setup user read buffer so it fully accepts the beginnig of response | 654 // We setup user read buffer so it fully accepts the beginnig of response |
648 // body, but it is larger that remaining part of body. | 655 // body, but it is larger that remaining part of body. |
649 TEST(HttpStreamParser, ReceivedBytesMultiReadExcludesNextResponse) { | 656 TEST(HttpStreamParser, ReceivedBytesMultiReadExcludesNextResponse) { |
650 std::string headers = "HTTP/1.1 200 OK\r\n" | 657 std::string headers = |
| 658 "HTTP/1.1 200 OK\r\n" |
651 "Content-Length: 36\r\n\r\n"; | 659 "Content-Length: 36\r\n\r\n"; |
652 int64 user_buf_len = 32; | 660 int64 user_buf_len = 32; |
653 std::string body_start = std::string(user_buf_len, '#'); | 661 std::string body_start = std::string(user_buf_len, '#'); |
654 int body_start_size = body_start.size(); | 662 int body_start_size = body_start.size(); |
655 EXPECT_EQ(user_buf_len, body_start_size); | 663 EXPECT_EQ(user_buf_len, body_start_size); |
656 std::string response_start = headers + body_start; | 664 std::string response_start = headers + body_start; |
657 std::string body_end = "abcd"; | 665 std::string body_end = "abcd"; |
658 std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO"; | 666 std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO"; |
659 std::string response_end = body_end + next_response; | 667 std::string response_end = body_end + next_response; |
660 | 668 |
(...skipping 11 matching lines...) Expand all Loading... |
672 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); | 680 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); |
673 int64 next_response_size = next_response.size(); | 681 int64 next_response_size = next_response.size(); |
674 EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset()); | 682 EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset()); |
675 } | 683 } |
676 | 684 |
677 // Test that "received_bytes" calculation works fine when there is no | 685 // Test that "received_bytes" calculation works fine when there is no |
678 // network activity at all; that is when all data is read from read buffer. | 686 // network activity at all; that is when all data is read from read buffer. |
679 // In this case read buffer contains two responses. We expect that only | 687 // In this case read buffer contains two responses. We expect that only |
680 // bytes that correspond to the first one are taken into account. | 688 // bytes that correspond to the first one are taken into account. |
681 TEST(HttpStreamParser, ReceivedBytesFromReadBufExcludesNextResponse) { | 689 TEST(HttpStreamParser, ReceivedBytesFromReadBufExcludesNextResponse) { |
682 std::string headers = "HTTP/1.1 200 OK\r\n" | 690 std::string headers = |
| 691 "HTTP/1.1 200 OK\r\n" |
683 "Content-Length: 7\r\n\r\n"; | 692 "Content-Length: 7\r\n\r\n"; |
684 std::string body = "content"; | 693 std::string body = "content"; |
685 std::string response = headers + body; | 694 std::string response = headers + body; |
686 std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO"; | 695 std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO"; |
687 std::string data = response + next_response; | 696 std::string data = response + next_response; |
688 | 697 |
689 SimpleGetRunner get_runner; | 698 SimpleGetRunner get_runner; |
690 get_runner.AddInitialData(data); | 699 get_runner.AddInitialData(data); |
691 get_runner.SetupParserAndSendRequest(); | 700 get_runner.SetupParserAndSendRequest(); |
692 get_runner.ReadHeaders(); | 701 get_runner.ReadHeaders(); |
(...skipping 26 matching lines...) Expand all Loading... |
719 int body_size = body.size(); | 728 int body_size = body.size(); |
720 int read_lengths[] = {body_size, 0}; | 729 int read_lengths[] = {body_size, 0}; |
721 get_runner.ReadBody(body_size, read_lengths); | 730 get_runner.ReadBody(body_size, read_lengths); |
722 EXPECT_EQ(headers_size + body_size, get_runner.parser()->received_bytes()); | 731 EXPECT_EQ(headers_size + body_size, get_runner.parser()->received_bytes()); |
723 EXPECT_EQ(0, get_runner.read_buffer()->offset()); | 732 EXPECT_EQ(0, get_runner.read_buffer()->offset()); |
724 } | 733 } |
725 | 734 |
726 // Test the case when the resulting read_buf contains both unused bytes and | 735 // Test the case when the resulting read_buf contains both unused bytes and |
727 // bytes ejected by chunked-encoding filter. | 736 // bytes ejected by chunked-encoding filter. |
728 TEST(HttpStreamParser, ReceivedBytesChunkedTransferExcludesNextResponse) { | 737 TEST(HttpStreamParser, ReceivedBytesChunkedTransferExcludesNextResponse) { |
729 std::string response = "HTTP/1.1 200 OK\r\n" | 738 std::string response = |
| 739 "HTTP/1.1 200 OK\r\n" |
730 "Transfer-Encoding: chunked\r\n\r\n" | 740 "Transfer-Encoding: chunked\r\n\r\n" |
731 "7\r\nChunk 1\r\n" | 741 "7\r\nChunk 1\r\n" |
732 "8\r\nChunky 2\r\n" | 742 "8\r\nChunky 2\r\n" |
733 "6\r\nTest 3\r\n" | 743 "6\r\nTest 3\r\n" |
734 "0\r\n\r\n"; | 744 "0\r\n\r\n"; |
735 std::string next_response = "foo bar\r\n"; | 745 std::string next_response = "foo bar\r\n"; |
736 std::string data = response + next_response; | 746 std::string data = response + next_response; |
737 | 747 |
738 SimpleGetRunner get_runner; | 748 SimpleGetRunner get_runner; |
739 get_runner.AddInitialData(data); | 749 get_runner.AddInitialData(data); |
740 get_runner.SetupParserAndSendRequest(); | 750 get_runner.SetupParserAndSendRequest(); |
741 get_runner.ReadHeaders(); | 751 get_runner.ReadHeaders(); |
742 int read_lengths[] = {4, 3, 6, 2, 6, 0}; | 752 int read_lengths[] = {4, 3, 6, 2, 6, 0}; |
743 get_runner.ReadBody(7, read_lengths); | 753 get_runner.ReadBody(7, read_lengths); |
744 int64 response_size = response.size(); | 754 int64 response_size = response.size(); |
745 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); | 755 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); |
746 int64 next_response_size = next_response.size(); | 756 int64 next_response_size = next_response.size(); |
747 EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset()); | 757 EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset()); |
748 } | 758 } |
749 | 759 |
750 // Test that data transfered in multiple reads is correctly processed. | 760 // Test that data transfered in multiple reads is correctly processed. |
751 // We feed data into 4-bytes reads. Also we set length of read | 761 // We feed data into 4-bytes reads. Also we set length of read |
752 // buffer to 5-bytes to test all possible buffer misaligments. | 762 // buffer to 5-bytes to test all possible buffer misaligments. |
753 TEST(HttpStreamParser, ReceivedBytesMultipleReads) { | 763 TEST(HttpStreamParser, ReceivedBytesMultipleReads) { |
754 std::string headers = "HTTP/1.1 200 OK\r\n" | 764 std::string headers = |
| 765 "HTTP/1.1 200 OK\r\n" |
755 "Content-Length: 33\r\n\r\n"; | 766 "Content-Length: 33\r\n\r\n"; |
756 std::string body = "foo bar baz\r\n" | 767 std::string body = |
| 768 "foo bar baz\r\n" |
757 "sputnik mir babushka"; | 769 "sputnik mir babushka"; |
758 std::string response = headers + body; | 770 std::string response = headers + body; |
759 | 771 |
760 size_t receive_length = 4; | 772 size_t receive_length = 4; |
761 std::vector<std::string> blocks; | 773 std::vector<std::string> blocks; |
762 for (size_t i = 0; i < response.size(); i += receive_length) { | 774 for (size_t i = 0; i < response.size(); i += receive_length) { |
763 size_t length = std::min(receive_length, response.size() - i); | 775 size_t length = std::min(receive_length, response.size() - i); |
764 blocks.push_back(response.substr(i, length)); | 776 blocks.push_back(response.substr(i, length)); |
765 } | 777 } |
766 | 778 |
767 SimpleGetRunner get_runner; | 779 SimpleGetRunner get_runner; |
768 for (std::vector<std::string>::size_type i = 0; i < blocks.size(); ++i) | 780 for (std::vector<std::string>::size_type i = 0; i < blocks.size(); ++i) |
769 get_runner.AddRead(blocks[i]); | 781 get_runner.AddRead(blocks[i]); |
770 get_runner.SetupParserAndSendRequest(); | 782 get_runner.SetupParserAndSendRequest(); |
771 get_runner.ReadHeaders(); | 783 get_runner.ReadHeaders(); |
772 int64 headers_size = headers.size(); | 784 int64 headers_size = headers.size(); |
773 EXPECT_EQ(headers_size, get_runner.parser()->received_bytes()); | 785 EXPECT_EQ(headers_size, get_runner.parser()->received_bytes()); |
774 int read_lengths[] = {1, 4, 4, 4, 4, 4, 4, 4, 4, 0}; | 786 int read_lengths[] = {1, 4, 4, 4, 4, 4, 4, 4, 4, 0}; |
775 get_runner.ReadBody(receive_length + 1, read_lengths); | 787 get_runner.ReadBody(receive_length + 1, read_lengths); |
776 int64 response_size = response.size(); | 788 int64 response_size = response.size(); |
777 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); | 789 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); |
778 } | 790 } |
779 | 791 |
780 // Test that "continue" HTTP header is counted as "received_bytes". | 792 // Test that "continue" HTTP header is counted as "received_bytes". |
781 TEST(HttpStreamParser, ReceivedBytesIncludesContinueHeader) { | 793 TEST(HttpStreamParser, ReceivedBytesIncludesContinueHeader) { |
782 std::string status100 = "HTTP/1.1 100 OK\r\n\r\n"; | 794 std::string status100 = "HTTP/1.1 100 OK\r\n\r\n"; |
783 std::string headers = "HTTP/1.1 200 OK\r\n" | 795 std::string headers = |
| 796 "HTTP/1.1 200 OK\r\n" |
784 "Content-Length: 7\r\n\r\n"; | 797 "Content-Length: 7\r\n\r\n"; |
785 int64 headers_size = status100.size() + headers.size(); | 798 int64 headers_size = status100.size() + headers.size(); |
786 std::string body = "content"; | 799 std::string body = "content"; |
787 std::string response = headers + body; | 800 std::string response = headers + body; |
788 | 801 |
789 SimpleGetRunner get_runner; | 802 SimpleGetRunner get_runner; |
790 get_runner.AddRead(status100); | 803 get_runner.AddRead(status100); |
791 get_runner.AddRead(response); | 804 get_runner.AddRead(response); |
792 get_runner.SetupParserAndSendRequest(); | 805 get_runner.SetupParserAndSendRequest(); |
793 get_runner.ReadHeaders(); | 806 get_runner.ReadHeaders(); |
794 EXPECT_EQ(100, get_runner.response_info()->headers->response_code()); | 807 EXPECT_EQ(100, get_runner.response_info()->headers->response_code()); |
795 int64 status100_size = status100.size(); | 808 int64 status100_size = status100.size(); |
796 EXPECT_EQ(status100_size, get_runner.parser()->received_bytes()); | 809 EXPECT_EQ(status100_size, get_runner.parser()->received_bytes()); |
797 get_runner.ReadHeaders(); | 810 get_runner.ReadHeaders(); |
798 EXPECT_EQ(200, get_runner.response_info()->headers->response_code()); | 811 EXPECT_EQ(200, get_runner.response_info()->headers->response_code()); |
799 EXPECT_EQ(headers_size, get_runner.parser()->received_bytes()); | 812 EXPECT_EQ(headers_size, get_runner.parser()->received_bytes()); |
800 int64 response_size = headers_size + body.size(); | 813 int64 response_size = headers_size + body.size(); |
801 int body_size = body.size(); | 814 int body_size = body.size(); |
802 int read_lengths[] = {body_size, 0}; | 815 int read_lengths[] = {body_size, 0}; |
803 get_runner.ReadBody(body_size, read_lengths); | 816 get_runner.ReadBody(body_size, read_lengths); |
804 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); | 817 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); |
805 } | 818 } |
806 | 819 |
807 } // namespace | 820 } // namespace |
808 | 821 |
809 } // namespace net | 822 } // namespace net |
OLD | NEW |