| Index: net/http/http_pipelined_network_transaction_unittest.cc
|
| diff --git a/net/http/http_pipelined_network_transaction_unittest.cc b/net/http/http_pipelined_network_transaction_unittest.cc
|
| deleted file mode 100644
|
| index 181895c8d15f720b018cc3fbb5c8c669710ba9e0..0000000000000000000000000000000000000000
|
| --- a/net/http/http_pipelined_network_transaction_unittest.cc
|
| +++ /dev/null
|
| @@ -1,1037 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <string>
|
| -
|
| -#include "base/memory/ref_counted.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/memory/scoped_vector.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "net/base/address_list.h"
|
| -#include "net/base/io_buffer.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/net_util.h"
|
| -#include "net/base/request_priority.h"
|
| -#include "net/dns/host_cache.h"
|
| -#include "net/dns/mock_host_resolver.h"
|
| -#include "net/http/http_auth_challenge_tokenizer.h"
|
| -#include "net/http/http_auth_handler_mock.h"
|
| -#include "net/http/http_network_session.h"
|
| -#include "net/http/http_network_transaction.h"
|
| -#include "net/http/http_request_info.h"
|
| -#include "net/http/http_server_properties_impl.h"
|
| -#include "net/proxy/proxy_config_service.h"
|
| -#include "net/proxy/proxy_service.h"
|
| -#include "net/socket/client_socket_handle.h"
|
| -#include "net/socket/client_socket_pool_histograms.h"
|
| -#include "net/socket/client_socket_pool_manager.h"
|
| -#include "net/socket/socket_test_util.h"
|
| -#include "net/ssl/ssl_config_service_defaults.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using testing::StrEq;
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -class SimpleProxyConfigService : public ProxyConfigService {
|
| - public:
|
| - virtual void AddObserver(Observer* observer) OVERRIDE {
|
| - observer_ = observer;
|
| - }
|
| -
|
| - virtual void RemoveObserver(Observer* observer) OVERRIDE {
|
| - if (observer_ == observer) {
|
| - observer_ = NULL;
|
| - }
|
| - }
|
| -
|
| - virtual ConfigAvailability GetLatestProxyConfig(
|
| - ProxyConfig* config) OVERRIDE {
|
| - *config = config_;
|
| - return CONFIG_VALID;
|
| - }
|
| -
|
| - void IncrementConfigId() {
|
| - config_.set_id(config_.id() + 1);
|
| - observer_->OnProxyConfigChanged(config_, ProxyConfigService::CONFIG_VALID);
|
| - }
|
| -
|
| - private:
|
| - ProxyConfig config_;
|
| - Observer* observer_;
|
| -};
|
| -
|
| -class HttpPipelinedNetworkTransactionTest : public testing::Test {
|
| - public:
|
| - HttpPipelinedNetworkTransactionTest()
|
| - : histograms_("a"),
|
| - pool_(1, 1, &histograms_, &factory_) {
|
| - }
|
| -
|
| - void Initialize(bool force_http_pipelining) {
|
| - // Normally, this code could just go in SetUp(). For a few of these tests,
|
| - // we change the default number of sockets per group. That needs to be done
|
| - // before we construct the HttpNetworkSession.
|
| - proxy_config_service_ = new SimpleProxyConfigService();
|
| - proxy_service_.reset(new ProxyService(proxy_config_service_, NULL, NULL));
|
| - ssl_config_ = new SSLConfigServiceDefaults;
|
| - auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory());
|
| -
|
| - HttpNetworkSession::Params session_params;
|
| - session_params.client_socket_factory = &factory_;
|
| - session_params.proxy_service = proxy_service_.get();
|
| - session_params.host_resolver = &mock_resolver_;
|
| - session_params.ssl_config_service = ssl_config_.get();
|
| - session_params.http_auth_handler_factory = auth_handler_factory_.get();
|
| - session_params.http_server_properties =
|
| - http_server_properties_.GetWeakPtr();
|
| - session_params.force_http_pipelining = force_http_pipelining;
|
| - session_params.http_pipelining_enabled = true;
|
| - session_ = new HttpNetworkSession(session_params);
|
| - }
|
| -
|
| - void AddExpectedConnection(MockRead* reads, size_t reads_count,
|
| - MockWrite* writes, size_t writes_count) {
|
| - DeterministicSocketData* data = new DeterministicSocketData(
|
| - reads, reads_count, writes, writes_count);
|
| - data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
|
| - if (reads_count || writes_count) {
|
| - data->StopAfter(reads_count + writes_count);
|
| - }
|
| - factory_.AddSocketDataProvider(data);
|
| - data_vector_.push_back(data);
|
| - }
|
| -
|
| - enum RequestInfoOptions {
|
| - REQUEST_DEFAULT,
|
| - REQUEST_MAIN_RESOURCE,
|
| - };
|
| -
|
| - HttpRequestInfo* GetRequestInfo(
|
| - const char* filename, RequestInfoOptions options = REQUEST_DEFAULT) {
|
| - std::string url = base::StringPrintf("http://localhost/%s", filename);
|
| - HttpRequestInfo* request_info = new HttpRequestInfo;
|
| - request_info->url = GURL(url);
|
| - request_info->method = "GET";
|
| - if (options == REQUEST_MAIN_RESOURCE) {
|
| - request_info->load_flags = LOAD_MAIN_FRAME;
|
| - }
|
| - request_info_vector_.push_back(request_info);
|
| - return request_info;
|
| - }
|
| -
|
| - void ExpectResponse(const std::string& expected,
|
| - HttpNetworkTransaction& transaction,
|
| - IoMode io_mode) {
|
| - scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size()));
|
| - if (io_mode == ASYNC) {
|
| - EXPECT_EQ(ERR_IO_PENDING, transaction.Read(buffer.get(), expected.size(),
|
| - callback_.callback()));
|
| - data_vector_[0]->RunFor(1);
|
| - EXPECT_EQ(static_cast<int>(expected.length()), callback_.WaitForResult());
|
| - } else {
|
| - EXPECT_EQ(static_cast<int>(expected.size()),
|
| - transaction.Read(buffer.get(), expected.size(),
|
| - callback_.callback()));
|
| - }
|
| - std::string actual(buffer->data(), expected.size());
|
| - EXPECT_THAT(actual, StrEq(expected));
|
| - EXPECT_EQ(OK, transaction.Read(buffer.get(), expected.size(),
|
| - callback_.callback()));
|
| - }
|
| -
|
| - void CompleteTwoRequests(int data_index, int stop_at_step) {
|
| - scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction->Start(GetRequestInfo("one.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| - EXPECT_EQ(OK, one_callback.WaitForResult());
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - TestCompletionCallback one_read_callback;
|
| - scoped_refptr<IOBuffer> buffer(new IOBuffer(8));
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction->Read(buffer.get(), 8,
|
| - one_read_callback.callback()));
|
| -
|
| - data_vector_[data_index]->SetStop(stop_at_step);
|
| - data_vector_[data_index]->Run();
|
| - EXPECT_EQ(8, one_read_callback.WaitForResult());
|
| - data_vector_[data_index]->SetStop(10);
|
| - std::string actual(buffer->data(), 8);
|
| - EXPECT_THAT(actual, StrEq("one.html"));
|
| - EXPECT_EQ(OK, one_transaction->Read(buffer.get(), 8,
|
| - one_read_callback.callback()));
|
| -
|
| - EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
|
| - }
|
| -
|
| - void CompleteFourRequests(RequestInfoOptions options) {
|
| - scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction->Start(GetRequestInfo("one.html", options),
|
| - one_callback.callback(), BoundNetLog()));
|
| - EXPECT_EQ(OK, one_callback.WaitForResult());
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html", options),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - HttpNetworkTransaction three_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback three_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - three_transaction.Start(GetRequestInfo("three.html", options),
|
| - three_callback.callback(),
|
| - BoundNetLog()));
|
| -
|
| - HttpNetworkTransaction four_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback four_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - four_transaction.Start(GetRequestInfo("four.html", options),
|
| - four_callback.callback(), BoundNetLog()));
|
| -
|
| - ExpectResponse("one.html", *one_transaction.get(), SYNCHRONOUS);
|
| - EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
|
| - EXPECT_EQ(OK, three_callback.WaitForResult());
|
| - ExpectResponse("three.html", three_transaction, SYNCHRONOUS);
|
| -
|
| - one_transaction.reset();
|
| - EXPECT_EQ(OK, four_callback.WaitForResult());
|
| - ExpectResponse("four.html", four_transaction, SYNCHRONOUS);
|
| - }
|
| -
|
| - DeterministicMockClientSocketFactory factory_;
|
| - ClientSocketPoolHistograms histograms_;
|
| - MockTransportClientSocketPool pool_;
|
| - ScopedVector<DeterministicSocketData> data_vector_;
|
| - TestCompletionCallback callback_;
|
| - ScopedVector<HttpRequestInfo> request_info_vector_;
|
| -
|
| - SimpleProxyConfigService* proxy_config_service_;
|
| - scoped_ptr<ProxyService> proxy_service_;
|
| - MockHostResolver mock_resolver_;
|
| - scoped_refptr<SSLConfigService> ssl_config_;
|
| - scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory_;
|
| - HttpServerPropertiesImpl http_server_properties_;
|
| - scoped_refptr<HttpNetworkSession> session_;
|
| -};
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, OneRequest) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /test.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 9\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "test.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - transaction.Start(GetRequestInfo("test.html"), callback_.callback(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, callback_.WaitForResult());
|
| - ExpectResponse("test.html", transaction, SYNCHRONOUS);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, ReusePipeline) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(ASYNC, 4, "one.html"),
|
| - MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 7, "two.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - CompleteTwoRequests(0, 5);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, ReusesOnSpaceAvailable) {
|
| - int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL);
|
| - ClientSocketPoolManager::set_max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "one.html"),
|
| - MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 8, "two.html"),
|
| - MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 11, "three.html"),
|
| - MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 15, "four.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - CompleteFourRequests(REQUEST_DEFAULT);
|
| -
|
| - ClientSocketPoolManager::set_max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, WontPipelineMainResource) {
|
| - int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL);
|
| - ClientSocketPoolManager::set_max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 8, "GET /three.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "one.html"),
|
| - MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 7, "two.html"),
|
| - MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 11, "three.html"),
|
| - MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 15, "four.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - CompleteFourRequests(REQUEST_MAIN_RESOURCE);
|
| -
|
| - ClientSocketPoolManager::set_max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, UnknownSizeEvictsToNewPipeline) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
|
| - MockRead(ASYNC, 2, "one.html"),
|
| - MockRead(SYNCHRONOUS, OK, 3),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - MockWrite writes2[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads2[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "two.html"),
|
| - };
|
| - AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
|
| -
|
| - CompleteTwoRequests(0, 3);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, ConnectionCloseEvictToNewPipeline) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(ASYNC, 4, "one.html"),
|
| - MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - MockWrite writes2[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads2[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "two.html"),
|
| - };
|
| - AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
|
| -
|
| - CompleteTwoRequests(0, 5);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, ErrorEvictsToNewPipeline) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, ERR_FAILED, 2),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - MockWrite writes2[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads2[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "two.html"),
|
| - };
|
| - AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
|
| -
|
| - HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction.Start(GetRequestInfo("one.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| - EXPECT_EQ(OK, one_callback.WaitForResult());
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - scoped_refptr<IOBuffer> buffer(new IOBuffer(1));
|
| - EXPECT_EQ(ERR_FAILED,
|
| - one_transaction.Read(buffer.get(), 1, callback_.callback()));
|
| - EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(ASYNC, ERR_FAILED, 0),
|
| - };
|
| - AddExpectedConnection(NULL, 0, writes, arraysize(writes));
|
| -
|
| - MockWrite writes2[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads2[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "two.html"),
|
| - };
|
| - AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
|
| -
|
| - HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction.Start(GetRequestInfo("one.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - data_vector_[0]->RunFor(1);
|
| - EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
|
| -
|
| - EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, RedirectDrained) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 302 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(ASYNC, 4, "redirect"),
|
| - MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 7, "two.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction->Start(GetRequestInfo("redirect.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| - EXPECT_EQ(OK, one_callback.WaitForResult());
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - one_transaction.reset();
|
| - data_vector_[0]->RunFor(2);
|
| - data_vector_[0]->SetStop(10);
|
| -
|
| - EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 5, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n"
|
| - "Authorization: auth_token\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 401 Authentication Required\r\n"),
|
| - MockRead(SYNCHRONOUS, 2,
|
| - "WWW-Authenticate: Basic realm=\"Secure Area\"\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "Content-Length: 20\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 4, "needs authentication"),
|
| - MockRead(SYNCHRONOUS, 6, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 7, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 8, "one.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - HttpAuthHandlerMock* mock_auth = new HttpAuthHandlerMock;
|
| - std::string challenge_text = "Basic";
|
| - HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
|
| - challenge_text.end());
|
| - GURL origin("localhost");
|
| - EXPECT_TRUE(mock_auth->InitFromChallenge(&challenge,
|
| - HttpAuth::AUTH_SERVER,
|
| - origin,
|
| - BoundNetLog()));
|
| - auth_handler_factory_->AddMockHandler(mock_auth, HttpAuth::AUTH_SERVER);
|
| -
|
| - HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - transaction.Start(GetRequestInfo("one.html"),
|
| - callback_.callback(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, callback_.WaitForResult());
|
| -
|
| - AuthCredentials credentials(base::ASCIIToUTF16("user"),
|
| - base::ASCIIToUTF16("pass"));
|
| - EXPECT_EQ(OK, transaction.RestartWithAuth(credentials, callback_.callback()));
|
| -
|
| - ExpectResponse("one.html", transaction, SYNCHRONOUS);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, OldVersionDisablesPipelining) {
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /pipelined.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.0 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 14\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "pipelined.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - MockWrite writes2[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads2[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(ASYNC, 3, "one.html"),
|
| - MockRead(SYNCHRONOUS, OK, 4),
|
| - };
|
| - AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
|
| -
|
| - MockWrite writes3[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads3[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "two.html"),
|
| - MockRead(SYNCHRONOUS, OK, 4),
|
| - };
|
| - AddExpectedConnection(reads3, arraysize(reads3), writes3, arraysize(writes3));
|
| -
|
| - HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction.Start(GetRequestInfo("pipelined.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| - EXPECT_EQ(OK, one_callback.WaitForResult());
|
| - ExpectResponse("pipelined.html", one_transaction, SYNCHRONOUS);
|
| -
|
| - CompleteTwoRequests(1, 4);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, PipelinesImmediatelyIfKnownGood) {
|
| - // The first request gets us an HTTP/1.1. The next 3 test pipelining. When the
|
| - // 3rd request completes, we know pipelining is safe. After the first 4
|
| - // complete, the 5th and 6th should then be immediately sent pipelined on a
|
| - // new HttpPipelinedConnection.
|
| - int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL);
|
| - ClientSocketPoolManager::set_max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 16, "GET /second-pipeline-one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(SYNCHRONOUS, 17, "GET /second-pipeline-two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 3, "one.html"),
|
| - MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 8, "two.html"),
|
| - MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 11, "three.html"),
|
| - MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 15, "four.html"),
|
| - MockRead(ASYNC, 18, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(ASYNC, 19, "Content-Length: 24\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 20, "second-pipeline-one.html"),
|
| - MockRead(SYNCHRONOUS, 21, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 22, "Content-Length: 24\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 23, "second-pipeline-two.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - CompleteFourRequests(REQUEST_DEFAULT);
|
| -
|
| - HttpNetworkTransaction second_one_transaction(
|
| - DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback second_one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - second_one_transaction.Start(
|
| - GetRequestInfo("second-pipeline-one.html"),
|
| - second_one_callback.callback(), BoundNetLog()));
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - HttpNetworkTransaction second_two_transaction(
|
| - DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback second_two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - second_two_transaction.Start(
|
| - GetRequestInfo("second-pipeline-two.html"),
|
| - second_two_callback.callback(), BoundNetLog()));
|
| -
|
| - data_vector_[0]->RunFor(3);
|
| - EXPECT_EQ(OK, second_one_callback.WaitForResult());
|
| - data_vector_[0]->StopAfter(100);
|
| - ExpectResponse("second-pipeline-one.html", second_one_transaction,
|
| - SYNCHRONOUS);
|
| - EXPECT_EQ(OK, second_two_callback.WaitForResult());
|
| - ExpectResponse("second-pipeline-two.html", second_two_transaction,
|
| - SYNCHRONOUS);
|
| -
|
| - ClientSocketPoolManager::set_max_sockets_per_group(
|
| - HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
|
| -}
|
| -
|
| -class DataRunnerObserver : public base::MessageLoop::TaskObserver {
|
| - public:
|
| - DataRunnerObserver(DeterministicSocketData* data, int run_before_task)
|
| - : data_(data),
|
| - run_before_task_(run_before_task),
|
| - current_task_(0) { }
|
| -
|
| - virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
|
| - ++current_task_;
|
| - if (current_task_ == run_before_task_) {
|
| - data_->Run();
|
| - base::MessageLoop::current()->RemoveTaskObserver(this);
|
| - }
|
| - }
|
| -
|
| - virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {}
|
| -
|
| - private:
|
| - DeterministicSocketData* data_;
|
| - int run_before_task_;
|
| - int current_task_;
|
| -};
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, OpenPipelinesWhileBinding) {
|
| - // There was a racy crash in the pipelining code. This test recreates that
|
| - // race. The steps are:
|
| - // 1. The first request starts a pipeline and requests headers.
|
| - // 2. HttpStreamFactoryImpl::Job tries to bind a pending request to a new
|
| - // pipeline and queues a task to do so.
|
| - // 3. Before that task runs, the first request receives its headers and
|
| - // determines this host is probably capable of pipelining.
|
| - // 4. All of the hosts' pipelines are notified they have capacity in a loop.
|
| - // 5. On the first iteration, the first pipeline is opened up to accept new
|
| - // requests and steals the request from step #2.
|
| - // 6. The pipeline from #2 is deleted because it has no streams.
|
| - // 7. On the second iteration, the host tries to notify the pipeline from step
|
| - // #2 that it has capacity. This is a use-after-free.
|
| - Initialize(false);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - MockWrite(ASYNC, 3, "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(ASYNC, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 4, "one.html"),
|
| - MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(SYNCHRONOUS, 7, "two.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - AddExpectedConnection(NULL, 0, NULL, 0);
|
| -
|
| - HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction.Start(GetRequestInfo("one.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| -
|
| - data_vector_[0]->SetStop(2);
|
| - data_vector_[0]->Run();
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| - // Posted tasks should be:
|
| - // 1. MockHostResolverBase::ResolveNow
|
| - // 2. HttpStreamFactoryImpl::Job::OnStreamReadyCallback for job 1
|
| - // 3. HttpStreamFactoryImpl::Job::OnStreamReadyCallback for job 2
|
| - //
|
| - // We need to make sure that the response that triggers OnPipelineFeedback(OK)
|
| - // is called in between when task #3 is scheduled and when it runs. The
|
| - // DataRunnerObserver does that.
|
| - DataRunnerObserver observer(data_vector_[0], 3);
|
| - base::MessageLoop::current()->AddTaskObserver(&observer);
|
| - data_vector_[0]->SetStop(4);
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| - data_vector_[0]->SetStop(10);
|
| -
|
| - EXPECT_EQ(OK, one_callback.WaitForResult());
|
| - ExpectResponse("one.html", one_transaction, SYNCHRONOUS);
|
| - EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, ProxyChangesWhileConnecting) {
|
| - Initialize(false);
|
| -
|
| - DeterministicSocketData data(NULL, 0, NULL, 0);
|
| - data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
|
| - factory_.AddSocketDataProvider(&data);
|
| -
|
| - DeterministicSocketData data2(NULL, 0, NULL, 0);
|
| - data2.set_connect_data(MockConnect(ASYNC, ERR_FAILED));
|
| - factory_.AddSocketDataProvider(&data2);
|
| -
|
| - HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - transaction.Start(GetRequestInfo("test.html"), callback_.callback(),
|
| - BoundNetLog()));
|
| -
|
| - proxy_config_service_->IncrementConfigId();
|
| -
|
| - EXPECT_EQ(ERR_FAILED, callback_.WaitForResult());
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineSharesConnection) {
|
| - Initialize(true);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(ASYNC, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"
|
| - "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(ASYNC, 2, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(ASYNC, 3, "one.html"),
|
| - MockRead(ASYNC, 4, "HTTP/1.1 200 OK\r\n"),
|
| - MockRead(ASYNC, 5, "Content-Length: 8\r\n\r\n"),
|
| - MockRead(ASYNC, 6, "two.html"),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction->Start(GetRequestInfo("one.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - data_vector_[0]->RunFor(3); // Send + 2 lines of headers.
|
| - EXPECT_EQ(OK, one_callback.WaitForResult());
|
| - ExpectResponse("one.html", *one_transaction.get(), ASYNC);
|
| - one_transaction.reset();
|
| -
|
| - data_vector_[0]->RunFor(2); // 2 lines of headers.
|
| - EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction, ASYNC);
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest,
|
| - ForcedPipelineConnectionErrorFailsBoth) {
|
| - Initialize(true);
|
| -
|
| - DeterministicSocketData data(NULL, 0, NULL, 0);
|
| - data.set_connect_data(MockConnect(ASYNC, ERR_FAILED));
|
| - factory_.AddSocketDataProvider(&data);
|
| -
|
| - scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction->Start(GetRequestInfo("one.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - data.Run();
|
| - EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
|
| - EXPECT_EQ(ERR_FAILED, two_callback.WaitForResult());
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineEvictionIsFatal) {
|
| - Initialize(true);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(ASYNC, 0, "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"
|
| - "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(ASYNC, ERR_FAILED, 1),
|
| - };
|
| - AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| -
|
| - scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction->Start(GetRequestInfo("one.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| -
|
| - HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction.Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - data_vector_[0]->RunFor(2);
|
| - EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
|
| - one_transaction.reset();
|
| - EXPECT_EQ(ERR_PIPELINE_EVICTION, two_callback.WaitForResult());
|
| -}
|
| -
|
| -TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineOrder) {
|
| - Initialize(true);
|
| -
|
| - MockWrite writes[] = {
|
| - MockWrite(ASYNC, 0,
|
| - "GET /one.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"
|
| - "GET /two.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"
|
| - "GET /three.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"
|
| - "GET /four.html HTTP/1.1\r\n"
|
| - "Host: localhost\r\n"
|
| - "Connection: keep-alive\r\n\r\n"
|
| - ),
|
| - };
|
| - MockRead reads[] = {
|
| - MockRead(ASYNC, ERR_FAILED, 1),
|
| - };
|
| - DeterministicSocketData data(
|
| - reads, arraysize(reads), writes, arraysize(writes));
|
| - data.set_connect_data(MockConnect(ASYNC, OK));
|
| - factory_.AddSocketDataProvider(&data);
|
| -
|
| - scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback one_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - one_transaction->Start(GetRequestInfo("one.html"),
|
| - one_callback.callback(), BoundNetLog()));
|
| -
|
| - scoped_ptr<HttpNetworkTransaction> two_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback two_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - two_transaction->Start(GetRequestInfo("two.html"),
|
| - two_callback.callback(), BoundNetLog()));
|
| -
|
| - scoped_ptr<HttpNetworkTransaction> three_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback three_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - three_transaction->Start(GetRequestInfo("three.html"),
|
| - three_callback.callback(), BoundNetLog()));
|
| -
|
| - scoped_ptr<HttpNetworkTransaction> four_transaction(
|
| - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
|
| - TestCompletionCallback four_callback;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - four_transaction->Start(GetRequestInfo("four.html"),
|
| - four_callback.callback(), BoundNetLog()));
|
| -
|
| - data.RunFor(3);
|
| - EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
|
| - one_transaction.reset();
|
| - EXPECT_EQ(ERR_PIPELINE_EVICTION, two_callback.WaitForResult());
|
| - two_transaction.reset();
|
| - EXPECT_EQ(ERR_PIPELINE_EVICTION, three_callback.WaitForResult());
|
| - three_transaction.reset();
|
| - EXPECT_EQ(ERR_PIPELINE_EVICTION, four_callback.WaitForResult());
|
| -}
|
| -
|
| -} // anonymous namespace
|
| -
|
| -} // namespace net
|
|
|