Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Unified Diff: net/quic/quic_network_transaction_unittest.cc

Issue 1540463003: Change the interface of GetAlternativeServicesFor, always return the best Alt-Svc entry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change hanging_data_ to vector Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/quic/quic_network_transaction_unittest.cc
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 4beb01dbff93a04014679744ca1779b77cc4dc63..b67d6461d8869ee626e5d36eecb9ebe4a2ee0cd7 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -195,7 +195,6 @@ class QuicNetworkTransactionTest
auth_handler_factory_(
HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
random_generator_(0),
- hanging_data_(nullptr, 0, nullptr, 0),
ssl_data_(ASYNC, OK) {
request_.method = "GET";
std::string url("https://");
@@ -233,7 +232,25 @@ class QuicNetworkTransactionTest
scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
QuicPacketNumber largest_received,
QuicPacketNumber least_unacked) {
- return maker_.MakeAckPacket(2, largest_received, least_unacked, true);
+ return maker_.MakeAckPacket(2, largest_received, least_unacked,
+ least_unacked, true);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
+ QuicPacketNumber largest_received,
+ QuicPacketNumber least_unacked,
+ QuicTestPacketMaker* maker) {
+ return maker->MakeAckPacket(2, largest_received, least_unacked,
+ least_unacked, true);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructAckAndConnectionClosePacket(
+ QuicPacketNumber packet_number,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber ack_least_unacked,
+ QuicPacketNumber stop_least_unacked) {
+ return maker_.MakeAckPacket(packet_number, largest_received,
+ ack_least_unacked, stop_least_unacked, true);
}
scoped_ptr<QuicEncryptedPacket> ConstructAckAndConnectionClosePacket(
@@ -256,16 +273,31 @@ class QuicNetworkTransactionTest
return maker_.MakeRstPacket(num, include_version, stream_id, error_code);
}
+ // Uses default QuicTestPacketMaker.
SpdyHeaderBlock GetRequestHeaders(const std::string& method,
const std::string& scheme,
const std::string& path) {
- return maker_.GetRequestHeaders(method, scheme, path);
+ return GetRequestHeaders(method, scheme, path, maker_);
+ }
+
+ // Uses customized QuicTestPacketMaker.
+ SpdyHeaderBlock GetRequestHeaders(const std::string& method,
+ const std::string& scheme,
+ const std::string& path,
+ QuicTestPacketMaker& maker) {
+ return maker.GetRequestHeaders(method, scheme, path);
}
SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
return maker_.GetResponseHeaders(status);
}
+ // Appends alt_svc headers in the response headers.
+ SpdyHeaderBlock GetResponseHeaders(const std::string& status,
+ const std::string& alt_svc) {
+ return maker_.GetResponseHeaders(status, alt_svc);
+ }
+
scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
@@ -282,12 +314,50 @@ class QuicNetworkTransactionTest
QuicStreamId stream_id,
bool should_include_version,
bool fin,
- const SpdyHeaderBlock& headers) {
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset) {
SpdyPriority priority =
ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
- return maker_.MakeRequestHeadersPacket(packet_number, stream_id,
- should_include_version, fin,
- priority, headers);
+ return maker_.MakeRequestHeadersPacketWithOffsetTracking(
+ packet_number, stream_id, should_include_version, fin, priority,
+ headers, offset);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset,
+ QuicTestPacketMaker* maker) {
+ SpdyPriority priority =
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
+ return maker->MakeRequestHeadersPacketWithOffsetTracking(
+ packet_number, stream_id, should_include_version, fin, priority,
+ headers, offset);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers) {
+ return ConstructRequestHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, &maker_);
+ }
+ scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicTestPacketMaker* maker) {
+ return ConstructRequestHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, maker);
}
scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
@@ -296,8 +366,44 @@ class QuicNetworkTransactionTest
bool should_include_version,
bool fin,
const SpdyHeaderBlock& headers) {
- return maker_.MakeResponseHeadersPacket(
- packet_number, stream_id, should_include_version, fin, headers);
+ return ConstructResponseHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, &maker_);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicTestPacketMaker* maker) {
+ return ConstructResponseHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, maker);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset) {
+ return maker_.MakeResponseHeadersPacketWithOffsetTracking(
+ packet_number, stream_id, should_include_version, fin, headers, offset);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset,
+ QuicTestPacketMaker* maker) {
+ return maker->MakeResponseHeadersPacketWithOffsetTracking(
+ packet_number, stream_id, should_include_version, fin, headers, offset);
}
void CreateSession() { CreateSessionWithFactory(&socket_factory_, false); }
@@ -433,9 +539,12 @@ class QuicNetworkTransactionTest
}
void AddHangingNonAlternateProtocolSocketData() {
+ scoped_ptr<StaticSocketDataProvider> hanging_data;
+ hanging_data.reset(new StaticSocketDataProvider());
MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
- hanging_data_.set_connect_data(hanging_connect);
- socket_factory_.AddSocketDataProvider(&hanging_data_);
+ hanging_data->set_connect_data(hanging_connect);
+ hanging_data_.push_back(std::move(hanging_data));
+ socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
}
@@ -459,7 +568,7 @@ class QuicNetworkTransactionTest
HttpNetworkSession::Params params_;
HttpRequestInfo request_;
BoundTestNetLog net_log_;
- StaticSocketDataProvider hanging_data_;
+ std::vector<scoped_ptr<StaticSocketDataProvider>> hanging_data_;
SSLSocketDataProvider ssl_data_;
private:
@@ -635,6 +744,7 @@ TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
MockQuicData mock_quic_data2;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
@@ -768,14 +878,13 @@ TEST_P(QuicNetworkTransactionTest,
}
// When multiple alternative services are advertised,
-// HttpStreamFactoryImpl::RequestStreamInternal() only passes the first one to
-// Job. This is what the following test verifies.
-// TODO(bnc): Update this test when multiple alternative services are handled
-// properly.
-TEST_P(QuicNetworkTransactionTest, UseFirstAlternativeServiceForQuic) {
+// HttpStreamFactoryImpl::RequestStreamInternal() should select the alternative
+// service which uses existing QUIC session if available. If no existing QUIC
+// session can be used, use the first alternative service from the list.
+TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
MockRead http_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Alt-Svc: quic=\":443\", quic=\":1234\"\r\n\r\n"),
+ MockRead("Alt-Svc: quic=\"foo.example.com:443\", quic=\":444\"\r\n\r\n"),
MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
@@ -785,15 +894,38 @@ TEST_P(QuicNetworkTransactionTest, UseFirstAlternativeServiceForQuic) {
socket_factory_.AddSocketDataProvider(&http_data);
socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+ QuicStreamOffset request_header_offset = 0;
+ QuicStreamOffset response_header_offset = 0;
+ // First QUIC request data.
+ // Open a session to foo.example.com:443 using the first entry of the
+ // alternative service list.
MockQuicData mock_quic_data;
- mock_quic_data.AddWrite(
- ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+
+ std::string alt_svc_list =
+ "quic=\"mail.example.com:444\", quic=\"foo.example.com:443\", "
+ "quic=\"bar.example.com:445\"";
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
- 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
+ 1, kClientDataStreamId1, false, false,
+ GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+
+ // Second QUIC request data.
+ // Connection pooling, using existing session, no need to include version
+ // as version negotiation has been completed.
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 3, kClientDataStreamId2, false, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 3, kClientDataStreamId2, false, false, GetResponseHeaders("200 OK"),
+ &response_header_offset));
+ mock_quic_data.AddRead(
+ ConstructDataPacket(4, kClientDataStreamId2, false, true, 0, "hello!"));
+ mock_quic_data.AddWrite(ConstructAckAndConnectionClosePacket(4, 4, 3, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddRead(ASYNC, 0); // EOF
@@ -803,7 +935,283 @@ TEST_P(QuicNetworkTransactionTest, UseFirstAlternativeServiceForQuic) {
CreateSessionWithNextProtos();
SendRequestAndExpectHttpResponse("hello world");
+
SendRequestAndExpectQuicResponseOnPort("hello!", 443);
+ SendRequestAndExpectQuicResponseOnPort("hello!", 443);
+}
+
+// When multiple alternative services that has existing QUIC session.
+// HttpStreamFactoryImpl::RequestStreamInternal() should select the first
+// alternative service which uses existing QUIC session.
+TEST_P(QuicNetworkTransactionTest, UseFirstExistingAlternativeServiceForQuic) {
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\"foo.example.com:443\", quic=\":446\"\r\n\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ QuicStreamOffset request_header_offset = 0;
+ QuicStreamOffset response_header_offset = 0;
+
+ QuicTestPacketMaker maker(GetParam(), 0, clock_, kDefaultServerHostName);
+
+ MockQuicData mock_quic_data;
+ MockQuicData mock_quic_data2;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
+ // First QUIC request data.
+ // Open a QUIC session to foo.example.com:443.
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+
+ std::string alt_svc_list =
+ "quic=\"bar.example.com:444\", quic=\"frog.example.com:445\", "
+ "quic=\"mail.example.com:446\"";
+ // Response header from the server resets the alt_svc list for the origin.
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false,
+ GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
+ mock_quic_data.AddRead(ConstructDataPacket(2, kClientDataStreamId1, false,
+ true, 0, "hello from foo!"));
+ mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+
+ // Second QUIC request data.
+ // Existing QUIC session to foo.example.com is not viable from the updated
+ // alt_svc. Unable to pool the existing QUIC session.
+ // Open a new QUIC session to bar.example.com:443.
+ mock_quic_data2.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/"), &maker));
+ alt_svc_list =
+ "quic=\"foo.example.com:443\", quic=\"mail.example.com:446\", "
+ "quic=\"bar.example.com:444\"";
+ // Response header from the server resets the alt_svc list for the origin.
+ mock_quic_data2.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false,
+ GetResponseHeaders("200 OK", alt_svc_list), &maker));
+ mock_quic_data2.AddRead(ConstructDataPacket(2, kClientDataStreamId1, false,
+ true, 0, "hello from bar!"));
+ mock_quic_data2.AddWrite(ConstructAckPacket(2, 1, &maker));
+ mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data2.AddRead(ASYNC, 0); // EOF
+
+ // Third QUIC request data.
+ // Connection pooling, using the first existing session to foo.example.com
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 3, kClientDataStreamId2, false, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 3, kClientDataStreamId2, false, false, GetResponseHeaders("200 OK"),
+ &response_header_offset));
+ mock_quic_data.AddRead(ConstructDataPacket(4, kClientDataStreamId2, false,
+ true, 0, "hello from foo!"));
+ mock_quic_data.AddWrite(ConstructAckAndConnectionClosePacket(4, 4, 3, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
+
+ AddHangingNonAlternateProtocolSocketData();
+
+ CreateSessionWithNextProtos();
+
+ SendRequestAndExpectHttpResponse("hello world");
+ SendRequestAndExpectQuicResponseOnPort("hello from foo!", 443);
+ SendRequestAndExpectQuicResponseOnPort("hello from bar!", 444);
+ SendRequestAndExpectQuicResponseOnPort("hello from foo!", 443);
+}
+
+// Multiple origins have listed the same alternative services. When there's a
+// existing QUIC session opened by a request to other origin,
+// if the cert is valid, should select this QUIC session to make the request
+// if this is also the first existing QUIC session.
+TEST_P(QuicNetworkTransactionTest,
+ UseSharedExistingAlternativeServiceForQuicWithValidCert) {
+ // Default cert is valid for the following origins:
+ // mail.example.com, mail.example.org, and www.example.org.
+
+ // HTTP data for request to mail.example.com.
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
+ MockRead("hello world from mail.example.com"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ // HTTP data for request to mail.example.org.
+ MockRead http_reads2[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\":444\", quic=\"mail.example.com:443\"\r\n\r\n"),
+ MockRead("hello world from mail.example.org"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data2(http_reads2, arraysize(http_reads2),
+ nullptr, 0);
+ socket_factory_.AddSocketDataProvider(&http_data2);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ QuicStreamOffset request_header_offset = 0;
+ QuicStreamOffset response_header_offset = 0;
+
+ QuicTestPacketMaker maker(GetParam(), 0, clock_, kDefaultServerHostName);
+ maker.set_hostname("mail.example.org");
+ MockQuicData mock_quic_data;
+
+ // First QUIC request data.
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK"),
+ &response_header_offset));
+ mock_quic_data.AddRead(ConstructDataPacket(2, kClientDataStreamId1, false,
+ true, 0, "hello from mail QUIC!"));
+ mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+
+ // Second QUIC request data.
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 3, kClientDataStreamId2, false, true,
+ GetRequestHeaders("GET", "https", "/", maker), &request_header_offset,
+ &maker));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 3, kClientDataStreamId2, false, false, GetResponseHeaders("200 OK"),
+ &response_header_offset));
+ mock_quic_data.AddRead(ConstructDataPacket(4, kClientDataStreamId2, false,
+ true, 0, "hello from mail QUIC!"));
+ mock_quic_data.AddWrite(ConstructAckAndConnectionClosePacket(4, 4, 3, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ CreateSessionWithNextProtos();
+
+ // Send two HTTP requests, responses set up alt-svc lists for the origins.
+ SendRequestAndExpectHttpResponse("hello world from mail.example.com");
+ request_.url = GURL("https://mail.example.org/");
+ SendRequestAndExpectHttpResponse("hello world from mail.example.org");
+
+ // Open a QUIC session to mail.example.com:443 when making request
+ // to mail.example.com.
+ request_.url = GURL("https://mail.example.com/");
+ SendRequestAndExpectQuicResponseOnPort("hello from mail QUIC!", 443);
+
+ // Uses the existing QUIC session when making request to mail.example.org.
+ request_.url = GURL("https://mail.example.org/");
+ SendRequestAndExpectQuicResponseOnPort("hello from mail QUIC!", 443);
+}
+
+// Multiple origins have listed the same alternative services. When there's a
+// existing QUIC session opened by a request to other origin,
+// if the cert is NOT valid, should ignore this QUIC session.
+TEST_P(QuicNetworkTransactionTest,
+ DoNotUseSharedExistingAlternativeServiceForQuicWithInvalidCert) {
+ // Default cert is only valid for the following origins:
+ // mail.example.com, mail.example.org, and www.example.org.
+ // NOT valid for docs.example.org.
+
+ // HTTP data for request to mail.example.com.
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
+ MockRead("hello world from mail.example.com"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ // HTTP data for request to docs.example.org.
+ MockRead http_reads2[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\":444\", quic=\"mail.example.com:443\"\r\n\r\n"),
+ MockRead("hello world from docs.example.org"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data2(http_reads2, arraysize(http_reads2),
+ nullptr, 0);
+ socket_factory_.AddSocketDataProvider(&http_data2);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ QuicTestPacketMaker maker(GetParam(), 0, clock_, kDefaultServerHostName);
+ maker.set_hostname("docs.example.org");
+ MockQuicData mock_quic_data;
+ MockQuicData mock_quic_data2;
+
+ // Adding a valid cert for *.example.org but not mail.example.com.
+ ProofVerifyDetailsChromium verify_details;
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
+ verify_details.cert_verify_result.verified_cert = cert;
+ verify_details.cert_verify_result.is_issued_by_known_root = true;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ // First QUIC request data.
+ mock_quic_data.AddWrite(
+ ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
+ mock_quic_data.AddRead(ConstructDataPacket(2, kClientDataStreamId1, false,
+ true, 0, "hello from mail QUIC!"));
+ mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+
+ // First QUIC request data.
+ mock_quic_data2.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/", maker), &maker));
+ mock_quic_data2.AddRead(
+ ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
+ GetResponseHeaders("200 OK"), &maker));
+ mock_quic_data2.AddRead(ConstructDataPacket(
+ 2, kClientDataStreamId1, false, true, 0, "hello from docs QUIC!"));
+ mock_quic_data2.AddWrite(ConstructAckPacket(2, 1, &maker));
+ mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data2.AddRead(ASYNC, 0); // EOF
+
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ CreateSessionWithNextProtos();
+
+ // Send HTTP requests, responses set up the alt-svc lists for the origins.
+ SendRequestAndExpectHttpResponse("hello world from mail.example.com");
+ request_.url = GURL("https://docs.example.org/");
+ SendRequestAndExpectHttpResponse("hello world from docs.example.org");
+
+ // Open a QUIC session to mail.example.com:443 when making request
+ // to mail.example.com.
+ request_.url = GURL("https://mail.example.com/");
+ SendRequestAndExpectQuicResponseOnPort("hello from mail QUIC!", 443);
+
+ // Open another new QUIC session to docs.example.org:444.
+ request_.url = GURL("https://docs.example.org/");
+ SendRequestAndExpectQuicResponseOnPort("hello from docs QUIC!", 444);
}
TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {

Powered by Google App Engine
This is Rietveld 408576698