summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-29 16:16:59 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-29 16:16:59 +0000
commit018aabcf36470b5d2cd625d1b5e1ce4b70772138 (patch)
treebef5a32916a962632c57e18352ad17e8a1c086fd
parentc8386693c8e8cb4b9da464a62d1004cb3cc8efff (diff)
downloadchromium_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.cc3
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc94
-rw-r--r--net/spdy/spdy_test_util.cc59
-rw-r--r--net/spdy/spdy_test_util.h8
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.