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

Unified Diff: chrome/browser/net/http_pipelining_compatibility_client.cc

Issue 275953002: Remove HTTP pipelining support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix line endings Created 6 years, 7 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: chrome/browser/net/http_pipelining_compatibility_client.cc
diff --git a/chrome/browser/net/http_pipelining_compatibility_client.cc b/chrome/browser/net/http_pipelining_compatibility_client.cc
deleted file mode 100644
index 3f2ee54f800e3ea434c3657c8359839e97c9d86d..0000000000000000000000000000000000000000
--- a/chrome/browser/net/http_pipelining_compatibility_client.cc
+++ /dev/null
@@ -1,542 +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 "chrome/browser/net/http_pipelining_compatibility_client.h"
-
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/stringprintf.h"
-#include "chrome/browser/io_thread.h"
-#include "chrome/common/chrome_version_info.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/load_flags.h"
-#include "net/base/network_change_notifier.h"
-#include "net/base/request_priority.h"
-#include "net/disk_cache/blockfile/histogram_macros.h"
-#include "net/http/http_network_layer.h"
-#include "net/http/http_network_session.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_version.h"
-#include "net/proxy/proxy_config.h"
-#include "net/proxy/proxy_service.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
-
-namespace chrome_browser_net {
-
-static const int kCanaryRequestId = 999;
-
-namespace {
-
-// There is one Request per RequestInfo passed in to Start() above.
-class Request : public internal::PipelineTestRequest,
- public net::URLRequest::Delegate {
- public:
- Request(int request_id,
- const std::string& base_url,
- const RequestInfo& info,
- internal::PipelineTestRequest::Delegate* delegate,
- net::URLRequestContext* url_request_context);
-
- virtual ~Request() {}
-
- virtual void Start() OVERRIDE;
-
- protected:
- // Called when this request has determined its result. Returns the result to
- // the |client_|.
- virtual void Finished(internal::PipelineTestRequest::Status result);
-
- const std::string& response() const { return response_; }
-
- internal::PipelineTestRequest::Delegate* delegate() { return delegate_; }
-
- private:
- // Called when a response can be read. Reads bytes into |response_| until it
- // consumes the entire response or it encounters an error.
- void DoRead();
-
- // Called when all bytes have been received. Compares the |response_| to
- // |info_|'s expected response.
- virtual void DoReadFinished();
-
- // net::URLRequest::Delegate interface
- virtual void OnReceivedRedirect(net::URLRequest* request,
- const GURL& new_url,
- bool* defer_redirect) OVERRIDE;
- virtual void OnSSLCertificateError(net::URLRequest* request,
- const net::SSLInfo& ssl_info,
- bool fatal) OVERRIDE;
- virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
- virtual void OnReadCompleted(net::URLRequest* request,
- int bytes_read) OVERRIDE;
-
- internal::PipelineTestRequest::Delegate* delegate_;
- const int request_id_;
- scoped_ptr<net::URLRequest> url_request_;
- const RequestInfo info_;
- scoped_refptr<net::IOBuffer> read_buffer_;
- std::string response_;
- int response_code_;
-};
-
-Request::Request(int request_id,
- const std::string& base_url,
- const RequestInfo& info,
- internal::PipelineTestRequest::Delegate* delegate,
- net::URLRequestContext* url_request_context)
- : delegate_(delegate),
- request_id_(request_id),
- url_request_(url_request_context->CreateRequest(GURL(base_url +
- info.filename),
- net::DEFAULT_PRIORITY,
- this,
- NULL)),
- info_(info),
- response_code_(0) {
- url_request_->SetLoadFlags(net::LOAD_BYPASS_CACHE |
- net::LOAD_DISABLE_CACHE |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_PROMPT_FOR_LOGIN |
- net::LOAD_DO_NOT_SEND_AUTH_DATA);
-}
-
-void Request::Start() {
- url_request_->Start();
-}
-
-void Request::OnReceivedRedirect(
- net::URLRequest* request,
- const GURL& new_url,
- bool* defer_redirect) {
- *defer_redirect = true;
- request->Cancel();
- Finished(STATUS_REDIRECTED);
-}
-
-void Request::OnSSLCertificateError(
- net::URLRequest* request,
- const net::SSLInfo& ssl_info,
- bool fatal) {
- Finished(STATUS_CERT_ERROR);
-}
-
-void Request::OnResponseStarted(net::URLRequest* request) {
- response_code_ = request->GetResponseCode();
- if (response_code_ != 200) {
- Finished(STATUS_BAD_RESPONSE_CODE);
- return;
- }
- const net::HttpVersion required_version(1, 1);
- if (request->response_info().headers->GetParsedHttpVersion() <
- required_version) {
- Finished(STATUS_BAD_HTTP_VERSION);
- return;
- }
- read_buffer_ = new net::IOBuffer(info_.expected_response.length());
- DoRead();
-}
-
-void Request::OnReadCompleted(net::URLRequest* request, int bytes_read) {
- if (bytes_read == 0) {
- DoReadFinished();
- } else if (bytes_read < 0) {
- Finished(STATUS_NETWORK_ERROR);
- } else {
- response_.append(read_buffer_->data(), bytes_read);
- if (response_.length() <= info_.expected_response.length()) {
- DoRead();
- } else if (response_.find(info_.expected_response) == 0) {
- Finished(STATUS_TOO_LARGE);
- } else {
- Finished(STATUS_CONTENT_MISMATCH);
- }
- }
-}
-
-void Request::DoRead() {
- int bytes_read = 0;
- if (url_request_->Read(read_buffer_.get(), info_.expected_response.length(),
- &bytes_read)) {
- OnReadCompleted(url_request_.get(), bytes_read);
- }
-}
-
-void Request::DoReadFinished() {
- if (response_.length() != info_.expected_response.length()) {
- if (info_.expected_response.find(response_) == 0) {
- Finished(STATUS_TOO_SMALL);
- } else {
- Finished(STATUS_CONTENT_MISMATCH);
- }
- } else if (response_ == info_.expected_response) {
- Finished(STATUS_SUCCESS);
- } else {
- Finished(STATUS_CONTENT_MISMATCH);
- }
-}
-
-void Request::Finished(internal::PipelineTestRequest::Status result) {
- const net::URLRequestStatus status = url_request_->status();
- url_request_.reset();
- if (response_code_ > 0) {
- delegate()->ReportResponseCode(request_id_, response_code_);
- }
- if (status.status() == net::URLRequestStatus::FAILED) {
- // Network errors trump all other status codes, because network errors can
- // be detected by the network stack even with real content. If we determine
- // that all pipelining errors can be detected by the network stack, then we
- // don't need to worry about broken proxies.
- delegate()->ReportNetworkError(request_id_, status.error());
- delegate()->OnRequestFinished(request_id_, STATUS_NETWORK_ERROR);
- } else {
- delegate()->OnRequestFinished(request_id_, result);
- }
- // WARNING: We may be deleted at this point.
-}
-
-// A special non-pipelined request sent before pipelining begins to test basic
-// HTTP connectivity.
-class CanaryRequest : public Request {
- public:
- CanaryRequest(int request_id,
- const std::string& base_url,
- const RequestInfo& info,
- internal::PipelineTestRequest::Delegate* delegate,
- net::URLRequestContext* url_request_context)
- : Request(request_id, base_url, info, delegate, url_request_context) {
- }
-
- virtual ~CanaryRequest() {}
-
- private:
- virtual void Finished(
- internal::PipelineTestRequest::Status result) OVERRIDE {
- delegate()->OnCanaryFinished(result);
- }
-};
-
-// A special request that parses a /stats.txt response from the test server.
-class StatsRequest : public Request {
- public:
- // Note that |info.expected_response| is only used to determine the correct
- // length of the response. The exact string content isn't used.
- StatsRequest(int request_id,
- const std::string& base_url,
- const RequestInfo& info,
- internal::PipelineTestRequest::Delegate* delegate,
- net::URLRequestContext* url_request_context)
- : Request(request_id, base_url, info, delegate, url_request_context) {
- }
-
- virtual ~StatsRequest() {}
-
- private:
- virtual void DoReadFinished() OVERRIDE {
- internal::PipelineTestRequest::Status status =
- internal::ProcessStatsResponse(response());
- Finished(status);
- }
-};
-
-class RequestFactory : public internal::PipelineTestRequest::Factory {
- public:
- virtual internal::PipelineTestRequest* NewRequest(
- int request_id,
- const std::string& base_url,
- const RequestInfo& info,
- internal::PipelineTestRequest::Delegate* delegate,
- net::URLRequestContext* url_request_context,
- internal::PipelineTestRequest::Type request_type) OVERRIDE {
- switch (request_type) {
- case internal::PipelineTestRequest::TYPE_PIPELINED:
- return new Request(request_id, base_url, info, delegate,
- url_request_context);
-
- case internal::PipelineTestRequest::TYPE_CANARY:
- return new CanaryRequest(request_id, base_url, info, delegate,
- url_request_context);
-
- case internal::PipelineTestRequest::TYPE_STATS:
- return new StatsRequest(request_id, base_url, info, delegate,
- url_request_context);
-
- default:
- NOTREACHED();
- return NULL;
- }
- }
-};
-
-} // anonymous namespace
-
-HttpPipeliningCompatibilityClient::HttpPipeliningCompatibilityClient(
- internal::PipelineTestRequest::Factory* factory)
- : factory_(factory),
- num_finished_(0),
- num_succeeded_(0) {
- if (!factory_.get()) {
- factory_.reset(new RequestFactory);
- }
-}
-
-HttpPipeliningCompatibilityClient::~HttpPipeliningCompatibilityClient() {
-}
-
-void HttpPipeliningCompatibilityClient::Start(
- const std::string& base_url,
- std::vector<RequestInfo>& requests,
- Options options,
- const net::CompletionCallback& callback,
- net::URLRequestContext* url_request_context) {
- net::HttpNetworkSession* old_session =
- url_request_context->http_transaction_factory()->GetSession();
- net::HttpNetworkSession::Params params = old_session->params();
- params.force_http_pipelining = true;
- scoped_refptr<net::HttpNetworkSession> session =
- new net::HttpNetworkSession(params);
- http_transaction_factory_.reset(
- net::HttpNetworkLayer::CreateFactory(session.get()));
-
- url_request_context_.reset(new net::URLRequestContext);
- url_request_context_->CopyFrom(url_request_context);
- url_request_context_->set_http_transaction_factory(
- http_transaction_factory_.get());
-
- finished_callback_ = callback;
- for (size_t i = 0; i < requests.size(); ++i) {
- requests_.push_back(factory_->NewRequest(
- i, base_url, requests[i], this, url_request_context_.get(),
- internal::PipelineTestRequest::TYPE_PIPELINED));
- }
- if (options == PIPE_TEST_COLLECT_SERVER_STATS ||
- options == PIPE_TEST_CANARY_AND_STATS) {
- RequestInfo info;
- info.filename = "stats.txt";
- // This is just to determine the expected length of the response.
- // StatsRequest doesn't expect this exact value, but it does expect this
- // exact length.
- info.expected_response =
- "were_all_requests_http_1_1:1,max_pipeline_depth:5";
- requests_.push_back(factory_->NewRequest(
- requests.size(), base_url, info, this, url_request_context_.get(),
- internal::PipelineTestRequest::TYPE_STATS));
- }
- if (options == PIPE_TEST_RUN_CANARY_REQUEST ||
- options == PIPE_TEST_CANARY_AND_STATS) {
- RequestInfo info;
- info.filename = "index.html";
- info.expected_response =
- "\nThis is a test server operated by Google. It's used by Google "
- "Chrome to test\nproxies for compatibility with HTTP pipelining. More "
- "information can be found\nhere:\n\nhttp://dev.chromium.org/developers/"
- "design-documents/network-stack/http-pipelining\n\nSource code can be "
- "found here:\n\nhttp://code.google.com/p/http-pipelining-test/\n";
- canary_request_.reset(factory_->NewRequest(
- kCanaryRequestId, base_url, info, this, url_request_context,
- internal::PipelineTestRequest::TYPE_CANARY));
- canary_request_->Start();
- } else {
- StartTestRequests();
- }
-}
-
-void HttpPipeliningCompatibilityClient::StartTestRequests() {
- for (size_t i = 0; i < requests_.size(); ++i) {
- requests_[i]->Start();
- }
-}
-
-void HttpPipeliningCompatibilityClient::OnCanaryFinished(
- internal::PipelineTestRequest::Status status) {
- canary_request_.reset();
- bool success = (status == internal::PipelineTestRequest::STATUS_SUCCESS);
- UMA_HISTOGRAM_BOOLEAN("NetConnectivity.Pipeline.CanarySuccess", success);
- if (success) {
- StartTestRequests();
- } else {
- finished_callback_.Run(0);
- }
-}
-
-void HttpPipeliningCompatibilityClient::OnRequestFinished(
- int request_id, internal::PipelineTestRequest::Status status) {
- // The CACHE_HISTOGRAM_* macros are used, because they allow dynamic metric
- // names.
- // TODO(gavinp): Clean up this dependency by moving the needed functionality
- // into base/.
- CACHE_HISTOGRAM_ENUMERATION(GetMetricName(request_id, "Status"),
- status,
- internal::PipelineTestRequest::STATUS_MAX);
-
- ++num_finished_;
- if (status == internal::PipelineTestRequest::STATUS_SUCCESS) {
- ++num_succeeded_;
- }
- if (num_finished_ == requests_.size()) {
- UMA_HISTOGRAM_BOOLEAN("NetConnectivity.Pipeline.Success",
- num_succeeded_ == requests_.size());
- finished_callback_.Run(0);
- }
-}
-
-void HttpPipeliningCompatibilityClient::ReportNetworkError(int request_id,
- int error_code) {
- CACHE_HISTOGRAM_ENUMERATION(GetMetricName(request_id, "NetworkError"),
- -error_code, 900);
-}
-
-void HttpPipeliningCompatibilityClient::ReportResponseCode(int request_id,
- int response_code) {
- CACHE_HISTOGRAM_ENUMERATION(GetMetricName(request_id, "ResponseCode"),
- response_code, 600);
-}
-
-std::string HttpPipeliningCompatibilityClient::GetMetricName(
- int request_id, const char* description) {
- return base::StringPrintf("NetConnectivity.Pipeline.%d.%s",
- request_id, description);
-}
-
-namespace internal {
-
-internal::PipelineTestRequest::Status ProcessStatsResponse(
- const std::string& response) {
- bool were_all_requests_http_1_1 = false;
- int max_pipeline_depth = 0;
-
- std::vector<std::pair<std::string, std::string> > kv_pairs;
- base::SplitStringIntoKeyValuePairs(response, ':', ',', &kv_pairs);
-
- if (kv_pairs.size() != 2) {
- return internal::PipelineTestRequest::STATUS_CORRUPT_STATS;
- }
-
- for (size_t i = 0; i < kv_pairs.size(); ++i) {
- const std::string& key = kv_pairs[i].first;
- int value;
- if (!base::StringToInt(kv_pairs[i].second, &value)) {
- return internal::PipelineTestRequest::STATUS_CORRUPT_STATS;
- }
-
- if (key == "were_all_requests_http_1_1") {
- were_all_requests_http_1_1 = (value == 1);
- } else if (key == "max_pipeline_depth") {
- max_pipeline_depth = value;
- } else {
- return internal::PipelineTestRequest::STATUS_CORRUPT_STATS;
- }
- }
-
- UMA_HISTOGRAM_BOOLEAN("NetConnectivity.Pipeline.AllHTTP11",
- were_all_requests_http_1_1);
- UMA_HISTOGRAM_ENUMERATION("NetConnectivity.Pipeline.Depth",
- max_pipeline_depth, 6);
-
- return internal::PipelineTestRequest::STATUS_SUCCESS;
-}
-
-} // namespace internal
-
-namespace {
-
-void DeleteClient(IOThread* io_thread, int /* rv */) {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- io_thread->globals()->http_pipelining_compatibility_client.reset();
-}
-
-void CollectPipeliningCapabilityStatsOnIOThread(
- const std::string& pipeline_test_server,
- IOThread* io_thread) {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-
- net::URLRequestContext* url_request_context =
- io_thread->globals()->system_request_context.get();
- if (!url_request_context->proxy_service()->config().proxy_rules().empty()) {
- // Pipelining with explicitly configured proxies is disabled for now.
- return;
- }
-
- const base::FieldTrial::Probability kDivisor = 100;
- base::FieldTrial::Probability probability_to_run_test = 0;
-
- const char* kTrialName = "HttpPipeliningCompatibility";
- base::FieldTrial* trial = base::FieldTrialList::Find(kTrialName);
- if (trial) {
- return;
- }
- // After May 4, 2012, the trial will disable itself.
- trial = base::FieldTrialList::FactoryGetFieldTrial(
- kTrialName, kDivisor, "disable_test", 2012, 5, 4,
- base::FieldTrial::SESSION_RANDOMIZED, NULL);
-
- chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
- if (channel == chrome::VersionInfo::CHANNEL_CANARY) {
- probability_to_run_test = 100;
- } else if (channel == chrome::VersionInfo::CHANNEL_DEV) {
- probability_to_run_test = 100;
- }
-
- int collect_stats_group = trial->AppendGroup("enable_test",
- probability_to_run_test);
- if (trial->group() != collect_stats_group) {
- return;
- }
-
- std::vector<RequestInfo> requests;
-
- RequestInfo info0;
- info0.filename = "alphabet.txt";
- info0.expected_response = "abcdefghijklmnopqrstuvwxyz";
- requests.push_back(info0);
-
- RequestInfo info1;
- info1.filename = "cached.txt";
- info1.expected_response = "azbycxdwevfugthsirjqkplomn";
- requests.push_back(info1);
-
- RequestInfo info2;
- info2.filename = "reverse.txt";
- info2.expected_response = "zyxwvutsrqponmlkjihgfedcba";
- requests.push_back(info2);
-
- RequestInfo info3;
- info3.filename = "chunked.txt";
- info3.expected_response = "chunkedencodingisfun";
- requests.push_back(info3);
-
- RequestInfo info4;
- info4.filename = "cached.txt";
- info4.expected_response = "azbycxdwevfugthsirjqkplomn";
- requests.push_back(info4);
-
- HttpPipeliningCompatibilityClient* client =
- new HttpPipeliningCompatibilityClient(NULL);
- client->Start(pipeline_test_server, requests,
- HttpPipeliningCompatibilityClient::PIPE_TEST_CANARY_AND_STATS,
- base::Bind(&DeleteClient, io_thread),
- url_request_context);
- io_thread->globals()->http_pipelining_compatibility_client.reset(client);
-}
-
-} // anonymous namespace
-
-void CollectPipeliningCapabilityStatsOnUIThread(
- const std::string& pipeline_test_server, IOThread* io_thread) {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- if (pipeline_test_server.empty())
- return;
-
- content::BrowserThread::PostTask(
- content::BrowserThread::IO,
- FROM_HERE,
- base::Bind(&CollectPipeliningCapabilityStatsOnIOThread,
- pipeline_test_server,
- io_thread));
-}
-
-} // namespace chrome_browser_net

Powered by Google App Engine
This is Rietveld 408576698