diff options
author | jgraettinger@chromium.org <jgraettinger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-06 16:26:39 +0000 |
---|---|---|
committer | jgraettinger@chromium.org <jgraettinger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-06 16:26:39 +0000 |
commit | 601e03f15b6070c6fbd2b72b225a6d5432019236 (patch) | |
tree | de4c703313dcce2a192eb4d0e4ae817ad9125d16 | |
parent | 347082f464018ed2b151b95374fe43ac2710e731 (diff) | |
download | chromium_src-601e03f15b6070c6fbd2b72b225a6d5432019236.zip chromium_src-601e03f15b6070c6fbd2b72b225a6d5432019236.tar.gz chromium_src-601e03f15b6070c6fbd2b72b225a6d5432019236.tar.bz2 |
SPDY4/HTTP2 header handling: :version & :authority
:version is not a meaningful header for HTTP2, and shouldn't be carried.
The :host header has also been renamed :authority, but is semantically
equivalent. This CL updates spdy_http_utils.cc to accomodate SPDY4 handling
of these headers.
The :version header is extensively baked into unit tests, as is :host to
a lesser degree. Update those tests which require it, incrementally
shifting towards using SPDY intermediate representations to synthesize
frame fixtures.
BUG=345769
Review URL: https://codereview.chromium.org/225593005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262052 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 49 | ||||
-rw-r--r-- | net/spdy/spdy_http_utils.cc | 30 | ||||
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 30 | ||||
-rw-r--r-- | net/spdy/spdy_protocol.h | 3 | ||||
-rw-r--r-- | net/spdy/spdy_proxy_client_socket_unittest.cc | 176 | ||||
-rw-r--r-- | net/spdy/spdy_session_unittest.cc | 4 | ||||
-rw-r--r-- | net/spdy/spdy_stream_unittest.cc | 13 | ||||
-rw-r--r-- | net/spdy/spdy_test_util_common.cc | 221 | ||||
-rw-r--r-- | net/spdy/spdy_test_util_common.h | 9 |
9 files changed, 218 insertions, 317 deletions
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 02a77e4..d702f11 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -3388,23 +3388,15 @@ TEST_P(HttpNetworkTransactionTest, spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size())); // CONNECT to news.google.com:443 via SPDY. - const char* const kConnectHeaders2[] = { - spdy_util_.GetMethodKey(), "CONNECT", - spdy_util_.GetPathKey(), "news.google.com:443", - spdy_util_.GetHostKey(), "news.google.com", - spdy_util_.GetVersionKey(), "HTTP/1.1", - }; + SpdySynStreamIR connect2_ir(3); + spdy_util_.SetPriority(LOWEST, &connect2_ir); + connect2_ir.SetHeader(spdy_util_.GetMethodKey(), "CONNECT"); + connect2_ir.SetHeader(spdy_util_.GetPathKey(), "news.google.com:443"); + connect2_ir.SetHeader(spdy_util_.GetHostKey(), "news.google.com"); + spdy_util_.MaybeAddVersionHeader(&connect2_ir); scoped_ptr<SpdyFrame> connect2( - spdy_util_.ConstructSpdyControlFrame(NULL, - 0, - /*compressed*/ false, - 3, - LOWEST, - SYN_STREAM, - CONTROL_FLAG_NONE, - kConnectHeaders2, - arraysize(kConnectHeaders2), - 0)); + spdy_util_.CreateFramer(false)->SerializeFrame(connect2_ir)); + scoped_ptr<SpdyFrame> conn_resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); @@ -11277,20 +11269,21 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { LOWEST)); scoped_ptr<SpdyFrame> req1( spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); - - // SPDY GET for HTTP URL (through the proxy, but not the tunnel) scoped_ptr<SpdyFrame> wrapped_req1( spdy_util_.ConstructWrappedSpdyFrame(req1, 1)); - const char* const headers[] = { - spdy_util_.GetMethodKey(), "GET", - spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/", - spdy_util_.GetHostKey(), "www.google.com:443", - spdy_util_.GetSchemeKey(), "http", - spdy_util_.GetVersionKey(), "HTTP/1.1" - }; - scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame( - NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN, - headers, arraysize(headers), 0)); + + // SPDY GET for HTTP URL (through the proxy, but not the tunnel). + SpdySynStreamIR req2_ir(3); + spdy_util_.SetPriority(MEDIUM, &req2_ir); + req2_ir.set_fin(true); + req2_ir.SetHeader(spdy_util_.GetMethodKey(), "GET"); + req2_ir.SetHeader(spdy_util_.GetPathKey(), + spdy_util_.is_spdy2() ? http_url.c_str() : "/"); + req2_ir.SetHeader(spdy_util_.GetHostKey(), "www.google.com:443"); + req2_ir.SetHeader(spdy_util_.GetSchemeKey(), "http"); + spdy_util_.MaybeAddVersionHeader(&req2_ir); + scoped_ptr<SpdyFrame> req2( + spdy_util_.CreateFramer(false)->SerializeFrame(req2_ir)); MockWrite writes1[] = { CreateMockWrite(*connect, 0), diff --git a/net/spdy/spdy_http_utils.cc b/net/spdy/spdy_http_utils.cc index 76a0031..448c82f 100644 --- a/net/spdy/spdy_http_utils.cc +++ b/net/spdy/spdy_http_utils.cc @@ -29,18 +29,21 @@ bool SpdyHeadersToHttpResponse(const SpdyHeaderBlock& headers, std::string version; std::string status; - // The "status" and "version" headers are required. + // The "status" header is required. "version" is required below SPDY4. SpdyHeaderBlock::const_iterator it; it = headers.find(status_key); if (it == headers.end()) return false; status = it->second; - it = headers.find(version_key); - if (it == headers.end()) - return false; - version = it->second; - + if (protocol_version >= SPDY4) { + version = "HTTP/1.1"; + } else { + it = headers.find(version_key); + if (it == headers.end()) + return false; + version = it->second; + } std::string raw_headers(version); raw_headers.push_back(' '); raw_headers.append(status); @@ -90,7 +93,7 @@ void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info, while (it.GetNext()) { std::string name = StringToLowerASCII(it.name()); if (name == "connection" || name == "proxy-connection" || - name == "transfer-encoding") { + name == "transfer-encoding" || name == "host") { continue; } if (headers->find(name) == headers->end()) { @@ -114,14 +117,16 @@ void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info, else (*headers)["url"] = HttpUtil::SpecForRequest(info.url); } else { - (*headers)[":version"] = kHttpProtocolVersion; + if (protocol_version < SPDY4) { + (*headers)[":version"] = kHttpProtocolVersion; + (*headers)[":host"] = GetHostAndOptionalPort(info.url); + } else { + (*headers)[":authority"] = GetHostAndOptionalPort(info.url); + } (*headers)[":method"] = info.method; - (*headers)[":host"] = GetHostAndOptionalPort(info.url); (*headers)[":scheme"] = info.url.scheme(); (*headers)[":path"] = HttpUtil::PathForRequest(info.url); - headers->erase("host"); // this is kinda insane, spdy 3 spec. } - } COMPILE_ASSERT(HIGHEST - LOWEST < 4 && @@ -170,7 +175,8 @@ GURL GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers, } const char* scheme_header = protocol_version >= SPDY3 ? ":scheme" : "scheme"; - const char* host_header = protocol_version >= SPDY3 ? ":host" : "host"; + const char* host_header = protocol_version >= SPDY4 ? ":authority" : + (protocol_version >= SPDY3 ? ":host" : "host"); const char* path_header = protocol_version >= SPDY3 ? ":path" : "url"; std::string scheme; diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 51db006..7ce565b 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -3288,16 +3288,20 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) { test_cases[0].expected_headers["cookie"] += "val2"; test_cases[0].expected_headers["hello"] = "bye"; test_cases[0].expected_headers["status"] = "200"; - test_cases[0].expected_headers["version"] = "HTTP/1.1"; test_cases[1].expected_headers["hello"] = "bye"; test_cases[1].expected_headers["status"] = "200"; - test_cases[1].expected_headers["version"] = "HTTP/1.1"; test_cases[2].expected_headers["cookie"] = "val1,val2"; test_cases[2].expected_headers["hello"] = "bye"; test_cases[2].expected_headers["status"] = "200"; - test_cases[2].expected_headers["version"] = "HTTP/1.1"; + + if (spdy_util_.spdy_version() < SPDY4) { + // SPDY4/HTTP2 eliminates use of the :version header. + test_cases[0].expected_headers["version"] = "HTTP/1.1"; + test_cases[1].expected_headers["version"] = "HTTP/1.1"; + test_cases[2].expected_headers["version"] = "HTTP/1.1"; + } for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { scoped_ptr<SpdyFrame> req( @@ -3842,9 +3846,12 @@ TEST_P(SpdyNetworkTransactionTest, NetLog) { expected.push_back(std::string(spdy_util_.GetHostKey()) + ": www.google.com"); expected.push_back(std::string(spdy_util_.GetPathKey()) + ": /"); expected.push_back(std::string(spdy_util_.GetSchemeKey()) + ": http"); - expected.push_back(std::string(spdy_util_.GetVersionKey()) + ": HTTP/1.1"); expected.push_back(std::string(spdy_util_.GetMethodKey()) + ": GET"); expected.push_back("user-agent: Chrome"); + if (spdy_util_.spdy_version() < SPDY4) { + // SPDY4/HTTP2 eliminates use of the :version header. + expected.push_back(std::string(spdy_util_.GetVersionKey()) + ": HTTP/1.1"); + } EXPECT_EQ(expected.size(), header_list->GetSize()); for (std::vector<std::string>::const_iterator it = expected.begin(); it != expected.end(); @@ -5332,7 +5339,10 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock()); (*late_headers)[spdy_util_.GetStatusKey()] = "200"; - (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; + if (spdy_util_.spdy_version() < SPDY4) { + // SPDY4/HTTP2 eliminates use of the :version header. + (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; + } scoped_ptr<SpdyFrame> stream2_headers2( spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), false, @@ -5430,13 +5440,17 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { EXPECT_TRUE(response2.headers->HasHeaderValue( "scheme", "http")); EXPECT_TRUE(response2.headers->HasHeaderValue( - "host", "www.google.com")); - EXPECT_TRUE(response2.headers->HasHeaderValue( "path", "/foo.dat")); + if (spdy_util_.spdy_version() < SPDY4) { + EXPECT_TRUE(response2.headers->HasHeaderValue( + "host", "www.google.com")); + } else { + EXPECT_TRUE(response2.headers->HasHeaderValue( + "authority", "www.google.com")); + } } EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye")); EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200")); - EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1")); // Read the final EOF (which will close the session) data.RunFor(1); diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h index b5cabfa..9696bf1 100644 --- a/net/spdy/spdy_protocol.h +++ b/net/spdy/spdy_protocol.h @@ -506,6 +506,9 @@ class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR const base::StringPiece& value) { name_value_block_[name.as_string()] = value.as_string(); } + SpdyNameValueBlock* mutable_name_value_block() { + return &name_value_block_; + } protected: explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id); diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc index 653504d..ac382a2 100644 --- a/net/spdy/spdy_proxy_client_socket_unittest.cc +++ b/net/spdy/spdy_proxy_client_socket_unittest.cc @@ -71,6 +71,8 @@ class SpdyProxyClientSocketTest protected: void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes, size_t writes_count); + void PopulateConnectRequestIR(SpdySynStreamIR* syn_ir); + void PopulateConnectReplyIR(SpdySynReplyIR* reply_ir, const char* status); SpdyFrame* ConstructConnectRequestFrame(); SpdyFrame* ConstructConnectAuthRequestFrame(); SpdyFrame* ConstructConnectReplyFrame(); @@ -230,7 +232,6 @@ void SpdyProxyClientSocketTest::AssertConnectionEstablished() { const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); ASSERT_TRUE(response != NULL); ASSERT_EQ(200, response->headers->response_code()); - ASSERT_EQ("Connection Established", response->headers->GetStatusText()); } void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data, @@ -311,152 +312,69 @@ void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds( write_callback_.WaitForResult(); } +void SpdyProxyClientSocketTest::PopulateConnectRequestIR( + SpdySynStreamIR* syn_ir) { + spdy_util_.SetPriority(LOWEST, syn_ir); + syn_ir->SetHeader(spdy_util_.GetMethodKey(), "CONNECT"); + syn_ir->SetHeader(spdy_util_.GetPathKey(), kOriginHostPort); + syn_ir->SetHeader(spdy_util_.GetHostKey(), kOriginHost); + syn_ir->SetHeader("user-agent", kUserAgent); + spdy_util_.MaybeAddVersionHeader(syn_ir); +} + +void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdySynReplyIR* reply_ir, + const char* status) { + reply_ir->SetHeader(spdy_util_.GetStatusKey(), status); + spdy_util_.MaybeAddVersionHeader(reply_ir); +} + // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request. SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRequestFrame() { - const SpdyHeaderInfo kSynStartHeader = { - SYN_STREAM, - kStreamId, - 0, - net::ConvertRequestPriorityToSpdyPriority( - LOWEST, spdy_util_.spdy_version()), - 0, - CONTROL_FLAG_NONE, - false, - RST_STREAM_INVALID, - NULL, - 0, - DATA_FLAG_NONE - }; - bool spdy2 = spdy_util_.is_spdy2(); - const char* const kConnectHeaders[] = { - spdy2 ? "method" : ":method", "CONNECT", - spdy2 ? "url" : ":path", kOriginHostPort, - spdy2 ? "host" : ":host", kOriginHost, - "user-agent", kUserAgent, - spdy2 ? "version" : ":version", "HTTP/1.1", - }; - return spdy_util_.ConstructSpdyFrame( - kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2); + SpdySynStreamIR syn_ir(kStreamId); + PopulateConnectRequestIR(&syn_ir); + return spdy_util_.CreateFramer(false)->SerializeFrame(syn_ir); } // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes // Proxy-Authorization headers. -SpdyFrame* -SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() { - const SpdyHeaderInfo kSynStartHeader = { - SYN_STREAM, - kStreamId, - 0, - net::ConvertRequestPriorityToSpdyPriority( - LOWEST, spdy_util_.spdy_version()), - 0, - CONTROL_FLAG_NONE, - false, - RST_STREAM_INVALID, - NULL, - 0, - DATA_FLAG_NONE - }; - bool spdy2 = spdy_util_.is_spdy2(); - const char* const kConnectHeaders[] = { - spdy2 ? "method" : ":method", "CONNECT", - spdy2 ? "url" : ":path", kOriginHostPort, - spdy2 ? "host" : ":host", kOriginHost, - "user-agent", kUserAgent, - spdy2 ? "version" : ":version", "HTTP/1.1", - "proxy-authorization", "Basic Zm9vOmJhcg==", - }; - return spdy_util_.ConstructSpdyFrame( - kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2); +SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() { + SpdySynStreamIR syn_ir(kStreamId); + PopulateConnectRequestIR(&syn_ir); + syn_ir.SetHeader("proxy-authorization", "Basic Zm9vOmJhcg=="); + return spdy_util_.CreateFramer(false)->SerializeFrame(syn_ir); } // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT. SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() { - bool spdy2 = spdy_util_.is_spdy2(); - const char* const kStandardReplyHeaders[] = { - spdy2 ? "status" : ":status", "200 Connection Established", - spdy2 ? "version" : ":version", "HTTP/1.1" - }; - return spdy_util_.ConstructSpdyControlFrame(NULL, - 0, - false, - kStreamId, - LOWEST, - SYN_REPLY, - CONTROL_FLAG_NONE, - kStandardReplyHeaders, - arraysize(kStandardReplyHeaders), - 0); + SpdySynReplyIR reply_ir(kStreamId); + PopulateConnectReplyIR(&reply_ir, "200"); + return spdy_util_.CreateFramer(false)->SerializeFrame(reply_ir); } -// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT. -SpdyFrame* -SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() { - bool spdy2 = spdy_util_.is_spdy2(); - - const char* const kStandardReplyHeaders[] = { - spdy2 ? "status" : ":status", "407 Proxy Authentication Required", - spdy2 ? "version" : ":version", "HTTP/1.1", - "proxy-authenticate", "Basic realm=\"MyRealm1\"", - }; - - return spdy_util_.ConstructSpdyControlFrame(NULL, - 0, - false, - kStreamId, - LOWEST, - SYN_REPLY, - CONTROL_FLAG_NONE, - kStandardReplyHeaders, - arraysize(kStandardReplyHeaders), - 0); +// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT, +// including Proxy-Authenticate headers. +SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() { + SpdySynReplyIR reply_ir(kStreamId); + PopulateConnectReplyIR(&reply_ir, "407"); + reply_ir.SetHeader("proxy-authenticate", "Basic realm=\"MyRealm1\""); + return framer_.SerializeFrame(reply_ir); } // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect. -SpdyFrame* -SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() { - bool spdy2 = spdy_util_.is_spdy2(); - - const char* const kStandardReplyHeaders[] = { - spdy2 ? "status" : ":status", "302 Found", - spdy2 ? "version" : ":version", "HTTP/1.1", - "location", kRedirectUrl, - "set-cookie", "foo=bar" - }; - - return spdy_util_.ConstructSpdyControlFrame(NULL, - 0, - false, - kStreamId, - LOWEST, - SYN_REPLY, - CONTROL_FLAG_NONE, - kStandardReplyHeaders, - arraysize(kStandardReplyHeaders), - 0); +SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() { + SpdySynReplyIR reply_ir(kStreamId); + PopulateConnectReplyIR(&reply_ir, "302"); + reply_ir.SetHeader("location", kRedirectUrl); + reply_ir.SetHeader("set-cookie", "foo=bar"); + return framer_.SerializeFrame(reply_ir); } // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error. -SpdyFrame* -SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() { - bool spdy2 = spdy_util_.is_spdy2(); - - const char* const kStandardReplyHeaders[] = { - spdy2 ? "status" : ":status", "500 Internal Server Error", - spdy2 ? "version" : ":version", "HTTP/1.1", - }; - - return spdy_util_.ConstructSpdyControlFrame(NULL, - 0, - false, - kStreamId, - LOWEST, - SYN_REPLY, - CONTROL_FLAG_NONE, - kStandardReplyHeaders, - arraysize(kStandardReplyHeaders), - 0); +SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() { + SpdySynReplyIR reply_ir(kStreamId); + PopulateConnectReplyIR(&reply_ir, "500"); + return framer_.SerializeFrame(reply_ir); } SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame( @@ -507,8 +425,6 @@ TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) { const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); ASSERT_TRUE(response != NULL); ASSERT_EQ(407, response->headers->response_code()); - ASSERT_EQ("Proxy Authentication Required", - response->headers->GetStatusText()); } TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) { diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc index f3fb735..c7cddc7 100644 --- a/net/spdy/spdy_session_unittest.cc +++ b/net/spdy/spdy_session_unittest.cc @@ -3613,7 +3613,6 @@ void SpdySessionTest::RunResumeAfterUnstallTest( EXPECT_TRUE(delegate.send_headers_completed()); EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); - EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version")); EXPECT_EQ(std::string(), delegate.TakeReceivedData()); EXPECT_TRUE(data.at_write_eof()); } @@ -3810,12 +3809,10 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { EXPECT_TRUE(delegate1.send_headers_completed()); EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); - EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version")); EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); EXPECT_TRUE(delegate2.send_headers_completed()); EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); - EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); EXPECT_TRUE(data.at_write_eof()); @@ -3999,7 +3996,6 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { EXPECT_TRUE(delegate2.send_headers_completed()); EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); - EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); EXPECT_TRUE(delegate3.send_headers_completed()); diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc index d6bf58d..a1a04ec 100644 --- a/net/spdy/spdy_stream_unittest.cc +++ b/net/spdy/spdy_stream_unittest.cc @@ -170,8 +170,6 @@ TEST_P(SpdyStreamTest, SendDataAfterOpen) { EXPECT_TRUE(delegate.send_headers_completed()); EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); - EXPECT_EQ("HTTP/1.1", - delegate.GetResponseHeaderValue(spdy_util_.GetVersionKey())); EXPECT_EQ(std::string(kPostBody, kPostBodyLength), delegate.TakeReceivedData()); EXPECT_TRUE(data.at_write_eof()); @@ -285,8 +283,6 @@ TEST_P(SpdyStreamTest, StreamError) { EXPECT_TRUE(delegate.send_headers_completed()); EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); - EXPECT_EQ("HTTP/1.1", - delegate.GetResponseHeaderValue(spdy_util_.GetVersionKey())); EXPECT_EQ(std::string(kPostBody, kPostBodyLength), delegate.TakeReceivedData()); EXPECT_TRUE(data.at_write_eof()); @@ -368,8 +364,6 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) { EXPECT_TRUE(delegate.send_headers_completed()); EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); - EXPECT_EQ("HTTP/1.1", - delegate.GetResponseHeaderValue(spdy_util_.GetVersionKey())); EXPECT_EQ(std::string(), delegate.TakeReceivedData()); EXPECT_TRUE(data.at_write_eof()); } @@ -431,8 +425,6 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) { EXPECT_TRUE(delegate.send_headers_completed()); EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); - EXPECT_EQ("HTTP/1.1", - delegate.GetResponseHeaderValue(spdy_util_.GetVersionKey())); EXPECT_EQ(std::string(), delegate.TakeReceivedData()); EXPECT_TRUE(data.at_write_eof()); } @@ -876,7 +868,6 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest( EXPECT_TRUE(delegate.send_headers_completed()); EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); - EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version")); EXPECT_EQ(std::string(), delegate.TakeReceivedData()); EXPECT_TRUE(data.at_write_eof()); } @@ -971,7 +962,6 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest( EXPECT_TRUE(delegate.send_headers_completed()); EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); - EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version")); EXPECT_EQ(std::string(kPostBody, kPostBodyLength), delegate.TakeReceivedData()); EXPECT_TRUE(data.at_write_eof()); @@ -1041,7 +1031,8 @@ TEST_P(SpdyStreamTest, ReceivedBytes) { EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); int64 reply_frame_len = reply->size(); - int64 data_header_len = spdy_util_.CreateFramer()->GetDataFrameMinimumSize(); + int64 data_header_len = spdy_util_.CreateFramer(false) + ->GetDataFrameMinimumSize(); int64 data_frame_len = data_header_len + kPostBodyLength; int64 response_len = reply_frame_len + data_frame_len; diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc index 22ff5f6..116669b 100644 --- a/net/spdy/spdy_test_util_common.cc +++ b/net/spdy/spdy_test_util_common.cc @@ -861,13 +861,13 @@ SpdyFrame* SpdyTestUtil::ConstructSpdySettings( (it->second.first & SETTINGS_FLAG_PERSISTED) != 0, it->second.second); } - return CreateFramer()->SerializeSettings(settings_ir); + return CreateFramer(false)->SerializeFrame(settings_ir); } SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32 ping_id, bool is_ack) const { SpdyPingIR ping_ir(ping_id); ping_ir.set_is_ack(is_ack); - return CreateFramer()->SerializePing(ping_ir); + return CreateFramer(false)->SerializeFrame(ping_ir); } SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway() const { @@ -877,13 +877,13 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway() const { SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway( SpdyStreamId last_good_stream_id) const { SpdyGoAwayIR go_ir(last_good_stream_id, GOAWAY_OK, "go away"); - return CreateFramer()->SerializeGoAway(go_ir); + return CreateFramer(false)->SerializeFrame(go_ir); } SpdyFrame* SpdyTestUtil::ConstructSpdyWindowUpdate( const SpdyStreamId stream_id, uint32 delta_window_size) const { SpdyWindowUpdateIR update_ir(stream_id, delta_window_size); - return CreateFramer()->SerializeWindowUpdate(update_ir); + return CreateFramer(false)->SerializeFrame(update_ir); } // TODO(jgraettinger): Eliminate uses of this method in tests (prefer @@ -892,7 +892,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyRstStream( SpdyStreamId stream_id, SpdyRstStreamStatus status) const { SpdyRstStreamIR rst_ir(stream_id, status, "RST"); - return CreateFramer()->SerializeRstStream(rst_ir); + return CreateFramer(false)->SerializeRstStream(rst_ir); } SpdyFrame* SpdyTestUtil::ConstructSpdyGet( @@ -922,25 +922,19 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGet(const char* const extra_headers[], int stream_id, RequestPriority request_priority, bool direct) const { - const bool spdy2 = is_spdy2(); - const char* url = (spdy2 && !direct) ? "http://www.google.com/" : "/"; - const char* const kStandardGetHeaders[] = { - GetMethodKey(), "GET", - GetHostKey(), "www.google.com", - GetSchemeKey(), "http", - GetVersionKey(), "HTTP/1.1", - GetPathKey(), url - }; - return ConstructSpdyControlFrame(extra_headers, - extra_header_count, - compressed, - stream_id, - request_priority, - SYN_STREAM, - CONTROL_FLAG_FIN, - kStandardGetHeaders, - arraysize(kStandardGetHeaders), - 0); + SpdySynStreamIR syn_stream(stream_id); + syn_stream.set_priority( + ConvertRequestPriorityToSpdyPriority(request_priority, spdy_version_)); + syn_stream.set_fin(true); + syn_stream.SetHeader(GetMethodKey(), "GET"); + syn_stream.SetHeader(GetHostKey(), "www.google.com"); + syn_stream.SetHeader(GetSchemeKey(), "http"); + syn_stream.SetHeader(GetPathKey(), (is_spdy2() && !direct) ? + "http://www.google.com/" : "/"); + MaybeAddVersionHeader(&syn_stream); + AppendToHeaderBlock(extra_headers, extra_header_count, + syn_stream.mutable_name_value_block()); + return CreateFramer(compressed)->SerializeFrame(syn_stream); } SpdyFrame* SpdyTestUtil::ConstructSpdyConnect( @@ -948,22 +942,16 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyConnect( int extra_header_count, int stream_id, RequestPriority priority) const { - const char* const kConnectHeaders[] = { - GetMethodKey(), "CONNECT", - GetPathKey(), "www.google.com:443", - GetHostKey(), "www.google.com", - GetVersionKey(), "HTTP/1.1", - }; - return ConstructSpdyControlFrame(extra_headers, - extra_header_count, - /*compressed*/ false, - stream_id, - priority, - SYN_STREAM, - CONTROL_FLAG_NONE, - kConnectHeaders, - arraysize(kConnectHeaders), - 0); + SpdySynStreamIR syn_stream(stream_id); + syn_stream.set_priority( + ConvertRequestPriorityToSpdyPriority(priority, spdy_version_)); + syn_stream.SetHeader(GetMethodKey(), "CONNECT"); + syn_stream.SetHeader(GetPathKey(), "www.google.com:443"); + syn_stream.SetHeader(GetHostKey(), "www.google.com"); + MaybeAddVersionHeader(&syn_stream); + AppendToHeaderBlock(extra_headers, extra_header_count, + syn_stream.mutable_name_value_block()); + return CreateFramer(false)->SerializeFrame(syn_stream); } SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[], @@ -974,7 +962,9 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[], scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); (*headers)["hello"] = "bye"; (*headers)[GetStatusKey()] = "200 OK"; - (*headers)[GetVersionKey()] = "HTTP/1.1"; + if (include_version_header()) { + (*headers)[GetVersionKey()] = "HTTP/1.1"; + } AddUrlToHeaderBlock(url, headers.get()); AppendToHeaderBlock(extra_headers, extra_header_count, headers.get()); return ConstructSpdyControlFrame(headers.Pass(), @@ -996,7 +986,9 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[], scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); (*headers)["hello"] = "bye"; (*headers)[GetStatusKey()] = status; - (*headers)[GetVersionKey()] = "HTTP/1.1"; + if (include_version_header()) { + (*headers)[GetVersionKey()] = "HTTP/1.1"; + } (*headers)["location"] = location; AddUrlToHeaderBlock(url, headers.get()); AppendToHeaderBlock(extra_headers, extra_header_count, headers.get()); @@ -1013,20 +1005,12 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPushHeaders( int stream_id, const char* const extra_headers[], int extra_header_count) { - const char* const kStandardGetHeaders[] = { - GetStatusKey(), "200 OK", - GetVersionKey(), "HTTP/1.1" - }; - return ConstructSpdyControlFrame(extra_headers, - extra_header_count, - false, - stream_id, - LOWEST, - HEADERS, - CONTROL_FLAG_NONE, - kStandardGetHeaders, - arraysize(kStandardGetHeaders), - 0); + SpdyHeadersIR headers(stream_id); + headers.SetHeader(GetStatusKey(), "200 OK"); + MaybeAddVersionHeader(&headers); + AppendToHeaderBlock(extra_headers, extra_header_count, + headers.mutable_name_value_block()); + return CreateFramer(false)->SerializeFrame(headers); } SpdyFrame* SpdyTestUtil::ConstructSpdySynReplyError( @@ -1034,21 +1018,13 @@ SpdyFrame* SpdyTestUtil::ConstructSpdySynReplyError( const char* const* const extra_headers, int extra_header_count, int stream_id) { - const char* const kStandardGetHeaders[] = { - "hello", "bye", - GetStatusKey(), status, - GetVersionKey(), "HTTP/1.1" - }; - return ConstructSpdyControlFrame(extra_headers, - extra_header_count, - false, - stream_id, - LOWEST, - SYN_REPLY, - CONTROL_FLAG_NONE, - kStandardGetHeaders, - arraysize(kStandardGetHeaders), - 0); + SpdySynReplyIR syn_reply(stream_id); + syn_reply.SetHeader("hello", "bye"); + syn_reply.SetHeader(GetStatusKey(), status); + MaybeAddVersionHeader(&syn_reply); + AppendToHeaderBlock(extra_headers, extra_header_count, + syn_reply.mutable_name_value_block()); + return CreateFramer(false)->SerializeFrame(syn_reply); } SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReplyRedirect(int stream_id) { @@ -1067,21 +1043,13 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReply( const char* const extra_headers[], int extra_header_count, int stream_id) { - const char* const kStandardGetHeaders[] = { - "hello", "bye", - GetStatusKey(), "200", - GetVersionKey(), "HTTP/1.1" - }; - return ConstructSpdyControlFrame(extra_headers, - extra_header_count, - false, - stream_id, - LOWEST, - SYN_REPLY, - CONTROL_FLAG_NONE, - kStandardGetHeaders, - arraysize(kStandardGetHeaders), - 0); + SpdySynReplyIR syn_reply(stream_id); + syn_reply.SetHeader("hello", "bye"); + syn_reply.SetHeader(GetStatusKey(), "200"); + MaybeAddVersionHeader(&syn_reply); + AppendToHeaderBlock(extra_headers, extra_header_count, + syn_reply.mutable_name_value_block()); + return CreateFramer(false)->SerializeFrame(syn_reply); } SpdyFrame* SpdyTestUtil::ConstructSpdyPost(const char* url, @@ -1110,44 +1078,29 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPost(const char* url, SpdyFrame* SpdyTestUtil::ConstructChunkedSpdyPost( const char* const extra_headers[], int extra_header_count) { - const char* post_headers[] = { - GetMethodKey(), "POST", - GetPathKey(), "/", - GetHostKey(), "www.google.com", - GetSchemeKey(), "http", - GetVersionKey(), "HTTP/1.1" - }; - return ConstructSpdyControlFrame(extra_headers, - extra_header_count, - false, - 1, - LOWEST, - SYN_STREAM, - CONTROL_FLAG_NONE, - post_headers, - arraysize(post_headers), - 0); + SpdySynStreamIR syn_stream(1); + syn_stream.SetHeader(GetMethodKey(), "POST"); + syn_stream.SetHeader(GetPathKey(), "/"); + syn_stream.SetHeader(GetHostKey(), "www.google.com"); + syn_stream.SetHeader(GetSchemeKey(), "http"); + MaybeAddVersionHeader(&syn_stream); + SetPriority(LOWEST, &syn_stream); + AppendToHeaderBlock(extra_headers, extra_header_count, + syn_stream.mutable_name_value_block()); + return CreateFramer(false)->SerializeFrame(syn_stream); } SpdyFrame* SpdyTestUtil::ConstructSpdyPostSynReply( const char* const extra_headers[], int extra_header_count) { - const char* const kStandardGetHeaders[] = { - "hello", "bye", - GetStatusKey(), "200", - GetPathKey(), "/index.php", - GetVersionKey(), "HTTP/1.1" - }; - return ConstructSpdyControlFrame(extra_headers, - extra_header_count, - false, - 1, - LOWEST, - SYN_REPLY, - CONTROL_FLAG_NONE, - kStandardGetHeaders, - arraysize(kStandardGetHeaders), - 0); + SpdySynReplyIR syn_reply(1); + syn_reply.SetHeader("hello", "bye"); + syn_reply.SetHeader(GetStatusKey(), "200"); + syn_reply.SetHeader(GetPathKey(), "/index.php"); + MaybeAddVersionHeader(&syn_reply); + AppendToHeaderBlock(extra_headers, extra_header_count, + syn_reply.mutable_name_value_block()); + return CreateFramer(false)->SerializeFrame(syn_reply); } SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id, bool fin) { @@ -1192,8 +1145,10 @@ const SpdyHeaderInfo SpdyTestUtil::MakeSpdyHeader(SpdyFrameType type) { return kHeader; } -scoped_ptr<SpdyFramer> SpdyTestUtil::CreateFramer() const { - return scoped_ptr<SpdyFramer>(new SpdyFramer(spdy_version_)); +scoped_ptr<SpdyFramer> SpdyTestUtil::CreateFramer(bool compressed) const { + scoped_ptr<SpdyFramer> framer(new SpdyFramer(spdy_version_)); + framer->set_enable_compression(compressed); + return framer.Pass(); } const char* SpdyTestUtil::GetMethodKey() const { @@ -1205,7 +1160,12 @@ const char* SpdyTestUtil::GetStatusKey() const { } const char* SpdyTestUtil::GetHostKey() const { - return is_spdy2() ? "host" : ":host"; + if (protocol_ < kProtoSPDY3) + return "host"; + if (protocol_ < kProtoSPDY4a2) + return ":host"; + else + return ":authority"; } const char* SpdyTestUtil::GetSchemeKey() const { @@ -1231,7 +1191,9 @@ scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock( (*headers)[GetPathKey()] = path.c_str(); (*headers)[GetHostKey()] = host.c_str(); (*headers)[GetSchemeKey()] = scheme.c_str(); - (*headers)[GetVersionKey()] = "HTTP/1.1"; + if (include_version_header()) { + (*headers)[GetVersionKey()] = "HTTP/1.1"; + } if (content_length) { std::string length_str = base::Int64ToString(*content_length); (*headers)["content-length"] = length_str; @@ -1239,4 +1201,17 @@ scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock( return headers.Pass(); } +void SpdyTestUtil::MaybeAddVersionHeader( + SpdyFrameWithNameValueBlockIR* frame_ir) const { + if (include_version_header()) { + frame_ir->SetHeader(GetVersionKey(), "HTTP/1.1"); + } +} + +void SpdyTestUtil::SetPriority(RequestPriority priority, + SpdySynStreamIR* ir) const { + ir->set_priority(ConvertRequestPriorityToSpdyPriority( + priority, spdy_version())); +} + } // namespace net diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h index 668a7e8..24dc1d5 100644 --- a/net/spdy/spdy_test_util_common.h +++ b/net/spdy/spdy_test_util_common.h @@ -508,10 +508,17 @@ class SpdyTestUtil { const SpdyHeaderInfo MakeSpdyHeader(SpdyFrameType type); + // For versions below SPDY4, adds the version HTTP/1.1 header. + void MaybeAddVersionHeader(SpdyFrameWithNameValueBlockIR* frame_ir) const; + + // Maps |priority| to SPDY version priority, and sets it on |frame_ir|. + void SetPriority(RequestPriority priority, SpdySynStreamIR* frame_ir) const; + NextProto protocol() const { return protocol_; } SpdyMajorVersion spdy_version() const { return spdy_version_; } bool is_spdy2() const { return protocol_ < kProtoSPDY3; } - scoped_ptr<SpdyFramer> CreateFramer() const; + bool include_version_header() const { return protocol_ < kProtoSPDY4a2; } + scoped_ptr<SpdyFramer> CreateFramer(bool compressed) const; const char* GetMethodKey() const; const char* GetStatusKey() const; |