diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-17 21:38:17 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-17 21:38:17 +0000 |
commit | e26fe0799b573ab97b9285844f27edd9017854f7 (patch) | |
tree | 8be96183af5d11c9e5c1e00e214a89ae3984b3c4 /net | |
parent | db0fa4785754f21d3cf69b5f523d24cb0580fb9b (diff) | |
download | chromium_src-e26fe0799b573ab97b9285844f27edd9017854f7.zip chromium_src-e26fe0799b573ab97b9285844f27edd9017854f7.tar.gz chromium_src-e26fe0799b573ab97b9285844f27edd9017854f7.tar.bz2 |
Create a URLRequestContextBuilder.
URLRequestContext has become quite complicated and difficult to instantiate
properly. Here I create a simplified URLRequestContext builder class to assist
in building it properly. I provide a few simple knobs and assume that people
generally just want the defaults.
BUG=122779
TEST=none
Review URL: http://codereview.chromium.org/9999023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132659 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/ftp/ftp_network_layer.h | 4 | ||||
-rw-r--r-- | net/net.gyp | 3 | ||||
-rw-r--r-- | net/url_request/url_request_context_builder.cc | 265 | ||||
-rw-r--r-- | net/url_request/url_request_context_builder.h | 101 | ||||
-rw-r--r-- | net/url_request/url_request_context_builder_unittest.cc | 72 |
5 files changed, 444 insertions, 1 deletions
diff --git a/net/ftp/ftp_network_layer.h b/net/ftp/ftp_network_layer.h index d4bfe46..0c48f13 100644 --- a/net/ftp/ftp_network_layer.h +++ b/net/ftp/ftp_network_layer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -6,6 +6,7 @@ #define NET_FTP_FTP_NETWORK_LAYER_H_ #pragma once +#include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "net/base/net_export.h" @@ -30,6 +31,7 @@ class NET_EXPORT FtpNetworkLayer : public FtpTransactionFactory { private: scoped_refptr<FtpNetworkSession> session_; bool suspended_; + DISALLOW_COPY_AND_ASSIGN(FtpNetworkLayer); }; } // namespace net diff --git a/net/net.gyp b/net/net.gyp index 8dacba7..cf23c45 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -713,6 +713,8 @@ 'url_request/url_request_about_job.h', 'url_request/url_request_context.cc', 'url_request/url_request_context.h', + 'url_request/url_request_context_builder.cc', + 'url_request/url_request_context_builder.h', 'url_request/url_request_context_getter.cc', 'url_request/url_request_context_getter.h', 'url_request/url_request_context_storage.cc', @@ -1234,6 +1236,7 @@ 'tools/dump_cache/url_utilities.cc', 'tools/dump_cache/url_utilities_unittest.cc', 'udp/udp_socket_unittest.cc', + 'url_request/url_request_context_builder_unittest.cc', 'url_request/url_request_job_factory_unittest.cc', 'url_request/url_request_job_unittest.cc', 'url_request/url_request_throttler_simulation_unittest.cc', diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc new file mode 100644 index 0000000..7a38431 --- /dev/null +++ b/net/url_request/url_request_context_builder.cc @@ -0,0 +1,265 @@ +// 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 "net/url_request/url_request_context_builder.h" + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/threading/thread.h" +#include "net/base/cert_verifier.h" +#include "net/base/host_resolver.h" +#include "net/base/net_errors.h" +#include "net/base/network_delegate.h" +#include "net/base/ssl_config_service_defaults.h" +#include "net/base/transport_security_state.h" +#include "net/cookies/cookie_monster.h" +#include "net/ftp/ftp_network_layer.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_cache.h" +#include "net/http/http_network_layer.h" +#include "net/http/http_network_session.h" +#include "net/http/http_server_properties_impl.h" +#include "net/proxy/proxy_service.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_storage.h" + +namespace net { + +namespace { + +class BasicNetworkDelegate : public NetworkDelegate { + public: + BasicNetworkDelegate() {} + virtual ~BasicNetworkDelegate() {} + + private: + virtual int OnBeforeURLRequest(URLRequest* request, + const CompletionCallback& callback, + GURL* new_url) OVERRIDE { + return OK; + } + + virtual int OnBeforeSendHeaders(URLRequest* request, + const CompletionCallback& callback, + HttpRequestHeaders* headers) OVERRIDE { + return OK; + } + + virtual void OnSendHeaders(URLRequest* request, + const HttpRequestHeaders& headers) OVERRIDE {} + + virtual int OnHeadersReceived( + URLRequest* request, + const CompletionCallback& callback, + HttpResponseHeaders* original_response_headers, + scoped_refptr<HttpResponseHeaders>* override_response_headers) + OVERRIDE { + return OK; + } + + virtual void OnBeforeRedirect(URLRequest* request, + const GURL& new_location) OVERRIDE {} + + virtual void OnResponseStarted(URLRequest* request) OVERRIDE {} + + virtual void OnRawBytesRead(const URLRequest& request, + int bytes_read) OVERRIDE {} + + virtual void OnCompleted(URLRequest* request, bool started) OVERRIDE {} + + virtual void OnURLRequestDestroyed(URLRequest* request) OVERRIDE {} + + virtual void OnPACScriptError(int line_number, + const string16& error) OVERRIDE {} + + virtual NetworkDelegate::AuthRequiredResponse OnAuthRequired( + URLRequest* request, + const AuthChallengeInfo& auth_info, + const AuthCallback& callback, + AuthCredentials* credentials) OVERRIDE { + return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; + } + + virtual bool CanGetCookies(const URLRequest* request, + const CookieList& cookie_list) OVERRIDE { + return true; + } + + virtual bool CanSetCookie(const URLRequest* request, + const std::string& cookie_line, + CookieOptions* options) OVERRIDE { + return true; + } + + DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate); +}; + +class BasicURLRequestContext : public URLRequestContext { + public: + BasicURLRequestContext() + : cache_thread_("Cache Thread"), + file_thread_("File Thread"), + ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {} + + URLRequestContextStorage* storage() { + return &storage_; + } + + void set_user_agent(const std::string& user_agent) { + user_agent_ = user_agent; + } + + void StartCacheThread() { + cache_thread_.StartWithOptions( + base::Thread::Options(MessageLoop::TYPE_IO, 0)); + } + + scoped_refptr<base::MessageLoopProxy> cache_message_loop_proxy() { + DCHECK(cache_thread_.IsRunning()); + return cache_thread_.message_loop_proxy(); + } + + void StartFileThread() { + file_thread_.StartWithOptions( + base::Thread::Options(MessageLoop::TYPE_DEFAULT, 0)); + } + + MessageLoop* file_message_loop() { + DCHECK(file_thread_.IsRunning()); + return file_thread_.message_loop(); + } + + virtual const std::string& GetUserAgent( + const GURL& /* url */) const OVERRIDE { + return user_agent_; + } + + protected: + virtual ~BasicURLRequestContext() {} + + private: + std::string user_agent_; + base::Thread cache_thread_; + base::Thread file_thread_; + URLRequestContextStorage storage_; + DISALLOW_COPY_AND_ASSIGN(BasicURLRequestContext); +}; + +} // namespace + +URLRequestContextBuilder::HostResolverParams::HostResolverParams() + : parallelism(HostResolver::kDefaultParallelism), + retry_attempts(HostResolver::kDefaultRetryAttempts) {} +URLRequestContextBuilder::HostResolverParams::~HostResolverParams() {} + +URLRequestContextBuilder::HttpCacheParams::HttpCacheParams() + : type(DISK), + max_size(0), + path(FILE_PATH_LITERAL("Cache")) {} +URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() {} + +URLRequestContextBuilder::URLRequestContextBuilder() + : ftp_enabled_(false), + http_cache_enabled_(true) {} +URLRequestContextBuilder::~URLRequestContextBuilder() {} + +scoped_refptr<URLRequestContext> URLRequestContextBuilder::Build() { + BasicURLRequestContext* context = new BasicURLRequestContext; + URLRequestContextStorage* storage = context->storage(); + + context->set_user_agent(user_agent_); + + BasicNetworkDelegate* network_delegate = new BasicNetworkDelegate; + storage->set_network_delegate(network_delegate); + + net::HostResolver* host_resolver = net::CreateSystemHostResolver( + host_resolver_params_.parallelism, + host_resolver_params_.retry_attempts, + NULL /* no NetLog */); + storage->set_host_resolver(host_resolver); + + if (ftp_enabled_) { + storage->set_ftp_transaction_factory(new FtpNetworkLayer(host_resolver)); + } + + context->StartFileThread(); + + storage->set_proxy_service( + ProxyService::CreateDirectWithNetLog(context->net_log())); + + // TODO(willchan): Switch to using this code when + // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck. +#if 0 + ProxyService::CreateUsingSystemProxyResolver( + ProxyService::CreateSystemProxyConfigService( + MessageLoop::current(), + context->file_message_loop()), + 4, // TODO(willchan): Find a better constant somewhere. + context->net_log())); +#endif + storage->set_ssl_config_service(new net::SSLConfigServiceDefaults); + storage->set_http_auth_handler_factory( + net::HttpAuthHandlerRegistryFactory::CreateDefault(host_resolver)); + storage->set_cookie_store(new CookieMonster(NULL, NULL)); + storage->set_transport_security_state(new net::TransportSecurityState("")); + storage->set_http_server_properties(new net::HttpServerPropertiesImpl); + storage->set_cert_verifier(CertVerifier::CreateDefault()); + + HttpTransactionFactory* http_transaction_factory = NULL; + if (http_cache_enabled_) { + HttpCache::BackendFactory* http_cache_backend = NULL; + if (http_cache_params_.type == HttpCacheParams::DISK) { + context->StartCacheThread(); + http_cache_backend = + new HttpCache::DefaultBackend(DISK_CACHE, + http_cache_params_.path, + http_cache_params_.max_size, + context->cache_message_loop_proxy()); + } else { + http_cache_backend = + HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size); + } + http_transaction_factory = new HttpCache( + context->host_resolver(), + context->cert_verifier(), + context->server_bound_cert_service(), + context->transport_security_state(), + context->proxy_service(), + "", + context->ssl_config_service(), + context->http_auth_handler_factory(), + context->network_delegate(), + context->http_server_properties(), + context->net_log(), + http_cache_backend); + } else { + HttpNetworkSession::Params session_params; + session_params.host_resolver = context->host_resolver(); + session_params.cert_verifier = context->cert_verifier(); + session_params.transport_security_state = + context->transport_security_state(); + session_params.proxy_service = context->proxy_service(); + session_params.ssl_config_service = context->ssl_config_service(); + session_params.http_auth_handler_factory = + context->http_auth_handler_factory(); + session_params.network_delegate = context->network_delegate(); + session_params.http_server_properties = + context->http_server_properties(); + session_params.net_log = context->net_log(); + scoped_refptr<net::HttpNetworkSession> network_session( + new net::HttpNetworkSession(session_params)); + + http_transaction_factory = new HttpNetworkLayer(network_session); + } + storage->set_http_transaction_factory(http_transaction_factory); + + // TODO(willchan): Support sdch. + + return context; +} + +} // namespace net diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h new file mode 100644 index 0000000..ba7541d --- /dev/null +++ b/net/url_request/url_request_context_builder.h @@ -0,0 +1,101 @@ +// 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. + +// This class is useful for building a simple URLRequestContext. Most creators +// of new URLRequestContexts should use this helper class to construct it. Call +// any configuration params, and when done, invoke Build() to construct the +// URLRequestContext. This URLRequestContext will own all its own storage. +// +// URLRequestContextBuilder and its associated params classes are initially +// populated with "sane" default values. Read through the comments to figure out +// what these are. + +#ifndef NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_H_ +#define NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_H_ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "base/file_path.h" +#include "base/memory/ref_counted.h" +#include "net/base/net_export.h" + +namespace net { + +class URLRequestContext; + +class NET_EXPORT URLRequestContextBuilder { + public: + struct NET_EXPORT HostResolverParams { + HostResolverParams(); + ~HostResolverParams(); + + // The limit on the number of parallel host resolutions. + size_t parallelism; + + // When the host resolution is taking too long, we'll retry this many times, + // in a backing off manner. + size_t retry_attempts; + }; + + struct NET_EXPORT HttpCacheParams { + enum Type { + IN_MEMORY, + DISK, + }; + + HttpCacheParams(); + ~HttpCacheParams(); + + // The type of HTTP cache. Default is DISK. + Type type; + + // The max size of the cache in bytes. Default is algorithmically determined + // based off available disk space. + int max_size; + + // The cache path (when type is DISK). + FilePath path; + }; + + URLRequestContextBuilder(); + ~URLRequestContextBuilder(); + + // Call this function to specify a hard-coded User-Agent for all requests that + // don't have a User-Agent already set. + void set_user_agent(const std::string& user_agent) { + user_agent_ = user_agent; + } + + // Allows for overriding the default HostResolver params. + void set_host_resolver_params( + const HostResolverParams& host_resolver_params) { + host_resolver_params_ = host_resolver_params; + } + + // By default it's disabled. + void set_ftp_enabled(bool enable) { + ftp_enabled_ = enable; + } + + // By default HttpCache is enabled with a default constructed HttpCacheParams. + void EnableHttpCache(const HttpCacheParams& params); + void DisableHttpCache(); + + scoped_refptr<URLRequestContext> Build(); + + private: + std::string user_agent_; + bool ftp_enabled_; + HostResolverParams host_resolver_params_; + bool http_cache_enabled_; + HttpCacheParams http_cache_params_; + + DISALLOW_COPY_AND_ASSIGN(URLRequestContextBuilder); +}; + +} // namespace net + +#endif // NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_H_ diff --git a/net/url_request/url_request_context_builder_unittest.cc b/net/url_request/url_request_context_builder_unittest.cc new file mode 100644 index 0000000..039b15d --- /dev/null +++ b/net/url_request/url_request_context_builder_unittest.cc @@ -0,0 +1,72 @@ +// 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 "net/url_request/url_request_context_builder.h" + +#include "net/test/test_server.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace net { + +namespace { + +// A subclass of TestServer that uses a statically-configured hostname. This is +// to work around mysterious failures in chrome_frame_net_tests. See: +// http://crbug.com/114369 +class LocalHttpTestServer : public TestServer { + public: + explicit LocalHttpTestServer(const FilePath& document_root) + : TestServer(TestServer::TYPE_HTTP, + ScopedCustomUrlRequestTestHttpHost::value(), + document_root) {} + LocalHttpTestServer() + : TestServer(TestServer::TYPE_HTTP, + ScopedCustomUrlRequestTestHttpHost::value(), + FilePath()) {} +}; + +class URLRequestContextBuilderTest : public PlatformTest { + protected: + URLRequestContextBuilderTest() + : test_server_( + FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))) {} + + LocalHttpTestServer test_server_; + URLRequestContextBuilder builder_; +}; + +TEST_F(URLRequestContextBuilderTest, DefaultSettings) { + ASSERT_TRUE(test_server_.Start()); + + scoped_refptr<URLRequestContext> context = builder_.Build(); + TestDelegate delegate; + URLRequest request(test_server_.GetURL("echoheader?Foo"), &delegate); + request.set_context(context); + request.set_method("GET"); + request.SetExtraRequestHeaderByName("Foo", "Bar", false); + request.Start(); + MessageLoop::current()->Run(); + EXPECT_EQ("Bar", delegate.data_received()); +} + +TEST_F(URLRequestContextBuilderTest, UserAgent) { + ASSERT_TRUE(test_server_.Start()); + + builder_.set_user_agent("Bar"); + scoped_refptr<URLRequestContext> context = builder_.Build(); + TestDelegate delegate; + URLRequest request(test_server_.GetURL("echoheader?User-Agent"), &delegate); + request.set_context(context); + request.set_method("GET"); + request.Start(); + MessageLoop::current()->Run(); + EXPECT_EQ("Bar", delegate.data_received()); +} + +} // namespace + +} // namespace net |