| 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 |