summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 21:38:17 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 21:38:17 +0000
commite26fe0799b573ab97b9285844f27edd9017854f7 (patch)
tree8be96183af5d11c9e5c1e00e214a89ae3984b3c4 /net
parentdb0fa4785754f21d3cf69b5f523d24cb0580fb9b (diff)
downloadchromium_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.h4
-rw-r--r--net/net.gyp3
-rw-r--r--net/url_request/url_request_context_builder.cc265
-rw-r--r--net/url_request/url_request_context_builder.h101
-rw-r--r--net/url_request/url_request_context_builder_unittest.cc72
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