OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 #include <string> | 6 #include <string> |
7 #include <sys/epoll.h> | 7 #include <sys/epoll.h> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 const char kBarResponseBody[] = "Palm hearts are pretty delicious, also."; | 84 const char kBarResponseBody[] = "Palm hearts are pretty delicious, also."; |
85 | 85 |
86 // Run all tests with the cross products of all versions. | 86 // Run all tests with the cross products of all versions. |
87 struct TestParams { | 87 struct TestParams { |
88 TestParams(const QuicVersionVector& client_supported_versions, | 88 TestParams(const QuicVersionVector& client_supported_versions, |
89 const QuicVersionVector& server_supported_versions, | 89 const QuicVersionVector& server_supported_versions, |
90 QuicVersion negotiated_version, | 90 QuicVersion negotiated_version, |
91 bool use_fec, | 91 bool use_fec, |
92 bool client_supports_stateless_rejects, | 92 bool client_supports_stateless_rejects, |
93 bool server_uses_stateless_rejects_if_peer_supported, | 93 bool server_uses_stateless_rejects_if_peer_supported, |
94 QuicTag congestion_control_tag) | 94 QuicTag congestion_control_tag, |
| 95 bool auto_tune_flow_control_window) |
95 : client_supported_versions(client_supported_versions), | 96 : client_supported_versions(client_supported_versions), |
96 server_supported_versions(server_supported_versions), | 97 server_supported_versions(server_supported_versions), |
97 negotiated_version(negotiated_version), | 98 negotiated_version(negotiated_version), |
98 use_fec(use_fec), | 99 use_fec(use_fec), |
99 client_supports_stateless_rejects(client_supports_stateless_rejects), | 100 client_supports_stateless_rejects(client_supports_stateless_rejects), |
100 server_uses_stateless_rejects_if_peer_supported( | 101 server_uses_stateless_rejects_if_peer_supported( |
101 server_uses_stateless_rejects_if_peer_supported), | 102 server_uses_stateless_rejects_if_peer_supported), |
102 congestion_control_tag(congestion_control_tag) {} | 103 congestion_control_tag(congestion_control_tag), |
| 104 auto_tune_flow_control_window(auto_tune_flow_control_window) {} |
103 | 105 |
104 friend ostream& operator<<(ostream& os, const TestParams& p) { | 106 friend ostream& operator<<(ostream& os, const TestParams& p) { |
105 os << "{ server_supported_versions: " | 107 os << "{ server_supported_versions: " |
106 << QuicVersionVectorToString(p.server_supported_versions); | 108 << QuicVersionVectorToString(p.server_supported_versions); |
107 os << " client_supported_versions: " | 109 os << " client_supported_versions: " |
108 << QuicVersionVectorToString(p.client_supported_versions); | 110 << QuicVersionVectorToString(p.client_supported_versions); |
109 os << " negotiated_version: " << QuicVersionToString(p.negotiated_version); | 111 os << " negotiated_version: " << QuicVersionToString(p.negotiated_version); |
110 os << " client_supports_stateless_rejects: " | 112 os << " client_supports_stateless_rejects: " |
111 << p.client_supports_stateless_rejects; | 113 << p.client_supports_stateless_rejects; |
112 os << " server_uses_stateless_rejects_if_peer_supported: " | 114 os << " server_uses_stateless_rejects_if_peer_supported: " |
113 << p.server_uses_stateless_rejects_if_peer_supported; | 115 << p.server_uses_stateless_rejects_if_peer_supported; |
114 os << " use_fec: " << p.use_fec; | 116 os << " use_fec: " << p.use_fec; |
115 os << " congestion_control_tag: " | 117 os << " congestion_control_tag: " |
116 << QuicUtils::TagToString(p.congestion_control_tag) << " }"; | 118 << QuicUtils::TagToString(p.congestion_control_tag); |
| 119 os << " auto_tune_flow_control_window: " << p.auto_tune_flow_control_window |
| 120 << " }"; |
117 return os; | 121 return os; |
118 } | 122 } |
119 | 123 |
120 QuicVersionVector client_supported_versions; | 124 QuicVersionVector client_supported_versions; |
121 QuicVersionVector server_supported_versions; | 125 QuicVersionVector server_supported_versions; |
122 QuicVersion negotiated_version; | 126 QuicVersion negotiated_version; |
123 bool use_fec; | 127 bool use_fec; |
124 bool client_supports_stateless_rejects; | 128 bool client_supports_stateless_rejects; |
125 bool server_uses_stateless_rejects_if_peer_supported; | 129 bool server_uses_stateless_rejects_if_peer_supported; |
126 QuicTag congestion_control_tag; | 130 QuicTag congestion_control_tag; |
| 131 bool auto_tune_flow_control_window; |
127 }; | 132 }; |
128 | 133 |
129 // Constructs various test permutations. | 134 // Constructs various test permutations. |
130 vector<TestParams> GetTestParams() { | 135 vector<TestParams> GetTestParams() { |
131 // Divide the versions into buckets in which the intra-frame format | 136 // Divide the versions into buckets in which the intra-frame format |
132 // is compatible. When clients encounter QUIC version negotiation | 137 // is compatible. When clients encounter QUIC version negotiation |
133 // they simply retransmit all packets using the new version's | 138 // they simply retransmit all packets using the new version's |
134 // QUIC framing. However, they are unable to change the intra-frame | 139 // QUIC framing. However, they are unable to change the intra-frame |
135 // layout (for example to change SPDY/4 headers to SPDY/3). So | 140 // layout (for example to change SPDY/4 headers to SPDY/3). So |
136 // these tests need to ensure that clients are never attempting | 141 // these tests need to ensure that clients are never attempting |
(...skipping 13 matching lines...) Expand all Loading... |
150 | 155 |
151 vector<TestParams> params; | 156 vector<TestParams> params; |
152 // TODO(rtenneti): Add kTBBR after BBR code is checked in. | 157 // TODO(rtenneti): Add kTBBR after BBR code is checked in. |
153 // for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC}) { | 158 // for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC}) { |
154 for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) { | 159 for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) { |
155 for (const bool use_fec : {false, true}) { | 160 for (const bool use_fec : {false, true}) { |
156 for (const QuicVersionVector& client_versions : client_version_buckets) { | 161 for (const QuicVersionVector& client_versions : client_version_buckets) { |
157 for (bool client_supports_stateless_rejects : {true, false}) { | 162 for (bool client_supports_stateless_rejects : {true, false}) { |
158 for (bool server_uses_stateless_rejects_if_peer_supported : | 163 for (bool server_uses_stateless_rejects_if_peer_supported : |
159 {true, false}) { | 164 {true, false}) { |
160 CHECK(!client_versions.empty()); | 165 for (bool auto_tune_flow_control_window : {true, false}) { |
161 // Add an entry for server and client supporting all versions. | 166 CHECK(!client_versions.empty()); |
162 params.push_back( | 167 // Add an entry for server and client supporting all versions. |
163 TestParams(client_versions, all_supported_versions, | 168 params.push_back(TestParams( |
164 client_versions.front(), use_fec, | 169 client_versions, all_supported_versions, |
165 client_supports_stateless_rejects, | 170 client_versions.front(), use_fec, |
166 server_uses_stateless_rejects_if_peer_supported, | 171 client_supports_stateless_rejects, |
167 congestion_control_tag)); | 172 server_uses_stateless_rejects_if_peer_supported, |
| 173 congestion_control_tag, auto_tune_flow_control_window)); |
168 | 174 |
169 // Test client supporting all versions and server supporting 1 | 175 // Test client supporting all versions and server supporting 1 |
170 // version. Simulate an old server and exercise version downgrade in | 176 // version. Simulate an old server and exercise version downgrade |
171 // the client. Protocol negotiation should occur. Skip the i = 0 | 177 // in the client. Protocol negotiation should occur. Skip the i = |
172 // case because it is essentially the same as the default case. | 178 // 0 case because it is essentially the same as the default case. |
173 for (const QuicVersion version : client_versions) { | 179 for (const QuicVersion version : client_versions) { |
174 QuicVersionVector server_supported_versions; | 180 QuicVersionVector server_supported_versions; |
175 server_supported_versions.push_back(version); | 181 server_supported_versions.push_back(version); |
176 params.push_back( | 182 params.push_back(TestParams( |
177 TestParams(client_versions, server_supported_versions, | 183 client_versions, server_supported_versions, |
178 server_supported_versions.front(), use_fec, | 184 server_supported_versions.front(), use_fec, |
179 client_supports_stateless_rejects, | 185 client_supports_stateless_rejects, |
180 server_uses_stateless_rejects_if_peer_supported, | 186 server_uses_stateless_rejects_if_peer_supported, |
181 congestion_control_tag)); | 187 congestion_control_tag, auto_tune_flow_control_window)); |
| 188 } |
182 } | 189 } |
183 } | 190 } |
184 } | 191 } |
185 } | 192 } |
186 } | 193 } |
187 } | 194 } |
188 return params; | 195 return params; |
189 } | 196 } |
190 | 197 |
191 class ServerDelegate : public PacketDroppingTestWriter::Delegate { | 198 class ServerDelegate : public PacketDroppingTestWriter::Delegate { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 // client as well according to the test parameter. | 314 // client as well according to the test parameter. |
308 copt.push_back(GetParam().congestion_control_tag); | 315 copt.push_back(GetParam().congestion_control_tag); |
309 | 316 |
310 if (GetParam().use_fec) { | 317 if (GetParam().use_fec) { |
311 // Set FEC config in client's connection options and in client session. | 318 // Set FEC config in client's connection options and in client session. |
312 copt.push_back(kFHDR); | 319 copt.push_back(kFHDR); |
313 } | 320 } |
314 if (GetParam().client_supports_stateless_rejects) { | 321 if (GetParam().client_supports_stateless_rejects) { |
315 copt.push_back(kSREJ); | 322 copt.push_back(kSREJ); |
316 } | 323 } |
| 324 if (GetParam().auto_tune_flow_control_window) { |
| 325 copt.push_back(kAFCW); |
| 326 copt.push_back(kIFW5); |
| 327 } |
317 client_config_.SetConnectionOptionsToSend(copt); | 328 client_config_.SetConnectionOptionsToSend(copt); |
318 | 329 |
319 // Start the server first, because CreateQuicClient() attempts | 330 // Start the server first, because CreateQuicClient() attempts |
320 // to connect to the server. | 331 // to connect to the server. |
321 StartServer(); | 332 StartServer(); |
322 client_.reset(CreateQuicClient(client_writer_)); | 333 client_.reset(CreateQuicClient(client_writer_)); |
323 if (GetParam().use_fec) { | 334 if (GetParam().use_fec) { |
324 // Set FecPolicy to always protect data on all streams. | 335 // Set FecPolicy to always protect data on all streams. |
325 client_->SetFecPolicy(FEC_PROTECT_ALWAYS); | 336 client_->SetFecPolicy(FEC_PROTECT_ALWAYS); |
326 } | 337 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 // The expect for packets received is equal to packets processed fails | 468 // The expect for packets received is equal to packets processed fails |
458 // due to version negotiation packets. | 469 // due to version negotiation packets. |
459 server_thread_->Resume(); | 470 server_thread_->Resume(); |
460 } | 471 } |
461 | 472 |
462 bool BothSidesSupportStatelessRejects() { | 473 bool BothSidesSupportStatelessRejects() { |
463 return (GetParam().server_uses_stateless_rejects_if_peer_supported && | 474 return (GetParam().server_uses_stateless_rejects_if_peer_supported && |
464 GetParam().client_supports_stateless_rejects); | 475 GetParam().client_supports_stateless_rejects); |
465 } | 476 } |
466 | 477 |
| 478 void ExpectFlowControlsSynced(QuicFlowController* client, |
| 479 QuicFlowController* server) { |
| 480 EXPECT_EQ(QuicFlowControllerPeer::SendWindowSize(client), |
| 481 QuicFlowControllerPeer::ReceiveWindowSize(server)); |
| 482 EXPECT_EQ(QuicFlowControllerPeer::ReceiveWindowSize(client), |
| 483 QuicFlowControllerPeer::SendWindowSize(server)); |
| 484 } |
| 485 |
467 bool initialized_; | 486 bool initialized_; |
468 IPEndPoint server_address_; | 487 IPEndPoint server_address_; |
469 string server_hostname_; | 488 string server_hostname_; |
470 scoped_ptr<ServerThread> server_thread_; | 489 scoped_ptr<ServerThread> server_thread_; |
471 scoped_ptr<QuicTestClient> client_; | 490 scoped_ptr<QuicTestClient> client_; |
472 PacketDroppingTestWriter* client_writer_; | 491 PacketDroppingTestWriter* client_writer_; |
473 PacketDroppingTestWriter* server_writer_; | 492 PacketDroppingTestWriter* server_writer_; |
474 bool server_started_; | 493 bool server_started_; |
475 QuicConfig client_config_; | 494 QuicConfig client_config_; |
476 QuicConfig server_config_; | 495 QuicConfig server_config_; |
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 | 1450 |
1432 TEST_P(EndToEndTest, DifferentFlowControlWindows) { | 1451 TEST_P(EndToEndTest, DifferentFlowControlWindows) { |
1433 // Client and server can set different initial flow control receive windows. | 1452 // Client and server can set different initial flow control receive windows. |
1434 // These are sent in CHLO/SHLO. Tests that these values are exchanged properly | 1453 // These are sent in CHLO/SHLO. Tests that these values are exchanged properly |
1435 // in the crypto handshake. | 1454 // in the crypto handshake. |
1436 const uint32 kClientStreamIFCW = 123456; | 1455 const uint32 kClientStreamIFCW = 123456; |
1437 const uint32 kClientSessionIFCW = 234567; | 1456 const uint32 kClientSessionIFCW = 234567; |
1438 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW); | 1457 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW); |
1439 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW); | 1458 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW); |
1440 | 1459 |
1441 const uint32 kServerStreamIFCW = 654321; | 1460 uint32 kServerStreamIFCW = |
1442 const uint32 kServerSessionIFCW = 765432; | 1461 GetParam().auto_tune_flow_control_window ? 32 * 1024 : 654321; |
| 1462 uint32 kServerSessionIFCW = |
| 1463 GetParam().auto_tune_flow_control_window ? 48 * 1024 : 765432; |
1443 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW); | 1464 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW); |
1444 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW); | 1465 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW); |
1445 | 1466 |
1446 ASSERT_TRUE(Initialize()); | 1467 ASSERT_TRUE(Initialize()); |
1447 | 1468 |
1448 // Values are exchanged during crypto handshake, so wait for that to finish. | 1469 // Values are exchanged during crypto handshake, so wait for that to finish. |
1449 client_->client()->WaitForCryptoHandshakeConfirmed(); | 1470 client_->client()->WaitForCryptoHandshakeConfirmed(); |
1450 server_thread_->WaitForCryptoHandshakeConfirmed(); | 1471 server_thread_->WaitForCryptoHandshakeConfirmed(); |
1451 | 1472 |
1452 // Open a data stream to make sure the stream level flow control is updated. | 1473 // Open a data stream to make sure the stream level flow control is updated. |
(...skipping 27 matching lines...) Expand all Loading... |
1480 EXPECT_EQ(kClientSessionIFCW, | 1501 EXPECT_EQ(kClientSessionIFCW, |
1481 session->config()->ReceivedInitialSessionFlowControlWindowBytes()); | 1502 session->config()->ReceivedInitialSessionFlowControlWindowBytes()); |
1482 EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset( | 1503 EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset( |
1483 session->flow_controller())); | 1504 session->flow_controller())); |
1484 server_thread_->Resume(); | 1505 server_thread_->Resume(); |
1485 } | 1506 } |
1486 | 1507 |
1487 TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) { | 1508 TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) { |
1488 // The special headers and crypto streams should be subject to per-stream flow | 1509 // The special headers and crypto streams should be subject to per-stream flow |
1489 // control limits, but should not be subject to connection level flow control. | 1510 // control limits, but should not be subject to connection level flow control. |
1490 const uint32 kStreamIFCW = 123456; | 1511 const uint32 kStreamIFCW = |
1491 const uint32 kSessionIFCW = 234567; | 1512 GetParam().auto_tune_flow_control_window ? 32 * 1024 : 123456; |
| 1513 const uint32 kSessionIFCW = |
| 1514 GetParam().auto_tune_flow_control_window ? 48 * 1024 : 234567; |
1492 set_client_initial_stream_flow_control_receive_window(kStreamIFCW); | 1515 set_client_initial_stream_flow_control_receive_window(kStreamIFCW); |
1493 set_client_initial_session_flow_control_receive_window(kSessionIFCW); | 1516 set_client_initial_session_flow_control_receive_window(kSessionIFCW); |
1494 set_server_initial_stream_flow_control_receive_window(kStreamIFCW); | 1517 set_server_initial_stream_flow_control_receive_window(kStreamIFCW); |
1495 set_server_initial_session_flow_control_receive_window(kSessionIFCW); | 1518 set_server_initial_session_flow_control_receive_window(kSessionIFCW); |
1496 | 1519 |
1497 ASSERT_TRUE(Initialize()); | 1520 ASSERT_TRUE(Initialize()); |
1498 | 1521 |
1499 // Wait for crypto handshake to finish. This should have contributed to the | 1522 // Wait for crypto handshake to finish. This should have contributed to the |
1500 // crypto stream flow control window, but not affected the session flow | 1523 // crypto stream flow control window, but not affected the session flow |
1501 // control window. | 1524 // control window. |
(...skipping 26 matching lines...) Expand all Loading... |
1528 QuicDispatcher* dispatcher = | 1551 QuicDispatcher* dispatcher = |
1529 QuicServerPeer::GetDispatcher(server_thread_->server()); | 1552 QuicServerPeer::GetDispatcher(server_thread_->server()); |
1530 QuicSession* session = dispatcher->session_map().begin()->second; | 1553 QuicSession* session = dispatcher->session_map().begin()->second; |
1531 QuicFlowController* server_connection_flow_controller = | 1554 QuicFlowController* server_connection_flow_controller = |
1532 session->flow_controller(); | 1555 session->flow_controller(); |
1533 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize( | 1556 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize( |
1534 server_connection_flow_controller)); | 1557 server_connection_flow_controller)); |
1535 server_thread_->Resume(); | 1558 server_thread_->Resume(); |
1536 } | 1559 } |
1537 | 1560 |
| 1561 TEST_P(EndToEndTest, FlowControlsSynced) { |
| 1562 const uint32 kClientIFCW = 64 * 1024; |
| 1563 const uint32 kServerIFCW = 1024 * 1024; |
| 1564 const float kSessionToStreamRatio = 1.5; |
| 1565 set_client_initial_stream_flow_control_receive_window(kClientIFCW); |
| 1566 set_client_initial_session_flow_control_receive_window(kSessionToStreamRatio * |
| 1567 kClientIFCW); |
| 1568 set_server_initial_stream_flow_control_receive_window(kServerIFCW); |
| 1569 set_server_initial_session_flow_control_receive_window(kSessionToStreamRatio * |
| 1570 kServerIFCW); |
| 1571 |
| 1572 ASSERT_TRUE(Initialize()); |
| 1573 |
| 1574 client_->client()->WaitForCryptoHandshakeConfirmed(); |
| 1575 server_thread_->WaitForCryptoHandshakeConfirmed(); |
| 1576 |
| 1577 server_thread_->Pause(); |
| 1578 QuicSpdySession* const client_session = client_->client()->session(); |
| 1579 QuicDispatcher* dispatcher = |
| 1580 QuicServerPeer::GetDispatcher(server_thread_->server()); |
| 1581 QuicSpdySession* server_session = dispatcher->session_map().begin()->second; |
| 1582 |
| 1583 ExpectFlowControlsSynced(client_session->flow_controller(), |
| 1584 server_session->flow_controller()); |
| 1585 ExpectFlowControlsSynced( |
| 1586 QuicSessionPeer::GetCryptoStream(client_session)->flow_controller(), |
| 1587 QuicSessionPeer::GetCryptoStream(server_session)->flow_controller()); |
| 1588 ExpectFlowControlsSynced( |
| 1589 QuicSpdySessionPeer::GetHeadersStream(client_session)->flow_controller(), |
| 1590 QuicSpdySessionPeer::GetHeadersStream(server_session)->flow_controller()); |
| 1591 |
| 1592 EXPECT_EQ(static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize( |
| 1593 client_session->flow_controller())) / |
| 1594 QuicFlowControllerPeer::ReceiveWindowSize( |
| 1595 QuicSpdySessionPeer::GetHeadersStream(client_session) |
| 1596 ->flow_controller()), |
| 1597 kSessionToStreamRatio); |
| 1598 |
| 1599 server_thread_->Resume(); |
| 1600 } |
| 1601 |
1538 TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) { | 1602 TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) { |
1539 // A stream created on receipt of a simple request with no body will never get | 1603 // A stream created on receipt of a simple request with no body will never get |
1540 // a stream frame with a FIN. Verify that we don't keep track of the stream in | 1604 // a stream frame with a FIN. Verify that we don't keep track of the stream in |
1541 // the locally closed streams map: it will never be removed if so. | 1605 // the locally closed streams map: it will never be removed if so. |
1542 ASSERT_TRUE(Initialize()); | 1606 ASSERT_TRUE(Initialize()); |
1543 | 1607 |
1544 // Send a simple headers only request, and receive response. | 1608 // Send a simple headers only request, and receive response. |
1545 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | 1609 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); |
1546 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | 1610 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); |
1547 | 1611 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1838 | 1902 |
1839 // The connection should not be terminated. | 1903 // The connection should not be terminated. |
1840 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); | 1904 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); |
1841 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); | 1905 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); |
1842 } | 1906 } |
1843 | 1907 |
1844 } // namespace | 1908 } // namespace |
1845 } // namespace test | 1909 } // namespace test |
1846 } // namespace tools | 1910 } // namespace tools |
1847 } // namespace net | 1911 } // namespace net |
OLD | NEW |