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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 MockWrite(SYNCHRONOUS, 0, "POST / HTTP/1.1\r\n"), | 105 MockWrite(SYNCHRONOUS, 0, "POST / HTTP/1.1\r\n"), |
106 MockWrite(SYNCHRONOUS, 1, "Content-Length: 12\r\n\r\n"), | 106 MockWrite(SYNCHRONOUS, 1, "Content-Length: 12\r\n\r\n"), |
107 }; | 107 }; |
108 | 108 |
109 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); | 109 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
110 std::unique_ptr<ClientSocketHandle> socket_handle = | 110 std::unique_ptr<ClientSocketHandle> socket_handle = |
111 CreateConnectedSocketHandle(&data); | 111 CreateConnectedSocketHandle(&data); |
112 | 112 |
113 ReadErrorUploadDataStream upload_data_stream( | 113 ReadErrorUploadDataStream upload_data_stream( |
114 ReadErrorUploadDataStream::FailureMode::SYNC); | 114 ReadErrorUploadDataStream::FailureMode::SYNC); |
| 115 |
| 116 // Test upload progress before init. |
| 117 UploadProgress progress = upload_data_stream.GetUploadProgress(); |
| 118 EXPECT_EQ(0u, progress.size()); |
| 119 EXPECT_EQ(0u, progress.position()); |
| 120 |
115 ASSERT_THAT(upload_data_stream.Init(TestCompletionCallback().callback(), | 121 ASSERT_THAT(upload_data_stream.Init(TestCompletionCallback().callback(), |
116 BoundNetLog()), | 122 BoundNetLog()), |
117 IsOk()); | 123 IsOk()); |
118 | 124 |
| 125 // Test upload progress after init. |
| 126 progress = upload_data_stream.GetUploadProgress(); |
| 127 EXPECT_EQ(0u, progress.size()); |
| 128 EXPECT_EQ(0u, progress.position()); |
| 129 |
119 HttpRequestInfo request; | 130 HttpRequestInfo request; |
120 request.method = "POST"; | 131 request.method = "POST"; |
121 request.url = GURL("http://localhost"); | 132 request.url = GURL("http://localhost"); |
122 request.upload_data_stream = &upload_data_stream; | 133 request.upload_data_stream = &upload_data_stream; |
123 | 134 |
124 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); | 135 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
125 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), | 136 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), |
126 BoundNetLog()); | 137 BoundNetLog()); |
127 | 138 |
128 HttpRequestHeaders headers; | 139 HttpRequestHeaders headers; |
129 headers.SetHeader("Content-Length", "12"); | 140 headers.SetHeader("Content-Length", "12"); |
130 | 141 |
131 HttpResponseInfo response; | 142 HttpResponseInfo response; |
132 TestCompletionCallback callback; | 143 TestCompletionCallback callback; |
133 int result = parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response, | 144 int result = parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response, |
134 callback.callback()); | 145 callback.callback()); |
135 EXPECT_THAT(callback.GetResult(result), IsError(ERR_FAILED)); | 146 EXPECT_THAT(callback.GetResult(result), IsError(ERR_FAILED)); |
136 | 147 |
| 148 progress = upload_data_stream.GetUploadProgress(); |
| 149 EXPECT_EQ(0u, progress.size()); |
| 150 EXPECT_EQ(0u, progress.position()); |
| 151 |
137 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); | 152 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
138 } | 153 } |
139 | 154 |
140 TEST(HttpStreamParser, DataReadErrorAsynchronous) { | 155 TEST(HttpStreamParser, DataReadErrorAsynchronous) { |
141 MockWrite writes[] = { | 156 MockWrite writes[] = { |
142 MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"), | 157 MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"), |
143 MockWrite(ASYNC, 1, "Content-Length: 12\r\n\r\n"), | 158 MockWrite(ASYNC, 1, "Content-Length: 12\r\n\r\n"), |
144 }; | 159 }; |
145 | 160 |
146 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); | 161 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
(...skipping 17 matching lines...) Expand all Loading... |
164 | 179 |
165 HttpRequestHeaders headers; | 180 HttpRequestHeaders headers; |
166 headers.SetHeader("Content-Length", "12"); | 181 headers.SetHeader("Content-Length", "12"); |
167 | 182 |
168 HttpResponseInfo response; | 183 HttpResponseInfo response; |
169 TestCompletionCallback callback; | 184 TestCompletionCallback callback; |
170 int result = parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response, | 185 int result = parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response, |
171 callback.callback()); | 186 callback.callback()); |
172 EXPECT_THAT(result, IsError(ERR_IO_PENDING)); | 187 EXPECT_THAT(result, IsError(ERR_IO_PENDING)); |
173 | 188 |
| 189 UploadProgress progress = upload_data_stream.GetUploadProgress(); |
| 190 EXPECT_EQ(0u, progress.size()); |
| 191 EXPECT_EQ(0u, progress.position()); |
| 192 |
174 EXPECT_THAT(callback.GetResult(result), IsError(ERR_FAILED)); | 193 EXPECT_THAT(callback.GetResult(result), IsError(ERR_FAILED)); |
| 194 |
175 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); | 195 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
176 } | 196 } |
177 | 197 |
| 198 class InitAsyncUploadDataStream : public ChunkedUploadDataStream { |
| 199 public: |
| 200 explicit InitAsyncUploadDataStream(int64_t identifier) |
| 201 : ChunkedUploadDataStream(identifier), weak_factory_(this) {} |
| 202 |
| 203 private: |
| 204 void CompleteInit() { UploadDataStream::OnInitCompleted(OK); } |
| 205 |
| 206 int InitInternal(const BoundNetLog& net_log) override { |
| 207 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 208 FROM_HERE, base::Bind(&InitAsyncUploadDataStream::CompleteInit, |
| 209 weak_factory_.GetWeakPtr())); |
| 210 return ERR_IO_PENDING; |
| 211 } |
| 212 |
| 213 base::WeakPtrFactory<InitAsyncUploadDataStream> weak_factory_; |
| 214 |
| 215 DISALLOW_COPY_AND_ASSIGN(InitAsyncUploadDataStream); |
| 216 }; |
| 217 |
| 218 TEST(HttpStreamParser, InitAsynchronousUploadDataStream) { |
| 219 InitAsyncUploadDataStream upload_data_stream(0); |
| 220 |
| 221 TestCompletionCallback callback; |
| 222 int result = upload_data_stream.Init(callback.callback(), BoundNetLog()); |
| 223 ASSERT_THAT(result, IsError(ERR_IO_PENDING)); |
| 224 |
| 225 // Should be empty progress while initialization is in progress. |
| 226 UploadProgress progress = upload_data_stream.GetUploadProgress(); |
| 227 EXPECT_EQ(0u, progress.size()); |
| 228 EXPECT_EQ(0u, progress.position()); |
| 229 EXPECT_THAT(callback.GetResult(result), IsOk()); |
| 230 |
| 231 // Initialization complete. |
| 232 progress = upload_data_stream.GetUploadProgress(); |
| 233 EXPECT_EQ(0u, progress.size()); |
| 234 EXPECT_EQ(0u, progress.position()); |
| 235 |
| 236 HttpRequestInfo request; |
| 237 request.method = "POST"; |
| 238 request.url = GURL("http://localhost"); |
| 239 request.upload_data_stream = &upload_data_stream; |
| 240 |
| 241 static const char kChunk[] = "Chunk 1"; |
| 242 MockWrite writes[] = { |
| 243 MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"), |
| 244 MockWrite(ASYNC, 1, "Transfer-Encoding: chunked\r\n\r\n"), |
| 245 MockWrite(ASYNC, 2, "7\r\nChunk 1\r\n"), |
| 246 }; |
| 247 |
| 248 SequencedSocketData data(nullptr, 0, writes, arraysize(writes)); |
| 249 std::unique_ptr<ClientSocketHandle> socket_handle = |
| 250 CreateConnectedSocketHandle(&data); |
| 251 |
| 252 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer); |
| 253 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), |
| 254 BoundNetLog()); |
| 255 |
| 256 HttpRequestHeaders headers; |
| 257 headers.SetHeader("Transfer-Encoding", "chunked"); |
| 258 |
| 259 HttpResponseInfo response; |
| 260 TestCompletionCallback callback1; |
| 261 int result1 = parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response, |
| 262 callback1.callback()); |
| 263 EXPECT_EQ(ERR_IO_PENDING, result1); |
| 264 base::RunLoop().RunUntilIdle(); |
| 265 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, true); |
| 266 |
| 267 // Check progress after read completes. |
| 268 progress = upload_data_stream.GetUploadProgress(); |
| 269 EXPECT_EQ(0u, progress.size()); |
| 270 EXPECT_EQ(7u, progress.position()); |
| 271 |
| 272 // Check progress after reset. |
| 273 upload_data_stream.Reset(); |
| 274 progress = upload_data_stream.GetUploadProgress(); |
| 275 EXPECT_EQ(0u, progress.size()); |
| 276 EXPECT_EQ(0u, progress.position()); |
| 277 } |
| 278 |
178 // The empty payload is how the last chunk is encoded. | 279 // The empty payload is how the last chunk is encoded. |
179 TEST(HttpStreamParser, EncodeChunk_EmptyPayload) { | 280 TEST(HttpStreamParser, EncodeChunk_EmptyPayload) { |
180 char output[kOutputSize]; | 281 char output[kOutputSize]; |
181 | 282 |
182 const base::StringPiece kPayload = ""; | 283 const base::StringPiece kPayload = ""; |
183 const base::StringPiece kExpected = "0\r\n\r\n"; | 284 const base::StringPiece kExpected = "0\r\n\r\n"; |
184 const int num_bytes_written = | 285 const int num_bytes_written = |
185 HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output)); | 286 HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output)); |
186 ASSERT_EQ(kExpected.size(), static_cast<size_t>(num_bytes_written)); | 287 ASSERT_EQ(kExpected.size(), static_cast<size_t>(num_bytes_written)); |
187 EXPECT_EQ(kExpected, base::StringPiece(output, num_bytes_written)); | 288 EXPECT_EQ(kExpected, base::StringPiece(output, num_bytes_written)); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 | 571 |
471 HttpRequestHeaders headers; | 572 HttpRequestHeaders headers; |
472 headers.SetHeader("Content-Length", "12"); | 573 headers.SetHeader("Content-Length", "12"); |
473 | 574 |
474 HttpResponseInfo response; | 575 HttpResponseInfo response; |
475 TestCompletionCallback callback; | 576 TestCompletionCallback callback; |
476 EXPECT_EQ(OK, parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response, | 577 EXPECT_EQ(OK, parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response, |
477 callback.callback())); | 578 callback.callback())); |
478 | 579 |
479 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); | 580 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 581 |
| 582 UploadProgress progress = upload_data_stream.GetUploadProgress(); |
| 583 EXPECT_EQ(12u, progress.size()); |
| 584 EXPECT_EQ(12u, progress.position()); |
480 } | 585 } |
481 | 586 |
482 TEST(HttpStreamParser, SentBytesChunkedPostError) { | 587 TEST(HttpStreamParser, SentBytesChunkedPostError) { |
483 static const char kChunk[] = "Chunk 1"; | 588 static const char kChunk[] = "Chunk 1"; |
484 | 589 |
485 MockWrite writes[] = { | 590 MockWrite writes[] = { |
486 MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"), | 591 MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"), |
487 MockWrite(ASYNC, 1, "Transfer-Encoding: chunked\r\n\r\n"), | 592 MockWrite(ASYNC, 1, "Transfer-Encoding: chunked\r\n\r\n"), |
488 MockWrite(ASYNC, 2, "7\r\nChunk 1\r\n"), | 593 MockWrite(ASYNC, 2, "7\r\nChunk 1\r\n"), |
489 MockWrite(SYNCHRONOUS, ERR_FAILED, 3), | 594 MockWrite(SYNCHRONOUS, ERR_FAILED, 3), |
(...skipping 27 matching lines...) Expand all Loading... |
517 | 622 |
518 base::RunLoop().RunUntilIdle(); | 623 base::RunLoop().RunUntilIdle(); |
519 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false); | 624 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false); |
520 | 625 |
521 base::RunLoop().RunUntilIdle(); | 626 base::RunLoop().RunUntilIdle(); |
522 // This write should fail. | 627 // This write should fail. |
523 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false); | 628 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false); |
524 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FAILED)); | 629 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FAILED)); |
525 | 630 |
526 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); | 631 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
| 632 |
| 633 UploadProgress progress = upload_data_stream.GetUploadProgress(); |
| 634 EXPECT_EQ(0u, progress.size()); |
| 635 EXPECT_EQ(14u, progress.position()); |
527 } | 636 } |
528 | 637 |
529 // Test to ensure the HttpStreamParser state machine does not get confused | 638 // Test to ensure the HttpStreamParser state machine does not get confused |
530 // when sending a request with a chunked body with only one chunk that becomes | 639 // when sending a request with a chunked body with only one chunk that becomes |
531 // available asynchronously. | 640 // available asynchronously. |
532 TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) { | 641 TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) { |
533 static const char kChunk[] = "Chunk"; | 642 static const char kChunk[] = "Chunk"; |
534 | 643 |
535 MockWrite writes[] = { | 644 MockWrite writes[] = { |
536 MockWrite(ASYNC, 0, | 645 MockWrite(ASYNC, 0, |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 ASSERT_EQ(kBodySize, parser.ReadResponseBody( | 1616 ASSERT_EQ(kBodySize, parser.ReadResponseBody( |
1508 body_buffer.get(), kBodySize, callback.callback())); | 1617 body_buffer.get(), kBodySize, callback.callback())); |
1509 | 1618 |
1510 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); | 1619 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes()); |
1511 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); | 1620 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes()); |
1512 } | 1621 } |
1513 | 1622 |
1514 } // namespace | 1623 } // namespace |
1515 | 1624 |
1516 } // namespace net | 1625 } // namespace net |
OLD | NEW |