OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/spdy/spdy_network_transaction.h" | 5 #include "net/spdy/spdy_network_transaction.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/ref_counted.h" | 8 #include "base/ref_counted.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "net/base/completion_callback.h" | 10 #include "net/base/completion_callback.h" |
11 #include "net/base/mock_host_resolver.h" | 11 #include "net/base/mock_host_resolver.h" |
12 #include "net/base/net_log_unittest.h" | 12 #include "net/base/net_log_unittest.h" |
13 #include "net/base/ssl_config_service_defaults.h" | 13 #include "net/base/ssl_config_service_defaults.h" |
14 #include "net/base/test_completion_callback.h" | 14 #include "net/base/test_completion_callback.h" |
15 #include "net/base/upload_data.h" | 15 #include "net/base/upload_data.h" |
16 #include "net/http/http_auth_handler_factory.h" | 16 #include "net/http/http_auth_handler_factory.h" |
17 #include "net/http/http_network_session.h" | 17 #include "net/http/http_network_session.h" |
18 #include "net/http/http_transaction_unittest.h" | 18 #include "net/http/http_transaction_unittest.h" |
19 #include "net/proxy/proxy_config_service_fixed.h" | 19 #include "net/proxy/proxy_config_service_fixed.h" |
20 #include "net/socket/socket_test_util.h" | 20 #include "net/socket/socket_test_util.h" |
21 #include "net/spdy/spdy_framer.h" | 21 #include "net/spdy/spdy_framer.h" |
22 #include "net/spdy/spdy_protocol.h" | 22 #include "net/spdy/spdy_protocol.h" |
| 23 #include "net/spdy/spdy_test_util.h" |
23 #include "testing/platform_test.h" | 24 #include "testing/platform_test.h" |
24 | 25 |
25 #define NET_TRACE(level, s) DLOG(level) << s << __FUNCTION__ << "() " | 26 #define NET_TRACE(level, s) DLOG(level) << s << __FUNCTION__ << "() " |
26 | 27 |
27 //----------------------------------------------------------------------------- | 28 //----------------------------------------------------------------------------- |
28 | 29 |
29 namespace net { | 30 namespace net { |
30 | 31 |
31 // NOTE: In GCC, on a Mac, this can't be in an anonymous namespace! | 32 // NOTE: In GCC, on a Mac, this can't be in an anonymous namespace! |
32 // This struct holds information used to construct spdy control and data frames. | 33 // This struct holds information used to construct spdy control and data frames. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 DLOG(INFO) << "Result: " << r.result; | 187 DLOG(INFO) << "Result: " << r.result; |
187 DumpData(r.data, r.data_len); | 188 DumpData(r.data, r.data_len); |
188 const char* stop = (r.sequence_number & MockRead::STOPLOOP) ? " (STOP)" : ""; | 189 const char* stop = (r.sequence_number & MockRead::STOPLOOP) ? " (STOP)" : ""; |
189 DLOG(INFO) << "Stage: " << (r.sequence_number & ~MockRead::STOPLOOP) | 190 DLOG(INFO) << "Stage: " << (r.sequence_number & ~MockRead::STOPLOOP) |
190 << stop; | 191 << stop; |
191 DLOG(INFO) << "Time: " << r.time_stamp.ToInternalValue(); | 192 DLOG(INFO) << "Time: " << r.time_stamp.ToInternalValue(); |
192 } | 193 } |
193 | 194 |
194 // ---------------------------------------------------------------------------- | 195 // ---------------------------------------------------------------------------- |
195 | 196 |
196 static const unsigned char kGetSyn[] = { | |
197 0x80, 0x01, 0x00, 0x01, // header | |
198 0x01, 0x00, 0x00, 0x49, // FIN, len | |
199 0x00, 0x00, 0x00, 0x01, // stream id | |
200 0x00, 0x00, 0x00, 0x00, // associated | |
201 0xc0, 0x00, 0x00, 0x03, // 3 headers | |
202 0x00, 0x06, 'm', 'e', 't', 'h', 'o', 'd', | |
203 0x00, 0x03, 'G', 'E', 'T', | |
204 0x00, 0x03, 'u', 'r', 'l', | |
205 0x00, 0x16, 'h', 't', 't', 'p', ':', '/', '/', 'w', 'w', 'w', | |
206 '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', | |
207 'm', '/', | |
208 0x00, 0x07, 'v', 'e', 'r', 's', 'i', 'o', 'n', | |
209 0x00, 0x08, 'H', 'T', 'T', 'P', '/', '1', '.', '1', | |
210 }; | |
211 | |
212 static const unsigned char kGetSynCompressed[] = { | |
213 0x80, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x47, | |
214 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, | |
215 0xc0, 0x00, 0x38, 0xea, 0xdf, 0xa2, 0x51, 0xb2, | |
216 0x62, 0x60, 0x66, 0x60, 0xcb, 0x05, 0xe6, 0xc3, | |
217 0xfc, 0x14, 0x06, 0x66, 0x77, 0xd7, 0x10, 0x06, | |
218 0x66, 0x90, 0xa0, 0x58, 0x46, 0x49, 0x49, 0x81, | |
219 0x95, 0xbe, 0x3e, 0x30, 0xe2, 0xf5, 0xd2, 0xf3, | |
220 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x92, 0xf3, 0x73, | |
221 0xf5, 0x19, 0xd8, 0xa1, 0x1a, 0x19, 0x38, 0x60, | |
222 0xe6, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff | |
223 }; | |
224 | |
225 static const unsigned char kGetSynReply[] = { | |
226 0x80, 0x01, 0x00, 0x02, // header | |
227 0x00, 0x00, 0x00, 0x45, | |
228 0x00, 0x00, 0x00, 0x01, | |
229 0x00, 0x00, 0x00, 0x04, // 4 headers | |
230 0x00, 0x05, 'h', 'e', 'l', 'l', 'o', // "hello" | |
231 0x00, 0x03, 'b', 'y', 'e', // "bye" | |
232 0x00, 0x06, 's', 't', 'a', 't', 'u', 's', // "status" | |
233 0x00, 0x03, '2', '0', '0', // "200" | |
234 0x00, 0x03, 'u', 'r', 'l', // "url" | |
235 0x00, 0x0a, '/', 'i', 'n', 'd', 'e', 'x', '.', 'p', 'h', 'p', // "/index... | |
236 0x00, 0x07, 'v', 'e', 'r', 's', 'i', 'o', 'n', // "version" | |
237 0x00, 0x08, 'H', 'T', 'T', 'P', '/', '1', '.', '1', // "HTTP/1.1" | |
238 }; | |
239 | |
240 static const unsigned char kGetBodyFrame[] = { | |
241 0x00, 0x00, 0x00, 0x01, // header | |
242 0x01, 0x00, 0x00, 0x06, // FIN, length | |
243 'h', 'e', 'l', 'l', 'o', '!', // "hello" | |
244 }; | |
245 | |
246 static const unsigned char kPostSyn[] = { | |
247 0x80, 0x01, 0x00, 0x01, // header | |
248 0x00, 0x00, 0x00, 0x4a, // flags, len | |
249 0x00, 0x00, 0x00, 0x01, // stream id | |
250 0x00, 0x00, 0x00, 0x00, // associated | |
251 0xc0, 0x00, 0x00, 0x03, // 4 headers | |
252 0x00, 0x06, 'm', 'e', 't', 'h', 'o', 'd', | |
253 0x00, 0x04, 'P', 'O', 'S', 'T', | |
254 0x00, 0x03, 'u', 'r', 'l', | |
255 0x00, 0x16, 'h', 't', 't', 'p', ':', '/', '/', 'w', 'w', 'w', | |
256 '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', | |
257 'm', '/', | |
258 0x00, 0x07, 'v', 'e', 'r', 's', 'i', 'o', 'n', | |
259 0x00, 0x08, 'H', 'T', 'T', 'P', '/', '1', '.', '1', | |
260 }; | |
261 | |
262 static const unsigned char kPostUploadFrame[] = { | |
263 0x00, 0x00, 0x00, 0x01, // header | |
264 0x01, 0x00, 0x00, 0x0c, // FIN flag | |
265 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0' | |
266 }; | |
267 | |
268 // The response | |
269 static const unsigned char kPostSynReply[] = { | |
270 0x80, 0x01, 0x00, 0x02, // header | |
271 0x00, 0x00, 0x00, 0x45, | |
272 0x00, 0x00, 0x00, 0x01, | |
273 0x00, 0x00, 0x00, 0x04, // 4 headers | |
274 0x00, 0x05, 'h', 'e', 'l', 'l', 'o', // "hello" | |
275 0x00, 0x03, 'b', 'y', 'e', // "bye" | |
276 0x00, 0x06, 's', 't', 'a', 't', 'u', 's', // "status" | |
277 0x00, 0x03, '2', '0', '0', // "200" | |
278 0x00, 0x03, 'u', 'r', 'l', // "url" | |
279 // "/index.php" | |
280 0x00, 0x0a, '/', 'i', 'n', 'd', 'e', 'x', '.', 'p', 'h', 'p', | |
281 0x00, 0x07, 'v', 'e', 'r', 's', 'i', 'o', 'n', // "version" | |
282 0x00, 0x08, 'H', 'T', 'T', 'P', '/', '1', '.', '1', // "HTTP/1.1" | |
283 }; | |
284 | |
285 static const unsigned char kPostBodyFrame[] = { | |
286 0x00, 0x00, 0x00, 0x01, // header | |
287 0x01, 0x00, 0x00, 0x06, // FIN, length | |
288 'h', 'e', 'l', 'l', 'o', '!', // "hello" | |
289 }; | |
290 | |
291 static const unsigned char kGoAway[] = { | |
292 0x80, 0x01, 0x00, 0x07, // header | |
293 0x00, 0x00, 0x00, 0x04, // flags, len | |
294 0x00, 0x00, 0x00, 0x00, // last-accepted-stream-id | |
295 }; | |
296 | |
297 // Adds headers and values to a map. | 197 // Adds headers and values to a map. |
298 // |extra_headers| is an array of { name, value } pairs, arranged as strings | 198 // |extra_headers| is an array of { name, value } pairs, arranged as strings |
299 // where the even entries are the header names, and the odd entries are the | 199 // where the even entries are the header names, and the odd entries are the |
300 // header values. | 200 // header values. |
301 // |headers| gets filled in from |extra_headers|. | 201 // |headers| gets filled in from |extra_headers|. |
302 void AppendHeadersToSpdyFrame(const char* const extra_headers[], | 202 void AppendHeadersToSpdyFrame(const char* const extra_headers[], |
303 int extra_header_count, | 203 int extra_header_count, |
304 spdy::SpdyHeaderBlock* headers) { | 204 spdy::SpdyHeaderBlock* headers) { |
305 std::string this_header; | 205 std::string this_header; |
306 std::string this_value; | 206 std::string this_value; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 return ConstructSpdyPacket( | 487 return ConstructSpdyPacket( |
588 &SynStartHeader, | 488 &SynStartHeader, |
589 extra_headers, | 489 extra_headers, |
590 extra_header_count, | 490 extra_header_count, |
591 kStandardGetHeaders, | 491 kStandardGetHeaders, |
592 arraysize(kStandardGetHeaders) / 2); | 492 arraysize(kStandardGetHeaders) / 2); |
593 } | 493 } |
594 | 494 |
595 } // namespace | 495 } // namespace |
596 | 496 |
597 // A DataProvider where the client must write a request before the reads (e.g. | |
598 // the response) will complete. | |
599 class DelayedSocketData : public StaticSocketDataProvider, | |
600 public base::RefCounted<DelayedSocketData> { | |
601 public: | |
602 // |write_delay| the number of MockWrites to complete before allowing | |
603 // a MockRead to complete. | |
604 // |reads| the list of MockRead completions. | |
605 // |writes| the list of MockWrite completions. | |
606 // Note: All MockReads and MockWrites must be async. | |
607 // Note: The MockRead and MockWrite lists musts end with a EOF | |
608 // e.g. a MockRead(true, 0, 0); | |
609 DelayedSocketData(int write_delay, | |
610 MockRead* reads, size_t reads_count, | |
611 MockWrite* writes, size_t writes_count) | |
612 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
613 write_delay_(write_delay), | |
614 ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) { | |
615 DCHECK_GE(write_delay_, 0); | |
616 } | |
617 | |
618 // |connect| the result for the connect phase. | |
619 // |reads| the list of MockRead completions. | |
620 // |write_delay| the number of MockWrites to complete before allowing | |
621 // a MockRead to complete. | |
622 // |writes| the list of MockWrite completions. | |
623 // Note: All MockReads and MockWrites must be async. | |
624 // Note: The MockRead and MockWrite lists musts end with a EOF | |
625 // e.g. a MockRead(true, 0, 0); | |
626 DelayedSocketData(const MockConnect& connect, int write_delay, | |
627 MockRead* reads, size_t reads_count, | |
628 MockWrite* writes, size_t writes_count) | |
629 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
630 write_delay_(write_delay), | |
631 ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) { | |
632 DCHECK_GE(write_delay_, 0); | |
633 set_connect_data(connect); | |
634 } | |
635 | |
636 virtual MockRead GetNextRead() { | |
637 if (write_delay_) | |
638 return MockRead(true, ERR_IO_PENDING); | |
639 return StaticSocketDataProvider::GetNextRead(); | |
640 } | |
641 | |
642 virtual MockWriteResult OnWrite(const std::string& data) { | |
643 MockWriteResult rv = StaticSocketDataProvider::OnWrite(data); | |
644 // Now that our write has completed, we can allow reads to continue. | |
645 if (!--write_delay_) | |
646 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
647 factory_.NewRunnableMethod(&DelayedSocketData::CompleteRead), 100); | |
648 return rv; | |
649 } | |
650 | |
651 virtual void Reset() { | |
652 set_socket(NULL); | |
653 factory_.RevokeAll(); | |
654 StaticSocketDataProvider::Reset(); | |
655 } | |
656 | |
657 void CompleteRead() { | |
658 if (socket()) | |
659 socket()->OnReadComplete(GetNextRead()); | |
660 } | |
661 | |
662 private: | |
663 int write_delay_; | |
664 ScopedRunnableMethodFactory<DelayedSocketData> factory_; | |
665 }; | |
666 | |
667 // A DataProvider where the reads are ordered. | 497 // A DataProvider where the reads are ordered. |
668 // If a read is requested before its sequence number is reached, we return an | 498 // If a read is requested before its sequence number is reached, we return an |
669 // ERR_IO_PENDING (that way we don't have to explicitly add a MockRead just to | 499 // ERR_IO_PENDING (that way we don't have to explicitly add a MockRead just to |
670 // wait). | 500 // wait). |
671 // The sequence number is incremented on every read and write operation. | 501 // The sequence number is incremented on every read and write operation. |
672 // The message loop may be interrupted by setting the high bit of the sequence | 502 // The message loop may be interrupted by setting the high bit of the sequence |
673 // number in the MockRead's sequence number. When that MockRead is reached, | 503 // number in the MockRead's sequence number. When that MockRead is reached, |
674 // we post a Quit message to the loop. This allows us to interrupt the reading | 504 // we post a Quit message to the loop. This allows us to interrupt the reading |
675 // of data before a complete message has arrived, and provides support for | 505 // of data before a complete message has arrived, and provides support for |
676 // testing server push when the request is issued while the response is in the | 506 // testing server push when the request is issued while the response is in the |
(...skipping 2053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2730 request.url = GURL("http://www.google.com/"); | 2560 request.url = GURL("http://www.google.com/"); |
2731 request.load_flags = 0; | 2561 request.load_flags = 0; |
2732 scoped_refptr<DelayedSocketData> data( | 2562 scoped_refptr<DelayedSocketData> data( |
2733 new DelayedSocketData(1, reads, arraysize(reads), | 2563 new DelayedSocketData(1, reads, arraysize(reads), |
2734 writes, arraysize(writes))); | 2564 writes, arraysize(writes))); |
2735 TransactionHelperResult out = TransactionHelper(request, data.get(), NULL); | 2565 TransactionHelperResult out = TransactionHelper(request, data.get(), NULL); |
2736 EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); | 2566 EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); |
2737 } | 2567 } |
2738 | 2568 |
2739 } // namespace net | 2569 } // namespace net |
OLD | NEW |