diff options
author | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-29 16:16:59 +0000 |
---|---|---|
committer | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-29 16:16:59 +0000 |
commit | 018aabcf36470b5d2cd625d1b5e1ce4b70772138 (patch) | |
tree | bef5a32916a962632c57e18352ad17e8a1c086fd | |
parent | c8386693c8e8cb4b9da464a62d1004cb3cc8efff (diff) | |
download | chromium_src-018aabcf36470b5d2cd625d1b5e1ce4b70772138.zip chromium_src-018aabcf36470b5d2cd625d1b5e1ce4b70772138.tar.gz chromium_src-018aabcf36470b5d2cd625d1b5e1ce4b70772138.tar.bz2 |
Add unit test for Basic authentication over SPDY.
BUG=46620
TEST=net_unittests --gtest_filter="*SpdyBasicAuth*"
Review URL: http://codereview.chromium.org/4148009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64433 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/http/http_proxy_client_socket_pool_unittest.cc | 3 | ||||
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 94 | ||||
-rw-r--r-- | net/spdy/spdy_test_util.cc | 59 | ||||
-rw-r--r-- | net/spdy/spdy_test_util.h | 8 |
4 files changed, 127 insertions, 37 deletions
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc index e1ca2fe..ae84ecc 100644 --- a/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/net/http/http_proxy_client_socket_pool_unittest.cc @@ -244,7 +244,8 @@ TEST_P(HttpProxyClientSocketPoolTest, NeedAuth) { CreateMockWrite(*rst, 2, true), }; scoped_ptr<spdy::SpdyFrame> resp( - ConstructSpdySynReplyError("407 Proxy Authentication Required", 1)); + ConstructSpdySynReplyError( + "407 Proxy Authentication Required", NULL, 0, 1)); MockRead spdy_reads[] = { CreateMockWrite(*resp, 1, true), MockRead(true, 0, 3) diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 99b50896..82be0c1 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -5,6 +5,7 @@ #include <string> #include <vector> +#include "net/base/auth.h" #include "net/base/net_log_unittest.h" #include "net/http/http_network_session_peer.h" #include "net/http/http_transaction_unittest.h" @@ -4511,7 +4512,8 @@ TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) { }; scoped_refptr<DelayedSocketData> data( - new DelayedSocketData(1, spdy_reads, arraysize(spdy_reads), + new DelayedSocketData(1, + spdy_reads, arraysize(spdy_reads), spdy_writes, arraysize(spdy_writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), BoundNetLog(), GetParam()); @@ -4541,4 +4543,94 @@ TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) { net::HttpStreamFactory::set_spdy_enabled(true); } + +// Tests that Basic authentication works over SPDY +TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) { + net::HttpStreamFactory::set_spdy_enabled(true); + + // The first request will be a bare GET, the second request will be a + // GET with an Authorization header. + scoped_ptr<spdy::SpdyFrame> req_get( + ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); + const char* const kExtraAuthorizationHeaders[] = { + "authorization", + "Basic Zm9vOmJhcg==", + }; + scoped_ptr<spdy::SpdyFrame> req_get_authorization( + ConstructSpdyGet( + kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders)/2, + false, 3, LOWEST)); + MockWrite spdy_writes[] = { + CreateMockWrite(*req_get, 1), + CreateMockWrite(*req_get_authorization, 4), + }; + + // The first response is a 401 authentication challenge, and the second + // response will be a 200 response since the second request includes a valid + // Authorization header. + const char* const kExtraAuthenticationHeaders[] = { + "WWW-Authenticate", + "Basic realm=\"MyRealm\"" + }; + scoped_ptr<spdy::SpdyFrame> resp_authentication( + ConstructSpdySynReplyError( + "401 Authentication Required", + kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2, + 1)); + scoped_ptr<spdy::SpdyFrame> body_authentication( + ConstructSpdyBodyFrame(1, true)); + scoped_ptr<spdy::SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3)); + scoped_ptr<spdy::SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true)); + MockRead spdy_reads[] = { + CreateMockRead(*resp_authentication, 2), + CreateMockRead(*body_authentication, 3), + CreateMockRead(*resp_data, 5), + CreateMockRead(*body_data, 6), + MockRead(true, 0, 7), + }; + + scoped_refptr<OrderedSocketData> data( + new OrderedSocketData(spdy_reads, arraysize(spdy_reads), + spdy_writes, arraysize(spdy_writes))); + HttpRequestInfo request(CreateGetRequest()); + BoundNetLog net_log; + NormalSpdyTransactionHelper helper(request, net_log, GetParam()); + + helper.RunPreTestSetup(); + helper.AddData(data.get()); + HttpNetworkTransaction* trans = helper.trans(); + TestCompletionCallback callback_start; + const int rv_start = trans->Start(&request, &callback_start, net_log); + EXPECT_EQ(ERR_IO_PENDING, rv_start); + const int rv_start_complete = callback_start.WaitForResult(); + EXPECT_EQ(OK, rv_start_complete); + + // Make sure the response has an auth challenge. + const HttpResponseInfo* const response_start = trans->GetResponseInfo(); + ASSERT_TRUE(response_start != NULL); + ASSERT_TRUE(response_start->headers != NULL); + EXPECT_EQ(401, response_start->headers->response_code()); + EXPECT_TRUE(response_start->was_fetched_via_spdy); + ASSERT_TRUE(response_start->auth_challenge.get() != NULL); + EXPECT_FALSE(response_start->auth_challenge->is_proxy); + EXPECT_EQ(L"basic", response_start->auth_challenge->scheme); + EXPECT_EQ(L"MyRealm", response_start->auth_challenge->realm); + + // Restart with a username/password. + const string16 kFoo(ASCIIToUTF16("foo")); + const string16 kBar(ASCIIToUTF16("bar")); + TestCompletionCallback callback_restart; + const int rv_restart = trans->RestartWithAuth(kFoo, kBar, &callback_restart); + EXPECT_EQ(ERR_IO_PENDING, rv_restart); + const int rv_restart_complete = callback_restart.WaitForResult(); + EXPECT_EQ(OK, rv_restart_complete); + // TODO(cbentzel): This is actually the same response object as before, but + // data has changed. + const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); + ASSERT_TRUE(response_restart != NULL); + ASSERT_TRUE(response_restart->headers != NULL); + EXPECT_EQ(200, response_restart->headers->response_code()); + EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); +} + } // namespace net diff --git a/net/spdy/spdy_test_util.cc b/net/spdy/spdy_test_util.cc index d3b82c0c6..896cd9d 100644 --- a/net/spdy/spdy_test_util.cc +++ b/net/spdy/spdy_test_util.cc @@ -519,23 +519,23 @@ spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[], associated_stream_id); } -// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET. -// |extra_headers| are the extra header-value pairs, which typically -// will vary the most between calls. +// Constructs a standard SPDY SYN_REPLY packet with the specified status code. // Returns a SpdyFrame. -spdy::SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id) { - static const char* const kStandardGetHeaders[] = { +spdy::SpdyFrame* ConstructSpdySynReplyError( + const char* const status, + const char* const* const extra_headers, + int extra_header_count, + int stream_id) { + const char* const kStandardGetHeaders[] = { "hello", "bye", "status", - "301 Moved Permanently", - "location", - "http://www.foo.com/index.php", + status, "version", "HTTP/1.1" }; - return ConstructSpdyControlFrame(NULL, - 0, + return ConstructSpdyControlFrame(extra_headers, + extra_header_count, false, stream_id, LOWEST, @@ -545,35 +545,28 @@ spdy::SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id) { arraysize(kStandardGetHeaders)); } +// Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET. +// |extra_headers| are the extra header-value pairs, which typically +// will vary the most between calls. +// Returns a SpdyFrame. +spdy::SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id) { + static const char* const kExtraHeaders[] = { + "location", + "http://www.foo.com/index.php", + }; + return ConstructSpdySynReplyError("301 Moved Permanently", kExtraHeaders, + arraysize(kExtraHeaders)/2, stream_id); +} + // Constructs a standard SPDY SYN_REPLY packet with an Internal Server // Error status code. // Returns a SpdyFrame. spdy::SpdyFrame* ConstructSpdySynReplyError(int stream_id) { - return ConstructSpdySynReplyError("500 Internal Server Error", 1); + return ConstructSpdySynReplyError("500 Internal Server Error", NULL, 0, 1); } -// Constructs a standard SPDY SYN_REPLY packet with the specified status code. -// Returns a SpdyFrame. -spdy::SpdyFrame* ConstructSpdySynReplyError(const char* const status, - int stream_id) { - static const char* const kStandardGetHeaders[] = { - "hello", - "bye", - "status", - status, - "version", - "HTTP/1.1" - }; - return ConstructSpdyControlFrame(NULL, - 0, - false, - stream_id, - LOWEST, - spdy::SYN_REPLY, - spdy::CONTROL_FLAG_NONE, - kStandardGetHeaders, - arraysize(kStandardGetHeaders)); -} + + // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET. // |extra_headers| are the extra header-value pairs, which typically diff --git a/net/spdy/spdy_test_util.h b/net/spdy/spdy_test_util.h index e3e85c8..aecf08e 100644 --- a/net/spdy/spdy_test_util.h +++ b/net/spdy/spdy_test_util.h @@ -260,8 +260,12 @@ spdy::SpdyFrame* ConstructSpdySynReplyError(int stream_id); // Constructs a standard SPDY SYN_REPLY packet with the specified status code. // Returns a SpdyFrame. -spdy::SpdyFrame* ConstructSpdySynReplyError(const char* const status, - int stream_id); +spdy::SpdyFrame* ConstructSpdySynReplyError( + const char* const status, + const char* const* const extra_headers, + int extra_header_count, + int stream_id); + // Constructs a standard SPDY POST SYN packet. // |extra_headers| are the extra header-value pairs, which typically // will vary the most between calls. |