Commit f17bc89e authored by Yoichi Osato's avatar Yoichi Osato Committed by Commit Bot

[net] Add preconnect error handling tests when uploading.

This CL extends
HttpNetworkTransactionTest::PreconnectErrorResendRequestTest() to
confirm upload success when the first attempt failed over both H/1 and
H/2.

This is a preparation to add caching mechanism in
ChunkedDataPipeUploadDataStream: crrev.com/c/2269622

Bug: 1077174
Change-Id: I75b277295652e87de7f2b6cde4e911d2669e9839
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2334726
Commit-Queue: Yoichi Osato <yoichio@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#794809}
parent f2bcab22
......@@ -460,7 +460,8 @@ class HttpNetworkTransactionTest : public PlatformTest,
// other argument should be NULL.
void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
const MockRead* read_failure,
bool use_spdy);
bool use_spdy,
bool upload = false);
SimpleGetHelperResult SimpleGetHelperForData(
base::span<StaticSocketDataProvider*> providers) {
......@@ -1883,13 +1884,24 @@ void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
const MockWrite* write_failure,
const MockRead* read_failure,
bool use_spdy) {
bool use_spdy,
bool chunked_upload) {
SpdyTestUtil spdy_util;
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("https://www.foo.com/");
request.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
const char upload_data[] = "foobar";
ChunkedUploadDataStream upload_data_stream(0);
if (chunked_upload) {
request.method = "POST";
upload_data_stream.AppendData(upload_data, base::size(upload_data) - 1,
true);
request.upload_data_stream = &upload_data_stream;
}
RecordingTestNetLog net_log;
session_deps_.net_log = &net_log;
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
......@@ -1904,17 +1916,32 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
// SPDY versions of the request and response.
spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
spdy::SpdyHeaderBlock spdy_post_header_block;
spdy_post_header_block[spdy::kHttp2MethodHeader] = "POST";
spdy_util.AddUrlToHeaderBlock(request.url.spec(), &spdy_post_header_block);
spdy::SpdySerializedFrame spdy_request(
chunked_upload
? spdy_util.ConstructSpdyHeaders(1, std::move(spdy_post_header_block),
DEFAULT_PRIORITY, false)
: spdy_util.ConstructSpdyGet(request.url.spec().c_str(), 1,
DEFAULT_PRIORITY));
spdy::SpdySerializedFrame spdy_request_body(
spdy_util.ConstructSpdyDataFrame(1, "foobar", true));
spdy::SpdySerializedFrame spdy_response(
spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
spdy::SpdySerializedFrame spdy_data(
spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
spdy_util.ConstructSpdyDataFrame(1, "hello", true));
// HTTP/1.1 versions of the request and response.
const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
const std::string http_request =
std::string(chunked_upload ? "POST" : "GET") +
" / HTTP/1.1\r\n"
"Host: www.foo.com\r\n"
"Connection: keep-alive\r\n\r\n";
"Connection: keep-alive\r\n" +
(chunked_upload ? "Transfer-Encoding: chunked\r\n\r\n" : "\r\n");
const char* kHttpRequest = http_request.c_str();
const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
const char kHttpData[] = "hello";
......@@ -1928,8 +1955,14 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
ASSERT_TRUE(read_failure);
if (use_spdy) {
data1_writes.push_back(CreateMockWrite(spdy_request));
if (chunked_upload)
data1_writes.push_back(CreateMockWrite(spdy_request_body));
} else {
data1_writes.push_back(MockWrite(kHttpRequest));
if (chunked_upload) {
data1_writes.push_back(MockWrite("6\r\nfoobar\r\n"));
data1_writes.push_back(MockWrite("0\r\n\r\n"));
}
}
data1_reads.push_back(*read_failure);
}
......@@ -1941,19 +1974,25 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
std::vector<MockWrite> data2_writes;
if (use_spdy) {
data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
data2_reads.push_back(MockRead(ASYNC, OK, 3));
int seq = 0;
data2_writes.push_back(CreateMockWrite(spdy_request, seq++, ASYNC));
if (chunked_upload)
data2_writes.push_back(CreateMockWrite(spdy_request_body, seq++, ASYNC));
data2_reads.push_back(CreateMockRead(spdy_response, seq++, ASYNC));
data2_reads.push_back(CreateMockRead(spdy_data, seq++, ASYNC));
data2_reads.push_back(MockRead(ASYNC, OK, seq++));
} else {
int seq = 0;
data2_writes.push_back(
MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), seq++));
if (chunked_upload) {
data2_writes.push_back(MockWrite(ASYNC, "6\r\nfoobar\r\n", 11, seq++));
data2_writes.push_back(MockWrite(ASYNC, "0\r\n\r\n", 5, seq++));
}
data2_reads.push_back(
MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
data2_reads.push_back(MockRead(ASYNC, OK, 3));
MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), seq++));
data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), seq++));
data2_reads.push_back(MockRead(ASYNC, OK, seq++));
}
SequencedSocketData data2(data2_reads, data2_writes);
session_deps_.socket_factory->AddSocketDataProvider(&data2);
......@@ -2118,22 +2157,34 @@ TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
PreconnectErrorResendRequestTest(&write_failure, nullptr,
false /* use_spdy */);
PreconnectErrorResendRequestTest(
&write_failure, nullptr, false /* use_spdy */, true /* chunked_upload */);
}
TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
PreconnectErrorResendRequestTest(nullptr, &read_failure,
false /* use_spdy */);
PreconnectErrorResendRequestTest(nullptr, &read_failure, false /* use_spdy */,
true /* chunked_upload */);
}
TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
MockRead read_failure(SYNCHRONOUS, OK); // EOF
PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
PreconnectErrorResendRequestTest(nullptr, &read_failure,
false /* use_spdy */);
PreconnectErrorResendRequestTest(nullptr, &read_failure, false /* use_spdy */,
true /* chunked_upload */);
}
TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
MockRead read_failure(ASYNC, OK); // EOF
PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
PreconnectErrorResendRequestTest(nullptr, &read_failure,
false /* use_spdy */);
PreconnectErrorResendRequestTest(nullptr, &read_failure, false /* use_spdy */,
true /* chunked_upload */);
}
// Make sure that on a 408 response (Request Timeout), the request is retried,
......@@ -2145,27 +2196,39 @@ TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
"Content-Length: 6\r\n\r\n"
"Pickle");
KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
PreconnectErrorResendRequestTest(nullptr, &read_failure,
false /* use_spdy */);
PreconnectErrorResendRequestTest(nullptr, &read_failure, false /* use_spdy */,
true /* chunked_upload */);
}
TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
PreconnectErrorResendRequestTest(&write_failure, nullptr,
true /* use_spdy */);
PreconnectErrorResendRequestTest(&write_failure, nullptr, true /* use_spdy */,
true /* chunked_upload */);
}
TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */);
PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */,
true /* chunked_upload */);
}
TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
MockRead read_failure(SYNCHRONOUS, OK); // EOF
PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */);
PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */,
true /* chunked_upload */);
}
TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
MockRead read_failure(ASYNC, OK); // EOF
PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */);
PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */,
true /* chunked_upload */);
}
TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment