summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorbengr@google.com <bengr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-03 04:09:29 +0000
committerbengr@google.com <bengr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-03 04:09:29 +0000
commit7c6f7ba3979d71df4c3914746ef3ab4b1b9c88eb (patch)
treea7632309261661d8f50d113f952d4a02930d60c4 /net
parent8ecd3cdd1876ff6b6079385ba05c666fc9580ec2 (diff)
downloadchromium_src-7c6f7ba3979d71df4c3914746ef3ab4b1b9c88eb.zip
chromium_src-7c6f7ba3979d71df4c3914746ef3ab4b1b9c88eb.tar.gz
chromium_src-7c6f7ba3979d71df4c3914746ef3ab4b1b9c88eb.tar.bz2
Enables a SPDY proxy to push resources from arbitrary origins.
This change will make it possible for Chromium to accept a resource that is pushed by a SPDY proxy, even if the SYN control frame advertises a URL whose origin is different from its associated request. The advantage of this change is, potentially, better performance. This change is disabled by default and activated by a new switch. BUG=113427 TEST= Review URL: http://codereview.chromium.org/9475037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130302 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_network_transaction_spdy21_unittest.cc107
-rw-r--r--net/http/http_network_transaction_spdy2_unittest.cc107
-rw-r--r--net/http/http_network_transaction_spdy3_unittest.cc107
-rw-r--r--net/spdy/spdy_network_transaction_spdy21_unittest.cc5
-rw-r--r--net/spdy/spdy_network_transaction_spdy2_unittest.cc5
-rw-r--r--net/spdy/spdy_network_transaction_spdy3_unittest.cc5
-rw-r--r--net/spdy/spdy_session.cc36
-rw-r--r--net/spdy/spdy_session.h8
8 files changed, 370 insertions, 10 deletions
diff --git a/net/http/http_network_transaction_spdy21_unittest.cc b/net/http/http_network_transaction_spdy21_unittest.cc
index 6a6e706..93b50a3 100644
--- a/net/http/http_network_transaction_spdy21_unittest.cc
+++ b/net/http/http_network_transaction_spdy21_unittest.cc
@@ -4883,6 +4883,113 @@ TEST_F(HttpNetworkTransactionSpdy21Test, BasicAuthSpdyProxy) {
session->CloseAllConnections();
}
+// Test that an explicitly trusted SPDY proxy can push a resource from an
+// origin that is different from that of its associated resource.
+TEST_F(HttpNetworkTransactionSpdy21Test, CrossOriginProxyPush) {
+ HttpRequestInfo request;
+ HttpRequestInfo push_request;
+
+ static const unsigned char kPushBodyFrame[] = {
+ 0x00, 0x00, 0x00, 0x02, // header, ID
+ 0x01, 0x00, 0x00, 0x06, // FIN, length
+ 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
+ };
+
+ request.method = "GET";
+ request.url = GURL("http://www.google.com/");
+ push_request.method = "GET";
+ push_request.url = GURL("http://www.another-origin.com/foo.dat");
+
+ // Enable cross-origin push.
+ net::SpdySession::set_allow_spdy_proxy_push_across_origins("myproxy:70");
+
+ // Configure against https proxy server "myproxy:70".
+ SessionDependencies session_deps(
+ ProxyService::CreateFixed("https://myproxy:70"));
+ CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
+ session_deps.net_log = log.bound().net_log();
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+
+ scoped_ptr<SpdyFrame>
+ stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
+
+ MockWrite spdy_writes[] = {
+ CreateMockWrite(*stream1_syn, 1, ASYNC)
+ };
+
+ scoped_ptr<SpdyFrame>
+ stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+
+ scoped_ptr<SpdyFrame>
+ stream1_body(ConstructSpdyBodyFrame(1, true));
+
+ scoped_ptr<SpdyFrame>
+ stream2_syn(ConstructSpdyPush(NULL,
+ 0,
+ 2,
+ 1,
+ "http://www.another-origin.com/foo.dat"));
+
+ MockRead spdy_reads[] = {
+ CreateMockRead(*stream1_reply, 2, ASYNC),
+ CreateMockRead(*stream2_syn, 3, ASYNC),
+ CreateMockRead(*stream1_body, 4, ASYNC),
+ MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+ arraysize(kPushBodyFrame), 5),
+ MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
+ };
+
+ scoped_ptr<OrderedSocketData> spdy_data(
+ new OrderedSocketData(
+ spdy_reads, arraysize(spdy_reads),
+ spdy_writes, arraysize(spdy_writes)));
+ session_deps.socket_factory.AddSocketDataProvider(spdy_data.get());
+ // Negotiate SPDY to the proxy
+ SSLSocketDataProvider proxy(ASYNC, OK);
+ proxy.SetNextProto(kProtoSPDY21);
+ session_deps.socket_factory.AddSSLSocketDataProvider(&proxy);
+
+ scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+
+ scoped_ptr<HttpTransaction> push_trans(new HttpNetworkTransaction(session));
+ rv = push_trans->Start(&push_request, callback.callback(), log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
+
+ ASSERT_TRUE(response != NULL);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+
+ EXPECT_EQ(200, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ std::string response_data;
+ rv = ReadTransaction(trans.get(), &response_data);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("hello!", response_data);
+
+ // Verify the pushed stream.
+ EXPECT_TRUE(push_response->headers != NULL);
+ EXPECT_EQ(200, push_response->headers->response_code());
+
+ rv = ReadTransaction(push_trans.get(), &response_data);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("pushed", response_data);
+
+ trans.reset();
+ push_trans.reset();
+ session->CloseAllConnections();
+}
+
// Test HTTPS connections to a site with a bad certificate, going through an
// HTTPS proxy
TEST_F(HttpNetworkTransactionSpdy21Test, HTTPSBadCertificateViaHttpsProxy) {
diff --git a/net/http/http_network_transaction_spdy2_unittest.cc b/net/http/http_network_transaction_spdy2_unittest.cc
index 29f8316..0ed4629 100644
--- a/net/http/http_network_transaction_spdy2_unittest.cc
+++ b/net/http/http_network_transaction_spdy2_unittest.cc
@@ -4883,6 +4883,113 @@ TEST_F(HttpNetworkTransactionSpdy2Test, BasicAuthSpdyProxy) {
session->CloseAllConnections();
}
+// Test that an explicitly trusted SPDY proxy can push a resource from an
+// origin that is different from that of its associated resource.
+TEST_F(HttpNetworkTransactionSpdy2Test, CrossOriginProxyPush) {
+ HttpRequestInfo request;
+ HttpRequestInfo push_request;
+
+ static const unsigned char kPushBodyFrame[] = {
+ 0x00, 0x00, 0x00, 0x02, // header, ID
+ 0x01, 0x00, 0x00, 0x06, // FIN, length
+ 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
+ };
+
+ request.method = "GET";
+ request.url = GURL("http://www.google.com/");
+ push_request.method = "GET";
+ push_request.url = GURL("http://www.another-origin.com/foo.dat");
+
+ // Enable cross-origin push.
+ net::SpdySession::set_allow_spdy_proxy_push_across_origins("myproxy:70");
+
+ // Configure against https proxy server "myproxy:70".
+ SessionDependencies session_deps(
+ ProxyService::CreateFixed("https://myproxy:70"));
+ CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
+ session_deps.net_log = log.bound().net_log();
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+
+ scoped_ptr<SpdyFrame>
+ stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
+
+ MockWrite spdy_writes[] = {
+ CreateMockWrite(*stream1_syn, 1, ASYNC)
+ };
+
+ scoped_ptr<SpdyFrame>
+ stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+
+ scoped_ptr<SpdyFrame>
+ stream1_body(ConstructSpdyBodyFrame(1, true));
+
+ scoped_ptr<SpdyFrame>
+ stream2_syn(ConstructSpdyPush(NULL,
+ 0,
+ 2,
+ 1,
+ "http://www.another-origin.com/foo.dat"));
+
+ MockRead spdy_reads[] = {
+ CreateMockRead(*stream1_reply, 2, ASYNC),
+ CreateMockRead(*stream2_syn, 3, ASYNC),
+ CreateMockRead(*stream1_body, 4, ASYNC),
+ MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+ arraysize(kPushBodyFrame), 5),
+ MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
+ };
+
+ scoped_ptr<OrderedSocketData> spdy_data(
+ new OrderedSocketData(
+ spdy_reads, arraysize(spdy_reads),
+ spdy_writes, arraysize(spdy_writes)));
+ session_deps.socket_factory.AddSocketDataProvider(spdy_data.get());
+ // Negotiate SPDY to the proxy
+ SSLSocketDataProvider proxy(ASYNC, OK);
+ proxy.SetNextProto(kProtoSPDY2);
+ session_deps.socket_factory.AddSSLSocketDataProvider(&proxy);
+
+ scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+
+ scoped_ptr<HttpTransaction> push_trans(new HttpNetworkTransaction(session));
+ rv = push_trans->Start(&push_request, callback.callback(), log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
+
+ ASSERT_TRUE(response != NULL);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+
+ EXPECT_EQ(200, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ std::string response_data;
+ rv = ReadTransaction(trans.get(), &response_data);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("hello!", response_data);
+
+ // Verify the pushed stream.
+ EXPECT_TRUE(push_response->headers != NULL);
+ EXPECT_EQ(200, push_response->headers->response_code());
+
+ rv = ReadTransaction(push_trans.get(), &response_data);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("pushed", response_data);
+
+ trans.reset();
+ push_trans.reset();
+ session->CloseAllConnections();
+}
+
// Test HTTPS connections to a site with a bad certificate, going through an
// HTTPS proxy
TEST_F(HttpNetworkTransactionSpdy2Test, HTTPSBadCertificateViaHttpsProxy) {
diff --git a/net/http/http_network_transaction_spdy3_unittest.cc b/net/http/http_network_transaction_spdy3_unittest.cc
index d3d6dab..b8779c8 100644
--- a/net/http/http_network_transaction_spdy3_unittest.cc
+++ b/net/http/http_network_transaction_spdy3_unittest.cc
@@ -4884,6 +4884,113 @@ TEST_F(HttpNetworkTransactionSpdy3Test, BasicAuthSpdyProxy) {
session->CloseAllConnections();
}
+// Test that an explicitly trusted SPDY proxy can push a resource from an
+// origin that is different from that of its associated resource.
+TEST_F(HttpNetworkTransactionSpdy3Test, CrossOriginProxyPush) {
+ HttpRequestInfo request;
+ HttpRequestInfo push_request;
+
+ static const unsigned char kPushBodyFrame[] = {
+ 0x00, 0x00, 0x00, 0x02, // header, ID
+ 0x01, 0x00, 0x00, 0x06, // FIN, length
+ 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
+ };
+
+ request.method = "GET";
+ request.url = GURL("http://www.google.com/");
+ push_request.method = "GET";
+ push_request.url = GURL("http://www.another-origin.com/foo.dat");
+
+ // Enable cross-origin push.
+ net::SpdySession::set_allow_spdy_proxy_push_across_origins("myproxy:70");
+
+ // Configure against https proxy server "myproxy:70".
+ SessionDependencies session_deps(
+ ProxyService::CreateFixed("https://myproxy:70"));
+ CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
+ session_deps.net_log = log.bound().net_log();
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+
+ scoped_ptr<SpdyFrame>
+ stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
+
+ MockWrite spdy_writes[] = {
+ CreateMockWrite(*stream1_syn, 1, ASYNC)
+ };
+
+ scoped_ptr<SpdyFrame>
+ stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1));
+
+ scoped_ptr<SpdyFrame>
+ stream1_body(ConstructSpdyBodyFrame(1, true));
+
+ scoped_ptr<SpdyFrame>
+ stream2_syn(ConstructSpdyPush(NULL,
+ 0,
+ 2,
+ 1,
+ "http://www.another-origin.com/foo.dat"));
+
+ MockRead spdy_reads[] = {
+ CreateMockRead(*stream1_reply, 2, ASYNC),
+ CreateMockRead(*stream2_syn, 3, ASYNC),
+ CreateMockRead(*stream1_body, 4, ASYNC),
+ MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
+ arraysize(kPushBodyFrame), 5),
+ MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
+ };
+
+ scoped_ptr<OrderedSocketData> spdy_data(
+ new OrderedSocketData(
+ spdy_reads, arraysize(spdy_reads),
+ spdy_writes, arraysize(spdy_writes)));
+ session_deps.socket_factory.AddSocketDataProvider(spdy_data.get());
+ // Negotiate SPDY to the proxy
+ SSLSocketDataProvider proxy(ASYNC, OK);
+ proxy.SetNextProto(kProtoSPDY3);
+ session_deps.socket_factory.AddSSLSocketDataProvider(&proxy);
+
+ scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+
+ scoped_ptr<HttpTransaction> push_trans(new HttpNetworkTransaction(session));
+ rv = push_trans->Start(&push_request, callback.callback(), log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
+
+ ASSERT_TRUE(response != NULL);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+
+ EXPECT_EQ(200, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ std::string response_data;
+ rv = ReadTransaction(trans.get(), &response_data);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("hello!", response_data);
+
+ // Verify the pushed stream.
+ EXPECT_TRUE(push_response->headers != NULL);
+ EXPECT_EQ(200, push_response->headers->response_code());
+
+ rv = ReadTransaction(push_trans.get(), &response_data);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("pushed", response_data);
+
+ trans.reset();
+ push_trans.reset();
+ session->CloseAllConnections();
+}
+
// Test HTTPS connections to a site with a bad certificate, going through an
// HTTPS proxy
TEST_F(HttpNetworkTransactionSpdy3Test, HTTPSBadCertificateViaHttpsProxy) {
diff --git a/net/spdy/spdy_network_transaction_spdy21_unittest.cc b/net/spdy/spdy_network_transaction_spdy21_unittest.cc
index 16918fe..c81f30a 100644
--- a/net/spdy/spdy_network_transaction_spdy21_unittest.cc
+++ b/net/spdy/spdy_network_transaction_spdy21_unittest.cc
@@ -5847,6 +5847,11 @@ TEST_P(SpdyNetworkTransactionSpdy21Test, ServerPushCrossOriginCorrectness) {
helper.RunPreTestSetup();
helper.AddData(data.get());
+ // Enable cross-origin push. Since we are not using a proxy, this should
+ // not actually enable cross-origin SPDY push.
+ net::SpdySession::set_allow_spdy_proxy_push_across_origins(
+ "123.45.67.89:8080");
+
HttpNetworkTransaction* trans = helper.trans();
// Start the transaction with basic parameters.
diff --git a/net/spdy/spdy_network_transaction_spdy2_unittest.cc b/net/spdy/spdy_network_transaction_spdy2_unittest.cc
index 47ea77ca..5e6cf17 100644
--- a/net/spdy/spdy_network_transaction_spdy2_unittest.cc
+++ b/net/spdy/spdy_network_transaction_spdy2_unittest.cc
@@ -5483,6 +5483,11 @@ TEST_P(SpdyNetworkTransactionSpdy2Test, ServerPushCrossOriginCorrectness) {
helper.RunPreTestSetup();
helper.AddData(data.get());
+ // Enable cross-origin push. Since we are not using a proxy, this should
+ // not actually enable cross-origin SPDY push.
+ net::SpdySession::set_allow_spdy_proxy_push_across_origins(
+ "123.45.67.89:8080");
+
HttpNetworkTransaction* trans = helper.trans();
// Start the transaction with basic parameters.
diff --git a/net/spdy/spdy_network_transaction_spdy3_unittest.cc b/net/spdy/spdy_network_transaction_spdy3_unittest.cc
index 5c4aa67..cb80d00 100644
--- a/net/spdy/spdy_network_transaction_spdy3_unittest.cc
+++ b/net/spdy/spdy_network_transaction_spdy3_unittest.cc
@@ -5855,6 +5855,11 @@ TEST_P(SpdyNetworkTransactionSpdy3Test, ServerPushCrossOriginCorrectness) {
helper.RunPreTestSetup();
helper.AddData(data.get());
+ // Enable cross-origin push. Since we are not using a proxy, this should
+ // not actually enable cross-origin SPDY push.
+ net::SpdySession::set_allow_spdy_proxy_push_across_origins(
+ "123.45.67.89:8080");
+
HttpNetworkTransaction* trans = helper.trans();
// Start the transaction with basic parameters.
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 8fce171..3815357 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -296,6 +296,7 @@ NextProto g_default_protocol = kProtoUnknown;
size_t g_init_max_concurrent_streams = 10;
size_t g_max_concurrent_stream_limit = 256;
bool g_enable_ping_based_connection_checking = true;
+const char* g_allow_spdy_proxy_push_across_origins = NULL;
} // namespace
@@ -321,12 +322,18 @@ void SpdySession::set_init_max_concurrent_streams(size_t value) {
}
// static
+void SpdySession::set_allow_spdy_proxy_push_across_origins(const char* value) {
+ g_allow_spdy_proxy_push_across_origins = value;
+}
+
+// static
void SpdySession::ResetStaticSettingsToInit() {
// WARNING: These must match the initializers above.
g_default_protocol = kProtoUnknown;
g_init_max_concurrent_streams = 10;
g_max_concurrent_stream_limit = 256;
g_enable_ping_based_connection_checking = true;
+ g_allow_spdy_proxy_push_across_origins = NULL;
}
SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair,
@@ -374,7 +381,11 @@ SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair,
trailing_ping_delay_time_(
base::TimeDelta::FromSeconds(kTrailingPingDelayTimeSeconds)),
hung_interval_(
- base::TimeDelta::FromSeconds(kHungIntervalSeconds)) {
+ base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
+ allow_spdy_proxy_push_across_origins_(
+ HostPortPair::FromString(
+ std::string(g_allow_spdy_proxy_push_across_origins == NULL ?
+ "" : g_allow_spdy_proxy_push_across_origins))) {
DCHECK(HttpStreamFactory::spdy_enabled());
net_log_.BeginEvent(
NetLog::TYPE_SPDY_SESSION,
@@ -1444,15 +1455,20 @@ void SpdySession::OnSynStream(
return;
}
- scoped_refptr<SpdyStream> associated_stream =
- active_streams_[associated_stream_id];
- GURL associated_url(associated_stream->GetUrl());
- if (associated_url.GetOrigin() != gurl.GetOrigin()) {
- ResetStream(stream_id, REFUSED_STREAM,
- base::StringPrintf(
- "Rejected Cross Origin Push Stream %d",
- associated_stream_id));
- return;
+ // Check that the SYN advertises the same origin as its associated stream.
+ // Bypass this check if and only if this session is with a SPDY proxy that
+ // is trusted explicitly via the allow_spdy_proxy_push_across_origins switch.
+ if (!allow_spdy_proxy_push_across_origins_.Equals(host_port_pair())) {
+ scoped_refptr<SpdyStream> associated_stream =
+ active_streams_[associated_stream_id];
+ GURL associated_url(associated_stream->GetUrl());
+ if (associated_url.GetOrigin() != gurl.GetOrigin()) {
+ ResetStream(stream_id, REFUSED_STREAM,
+ base::StringPrintf(
+ "Rejected Cross Origin Push Stream %d",
+ associated_stream_id));
+ return;
+ }
}
// There should not be an existing pushed stream with the same path.
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 2fbfd1e..5c7b11e 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -188,6 +188,10 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
// server via SETTINGS.
static void set_init_max_concurrent_streams(size_t value);
+ // Allow a SPDY proxy to push resources from origins that are different from
+ // those of their associated streams.
+ static void set_allow_spdy_proxy_push_across_origins(const char* proxy);
+
// Send WINDOW_UPDATE frame, called by a stream whenever receive window
// size is increased.
void SendWindowUpdate(SpdyStreamId stream_id, int32 delta_window_size);
@@ -639,6 +643,10 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
// (of any form), while there is a ping in flight, before we declare the
// connection to be hung.
base::TimeDelta hung_interval_;
+
+ // Allows a proxy to push a resource that has an origin that is different
+ // from its associated url.
+ HostPortPair allow_spdy_proxy_push_across_origins_;
};
class NetLogSpdySynParameter : public NetLog::EventParameters {