| // Copyright 2014 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 "components/cronet/url_request_context_config.h" |
| |
| #include "base/basictypes.h" |
| #include "base/json/json_reader.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_piece.h" |
| #include "base/values.h" |
| #include "net/cert/cert_verifier.h" |
| #include "net/quic/quic_protocol.h" |
| #include "net/quic/quic_utils.h" |
| #include "net/url_request/url_request_context_builder.h" |
| |
| namespace cronet { |
| |
| namespace { |
| |
| // TODO(xunjieli): Refactor constants in io_thread.cc. |
| const char kQuicFieldTrialName[] = "QUIC"; |
| const char kQuicConnectionOptions[] = "connection_options"; |
| |
| // Using a reference to scoped_ptr is unavoidable because of the semantics of |
| // RegisterCustomField. |
| // TODO(xunjieli): Remove this once crbug.com/544976 is fixed. |
| bool GetMockCertVerifierFromString( |
| const base::StringPiece& mock_cert_verifier_string, |
| scoped_ptr<net::CertVerifier>* result) { |
| int64 val; |
| bool success = base::StringToInt64(mock_cert_verifier_string, &val); |
| *result = make_scoped_ptr(reinterpret_cast<net::CertVerifier*>(val)); |
| return success; |
| } |
| |
| void ParseAndSetExperimentalOptions( |
| const std::string& experimental_options, |
| net::URLRequestContextBuilder* context_builder) { |
| if (experimental_options.empty()) |
| return; |
| |
| scoped_ptr<base::Value> options = |
| base::JSONReader::Read(experimental_options); |
| |
| if (!options) { |
| DCHECK(false) << "Parsing experimental options failed: " |
| << experimental_options; |
| return; |
| } |
| |
| scoped_ptr<base::DictionaryValue> dict = |
| base::DictionaryValue::From(options.Pass()); |
| |
| if (!dict) { |
| DCHECK(false) << "Experimental options string is not a dictionary: " |
| << experimental_options; |
| return; |
| } |
| |
| const base::DictionaryValue* quic_args = nullptr; |
| if (dict->GetDictionary(kQuicFieldTrialName, &quic_args)) { |
| std::string quic_connection_options; |
| if (quic_args->GetString(kQuicConnectionOptions, |
| &quic_connection_options)) { |
| context_builder->set_quic_connection_options( |
| net::QuicUtils::ParseQuicConnectionOptions(quic_connection_options)); |
| } |
| } |
| } |
| |
| } // namespace |
| |
| #define DEFINE_CONTEXT_CONFIG(x) const char REQUEST_CONTEXT_CONFIG_##x[] = #x; |
| #include "components/cronet/url_request_context_config_list.h" |
| #undef DEFINE_CONTEXT_CONFIG |
| |
| URLRequestContextConfig::QuicHint::QuicHint() { |
| } |
| |
| URLRequestContextConfig::QuicHint::~QuicHint() { |
| } |
| |
| // static |
| void URLRequestContextConfig::QuicHint::RegisterJSONConverter( |
| base::JSONValueConverter<URLRequestContextConfig::QuicHint>* converter) { |
| converter->RegisterStringField(REQUEST_CONTEXT_CONFIG_QUIC_HINT_HOST, |
| &URLRequestContextConfig::QuicHint::host); |
| converter->RegisterIntField( |
| REQUEST_CONTEXT_CONFIG_QUIC_HINT_PORT, |
| &URLRequestContextConfig::QuicHint::port); |
| converter->RegisterIntField( |
| REQUEST_CONTEXT_CONFIG_QUIC_HINT_ALT_PORT, |
| &URLRequestContextConfig::QuicHint::alternate_port); |
| } |
| |
| URLRequestContextConfig::URLRequestContextConfig() {} |
| |
| URLRequestContextConfig::~URLRequestContextConfig() {} |
| |
| bool URLRequestContextConfig::LoadFromJSON(const std::string& config_string) { |
| scoped_ptr<base::Value> config_value = base::JSONReader::Read(config_string); |
| if (!config_value || !config_value->IsType(base::Value::TYPE_DICTIONARY)) { |
| DLOG(ERROR) << "Bad JSON: " << config_string; |
| return false; |
| } |
| |
| base::JSONValueConverter<URLRequestContextConfig> converter; |
| if (!converter.Convert(*config_value, this)) { |
| DLOG(ERROR) << "Bad Config: " << config_value; |
| return false; |
| } |
| return true; |
| } |
| |
| void URLRequestContextConfig::ConfigureURLRequestContextBuilder( |
| net::URLRequestContextBuilder* context_builder) { |
| std::string config_cache; |
| if (http_cache != REQUEST_CONTEXT_CONFIG_HTTP_CACHE_DISABLED) { |
| net::URLRequestContextBuilder::HttpCacheParams cache_params; |
| if (http_cache == REQUEST_CONTEXT_CONFIG_HTTP_CACHE_DISK && |
| !storage_path.empty()) { |
| cache_params.type = net::URLRequestContextBuilder::HttpCacheParams::DISK; |
| cache_params.path = base::FilePath(storage_path); |
| } else { |
| cache_params.type = |
| net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY; |
| } |
| cache_params.max_size = http_cache_max_size; |
| context_builder->EnableHttpCache(cache_params); |
| } else { |
| context_builder->DisableHttpCache(); |
| } |
| context_builder->set_user_agent(user_agent); |
| context_builder->SetSpdyAndQuicEnabled(enable_spdy, enable_quic); |
| context_builder->set_sdch_enabled(enable_sdch); |
| |
| ParseAndSetExperimentalOptions(experimental_options, context_builder); |
| |
| if (mock_cert_verifier) |
| context_builder->SetCertVerifier(mock_cert_verifier.Pass()); |
| // TODO(mef): Use |config| to set cookies. |
| } |
| |
| // static |
| void URLRequestContextConfig::RegisterJSONConverter( |
| base::JSONValueConverter<URLRequestContextConfig>* converter) { |
| converter->RegisterStringField(REQUEST_CONTEXT_CONFIG_USER_AGENT, |
| &URLRequestContextConfig::user_agent); |
| converter->RegisterStringField(REQUEST_CONTEXT_CONFIG_STORAGE_PATH, |
| &URLRequestContextConfig::storage_path); |
| converter->RegisterBoolField(REQUEST_CONTEXT_CONFIG_ENABLE_QUIC, |
| &URLRequestContextConfig::enable_quic); |
| converter->RegisterBoolField(REQUEST_CONTEXT_CONFIG_ENABLE_SPDY, |
| &URLRequestContextConfig::enable_spdy); |
| converter->RegisterBoolField(REQUEST_CONTEXT_CONFIG_ENABLE_SDCH, |
| &URLRequestContextConfig::enable_sdch); |
| converter->RegisterStringField(REQUEST_CONTEXT_CONFIG_HTTP_CACHE, |
| &URLRequestContextConfig::http_cache); |
| converter->RegisterBoolField(REQUEST_CONTEXT_CONFIG_LOAD_DISABLE_CACHE, |
| &URLRequestContextConfig::load_disable_cache); |
| converter->RegisterIntField(REQUEST_CONTEXT_CONFIG_HTTP_CACHE_MAX_SIZE, |
| &URLRequestContextConfig::http_cache_max_size); |
| converter->RegisterRepeatedMessage(REQUEST_CONTEXT_CONFIG_QUIC_HINTS, |
| &URLRequestContextConfig::quic_hints); |
| converter->RegisterStringField( |
| REQUEST_CONTEXT_CONFIG_EXPERIMENTAL_OPTIONS, |
| &URLRequestContextConfig::experimental_options); |
| converter->RegisterStringField( |
| REQUEST_CONTEXT_CONFIG_DATA_REDUCTION_PRIMARY_PROXY, |
| &URLRequestContextConfig::data_reduction_primary_proxy); |
| converter->RegisterStringField( |
| REQUEST_CONTEXT_CONFIG_DATA_REDUCTION_FALLBACK_PROXY, |
| &URLRequestContextConfig::data_reduction_fallback_proxy); |
| converter->RegisterStringField( |
| REQUEST_CONTEXT_CONFIG_DATA_REDUCTION_SECURE_PROXY_CHECK_URL, |
| &URLRequestContextConfig::data_reduction_secure_proxy_check_url); |
| converter->RegisterStringField( |
| REQUEST_CONTEXT_CONFIG_DATA_REDUCTION_PROXY_KEY, |
| &URLRequestContextConfig::data_reduction_proxy_key); |
| |
| // For Testing. |
| converter->RegisterCustomField<scoped_ptr<net::CertVerifier>>( |
| REQUEST_CONTEXT_CONFIG_MOCK_CERT_VERIFIER, |
| &URLRequestContextConfig::mock_cert_verifier, |
| &GetMockCertVerifierFromString); |
| } |
| |
| } // namespace cronet |