OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_proxy_client_socket.h" | 5 #include "net/spdy/spdy_proxy_client_socket.h" |
6 | 6 |
7 #include "base/utf_string_conversions.h" | 7 #include "base/utf_string_conversions.h" |
8 #include "net/base/address_list.h" | 8 #include "net/base/address_list.h" |
9 #include "net/base/net_log.h" | 9 #include "net/base/net_log.h" |
10 #include "net/base/net_log_unittest.h" | 10 #include "net/base/net_log_unittest.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 | 59 |
60 virtual void TearDown(); | 60 virtual void TearDown(); |
61 | 61 |
62 protected: | 62 protected: |
63 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes, | 63 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes, |
64 size_t writes_count); | 64 size_t writes_count); |
65 spdy::SpdyFrame* ConstructConnectRequestFrame(); | 65 spdy::SpdyFrame* ConstructConnectRequestFrame(); |
66 spdy::SpdyFrame* ConstructConnectAuthRequestFrame(); | 66 spdy::SpdyFrame* ConstructConnectAuthRequestFrame(); |
67 spdy::SpdyFrame* ConstructConnectReplyFrame(); | 67 spdy::SpdyFrame* ConstructConnectReplyFrame(); |
68 spdy::SpdyFrame* ConstructConnectAuthReplyFrame(); | 68 spdy::SpdyFrame* ConstructConnectAuthReplyFrame(); |
69 spdy::SpdyFrame* ConstructNtlmAuthReplyFrame(); | |
70 spdy::SpdyFrame* ConstructConnectErrorReplyFrame(); | 69 spdy::SpdyFrame* ConstructConnectErrorReplyFrame(); |
71 spdy::SpdyFrame* ConstructBodyFrame(const char* data, int length); | 70 spdy::SpdyFrame* ConstructBodyFrame(const char* data, int length); |
72 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size); | 71 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size); |
73 void AssertConnectSucceeds(); | 72 void AssertConnectSucceeds(); |
74 void AssertConnectFails(int result); | 73 void AssertConnectFails(int result); |
75 void AssertConnectionEstablished(); | 74 void AssertConnectionEstablished(); |
76 void AssertSyncReadEquals(const char* data, int len); | 75 void AssertSyncReadEquals(const char* data, int len); |
77 void AssertAsyncReadEquals(const char* data, int len); | 76 void AssertAsyncReadEquals(const char* data, int len); |
78 void AssertReadStarts(const char* data, int len); | 77 void AssertReadStarts(const char* data, int len); |
79 void AssertReadReturns(const char* data, int len); | 78 void AssertReadReturns(const char* data, int len); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 0, | 380 0, |
382 false, | 381 false, |
383 kStreamId, | 382 kStreamId, |
384 LOWEST, | 383 LOWEST, |
385 spdy::SYN_REPLY, | 384 spdy::SYN_REPLY, |
386 spdy::CONTROL_FLAG_NONE, | 385 spdy::CONTROL_FLAG_NONE, |
387 kStandardReplyHeaders, | 386 kStandardReplyHeaders, |
388 arraysize(kStandardReplyHeaders)); | 387 arraysize(kStandardReplyHeaders)); |
389 } | 388 } |
390 | 389 |
391 // Constructs a SPDY SYN_REPLY frame to match the SPDY CONNECT which | |
392 // requires Proxy Authentication using NTLM. | |
393 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructNtlmAuthReplyFrame() { | |
394 const char* const kStandardReplyHeaders[] = { | |
395 "status", "407 Proxy Authentication Required", | |
396 "version", "HTTP/1.1", | |
397 "proxy-authenticate", "NTLM", | |
398 }; | |
399 | |
400 return ConstructSpdyControlFrame(NULL, | |
401 0, | |
402 false, | |
403 kStreamId, | |
404 LOWEST, | |
405 spdy::SYN_REPLY, | |
406 spdy::CONTROL_FLAG_NONE, | |
407 kStandardReplyHeaders, | |
408 arraysize(kStandardReplyHeaders)); | |
409 } | |
410 | |
411 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error. | 390 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error. |
412 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() { | 391 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() { |
413 const char* const kStandardReplyHeaders[] = { | 392 const char* const kStandardReplyHeaders[] = { |
414 "status", "500 Internal Server Error", | 393 "status", "500 Internal Server Error", |
415 "version", "HTTP/1.1", | 394 "version", "HTTP/1.1", |
416 }; | 395 }; |
417 | 396 |
418 return ConstructSpdyControlFrame(NULL, | 397 return ConstructSpdyControlFrame(NULL, |
419 0, | 398 0, |
420 false, | 399 false, |
(...skipping 26 matching lines...) Expand all Loading... |
447 | 426 |
448 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | 427 Initialize(reads, arraysize(reads), writes, arraysize(writes)); |
449 | 428 |
450 ASSERT_FALSE(sock_->IsConnected()); | 429 ASSERT_FALSE(sock_->IsConnected()); |
451 | 430 |
452 AssertConnectSucceeds(); | 431 AssertConnectSucceeds(); |
453 | 432 |
454 AssertConnectionEstablished(); | 433 AssertConnectionEstablished(); |
455 } | 434 } |
456 | 435 |
457 TEST_F(SpdyProxyClientSocketTest, ConnectWithUnsupportedAuth) { | |
458 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); | |
459 MockWrite writes[] = { | |
460 CreateMockWrite(*conn, 0, false), | |
461 }; | |
462 | |
463 scoped_ptr<spdy::SpdyFrame> resp(ConstructNtlmAuthReplyFrame()); | |
464 MockRead reads[] = { | |
465 CreateMockRead(*resp, 1, true), | |
466 MockRead(true, 0, 3), // EOF | |
467 }; | |
468 | |
469 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
470 | |
471 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED); | |
472 } | |
473 | |
474 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRequested) { | 436 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRequested) { |
475 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); | 437 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); |
476 MockWrite writes[] = { | 438 MockWrite writes[] = { |
477 CreateMockWrite(*conn, 0, false), | 439 CreateMockWrite(*conn, 0, false), |
478 }; | 440 }; |
479 | 441 |
480 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame()); | 442 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame()); |
481 MockRead reads[] = { | 443 MockRead reads[] = { |
482 CreateMockRead(*resp, 1, true), | 444 CreateMockRead(*resp, 1, true), |
483 MockRead(true, 0, 3), // EOF | 445 MockRead(true, 0, 3), // EOF |
484 }; | 446 }; |
485 | 447 |
486 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | 448 Initialize(reads, arraysize(reads), writes, arraysize(writes)); |
487 | 449 |
488 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED); | 450 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED); |
489 | 451 |
490 const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); | 452 const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); |
491 ASSERT_TRUE(response != NULL); | 453 ASSERT_TRUE(response != NULL); |
492 ASSERT_EQ(407, response->headers->response_code()); | 454 ASSERT_EQ(407, response->headers->response_code()); |
493 ASSERT_EQ("Proxy Authentication Required", | 455 ASSERT_EQ("Proxy Authentication Required", |
494 response->headers->GetStatusText()); | 456 response->headers->GetStatusText()); |
495 } | 457 } |
496 | 458 |
497 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) { | 459 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) { |
498 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectAuthRequestFrame()); | 460 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectAuthRequestFrame()); |
499 MockWrite writes[] = { | 461 MockWrite writes[] = { |
500 CreateMockWrite(*conn, 0, false), | 462 CreateMockWrite(*conn, 0, false), |
501 }; | 463 }; |
502 | 464 |
503 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame()); | 465 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame()); |
504 MockRead reads[] = { | 466 MockRead reads[] = { |
505 CreateMockRead(*resp, 1, true), | 467 CreateMockRead(*resp, 1, true), |
506 MockRead(true, 0, 3), // EOF | 468 MockRead(true, 0, 3), // EOF |
507 }; | 469 }; |
508 | 470 |
509 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | 471 Initialize(reads, arraysize(reads), writes, arraysize(writes)); |
510 AddAuthToCache(); | 472 AddAuthToCache(); |
511 | 473 |
512 AssertConnectSucceeds(); | 474 AssertConnectSucceeds(); |
513 | 475 |
514 AssertConnectionEstablished(); | 476 AssertConnectionEstablished(); |
515 } | 477 } |
516 | 478 |
517 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRestart) { | |
518 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); | |
519 scoped_ptr<spdy::SpdyFrame> auth(ConstructConnectAuthRequestFrame()); | |
520 MockWrite writes[] = { | |
521 CreateMockWrite(*conn, 0, false), | |
522 }; | |
523 | |
524 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame()); | |
525 scoped_ptr<spdy::SpdyFrame> auth_resp(ConstructConnectReplyFrame()); | |
526 MockRead reads[] = { | |
527 CreateMockRead(*resp, 1, true), | |
528 MockRead(true, 0, 3), // EOF | |
529 }; | |
530 | |
531 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
532 | |
533 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED); | |
534 | |
535 const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); | |
536 ASSERT_TRUE(response != NULL); | |
537 ASSERT_EQ(407, response->headers->response_code()); | |
538 ASSERT_EQ("Proxy Authentication Required", | |
539 response->headers->GetStatusText()); | |
540 | |
541 AddAuthToCache(); | |
542 | |
543 ASSERT_EQ(OK, sock_->RestartWithAuth(&read_callback_)); | |
544 // A SpdyProxyClientSocket sits on a single SPDY stream which can | |
545 // only be used for a single request/response. | |
546 ASSERT_FALSE(sock_->IsConnectedAndIdle()); | |
547 } | |
548 | |
549 TEST_F(SpdyProxyClientSocketTest, ConnectFails) { | 479 TEST_F(SpdyProxyClientSocketTest, ConnectFails) { |
550 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); | 480 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); |
551 MockWrite writes[] = { | 481 MockWrite writes[] = { |
552 CreateMockWrite(*conn, 0, false), | 482 CreateMockWrite(*conn, 0, false), |
553 }; | 483 }; |
554 | 484 |
555 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame()); | 485 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame()); |
556 MockRead reads[] = { | 486 MockRead reads[] = { |
557 MockRead(true, 0, 1), // EOF | 487 MockRead(true, 0, 1), // EOF |
558 }; | 488 }; |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); | 814 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); |
885 MockRead reads[] = { | 815 MockRead reads[] = { |
886 CreateMockRead(*resp, 1, true), | 816 CreateMockRead(*resp, 1, true), |
887 CreateMockRead(*msg1, 2, true), | 817 CreateMockRead(*msg1, 2, true), |
888 CreateMockRead(*msg2, 3, true), | 818 CreateMockRead(*msg2, 3, true), |
889 MockRead(true, 0, 4), // EOF | 819 MockRead(true, 0, 4), // EOF |
890 }; | 820 }; |
891 | 821 |
892 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | 822 Initialize(reads, arraysize(reads), writes, arraysize(writes)); |
893 | 823 |
894 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED); | 824 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED); |
895 | 825 |
896 Run(2); // SpdySession consumes the next two reads and sends then to | 826 Run(2); // SpdySession consumes the next two reads and sends then to |
897 // sock_ to be buffered. | 827 // sock_ to be buffered. |
898 AssertSyncReadEquals(kMsg1, kLen1); | 828 AssertSyncReadEquals(kMsg1, kLen1); |
899 AssertSyncReadEquals(kMsg2, kLen2); | 829 AssertSyncReadEquals(kMsg2, kLen2); |
900 } | 830 } |
901 | 831 |
902 TEST_F(SpdyProxyClientSocketTest, ReadErrorResponseBody) { | 832 TEST_F(SpdyProxyClientSocketTest, ReadErrorResponseBody) { |
903 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); | 833 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); |
904 MockWrite writes[] = { | 834 MockWrite writes[] = { |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1)); | 1162 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1)); |
1233 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, kLen1, &read_callback_)); | 1163 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, kLen1, &read_callback_)); |
1234 | 1164 |
1235 sock_->Disconnect(); | 1165 sock_->Disconnect(); |
1236 | 1166 |
1237 EXPECT_FALSE(sock_->IsConnected()); | 1167 EXPECT_FALSE(sock_->IsConnected()); |
1238 EXPECT_FALSE(read_callback_.have_result()); | 1168 EXPECT_FALSE(read_callback_.have_result()); |
1239 } | 1169 } |
1240 | 1170 |
1241 } // namespace net | 1171 } // namespace net |
OLD | NEW |