| // 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. |
| |
| #ifndef CHROME_BROWSER_NET_HTTP_PIPELINING_COMPATIBILITY_CLIENT_H_ |
| #define CHROME_BROWSER_NET_HTTP_PIPELINING_COMPATIBILITY_CLIENT_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/memory/scoped_vector.h" |
| #include "net/base/completion_callback.h" |
| #include "net/base/io_buffer.h" |
| #include "net/url_request/url_request.h" |
| #include "net/url_request/url_request_context.h" |
| |
| class IOThread; |
| |
| namespace chrome_browser_net { |
| |
| struct RequestInfo { |
| std::string filename; // The path relative to the test server's base_url. |
| std::string expected_response; // The expected body of the response. |
| }; |
| |
| namespace internal { |
| |
| class PipelineTestRequest { |
| public: |
| enum Status { |
| STATUS_SUCCESS, |
| STATUS_REDIRECTED, // Response was redirected. We won't follow. |
| STATUS_CERT_ERROR, // Any certificate problem. |
| STATUS_BAD_RESPONSE_CODE, // Any non-200 response. |
| STATUS_NETWORK_ERROR, // Any socket error reported by the network |
| // layer. |
| STATUS_TOO_LARGE, // The response matched, but had extra data on |
| // the end. |
| STATUS_TOO_SMALL, // The response was shorter than expected, but |
| // what we got matched. |
| STATUS_CONTENT_MISMATCH, // The response didn't match the expected value. |
| STATUS_BAD_HTTP_VERSION, // Any version older than HTTP/1.1. |
| STATUS_CORRUPT_STATS, // The stats.txt response was corrupt. |
| STATUS_MAX, |
| }; |
| |
| enum Type { |
| TYPE_PIPELINED, // Pipelined test requests. |
| TYPE_CANARY, // A non-pipelined request to verify basic HTTP |
| // connectivity. |
| TYPE_STATS, // Collects stats from the test server. |
| }; |
| |
| class Delegate { |
| public: |
| virtual ~Delegate() {} |
| |
| // Called when the canary request completes. |
| virtual void OnCanaryFinished(Status status) = 0; |
| |
| // Called when a Request determines its result. Reports to UMA. |
| virtual void OnRequestFinished(int request_id, Status status) = 0; |
| |
| // Called when a Request encounters a network error. Reports to UMA. |
| virtual void ReportNetworkError(int request_id, int error_code) = 0; |
| |
| // Called when a Request determines its HTTP response code. Reports to UMA. |
| virtual void ReportResponseCode(int request_id, int response_code) = 0; |
| }; |
| |
| class Factory { |
| public: |
| virtual ~Factory() {} |
| |
| virtual PipelineTestRequest* NewRequest( |
| int request_id, |
| const std::string& base_url, |
| const RequestInfo& info, |
| Delegate* delegate, |
| net::URLRequestContext* url_request_context, |
| Type type) = 0; |
| }; |
| |
| virtual ~PipelineTestRequest() {} |
| |
| virtual void Start() = 0; |
| }; |
| |
| PipelineTestRequest::Status ProcessStatsResponse( |
| const std::string& response); |
| |
| } // namespace internal |
| |
| // Class for performing a background test of users' Internet connections. |
| // Fetches a collection of resources on a test server and verifies all were |
| // received correctly. This will be used to determine whether or not proxies are |
| // interfering with a user's ability to use HTTP pipelining. Results are |
| // recorded with UMA. |
| class HttpPipeliningCompatibilityClient |
| : public internal::PipelineTestRequest::Delegate { |
| public: |
| enum Options { |
| PIPE_TEST_DEFAULTS, // Only run the |requests| passed to Start. |
| PIPE_TEST_RUN_CANARY_REQUEST, // Also perform a canary request before |
| // testing pipelining. |
| PIPE_TEST_COLLECT_SERVER_STATS, // Also request stats from the server after |
| // the pipeline test completes. |
| PIPE_TEST_CANARY_AND_STATS, // Both of the above. |
| }; |
| |
| HttpPipeliningCompatibilityClient( |
| internal::PipelineTestRequest::Factory* factory); |
| virtual ~HttpPipeliningCompatibilityClient(); |
| |
| // Launches the asynchronous URLRequests to fetch the URLs specified by |
| // |requests| combined with |base_url|. |base_url| should match the pattern |
| // "http://host/". |callback| is invoked once all the requests have completed. |
| // URLRequests are initiated in |url_request_context|. Results are recorded to |
| // UMA as they are received. If |collect_server_stats| is true, also collects |
| // pipelining information recorded by the server. |
| void Start(const std::string& base_url, |
| std::vector<RequestInfo>& requests, |
| Options options, |
| const net::CompletionCallback& callback, |
| net::URLRequestContext* url_request_context); |
| |
| private: |
| // Sends the pipelining test requests. |
| void StartTestRequests(); |
| |
| // Returns the full UMA metric name based on |request_id| and |description|. |
| std::string GetMetricName(int request_id, const char* description); |
| |
| // PipelineTestRequest::Delegate interface. |
| virtual void OnCanaryFinished( |
| internal::PipelineTestRequest::Status status) OVERRIDE; |
| virtual void OnRequestFinished( |
| int request_id, |
| internal::PipelineTestRequest::Status status) OVERRIDE; |
| virtual void ReportNetworkError(int request_id, int error_code) OVERRIDE; |
| virtual void ReportResponseCode(int request_id, int response_code) OVERRIDE; |
| |
| scoped_ptr<net::HttpTransactionFactory> http_transaction_factory_; |
| scoped_ptr<net::URLRequestContext> url_request_context_; |
| scoped_ptr<internal::PipelineTestRequest::Factory> factory_; |
| ScopedVector<internal::PipelineTestRequest> requests_; |
| scoped_ptr<internal::PipelineTestRequest> canary_request_; |
| net::CompletionCallback finished_callback_; |
| size_t num_finished_; |
| size_t num_succeeded_; |
| }; |
| |
| void CollectPipeliningCapabilityStatsOnUIThread( |
| const std::string& pipeline_test_server, IOThread* io_thread); |
| |
| } // namespace chrome_browser_net |
| |
| #endif // CHROME_BROWSER_NET_HTTP_PIPELINING_COMPATIBILITY_CLIENT_H_ |