From 5fbe95affc8eeed93c678b1d271f64dcc4dd919b Mon Sep 17 00:00:00 2001 From: Ebrahem Qassem Date: Sun, 20 Nov 2011 14:57:09 +0200 Subject: net: networking optimizations features: - early connection - memory cache - caching of redirection - request queue priority - closing unused sockets - SHUTR - fin aggregation - object prefetch - dns host name prioritization Change-Id: Ief90b8206ba48115eaeb12d554424d65f36427ac --- Android.mk | 20 +- chrome/browser/net/preconnect.cc | 36 +- chrome/browser/net/preconnect.h | 12 +- net/base/host_resolver.h | 16 + net/base/host_resolver_impl.cc | 49 ++- net/base/host_resolver_impl.h | 9 +- net/base/net_error_list.h | 4 + net/base/request_priority.cc | 67 ++++ net/base/request_priority.h | 6 + net/disk_cache/hostres_plugin_bridge.cc | 76 ++++ net/disk_cache/hostres_plugin_bridge.h | 40 ++ net/disk_cache/stat_hub.cc | 480 +++++++++++++++++++++++ net/disk_cache/stat_hub.h | 268 +++++++++++++ net/disk_cache/stat_hub_api.cc | 377 ++++++++++++++++++ net/disk_cache/stat_hub_api.h | 118 ++++++ net/disk_cache/stat_hub_cmd_api.h | 74 ++++ net/host_resolver_helper/dyn_lib_loader.cc | 76 ++++ net/host_resolver_helper/dyn_lib_loader.h | 103 +++++ net/host_resolver_helper/dyn_lib_loader_decl.h | 51 +++ net/host_resolver_helper/host_resolver_helper.cc | 157 ++++++++ net/host_resolver_helper/host_resolver_helper.h | 105 +++++ net/host_resolver_helper/hosts_provider.h | 44 +++ net/http/http_basic_stream.cc | 3 +- net/http/http_cache.cc | 36 +- net/http/http_cache.h | 10 +- net/http/http_cache_transaction.cc | 11 +- net/http/http_getzip_bridge.cc | 142 +++++++ net/http/http_getzip_bridge.h | 66 ++++ net/http/http_getzip_factory.cc | 127 ++++++ net/http/http_getzip_factory.h | 137 +++++++ net/http/http_network_layer.cc | 3 + net/http/http_network_session.cc | 4 +- net/http/http_network_transaction.cc | 114 +++++- net/http/http_network_transaction.h | 26 +- net/http/http_proxy_client_socket_pool.cc | 7 +- net/http/http_proxy_client_socket_pool.h | 5 +- net/http/http_request_headers.cc | 2 + net/http/http_request_headers.h | 2 + net/http/http_stream_parser.cc | 39 +- net/http/http_stream_parser.h | 9 +- net/http/net-plugin-bridge-exports.h | 44 +++ net/http/net-plugin-bridge.cc | 95 +++++ net/http/net-plugin-bridge.h | 37 ++ net/http/preconnect.cc | 70 ++++ net/http/preconnect.h | 66 ++++ net/http/tcp-connections-bridge-exports.h | 39 ++ net/http/tcp-connections-bridge.cc | 79 ++++ net/http/tcp-connections-bridge.h | 41 ++ net/socket/client_socket_pool_base.cc | 119 +++++- net/socket/client_socket_pool_base.h | 105 +++-- net/socket/client_socket_pool_manager.cc | 31 +- net/socket/client_socket_pool_manager.h | 6 +- net/socket/socks_client_socket_pool.cc | 7 +- net/socket/socks_client_socket_pool.h | 4 +- net/socket/ssl_client_socket_pool.cc | 7 +- net/socket/ssl_client_socket_pool.h | 4 +- net/socket/tcp_client_socket_libevent.cc | 4 + net/socket/tcp_client_socket_pool.cc | 7 +- net/socket/tcp_client_socket_pool.h | 4 +- net/socket/tcp_fin_aggregation.h | 52 +++ net/socket/tcp_fin_aggregation_bridge.h | 46 +++ net/socket/tcp_fin_aggregation_factory.cc | 88 +++++ net/socket/tcp_fin_aggregation_factory.h | 71 ++++ net/socket/transport_client_socket_pool.cc | 7 +- net/socket/transport_client_socket_pool.h | 4 +- net/url_request/url_request_http_job.cc | 12 + 66 files changed, 3818 insertions(+), 162 deletions(-) create mode 100644 net/base/request_priority.cc create mode 100644 net/disk_cache/hostres_plugin_bridge.cc create mode 100644 net/disk_cache/hostres_plugin_bridge.h create mode 100755 net/disk_cache/stat_hub.cc create mode 100755 net/disk_cache/stat_hub.h create mode 100755 net/disk_cache/stat_hub_api.cc create mode 100755 net/disk_cache/stat_hub_api.h create mode 100644 net/disk_cache/stat_hub_cmd_api.h create mode 100644 net/host_resolver_helper/dyn_lib_loader.cc create mode 100644 net/host_resolver_helper/dyn_lib_loader.h create mode 100644 net/host_resolver_helper/dyn_lib_loader_decl.h create mode 100644 net/host_resolver_helper/host_resolver_helper.cc create mode 100644 net/host_resolver_helper/host_resolver_helper.h create mode 100644 net/host_resolver_helper/hosts_provider.h create mode 100644 net/http/http_getzip_bridge.cc create mode 100644 net/http/http_getzip_bridge.h create mode 100644 net/http/http_getzip_factory.cc create mode 100644 net/http/http_getzip_factory.h create mode 100644 net/http/net-plugin-bridge-exports.h create mode 100644 net/http/net-plugin-bridge.cc create mode 100644 net/http/net-plugin-bridge.h create mode 100644 net/http/preconnect.cc create mode 100644 net/http/preconnect.h create mode 100644 net/http/tcp-connections-bridge-exports.h create mode 100644 net/http/tcp-connections-bridge.cc create mode 100644 net/http/tcp-connections-bridge.h create mode 100644 net/socket/tcp_fin_aggregation.h create mode 100644 net/socket/tcp_fin_aggregation_bridge.h create mode 100644 net/socket/tcp_fin_aggregation_factory.cc create mode 100644 net/socket/tcp_fin_aggregation_factory.h diff --git a/Android.mk b/Android.mk index 7d1034e..42e3ec7 100644 --- a/Android.mk +++ b/Android.mk @@ -209,6 +209,10 @@ LOCAL_SRC_FILES += \ net/base/x509_certificate_openssl.cc \ net/base/x509_certificate_openssl_android.cc \ net/base/x509_openssl_util.cc \ + net/base/request_priority.cc \ + \ + net/host_resolver_helper/dyn_lib_loader.cc \ + net/host_resolver_helper/host_resolver_helper.cc \ \ net/disk_cache/addr.cc \ net/disk_cache/backend_impl.cc \ @@ -278,6 +282,10 @@ LOCAL_SRC_FILES += \ net/http/http_vary_data.cc \ net/http/md4.cc \ net/http/partial_data.cc \ + net/http/preconnect.cc \ + net/http/tcp-connections-bridge.cc \ + net/http/http_getzip_factory.cc \ + net/http/http_getzip_bridge.cc \ \ net/proxy/init_proxy_resolver.cc \ net/proxy/multi_threaded_proxy_resolver.cc \ @@ -311,6 +319,7 @@ LOCAL_SRC_FILES += \ net/socket/tcp_client_socket.cc \ net/socket/tcp_client_socket_libevent.cc \ net/socket/transport_client_socket_pool.cc \ + net/socket/tcp_fin_aggregation_factory.cc \ \ net/spdy/spdy_framer.cc \ net/spdy/spdy_frame_builder.cc \ @@ -407,6 +416,15 @@ LOCAL_SRC_FILES += \ webkit/glue/form_data.cc \ webkit/glue/form_field.cc +LOCAL_SRC_FILES += net/http/net-plugin-bridge.cc + +LOCAL_SRC_FILES += net/disk_cache/stat_hub.cc \ + net/disk_cache/stat_hub_api.cc \ + +LOCAL_SRC_FILES += \ + net/disk_cache/hostres_plugin_bridge.cc + + LOCAL_C_INCLUDES := \ $(LOCAL_PATH) \ $(LOCAL_PATH)/chrome \ @@ -468,7 +486,7 @@ $(GEN): LOCAL_GENERATED_SOURCES += $(GEN) LOCAL_CFLAGS := -DHAVE_CONFIG_H -DANDROID -DEXPAT_RELATIVE_PATH -DALLOW_QUOTED_COOKIE_VALUES -DCOMPONENT_BUILD -DGURL_DLL -LOCAL_CPPFLAGS := -Wno-sign-promo -Wno-missing-field-initializers -fvisibility=hidden -fvisibility-inlines-hidden +LOCAL_CPPFLAGS := -Wno-sign-promo -Wno-missing-field-initializers -fvisibility-inlines-hidden # Just a few definitions not provided by bionic. LOCAL_CFLAGS += -include "android/prefix.h" diff --git a/chrome/browser/net/preconnect.cc b/chrome/browser/net/preconnect.cc index b5fd87b..e6c1fd4 100644 --- a/chrome/browser/net/preconnect.cc +++ b/chrome/browser/net/preconnect.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -32,12 +33,11 @@ void PreconnectOnUIThread( return; } - void PreconnectOnIOThread( const GURL& url, UrlInfo::ResolutionMotivation motivation, int count) { - net::URLRequestContextGetter* getter = Profile::GetDefaultRequestContext(); + URLRequestContextGetter* getter = Profile::GetDefaultRequestContext(); if (!getter) return; if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { @@ -53,26 +53,9 @@ void PreconnectOnIOThread( net::HttpTransactionFactory* factory = context->http_transaction_factory(); net::HttpNetworkSession* session = factory->GetSession(); - net::HttpRequestInfo request_info; - request_info.url = url; - request_info.method = "GET"; - request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kUserAgent, - context->GetUserAgent(url)); - // It almost doesn't matter whether we use net::LOWEST or net::HIGHEST - // priority here, as we won't make a request, and will surrender the created - // socket to the pool as soon as we can. However, we would like to mark the - // speculative socket as such, and IF we use a net::LOWEST priority, and if - // a navigation asked for a socket (after us) then it would get our socket, - // and we'd get its later-arriving socket, which might make us record that - // the speculation didn't help :-/. By using net::HIGHEST, we ensure that - // a socket is given to us if "we asked first" and this allows us to mark it - // as speculative, and better detect stats (if it gets used). - // TODO(jar): histogram to see how often we accidentally use a previously- - // unused socket, when a previously used socket was available. - request_info.priority = net::HIGHEST; - // Translate the motivation from UrlRequest motivations to HttpRequest // motivations. + net::HttpRequestInfo::RequestMotivation motivation_; switch (motivation) { case UrlInfo::OMNIBOX_MOTIVATED: request_info.motivation = net::HttpRequestInfo::OMNIBOX_MOTIVATED; @@ -90,18 +73,7 @@ void PreconnectOnIOThread( break; } - // Setup the SSL Configuration. - net::SSLConfig ssl_config; - session->ssl_config_service()->GetSSLConfig(&ssl_config); - if (session->http_stream_factory()->next_protos()) - ssl_config.next_protos = *session->http_stream_factory()->next_protos(); - - // All preconnects should perform EV certificate verification. - ssl_config.verify_ev_cert = true; - - net::HttpStreamFactory* http_stream_factory = session->http_stream_factory(); - http_stream_factory->PreconnectStreams( - count, request_info, ssl_config, net::BoundNetLog()); + net::Preconnect::DoPreconnect(session, url, count, motivation_); } } // namespace chrome_browser_net diff --git a/chrome/browser/net/preconnect.h b/chrome/browser/net/preconnect.h index 056d5d6..0d7ed21 100644 --- a/chrome/browser/net/preconnect.h +++ b/chrome/browser/net/preconnect.h @@ -1,23 +1,18 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// A Preconnect instance maintains state while a TCP/IP connection is made, and -// and then released into the pool of available connections for future use. - #ifndef CHROME_BROWSER_NET_PRECONNECT_H_ #define CHROME_BROWSER_NET_PRECONNECT_H_ #pragma once -#include "chrome/browser/net/url_info.h" +#include "net/http/preconnect.h" -class GURL; +#include "chrome/browser/net/url_info.h" namespace chrome_browser_net { -// Try to preconnect. Typically motivated by OMNIBOX to reach search service. -// |count| may be used to request more than one connection be established in -// parallel. void PreconnectOnUIThread(const GURL& url, UrlInfo::ResolutionMotivation motivation, int count); @@ -28,7 +23,6 @@ void PreconnectOnUIThread(const GURL& url, void PreconnectOnIOThread(const GURL& url, UrlInfo::ResolutionMotivation motivation, int count); - } // namespace chrome_browser_net #endif // CHROME_BROWSER_NET_PRECONNECT_H_ diff --git a/net/base/host_resolver.h b/net/base/host_resolver.h index 8f53b6b..004e49f 100644 --- a/net/base/host_resolver.h +++ b/net/base/host_resolver.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -16,6 +17,8 @@ #include "net/base/net_export.h" #include "net/base/request_priority.h" +class MessageLoop; + namespace net { class AddressList; @@ -124,6 +127,13 @@ class NET_EXPORT HostResolver { virtual void OnCancelResolution(int id, const RequestInfo& info) = 0; }; + class HostnameResolverExt { + public: + virtual ~HostnameResolverExt() {} + virtual void Resolve()=0; + }; + + virtual void SetResolverExt(HostnameResolverExt* preresolver) {}; // Opaque type used to cancel a request. typedef void* RequestHandle; @@ -245,6 +255,12 @@ NET_EXPORT HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves HostResolverProc* resolver_proc, NetLog* net_log); +// If specified |net_notification_messageloop| provides a message loop +// to be used for network notifications. +HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, + HostResolverProc* resolver_proc, + NetLog* net_log, + MessageLoop* net_notification_messageloop); } // namespace net #endif // NET_BASE_HOST_RESOLVER_H_ diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc index 1f33369..7fd04fc 100644 --- a/net/base/host_resolver_impl.cc +++ b/net/base/host_resolver_impl.cc @@ -1,4 +1,5 @@ // Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -35,7 +36,6 @@ #include "net/base/net_errors.h" #include "net/base/net_log.h" #include "net/base/net_util.h" - #if defined(OS_WIN) #include "net/base/winsock_init.h" #endif @@ -74,6 +74,17 @@ HostCache* CreateDefaultCache() { HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, HostResolverProc* resolver_proc, NetLog* net_log) { +return CreateSystemHostResolver(max_concurrent_resolves, + resolver_proc, + net_log, + NULL); +} + +HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, + HostResolverProc* resolver_proc, + NetLog* net_log, + MessageLoop* net_notification_messageloop + ) { // Maximum of 8 concurrent resolver threads. // Some routers (or resolvers) appear to start to provide host-not-found if // too many simultaneous resolutions are pending. This number needs to be @@ -85,7 +96,7 @@ HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, HostResolverImpl* resolver = new HostResolverImpl(resolver_proc, CreateDefaultCache(), - max_concurrent_resolves, net_log); + max_concurrent_resolves, net_log,net_notification_messageloop); return resolver; } @@ -904,7 +915,9 @@ HostResolverImpl::HostResolverImpl( HostResolverProc* resolver_proc, HostCache* cache, size_t max_jobs, - NetLog* net_log) + NetLog* net_log, + MessageLoop* net_notification_messageloop + ) : cache_(cache), max_jobs_(max_jobs), next_request_id_(0), @@ -914,7 +927,10 @@ HostResolverImpl::HostResolverImpl( shutdown_(false), ipv6_probe_monitoring_(false), additional_resolver_flags_(0), - net_log_(net_log) { + net_log_(net_log), + net_notification_messageloop_(net_notification_messageloop), + resolverext_(NULL) +{ DCHECK_GT(max_jobs, 0u); // It is cumbersome to expose all of the constraints in the constructor, @@ -928,7 +944,17 @@ HostResolverImpl::HostResolverImpl( if (HaveOnlyLoopbackAddresses()) additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; #endif - NetworkChangeNotifier::AddIPAddressObserver(this); + + //register to network notifications via the current thread message loop (if exsits) + //or use the message loop provided in the constructor parameter + if (NULL==net_notification_messageloop_) { + net_notification_messageloop_ = MessageLoop::current(); + } + //add this class as observer for NetworkChangeNotifier + if (net_notification_messageloop_) { + net_notification_messageloop_->PostTask(FROM_HERE, + NewRunnableFunction( &NetworkChangeNotifier::AddIPAddressObserver,this)); + } } HostResolverImpl::~HostResolverImpl() { @@ -942,7 +968,10 @@ HostResolverImpl::~HostResolverImpl() { if (cur_completing_job_) cur_completing_job_->Cancel(); - NetworkChangeNotifier::RemoveIPAddressObserver(this); + if (net_notification_messageloop_) { + net_notification_messageloop_->PostTask(FROM_HERE, + NewRunnableFunction( &NetworkChangeNotifier::RemoveIPAddressObserver,this)); + } // Delete the job pools. for (size_t i = 0u; i < arraysize(job_pools_); ++i) @@ -1471,6 +1500,14 @@ void HostResolverImpl::OnIPAddressChanged() { #endif AbortAllInProgressJobs(); // |this| may be deleted inside AbortAllInProgressJobs(). + + if (resolverext_) { + resolverext_->Resolve(); + } } +void HostResolverImpl::SetResolverExt(HostnameResolverExt* resolverext) { + LOG(INFO)<<"HostResolverImpl::SetPreresolver preresolver:"<OpenPlugin(fh); + if (dll_ok) { + LOG(INFO) << "StatHubCreateHostResPlugin plugin connected";; + return hp; + } + } + else { + LOG(INFO) << "netstack: Failed to open plugin:" << hostres_plugin_name; + } + delete hp; + } + + LOG(INFO) << "netstack: Failed to find symbols in plugin: " << hostres_plugin_name; + return NULL; +} + diff --git a/net/disk_cache/hostres_plugin_bridge.h b/net/disk_cache/hostres_plugin_bridge.h new file mode 100644 index 0000000..a45da56 --- /dev/null +++ b/net/disk_cache/hostres_plugin_bridge.h @@ -0,0 +1,40 @@ +/** --------------------------------------------------------------------------- + Copyright (c) 2011, Code Aurora Forum. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -----------------------------------------------------------------------------**/ + +#ifndef HOSTRES_PLUGIN_BRIDGE_H_ +#define HOSTRES_PLUGIN_BRIDGE_H_ + + +namespace stat_hub { + class StatProcessor; +} + +extern stat_hub::StatProcessor* StatHubCreateHostResPlugin(); + +#endif /* HOSTRES_PLUGIN_BRIDGE_H_ */ diff --git a/net/disk_cache/stat_hub.cc b/net/disk_cache/stat_hub.cc new file mode 100755 index 0000000..1169528 --- /dev/null +++ b/net/disk_cache/stat_hub.cc @@ -0,0 +1,480 @@ +/** --------------------------------------------------------------------------- +Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------------**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "app/sql/statement.h" +#include "app/sql/transaction.h" +#include "base/command_line.h" +#include "base/file_util.h" +#include "base/time.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "base/task.h" +#include "base/threading/thread.h" +#include "net/disk_cache/hash.h" + +#include "stat_hub.h" + +namespace stat_hub { + +#define FLUSH_DB_TIMEOUT_THRESHOLD_DEF 30000 + +typedef enum { + INPUT_STATE_READ_MARKER, + INPUT_STATE_READ_CMD, + INPUT_STATE_READ_STRING_LEN, + INPUT_STATE_READ_STRING_DATA, + INPUT_STATE_READ_INT32, +} InputState; + +const char* kPropNameEnabled = "stathub.enabled"; +const char* kPropNameDbpath = "stathub.dbpath"; +const char* kPropNameVerbose = "stathub.verbose"; +const char* kPropNameFlushDelay = "stathub.flushdelay"; +const char* kPropNameEnabledAppName = "stathub.appname"; +const char* kPropNamePlugin = "stathub.plugin"; + +const char* kEnabledAppName = "com.android.browser"; + +void DoFlushDB(StatHub* database) { + database->FlushDBrequest(); +} + +// Version number of the database. +static const int kCurrentVersionNumber = 1; +static const int kCompatibleVersionNumber = 1; + +StatHub* StatHub::GetInstance() { + static StatHub hub; + return &hub; +} + +StatHub::StatHub() : + db_(NULL), + ready_(false), + flush_db_required_(false), + flush_db_scheduled_(false), + first_processor_(NULL), + thread_(NULL), + flush_delay_(FLUSH_DB_TIMEOUT_THRESHOLD_DEF), + verbose_level_(STAT_HUB_VERBOSE_LEVEL_DISABLED) { + + cmd_mask_ |= (1<OpenPlugin()) { + RegisterProcessor(plugin); + LOG(INFO) << "netstack: succeeded to load StatHub plugin: " << name; + return true; + } + + LOG(INFO) << "netstack: failed to load StatHub plugin: " << name; + return false; +} + +void StatHub::RegisterProcessor(StatProcessor* processor) { + if (NULL!=processor) { + processor->next_ = first_processor_; + first_processor_ = processor; + } +} + +StatProcessor* StatHub::DeleteProcessor(StatProcessor* processor) { + if (NULL!=processor) { + StatProcessor* next = processor->next_; + if (first_processor_==processor) { + first_processor_ = next; + } + else { + for (StatProcessor* tmp_processor=first_processor_; tmp_processor!=NULL; tmp_processor=tmp_processor->next_ ) { + if (tmp_processor->next_==processor) { + tmp_processor->next_=next; + break; + } + } + } + delete processor; + return next; + } + return NULL; +} + +bool StatHub::IsProcReady(const char* name) { + if (IsReady()) { + std::string proc_name; + + for (StatProcessor* processor=first_processor_; processor!=NULL; processor=processor->next_) { + if (processor->OnGetProcName(proc_name)) { + //if (proc_name==name) { + size_t found = proc_name.find(name); + if (found != std::string::npos) { + if (IsVerboseEnabled()) { + LOG(INFO) << "StatHub::IsProcReady:(true) for:" << name; + } + return true; + } + } + } + } + if (IsVerboseEnabled()) { + LOG(INFO) << "StatHub::(false) for:" << name; + } + return false; +} + +bool StatHub::Init(const std::string& db_path, MessageLoop* message_loop, net::HttpCache* http_cache) { + char value[PROPERTY_VALUE_MAX] = {'\0'}; + + if (ready_) { + LOG(INFO) << "StatHub::Init - Already initializes"; + return false; + } + + if (db_path.empty() || NULL==message_loop) { + LOG(ERROR) << "StatHub::Init - Bad parameters"; + return false; + } + + property_get(kPropNameEnabled, value, "1"); //!!!!!!!!! ENABLED by default !!!!!!!!! + if (!atoi(value)) { + LOG(INFO) << "StatHub::Init - Disabled"; + return false; + } + + property_get(kPropNameVerbose, value, "0"); //STAT_HUB_VERBOSE_LEVEL_DISABLED - 0 + verbose_level_ = (StatHubVerboseLevel)atoi(value); + if (IsVerboseEnabled()) { + LOG(INFO) << "StatHub::Init - Verbose Level: " << verbose_level_; + } + + //Check application restriction + property_get(kPropNameEnabledAppName, value, kEnabledAppName); + enabled_app_name_ = value; + + char path[128] = {'\0'}; + pid_t pid = getpid(); + snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); + int fd = open(path, O_RDONLY); + int rd_len = read(fd, path , sizeof(path)-1); + if (0 > rd_len) { + rd_len = 0; + } + path[rd_len] = 0; + close(fd); + + if(IsVerboseEnabled()) { + LOG(INFO) << "CacheDatabase::Init - Prc Name: " << path << "(" << (int)pid << ")"; + } + if (strcmp(path, enabled_app_name_.c_str())) { + LOG(ERROR) << "StatHub::Init - App " << path << " isn't supported."; + return false; + } + + base::Time start(StatHubGetSystemTime()); + + property_get(kPropNameFlushDelay, value, PROP_VAL_TO_STR(FLUSH_DB_TIMEOUT_THRESHOLD_DEF)); + flush_delay_ = atoi(value); + if (flush_delay_<=0) { + flush_delay_ = FLUSH_DB_TIMEOUT_THRESHOLD_DEF; + } + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::Init - Flush delay: " << flush_delay_; + } + + std::string db_path_def = db_path + "/db.sql"; + property_get(kPropNameDbpath, value, db_path_def.c_str()); + db_path_ = value; + + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::Init - DB path: " << db_path.c_str(); + LOG(INFO) << "StatHub::Init - Finale DB path: " << db_path_.c_str(); + } + + message_loop_ = message_loop; + http_cache_ = http_cache; + + #if defined(NOT_NOW) + db_->set_page_size(2048); + db_->set_cache_size(32); + //Run the database in exclusive mode. Nobody else should be accessing the + //database while we're running, and this will give somewhat improved perf. + db_->set_exclusive_locking(); + #endif //defined(NOT_NOW) + db_ = new sql::Connection(); + if (!db_->Open(FilePath(db_path_.c_str()))) { + LOG(ERROR) << "StatHub::Init - Unable to open DB " << db_path_.c_str(); + Release(); + return false; + } + + // Scope initialization in a transaction so we can't be partially initialized. + if (!StatHubBeginTransaction(db_)) { + LOG(ERROR) << "StatHub::Init - Unable to start transaction"; + Release(); + return false; + } + + // Create tables. + if (!InitTables()) { + LOG(ERROR) << "StatHub::Init - Unable to initialize DB tables"; + Release(); + return false; + } + + //load mandatory plugins + LoadPlugin("pp_proc_plugin.so"); + LoadPlugin("pageload_proc_plugin.so"); + +#ifdef STAT_HUB_DYNAMIC_BIND_ON + //load arbitrary plugins + for(int index=1; ; index++) { + std::ostringstream index_str; + index_str << "." << index; + std::string plugin_prop_name = kPropNamePlugin + index_str.str(); + property_get(plugin_prop_name.c_str(), value, ""); + if (!value[0]) { + break; + } + LoadPlugin(value); + } +#endif // STAT_HUB_DYNAMIC_BIND_ON + + std::string proc_name; + for (StatProcessor* processor=first_processor_; processor!=NULL;) { + if (!processor->OnGetProcName(proc_name)) { + proc_name = "Undefined"; + } + if(!processor->OnInit(db_, message_loop_)) { + LOG(INFO) << "StatHub::Init - processor " << proc_name.c_str() << " initialization failed!"; + processor = DeleteProcessor(processor); + } else { + LOG(INFO) << "StatHub::Init - processor " << proc_name.c_str() << " is ready."; + unsigned int cmd_mask; + if (processor->OnGetCmdMask(cmd_mask)) { + cmd_mask_ |= cmd_mask; + } + processor=processor->next_ ; + } + } + + // Initialization is complete. + if (!StatHubCommitTransaction(db_)) { + LOG(ERROR) << "StatHub::Init - Unable to commist transaction"; + Release(); + return false; + } + + for (StatProcessor* processor=first_processor_; processor!=NULL; processor=processor->next_ ) { + processor->OnFetchDb(db_); + } + + thread_ = new base::Thread("event_handler"); + if (!thread_->StartWithOptions(base::Thread::Options(MessageLoop::TYPE_IO, 0))) { + LOG(ERROR) << "StatHub::Init event thread start error"; + Release(); + return false; + } + + ready_ = true; + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::Init: Init DB Time: " << StatHubGetTimeDeltaInMs(start, StatHubGetSystemTime()); + } + + LOG(INFO) << "netstack: StatHub was initialized"; + return true; +} + +void StatHub::Release() { + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::Release"; + } + + //thread + if(NULL!=thread_) { + delete thread_; + thread_ = NULL; + } + + //processors + StatProcessor* next_processor; + for (StatProcessor* processor=first_processor_; processor!=NULL; processor=next_processor ) { + next_processor = processor->next_; + delete processor; + } + first_processor_ = NULL; + + //DataBase + if (NULL!=db_) { + db_->Close(); + delete db_; + db_ = NULL; + } + + //Rest + flush_db_required_ = false; + flush_db_scheduled_ = false; + ready_ = false; +} + +bool StatHub::InitTables() { + if (!StatHubDoesTableExist(db_, "meta")) { + if (!StatHubExecute(db_, "CREATE TABLE meta (" + "key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," + "value LONGVARCHAR" + ")")) { + return false; + } + } + return true; +} + +bool StatHub::GetDBmetaData(const char* key, std::string& val) { + bool ret = false; + + sql::Statement* statement = StatHubGetStatement(db_, SQL_FROM_HERE, + "SELECT * FROM meta WHERE key=?"); + StatHubStatementBindCString(statement, 0 , key); + if(StatHubStatementStep(statement)) { + ret = true; + val = StatHubStatementColumnString(statement, 1); + } + StatHubReleaseStatement(statement); + return ret; +} + +bool StatHub::SetDBmetaData(const char* key, const char* val) { + bool ret = true; + + sql::Statement* statement = StatHubGetStatement(db_, SQL_FROM_HERE, + "INSERT OR REPLACE INTO meta " + "(key, value) " + "VALUES (?,?)"); + StatHubStatementBindCString(statement, 0 , key); + StatHubStatementBindCString(statement, 1 , val); + ret = StatHubStatementRun(statement); + StatHubReleaseStatement(statement); + return ret; +} + +void StatHub::MainUrlLoaded(const char* url) { + flush_db_request_time_ = StatHubGetSystemTime(); + flush_db_required_ = true; + if (!flush_db_scheduled_) { + flush_db_scheduled_ = true; + if(IsVerboseEnabled()) { + LOG(INFO) << "CacheDatabase::MainUrlLoaded : Request DB flush (" << flush_delay_ << ")"; + } + message_loop_->PostDelayedTask(FROM_HERE, NewRunnableFunction(&DoFlushDB, this), flush_delay_); + } +} + +void StatHub::Cmd(StatHubTimeStamp timestamp, unsigned short cmd, void* param1, int sizeofparam1, void* param2, int sizeofparam2) { + switch (cmd) { + case INPUT_CMD_WK_MMC_CLEAR: + for (StatProcessor* processor=first_processor_; processor!=NULL; processor=processor->next_ ) { + processor->OnClearDb(db_); + } + break; + default: + for (StatProcessor* processor=first_processor_; processor!=NULL; processor=processor->next_ ) { + processor->OnCmd(timestamp, cmd, param1, sizeofparam1, param2, sizeofparam2); + } + break; + } + if (INPUT_CMD_WK_MAIN_URL_LOADED==cmd) { + MainUrlLoaded((const char*)param1); + } +} + +void StatHub::FlushDBrequest() { + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::FlushDBrequest : Start"; + } + + int delta = StatHubGetTimeDeltaInMs(flush_db_request_time_, StatHubGetSystemTime()); + flush_db_scheduled_ = false; + if (flush_db_required_) { + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::FlushDBrequest : Flush - " << delta; + } + + if (delta>=flush_delay_) { + FlushDB(); + } + else { + if (!flush_db_scheduled_) { + flush_db_scheduled_ = true; + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::FlushDBrequest : Restart - " << flush_delay_ - delta; + } + thread_->message_loop()->PostDelayedTask(FROM_HERE, NewRunnableFunction(&DoFlushDB, this), flush_delay_ - delta); + } + } + } +} + +bool StatHub::FlushDB() { + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::FlushDB: Begin"; + } + base::Time start(StatHubGetSystemTime()); + + for (StatProcessor* processor=first_processor_; processor!=NULL; processor=processor->next_ ) { + processor->OnFlushDb(db_); + } + + if(IsVerboseEnabled()) { + LOG(INFO) << "StatHub::FlushDB time :" << StatHubGetTimeDeltaInMs(start, StatHubGetSystemTime()); + } + return true; +} + +} // namespace stat_hub + diff --git a/net/disk_cache/stat_hub.h b/net/disk_cache/stat_hub.h new file mode 100755 index 0000000..8006544 --- /dev/null +++ b/net/disk_cache/stat_hub.h @@ -0,0 +1,268 @@ +/** --------------------------------------------------------------------------- +Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------------**/ + +#ifndef NET_STAT_HUB_H_ +#define NET_STAT_HUB_H_ +#pragma once + +#include "googleurl/src/gurl.h" +#include "app/sql/connection.h" +#include "app/sql/init_status.h" +#include + +#include "stat_hub_api.h" + +class MessageLoop; + +namespace base { + class Time; + class Thread; +} + +namespace stat_hub { + +extern const char* kEnabledAppName; + +typedef void(* event_cb)(int fd, short event, void* arg); + +class StatProcessor { +public: + StatProcessor(): next_(NULL){ + } + +virtual ~StatProcessor() { + } + + //Events +virtual bool OnInit(sql::Connection* db, MessageLoop* message_loop)=0; +virtual bool OnFetchDb(sql::Connection* db)=0; +virtual bool OnFlushDb(sql::Connection* db)=0; +virtual bool OnClearDb(sql::Connection* db)=0; +virtual bool OnCmd(StatHubTimeStamp timestamp, unsigned short cmd, void* param1, int sizeofparam1, void* param2, int sizeofparam2) {return false;} +virtual bool OnGetProcName(std::string& name)=0; +virtual bool OnGetCmdMask(unsigned int& cmd_mask)=0; + +private: + friend class StatHub; + + StatProcessor* next_; +}; + +#define STAT_PLUGIN_METHOD_0(name, ret) \ + ret (*Do##name)(); \ + virtual ret name() { if(NULL!=Do##name) return Do##name(); return (ret)0;} + +#define STAT_PLUGIN_METHOD_1(name, ret, type1, param1) \ + ret (*Do##name)(type1 param1); \ + virtual ret name(type1 param1) { if(NULL!=Do##name) return Do##name(param1); return (ret)0;} + +#define STAT_PLUGIN_METHOD_2(name, ret, type1, param1, type2, param2) \ + ret (*Do##name)(type1 param1, type2 param2); \ + virtual ret name(type1 param1,type2 param2) { if(NULL!=Do##name) return Do##name(param1, param2); return (ret)0;} + +#define STAT_PLUGIN_METHOD_3(name, ret, type1, param1, type2, param2, type3, param3) \ + ret (*Do##name)(type1 param1, type2 param2, type3 param3); \ + virtual ret name(type1 param1,type2 param2,type3 param3) \ + { if(NULL!=Do##name) return Do##name(param1, param2, param3); return (ret)0;} + +#define STAT_PLUGIN_METHOD_4(name, ret, type1, param1, type2, param2, type3, param3, type4, param4) \ + ret (*Do##name)(type1 param1, type2 param2, type3 param3, type4 param4); \ + virtual ret name(type1 param1,type2 param2,type3 param3, type4 param4) \ + { if(NULL!=Do##name) return Do##name(param1, param2, param3, param4); return (ret)0;} + +#define STAT_PLUGIN_METHOD_5(name, ret, type1, param1, type2, param2, type3, param3, type4, param4, type5, param5) \ + ret (*Do##name)(type1 param1, type2 param2, type3 param3, type4 param4, type5 param5); \ + virtual ret name(type1 param1,type2 param2,type3 param3, type4 param4, type5 param5) \ + { if(NULL!=Do##name) return Do##name(param1, param2, param3, param4, param5); return (ret)0;} + +#define STAT_PLUGIN_METHOD_6(name, ret, type1, param1, type2, param2, type3, param3, type4, param4, type5, param5, type6, param6) \ + ret (*Do##name)(type1 param1, type2 param2, type3 param3, type4 param4, type5 param5, type6 param6); \ + virtual ret name(type1 param1,type2 param2,type3 param3, type4 param4, type5 param5, type6 param6) \ + { if(NULL!=Do##name) return Do##name(param1, param2, param3, param4, param5, param6); return (ret)0;} + +#define STAT_PLUGIN_IF_DEFINE(name) \ + Do##name = NULL; + +#define STAT_PLUGIN_IMPORT(handle, name) \ + *(void **)(&Do##name) = dlsym(handle, #name); + +class StatProcessorGenericPlugin : public StatProcessor { +public: + StatProcessorGenericPlugin(const char* name) : + initialized_(false) { + if (NULL!=name) { + name_ = name; + } + STAT_PLUGIN_IF_DEFINE(OnInit) + STAT_PLUGIN_IF_DEFINE(OnFetchDb) + STAT_PLUGIN_IF_DEFINE(OnFlushDb) + STAT_PLUGIN_IF_DEFINE(OnClearDb) + STAT_PLUGIN_IF_DEFINE(OnCmd) + STAT_PLUGIN_IF_DEFINE(OnGetProcName) + STAT_PLUGIN_IF_DEFINE(OnGetCmdMask) + } + +virtual ~StatProcessorGenericPlugin() { + } + + STAT_PLUGIN_METHOD_2(OnInit, bool, sql::Connection*, db, MessageLoop*, message_loop) + STAT_PLUGIN_METHOD_1(OnFetchDb, bool, sql::Connection*, db) + STAT_PLUGIN_METHOD_1(OnFlushDb, bool, sql::Connection*, db) + STAT_PLUGIN_METHOD_1(OnClearDb, bool, sql::Connection*, db) + STAT_PLUGIN_METHOD_6(OnCmd, bool, StatHubTimeStamp, timestamp, unsigned short, cmd, void*, param1, int, sizeofparam1, void*, param2, int, sizeofparam2) + STAT_PLUGIN_METHOD_1(OnGetProcName, bool, std::string&, name) + STAT_PLUGIN_METHOD_1(OnGetCmdMask, bool, unsigned int&, cmd_mask) + + bool OpenPlugin(void* fh=NULL) { + if (!initialized_) { + if (NULL==fh && !name_.empty()) { + fh = dlopen(name_.c_str(), RTLD_NOW); + } + if (fh) { + initialized_ = true; + STAT_PLUGIN_IMPORT(fh, OnInit) + STAT_PLUGIN_IMPORT(fh, OnFetchDb) + STAT_PLUGIN_IMPORT(fh, OnFlushDb) + STAT_PLUGIN_IMPORT(fh, OnClearDb) + STAT_PLUGIN_IMPORT(fh, OnCmd) + STAT_PLUGIN_IMPORT(fh, OnGetProcName) + STAT_PLUGIN_IMPORT(fh, OnGetCmdMask) + } + else { + if(!name_.empty()) { + LOG(INFO) << "Failed to open plugin:" << name_.c_str(); + } + } + } + return initialized_; + } + +private: + bool initialized_; + std::string name_; +}; + +class StatHub { +public: + +virtual ~StatHub(); + +static StatHub* GetInstance(); + + void RegisterProcessor(StatProcessor* processor); + StatProcessor* DeleteProcessor(StatProcessor* processor); + + bool Init(const std::string& db_path, MessageLoop* message_loop, net::HttpCache* http_cache); + void Release(); + bool LoadPlugin(const char* name); + + void UpdateMainUrl(const char* url); + void UpdateSubUrl(const char* main_url,const char* sub_url); + void MainUrlLoaded(const char* url); + void Cmd(StatHubTimeStamp timestamp, unsigned short cmd, void* param1, int sizeofparam1, void* param2, int sizeofparam2); + + void FlushDBrequest(); + bool FlushDB(); + + bool GetDBmetaData(const char* key, std::string& val); + bool SetDBmetaData(const char* key, const char* val); + + bool IsReady() { + return ready_; + } + bool IsProcReady(const char *name); + MessageLoop* GetMessageLoop() { + return message_loop_; + } + + net::HttpCache* GetHttpCache() { + return http_cache_; + } + + sql::Connection* GetDb() { + return db_; + } + + base::Thread* GetThread() { + return thread_; + } + + bool IsVerboseEnabled() { + return (verbose_level_!=STAT_HUB_VERBOSE_LEVEL_DISABLED); + } + + StatHubVerboseLevel GetVerboseLevel() { + return verbose_level_; + } + + unsigned int GetCmdMask() { + return cmd_mask_; + } + + private: + + StatHub(); + + #if defined(NOT_NOW) + // Vacuums the database. This will cause sqlite to defragment and collect + // unused space in the file. It can be VERY SLOW. + void Vacuum(); + #endif //defined(NOT_NOW) + + // Creates tables, returning true if the table already exists + // or was successfully created. + bool InitTables(); + + sql::Connection* db_; + + std::string db_path_; + bool ready_; + bool flush_db_required_; + bool flush_db_scheduled_; + base::Time flush_db_request_time_; + + MessageLoop* message_loop_; + net::HttpCache* http_cache_; + + std::string enabled_app_name_; + + StatProcessor* first_processor_; + + // Separate thread on which we run blocking read for notify events. + base::Thread* thread_; + int flush_delay_; + StatHubVerboseLevel verbose_level_; + + DISALLOW_COPY_AND_ASSIGN(StatHub); + unsigned int cmd_mask_; +}; + +} // namespace stat_hub + +#endif // NET_STAT_HUB_H_ diff --git a/net/disk_cache/stat_hub_api.cc b/net/disk_cache/stat_hub_api.cc new file mode 100755 index 0000000..47c9dde --- /dev/null +++ b/net/disk_cache/stat_hub_api.cc @@ -0,0 +1,377 @@ +/** --------------------------------------------------------------------------- +Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------------**/ + +#include +#include +#include + +#include "build/build_config.h" +#include "googleurl/src/gurl.h" +#include "base/compiler_specific.h" +#include "base/task.h" +#include "base/memory/ref_counted.h" +#include "base/threading/thread.h" +#include "net/base/completion_callback.h" +#include "net/base/net_log.h" +#include "net/base/net_errors.h" +#include "net/base/request_priority.h" +#include "net/base/load_flags.h" +#include "net/base/io_buffer.h" +#include "net/disk_cache/hash.h" +#if defined(STAT_HUB_PRECONNECT_ENABLED) + #include "net/http/preconnect.h" +#endif //defined(STAT_HUB_PRECONNECT_ENABLED) +#include "net/http/http_cache_transaction.h" +#include "net/http/http_request_info.h" +#include "net/http/http_request_headers.h" + +#include "stat_hub.h" +#include "stat_hub_api.h" + +#define READ_BUF_SIZE (50*1024) + +class FetchRequest { + public: + explicit FetchRequest(std::string& dest, std::string& headers): + dest_(dest), + headers_(headers), + ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_(this, &FetchRequest::OnStartComplete)), + ALLOW_THIS_IN_INITIALIZER_LIST(read_callback_(this, &FetchRequest::OnReadComplete)), + read_in_progress_(false), + buf_(NULL){ + } + + void StartFetch(net::HttpCache* cache){ + request_info_.reset(new net::HttpRequestInfo()); + if(StatHubIsVerboseEnabled()) { + LOG(INFO) << "Fetch: " << dest_.spec().c_str(); + } + request_info_->url = dest_; + request_info_->motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED; + request_info_->priority = net::LOWEST; + request_info_->method = net::HttpRequestHeaders::kGetMethod; + request_info_->load_flags |= net::LOAD_PREFETCH; + request_info_->extra_headers.AddHeadersFromString(headers_); + int rv = cache->CreateTransaction(&trans_); + rv = trans_->Start(request_info_.get(), &start_callback_, net::BoundNetLog()); + if (rv != net::ERR_IO_PENDING) { + delete this; + } + } + + private: + + virtual ~FetchRequest() { + } + + void Read() { + int rv = trans_->Read(buf_, READ_BUF_SIZE, &read_callback_); + if (rv >= 0) { + delete this; + } + else { + if (rv == net::ERR_IO_PENDING) { + read_in_progress_ = true; + } + else { + LOG(INFO) << "FetchRequest::Read : ERROR " << rv << ":" << dest_.spec().c_str(); + delete this; + } + } + } + + void OnStartComplete(int error_code) { + if (error_code == net::OK) { + buf_ = new net::IOBuffer(READ_BUF_SIZE); + + Read(); + } + else { + LOG(INFO) << "FetchRequest::OnStartComplete : ERROR " << error_code << ":" << dest_.spec().c_str(); + delete this; + } + } + + void OnReadComplete(int error_code) { + read_in_progress_ = false; + if (error_code == net::OK) { + delete this; + } + else { + Read(); + } + } + + GURL dest_; + std::string headers_; + scoped_ptr request_info_; + scoped_ptr trans_; + + net::CompletionCallbackImpl start_callback_; + net::CompletionCallbackImpl read_callback_; + + bool read_in_progress_; + scoped_refptr buf_; + + DISALLOW_COPY_AND_ASSIGN(FetchRequest); +}; + +static void DoPreconnect(net::HttpCache* cache, std::string* dest, uint32 count) { + if(StatHubIsVerboseEnabled()) { + LOG(INFO) << "Preconnect: " << dest->c_str() << " : " << count; + } + if (NULL!=cache) { + net::HttpNetworkSession* session = cache->GetSession(); + if (NULL!=session) { + #if defined(STAT_HUB_PRECONNECT_ENABLED) + net::Preconnect::DoPreconnect(session, GURL(*dest), count); + #endif //defined(STAT_HUB_PRECONNECT_ENABLED) + } + } + delete dest; +} + +static void DoFetch(net::HttpCache* cache, std::string* dest, std::string* headers) { + FetchRequest* fetch = new FetchRequest(*dest, *headers); + fetch->StartFetch(cache); + delete dest; + delete headers; +} + + +// ======================================= Exports ============================================== + +bool StatHubIsVerboseEnabled() { + return stat_hub::StatHub::GetInstance()->IsVerboseEnabled(); +} + +StatHubVerboseLevel StatHubGetVerboseLevel() { + return stat_hub::StatHub::GetInstance()->GetVerboseLevel(); +} + +base::Time StatHubGetSystemTime() { + return base::Time::NowFromSystemTime(); +} + +int StatHubGetTimeDeltaInMs(const base::Time& start_time, const base::Time& finish_time) { + base::TimeDelta delta = finish_time - start_time; + return (int)delta.InMilliseconds(); //int64 +} + +const char* StatHubGetHostFromUrl(std::string& url, std::string& host) { + GURL dest(url); + host = dest.GetOrigin().spec(); + return host.c_str(); +} + +unsigned int StatHubHash(const char* str) { + return disk_cache::Hash(str, strlen(str)); +} + +void StatHubPreconnect(MessageLoop* message_loop, net::HttpCache* cache, const char* url, uint32 count) { + message_loop->PostTask(FROM_HERE, NewRunnableFunction(&DoPreconnect, cache, new std::string(url), count)); +} + +void StatHubFetch(MessageLoop* message_loop, net::HttpCache* cache, const char* url, const char* headers) { + message_loop->PostTask(FROM_HERE, NewRunnableFunction(&DoFetch, cache, new std::string(url), new std::string(headers))); +} + +bool StatHubGetDBmetaData(const char* key, std::string& val) { + return stat_hub::StatHub::GetInstance()->GetDBmetaData(key, val); +} + +bool StatHubSetDBmetaData(const char* key, const char* val) { + return stat_hub::StatHub::GetInstance()->SetDBmetaData(key, val); +} + +net::HttpCache* StatHubGetHttpCache() { + return stat_hub::StatHub::GetInstance()->GetHttpCache(); +} + +// ================================ StatHub SQL Interface ==================================== + +bool StatHubBeginTransaction(sql::Connection* db) { + return db->BeginTransaction(); +} + +bool StatHubCommitTransaction(sql::Connection* db) { + return db->CommitTransaction(); +} + +bool StatHubDoesTableExist(sql::Connection* db, const char* table_name) { + return db->DoesTableExist(table_name); +} + +bool StatHubExecute(sql::Connection* db, const char* sql) { + return db->Execute(sql); +} + +sql::Statement* StatHubGetStatement(sql::Connection* db, const sql::StatementID& id, const char* sql) { + if(NULL!=db && NULL!=sql) { + return new sql::Statement(db->GetCachedStatement(id, sql)); + } + return NULL; +} + +void StatHubReleaseStatement(sql::Statement* st) { + if (NULL!=st) { + delete st; + } +} + +bool StatHubStatementStep(sql::Statement* st) { + if (NULL!=st) { + return st->Step(); + } + return false; +} + +bool StatHubStatementRun(sql::Statement* st) { + if (NULL!=st) { + return st->Run(); + } + return false; +} + +void StatHubStatementReset(sql::Statement* st) { + if (NULL!=st) { + st->Reset(); + } +} + +int StatHubStatementColumnInt(sql::Statement* st, int col) { + if (NULL!=st) { + return st->ColumnInt(col); + } + return 0; +} + +int64 StatHubStatementColumnInt64(sql::Statement* st, int col) { + if (NULL!=st) { + return st->ColumnInt64(col); + } + return 0; +} + +bool StatHubStatementColumnBool(sql::Statement* st, int col) { + if (NULL!=st) { + return st->ColumnBool(col); + } + return false; +} + +std::string StatHubStatementColumnString(sql::Statement* st, int col) { + if (NULL!=st) { + return st->ColumnString(col); + } + return std::string(""); +} + +bool StatHubStatementBindInt(sql::Statement* st, int col, int val) { + if (NULL!=st) { + return st->BindInt(col, val); + } + return false; +} + +bool StatHubStatementBindInt64(sql::Statement* st, int col, int64 val) { + if (NULL!=st) { + return st->BindInt64(col, val); + } + return false; +} + +bool StatHubStatementBindBool(sql::Statement* st, int col, bool val) { + if (NULL!=st) { + return st->BindBool(col, val); + } + return false; +} + +bool StatHubStatementBindCString(sql::Statement* st, int col, const char* val) { + if (NULL!=st) { + return st->BindCString(col, val); + } + return false; +} + +// ============================ StatHub Functional Interface Proxies =============================== + +void CmdProxy(StatHubTimeStamp timestamp, unsigned short cmd, void* param1, int sizeofparam1, void* param2, int sizeofparam2) { + stat_hub::StatHub::GetInstance()->Cmd(timestamp, cmd, param1, sizeofparam1, param2, sizeofparam2); + if (sizeofparam1) { + delete (char*)param1; + } + if (sizeofparam2) { + delete (char*)param2; + } +} + +// ================================ StatHub Functional Interface ==================================== +void StatHubCmd(unsigned short cmd, void* param1, int sizeofparam1, void* param2, int sizeofparam2){ + unsigned int cmd_mask = stat_hub::StatHub::GetInstance()->GetCmdMask(); + + if ((cmd>INPUT_CMD_USER_DEFINED || (cmd_mask&(1<IsReady()) { + // create persistence storage to safely pass data to another thread + char* tmp_param1 = (char*)param1; + char* tmp_param2 = (char*)param2; + if (sizeofparam1) { + tmp_param1 = new char[sizeofparam1]; + memcpy(tmp_param1, param1, sizeofparam1); + } + if (sizeofparam2) { + tmp_param2 = new char[sizeofparam2]; + memcpy(tmp_param2, param2, sizeofparam2); + } + stat_hub::StatHub::GetInstance()->GetThread()->message_loop()->PostTask( FROM_HERE, NewRunnableFunction( + &CmdProxy, base::Time::NowFromSystemTime(), cmd, (void*)tmp_param1, sizeofparam1, (void*)tmp_param2, sizeofparam2)); + } +} + +void StatHubUpdateMainUrl(const char* url) { + if(NULL!=url) { + StatHubCmd(INPUT_CMD_WK_MAIN_URL, (void*)url, strlen(url)+1, NULL, 0); + } +} + +void StatHubUpdateSubUrl(const char* main_url, const char* sub_url) { + if(NULL!=main_url && NULL!=sub_url) { + StatHubCmd(INPUT_CMD_WK_SUB_URL_REQUEST, (void*)main_url, strlen(main_url)+1, (void*)sub_url, strlen(sub_url)+1); + } +} + +void StatHubMainUrlLoaded(const char* url) { + if(NULL!=url) { + StatHubCmd(INPUT_CMD_WK_MAIN_URL_LOADED, (void*)url, strlen(url)+1, NULL, 0); + } +} + +bool StatHubIsProcReady(const char* name) { + return stat_hub::StatHub::GetInstance()->IsProcReady(name); +} diff --git a/net/disk_cache/stat_hub_api.h b/net/disk_cache/stat_hub_api.h new file mode 100755 index 0000000..6fd771a --- /dev/null +++ b/net/disk_cache/stat_hub_api.h @@ -0,0 +1,118 @@ +/** --------------------------------------------------------------------------- +Copyright (c) 2011, Code Aurora Forum. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------------**/ + +// API for the network plug-in +#ifndef STAT_HUB_API_H_ +#define STAT_HUB_API_H_ + +#include +#include "base/time.h" +#include "app/sql/connection.h" +#include "app/sql/statement.h" +#include "net/http/http_cache.h" +#include "stat_hub_cmd_api.h" + +#define PROP_VAL_TO_STR(val) PROP_VAL_TO_STR_HELPER(val) +#define PROP_VAL_TO_STR_HELPER(val) #val +#define STAT_MAX_PARAM_LEN 2048 + +#define STAT_HUB_IS_VERBOSE_LEVEL_ERROR (StatHubGetVerboseLevel()>=STAT_HUB_VERBOSE_LEVEL_ERROR) +#define STAT_HUB_IS_VERBOSE_LEVEL_WARNING (StatHubGetVerboseLevel()>=STAT_HUB_VERBOSE_LEVEL_WARNING) +#define STAT_HUB_IS_VERBOSE_LEVEL_INFO (StatHubGetVerboseLevel()>=STAT_HUB_VERBOSE_LEVEL_INFO) +#define STAT_HUB_IS_VERBOSE_LEVEL_DEBUG (StatHubGetVerboseLevel()>=STAT_HUB_VERBOSE_LEVEL_DEBUG) + +typedef enum StatHubVerboseLevel { + STAT_HUB_VERBOSE_LEVEL_DISABLED,// 0 + STAT_HUB_VERBOSE_LEVEL_ERROR, // 1 + STAT_HUB_VERBOSE_LEVEL_WARNING, // 2 + STAT_HUB_VERBOSE_LEVEL_INFO, // 3 + STAT_HUB_VERBOSE_LEVEL_DEBUG // 4 +} StatHubVerboseLevel; + +typedef base::Time StatHubTimeStamp; +class MessageLoop; + +extern bool StatHubIsVerboseEnabled() + __attribute__ ((visibility ("default"), used)); +extern StatHubVerboseLevel StatHubGetVerboseLevel() + __attribute__ ((visibility ("default"), used)); +extern base::Time StatHubGetSystemTime() + __attribute__ ((visibility ("default"), used)); +extern int StatHubGetTimeDeltaInMs(const base::Time& start_time, const base::Time& finish_time) + __attribute__ ((visibility ("default"), used)); +extern const char* StatHubGetHostFromUrl(std::string& url, std::string& host) + __attribute__ ((visibility ("default"), used)); +extern void StatHubPreconnect(MessageLoop* message_loop, net::HttpCache* cache, const char* url, uint32 count) + __attribute__ ((visibility ("default"), used)); +extern void StatHubFetch(MessageLoop* message_loop, net::HttpCache* cache, const char* url, const char* headers) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubGetDBmetaData(const char* key, std::string& val) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubSetDBmetaData(const char* key, const char* val) + __attribute__ ((visibility ("default"), used)); +extern net::HttpCache* StatHubGetHttpCache() + __attribute__ ((visibility ("default"), used)); + +// ================================ StatHub SQL Interface ==================================== +extern bool StatHubBeginTransaction(sql::Connection* db) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubCommitTransaction(sql::Connection* db) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubDoesTableExist(sql::Connection* db, const char* table_name) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubExecute(sql::Connection* db, const char* sql) + __attribute__ ((visibility ("default"), used)); +extern sql::Statement* StatHubGetStatement(sql::Connection* db, const sql::StatementID& id, const char* sql) + __attribute__ ((visibility ("default"), used)); +extern void StatHubReleaseStatement(sql::Statement* st) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubStatementStep(sql::Statement* st) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubStatementRun(sql::Statement* st) + __attribute__ ((visibility ("default"), used)); +extern void StatHubStatementReset(sql::Statement* st) + __attribute__ ((visibility ("default"), used)); +extern int StatHubStatementColumnInt(sql::Statement* st, int col) + __attribute__ ((visibility ("default"), used)); +extern int64 StatHubStatementColumnInt64(sql::Statement* st, int col) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubStatementColumnBool(sql::Statement* st, int col) + __attribute__ ((visibility ("default"), used)); +extern std::string StatHubStatementColumnString(sql::Statement* st, int col) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubStatementBindInt(sql::Statement* st, int col, int val) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubStatementBindInt64(sql::Statement* st, int col, int64 val) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubStatementBindBool(sql::Statement* st, int col, bool val) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubStatementBindCString(sql::Statement* st, int col, const char* val) + __attribute__ ((visibility ("default"), used)); + +#endif /* STAT_HUB_API_H_ */ diff --git a/net/disk_cache/stat_hub_cmd_api.h b/net/disk_cache/stat_hub_cmd_api.h new file mode 100644 index 0000000..71ee934 --- /dev/null +++ b/net/disk_cache/stat_hub_cmd_api.h @@ -0,0 +1,74 @@ +/** --------------------------------------------------------------------------- +Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------------**/ + +#ifndef STAT_HUB_CMD_API_H_ +#define STAT_HUB_CMD_API_H_ + +typedef enum { + INPUT_CMD_TBD_0, // 0 TBD + INPUT_CMD_WK_MAIN_URL, // 1 + INPUT_CMD_WK_SUB_URL_REQUEST, // 2 + INPUT_CMD_TBD_3, // 3 TBD + INPUT_CMD_WK_MAIN_URL_LOADED, // 4 + INPUT_CMD_WK_RES_MMC_STATUS, // 5 + INPUT_CMD_WK_MMC_CLEAR, // 6 + INPUT_CMD_TBD_7, // 7 TBD + INPUT_CMD_CH_URL_REQUEST, // 8 + INPUT_CMD_WK_RES_LOAD_FINISHED, // 9 + INPUT_CMD_WK_START_PAGE_LOAD, // 10 + INPUT_CMD_WK_FINISH_PAGE_LOAD, // 11 + INPUT_CMD_TBD_12, // 12 TBD + INPUT_CMD_CH_URL_REQUEST_DONE, // 13 + INPUT_CMD_WK_JS_SEQ, // 14 + + INPUT_CMD_USER_DEFINED = 32 // 256 +} StatHubInputCmd; + +typedef union { + unsigned value; + struct bf { + unsigned cacheable:1; // first bit + unsigned mime_type:3; // 3 bits: up to 6 types defined in CachedResource.cpp + } bf; +} UrlProperty; + +// ================================ StatHub CMD Interface ==================================== +extern unsigned int StatHubHash(const char* str) + __attribute__ ((visibility ("default"), used)); +extern void StatHubUpdateMainUrl(const char* url) + __attribute__ ((visibility ("default"), used)); +extern void StatHubUpdateSubUrl(const char* main_url, const char* sub_url) + __attribute__ ((visibility ("default"), used)); +extern void StatHubMainUrlLoaded(const char* url) + __attribute__ ((visibility ("default"), used)); +extern void StatHubCmd(unsigned short cmd, void* param1, int sizeofparam1, void* param2, int sizeofparam2) + __attribute__ ((visibility ("default"), used)); +extern bool StatHubIsProcReady(const char* name) + __attribute__ ((visibility ("default"), used)); +#endif /* STAT_HUB_CMD_API_H_ */ diff --git a/net/host_resolver_helper/dyn_lib_loader.cc b/net/host_resolver_helper/dyn_lib_loader.cc new file mode 100644 index 0000000..043e81a --- /dev/null +++ b/net/host_resolver_helper/dyn_lib_loader.cc @@ -0,0 +1,76 @@ +/** --------------------------------------------------------------------------- + Copyright (c) 2011, Code Aurora Forum. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -----------------------------------------------------------------------------**/ +#include "dyn_lib_loader.h" + +LibraryManager* LibraryManager::GetInstance() { + static LibraryManager mgr; + return &mgr; +} + +LibraryManager::~LibraryManager() { + for (LibDictionary::iterator it = libdict.begin(); it != libdict.end(); + it++) { + if (it->second) { + ReleaseLibraryModule(it->second); + } + } +} + +LibraryManager::MODULE_HANDLE_TYPE LibraryManager::GetLibraryHandleInternal(const std::string& libname) { + LibHandle& handle = libdict[libname]; + if (NULL == handle) { + //load module + handle = LoadLibraryModule(libname); + } + return handle; +} + +void* LibraryManager::GetSymbolInternal(const std::string& libname, const std::string& symbol) { + return LoadLibrarySymbol(GetLibraryHandleInternal(libname), symbol); +} + +void * LibraryManager::LoadLibrarySymbol(const MODULE_HANDLE_TYPE& lh, + const std::string& symname) { + void* symptr = NULL; + if (lh) { + symptr = dlsym(lh, symname.c_str()); + } + return symptr; +} + +LibraryManager::MODULE_HANDLE_TYPE LibraryManager::LoadLibraryModule(const std::string& libname) { + return dlopen(libname.c_str(), RTLD_LAZY); +} + +void LibraryManager::ReleaseLibraryModule(const MODULE_HANDLE_TYPE& lh) { + if (lh) { + dlclose(lh); + } +} + diff --git a/net/host_resolver_helper/dyn_lib_loader.h b/net/host_resolver_helper/dyn_lib_loader.h new file mode 100644 index 0000000..6e3b0f0 --- /dev/null +++ b/net/host_resolver_helper/dyn_lib_loader.h @@ -0,0 +1,103 @@ +/** --------------------------------------------------------------------------- + Copyright (c) 2011, Code Aurora Forum. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -----------------------------------------------------------------------------**/ +#ifndef __DYN_LIB_LOADER_H__ +#define __DYN_LIB_LOADER_H__ + +#include +#include +#include +#include "dyn_lib_loader_decl.h" + +template +inline T* GetInterfacePtr(void* funptr) { + typedef T* (*InterfaceFunPtr)(void); + if (NULL==funptr) { + return NULL; + } + InterfaceFunPtr fun = (InterfaceFunPtr) (funptr); + return fun(); +} + +//This macro is used by module which wishes to use the interface object exported by some other module +// libname - is the dynamic library full name, interface_class - is the interface class for which +// the object will be imported +// EXAMPLE: Interface* ptr = GET_DYNAMIC_OBJECT_INTERFACE_PTR("libmy.so",Interface); +#define GET_DYNAMIC_OBJECT_INTERFACE_PTR(__libname__,__interface_class__) \ + GetInterfacePtr<__interface_class__>(LibraryManager::GetFunctionPtr<__interface_class__>(__libname__,"Get" #__interface_class__ "Object")) + +//LibraryManager Connects to shared library reusing the lib handle +//if called from mutiple places. Get retrieve exported functions and library handle. +//This class is module level singletone. +class LibraryManager { +public: + + typedef void* MODULE_HANDLE_TYPE; + template + static RET_TYPE* GetFunctionPtr(const char* libname, const char* symbol) { + return static_cast(GetInstance()->GetSymbolInternal(libname, + symbol)); + } + + static MODULE_HANDLE_TYPE GetLibraryHandle(const char* libname) { + return GetInstance()->GetLibraryHandleInternal(libname); + } + +private: + template + class LibHandleType { + public: + LibHandleType() : + handle(NULL) { + } + LibHandleType(MODULE_HANDLE_TYPE h) : + handle(h) { + } + operator MODULE_HANDLE_TYPE() { + return handle; + } + private: + MODULE_HANDLE_TYPE handle; + }; + + typedef LibHandleType LibHandle; + typedef std::map LibDictionary; + + static LibraryManager* GetInstance(); + LibraryManager() {} + ~LibraryManager(); + void* GetSymbolInternal(const std::string& libname, const std::string& symbol); + MODULE_HANDLE_TYPE GetLibraryHandleInternal(const std::string& libname); + void * LoadLibrarySymbol(const MODULE_HANDLE_TYPE& lh, const std::string& symname); + MODULE_HANDLE_TYPE LoadLibraryModule(const std::string& libname); + void ReleaseLibraryModule(const MODULE_HANDLE_TYPE& lh); + + std::map libdict; +}; + +#endif //__DYN_LIB_LOADER_H__ diff --git a/net/host_resolver_helper/dyn_lib_loader_decl.h b/net/host_resolver_helper/dyn_lib_loader_decl.h new file mode 100644 index 0000000..a0ca0d6 --- /dev/null +++ b/net/host_resolver_helper/dyn_lib_loader_decl.h @@ -0,0 +1,51 @@ +/** --------------------------------------------------------------------------- + Copyright (c) 2011, Code Aurora Forum. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -----------------------------------------------------------------------------**/ + +#ifndef __DYN_LIB_LOADER_DECL_H__ +#define __DYN_LIB_LOADER_DECL_H__ + +//This macro should be placed in module which is exporting the interface +//first parameter is the interface class, second is the function which returns the interface object +//EXAMPLE: DECLARE_DYNAMIC_OBJECT_INTERFACE(Interface,InterfaceImpl::GetInstance) +#define DECLARE_DYNAMIC_OBJECT_INTERFACE_EX(__interface_class__, __get_instance_method__) \ + extern "C" void* Get##__interface_class__##Object() \ + __attribute__ ((visibility ("default"))); \ + void* Get##__interface_class__##Object() {\ + __interface_class__* ptr = __get_instance_method__();\ + return static_cast(ptr);\ + } \ + +//This macro should be placed in module which is exporting the interface +//first parameter is the interface class, second is the class implemeting the static +//GetInstance function to get the interface object +//EXAMPLE: DECLARE_DYNAMIC_OBJECT_INTERFACE(Interface,InterfaceImpl) +#define DECLARE_DYNAMIC_OBJECT_INTERFACE(__interface_class__,__impl_class__) \ + DECLARE_DYNAMIC_OBJECT_INTERFACE_EX(__interface_class__,__impl_class__::GetInstance) \ + +#endif //__DYN_LIB_LOADER_DECL_H__ diff --git a/net/host_resolver_helper/host_resolver_helper.cc b/net/host_resolver_helper/host_resolver_helper.cc new file mode 100644 index 0000000..7c60fb5 --- /dev/null +++ b/net/host_resolver_helper/host_resolver_helper.cc @@ -0,0 +1,157 @@ +/** --------------------------------------------------------------------------- + Copyright (c) 2011, Code Aurora Forum. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -----------------------------------------------------------------------------**/ +#include "host_resolver_helper.h" + +#include +#include + +#include "net/base/address_list.h" +#include "net/base/host_port_pair.h" +#include "net/base/completion_callback.h" +#include "net/base/host_port_pair.h" +#include "net/base/host_resolver.h" +#include "net/base/net_errors.h" +#include "net/base/net_log.h" +#include +#include "dyn_lib_loader.h" + +#define NUM_HOSTS_TO_RESOLVE 30 + +HostResolverHelper::HostResolverHelper(net::HostResolver* hostresolver) : + num_of_hosts_to_resolve(NUM_HOSTS_TO_RESOLVE), hostresolver_( + hostresolver), hostname_provider_(NULL) +{ + char value[PROPERTY_VALUE_MAX] = { '\0' }; + property_get("net.dnshostprio.num_hosts", value, NULL); + if (NULL != value && value[0] != '\0') { + int host_num = atol(value); + if (host_num <= 0) { + host_num = NUM_HOSTS_TO_RESOLVE; + } + num_of_hosts_to_resolve = host_num; + } +} + +HostResolverHelper::~HostResolverHelper() { +} + +void HostResolverHelper::Init(HostsProvider* provider) { + hostname_provider_ = provider; + LOG(INFO) << "DNSPreResolver::Init got hostprovider:" << provider; + if (hostresolver_) + hostresolver_->SetResolverExt(this); +} + +void HostResolverHelper::DoResolve(HostResolverHelper* obj) { + //TODO: Check there is another task like this in the queue and + // skip execution of the current one + obj->StartHostsResolution(); +} + +void HostResolverHelper::CancelAllRequests() { + //loop through all requests and cancel those that still pending + for (unsigned int i = 0; i < hostinfo_list_.size(); i++) { + if (hostinfo_list_[i]->pending) { + hostinfo_list_[i]->pending = false; + hostresolver_->CancelRequest(hostinfo_list_[i]->reqhandle); + } + } +} + +void HostResolverHelper::PrepareRequestsData(const std::vector& hostnames) { + const int actual_hosts_num = hostnames.size(); + hostinfo_list_.clear(); + hostinfo_list_.reserve(actual_hosts_num); + for (int i = 0; i < actual_hosts_num; i++) { + hostinfo_list_.push_back(new HostInfo(hostnames[i].c_str())); + } +} + +bool HostResolverHelper::StartHostsResolution() { + if (NULL == hostresolver_) { + return false; + } + if (NULL == hostname_provider_) { + return false; + } + + //get hosts from the provider + std::vector < std::string > hostnames; + hostname_provider_->GetHosts(num_of_hosts_to_resolve, hostnames); + if (0 == hostnames.size()) { + return true; + } + //free old requests if any still active + CancelAllRequests(); + PrepareRequestsData(hostnames); + + const int actual_hosts_num = hostnames.size(); + //now issue resolve for each host + for (int i = 0; i < actual_hosts_num; i++) { + //TODO: set request priority + hostinfo_list_[i]->pending = true; + int rv = hostresolver_->Resolve(hostinfo_list_[i]->reqinfo, &hostinfo_list_[i]->addrlist, + &hostinfo_list_[i]->completion_callback_, &hostinfo_list_[i]->reqhandle, net::BoundNetLog()); + //in case we got it resolved synchronously (or error) - set as not pending + if (rv != net::ERR_IO_PENDING) { + hostinfo_list_[i]->pending = false; + } + } + return true; +} + +void HostResolverHelper::HostInfo::OnLookupFinished(int result) { + pending = false; +} + +HostResolverHelper::HostInfo::HostInfo(const std::string& hostname) : + reqinfo(net::HostPortPair(hostname, 80)), reqhandle(NULL), pending(false), completion_callback_(this, + &HostInfo::OnLookupFinished) { +} + + +net::HostResolver::HostnameResolverExt* CreateResolverIPObserver(net::HostResolver* hostResolver) { + char value[PROPERTY_VALUE_MAX] = { '\0' }; + const char* DNS_PRIORITY_EXTERNAL_LIB = "libdnshostprio.so"; + + if (NULL == hostResolver) { + return NULL; + } + property_get("net.dnshostprio.enable", value, NULL); + if (NULL != value && value[0] == '0') { + return NULL; + } + HostResolverHelper* dnsPreresolver = new HostResolverHelper(hostResolver); + if (NULL == dnsPreresolver) { + return NULL; + } + HostsProvider* provider = GET_DYNAMIC_OBJECT_INTERFACE_PTR(DNS_PRIORITY_EXTERNAL_LIB,HostsProvider); + dnsPreresolver->Init(provider); + return dnsPreresolver; +} diff --git a/net/host_resolver_helper/host_resolver_helper.h b/net/host_resolver_helper/host_resolver_helper.h new file mode 100644 index 0000000..bc18a21 --- /dev/null +++ b/net/host_resolver_helper/host_resolver_helper.h @@ -0,0 +1,105 @@ +/** --------------------------------------------------------------------------- + Copyright (c) 2011, Code Aurora Forum. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -----------------------------------------------------------------------------**/ +#ifndef __DNSRESOLVERHELPER_H__ +#define __DNSRESOLVERHELPER_H__ + +#include +#include + +#include "config.h" +#include "net/base/host_resolver.h" +#include "net/base/address_list.h" +#include "net/base/net_log.h" +#include "net/base/net_errors.h" +#include "base/message_loop.h" +#include "net/base/completion_callback.h" +#include "hosts_provider.h" + +//This class does DNS pre-resolution and should be used by net::HostResolver +//It's lifetime is depending on the host resolver and they should be created and destroyed +// in the correct order +//TODO: make sure the resolver is never destroyed before the pre-resolver +class HostResolverHelper: public net::HostResolver::HostnameResolverExt { +public: + HostResolverHelper(net::HostResolver* hostresolver); + virtual ~HostResolverHelper(); + + /////////////////////////////////////////////////////////////////////////////////////// + // net::HostResolver::HostnamePreresolver interface + virtual void Resolve() { + MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableFunction(&HostResolverHelper::DoResolve, this), + 500); + } + /////////////////////////////////////////////////////////////////////////////////////// + + //task which is executed through the message loop + static void DoResolve(HostResolverHelper* obj); + + //call it to connect with the hostnames provider + void Init(HostsProvider* provider); + +private: + + //to be called when hosts pre-resolution is requested (worker function) + bool StartHostsResolution(); + +private: + int num_of_hosts_to_resolve; + net::HostResolver* hostresolver_; + HostsProvider* hostname_provider_; + // Delegate interface, for notification when the ResolveRequest completes. + + class HostInfo: public base::RefCounted { + public: + net::AddressList addrlist; + net::HostResolver::RequestInfo reqinfo; + net::HostResolver::RequestHandle reqhandle; + bool pending; + net::CompletionCallbackImpl completion_callback_; + + HostInfo(const std::string& hostname); + ~HostInfo() { + } + + void OnLookupFinished(int result); + + }; + + std::vector > hostinfo_list_; + + //used to cancel all pending requests before issuing new ones + void CancelAllRequests(); + void PrepareRequestsData(const std::vector& hostnames); + +}; + +//intialization for the webkit +net::HostResolver::HostnameResolverExt* CreateResolverIPObserver(net::HostResolver* hostResolver); + +#endif diff --git a/net/host_resolver_helper/hosts_provider.h b/net/host_resolver_helper/hosts_provider.h new file mode 100644 index 0000000..19b847d --- /dev/null +++ b/net/host_resolver_helper/hosts_provider.h @@ -0,0 +1,44 @@ +/** --------------------------------------------------------------------------- + Copyright (c) 2011, Code Aurora Forum. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Code Aurora Forum, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -----------------------------------------------------------------------------**/ +#ifndef __HOSTSPROVIDER_H_INCL__ +#define __HOSTSPROVIDER_H_INCL__ + +#include +#include + +class HostsProvider { +public: + virtual bool GetHosts(int max_hosts, std::vector& list)=0; + virtual void ClearStatistics()=0; + virtual ~HostsProvider() { + } + ; +}; + +#endif // __HOSTSPROVIDER_H_INCL__ diff --git a/net/http/http_basic_stream.cc b/net/http/http_basic_stream.cc index 6501a59..f74614b 100644 --- a/net/http/http_basic_stream.cc +++ b/net/http/http_basic_stream.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -33,7 +34,7 @@ int HttpBasicStream::InitializeStream(const HttpRequestInfo* request_info, DCHECK(!parser_.get()); request_info_ = request_info; parser_.reset(new HttpStreamParser(connection_.get(), request_info, - read_buf_, net_log)); + read_buf_, net_log, using_proxy_)); return OK; } diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index d53d525..4a2313c 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -35,6 +36,9 @@ #include "net/http/http_util.h" #include "net/socket/ssl_host_info.h" +#include "net/disk_cache/stat_hub.h" +#include "net/disk_cache/hostres_plugin_bridge.h" + namespace net { namespace { @@ -85,8 +89,14 @@ HttpCache::BackendFactory* HttpCache::DefaultBackend::InMemory(int max_bytes) { int HttpCache::DefaultBackend::CreateBackend(NetLog* net_log, disk_cache::Backend** backend, - CompletionCallback* callback) { + CompletionCallback* callback, + FilePath** stat_db_path) { DCHECK_GE(max_bytes_, 0); + (*stat_db_path) = NULL; + if (type_ == net::DISK_CACHE) { + std::string dataPath = "/data/data/"; + (*stat_db_path) = new FilePath(dataPath + stat_hub::kEnabledAppName + "/databases"); + } return disk_cache::CreateCacheBackend(type_, path_, max_bytes_, true, thread_, net_log, backend, callback); } @@ -339,7 +349,8 @@ HttpCache::HttpCache(HostResolver* host_resolver, http_auth_handler_factory, network_delegate, net_log))), - ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { + ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) + , stat_db_path_(NULL) { } @@ -408,6 +419,10 @@ HttpCache::~HttpCache() { if (delete_pending_op) delete pending_op; } + + if (NULL!=stat_db_path_) { + delete stat_db_path_; + } } int HttpCache::GetBackend(disk_cache::Backend** backend, @@ -518,7 +533,7 @@ int HttpCache::CreateBackend(disk_cache::Backend** backend, pending_op->callback = my_callback; int rv = backend_factory_->CreateBackend(net_log_, &pending_op->backend, - my_callback); + my_callback, &stat_db_path_ ); if (rv != ERR_IO_PENDING) { pending_op->writer->ClearCallback(); my_callback->Run(rv); @@ -1143,8 +1158,21 @@ void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) { } // The cache may be gone when we return from the callback. - if (!item->DoCallback(result, backend)) + if (!item->DoCallback(result, backend)) { item->NotifyTransaction(result, NULL); + if (NULL!=stat_db_path_) { + if(!stat_hub::StatHub::GetInstance()->IsReady()) { + stat_hub::StatProcessor* hp = StatHubCreateHostResPlugin(); + if (NULL!=hp) { + stat_hub::StatHub::GetInstance()->RegisterProcessor(hp); + LOG(INFO) << "HttpCache::OnBackendCreated HostStat created"; + } + if(stat_hub::StatHub::GetInstance()->Init(stat_db_path_->value(), MessageLoop::current(), this)) { + LOG(INFO) << "HttpCache::OnBackendCreated : StatHub is ready."; + } + } + } + } } } // namespace net diff --git a/net/http/http_cache.h b/net/http/http_cache.h index 0c2dc35..2ff5eff 100644 --- a/net/http/http_cache.h +++ b/net/http/http_cache.h @@ -1,4 +1,6 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, Code Aurora Forum. All rights reserved + // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -88,7 +90,8 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, // |callback| because the object can be deleted from within the callback. virtual int CreateBackend(NetLog* net_log, disk_cache::Backend** backend, - CompletionCallback* callback) = 0; + CompletionCallback* callback, + FilePath** stat_db_path) = 0; }; // A default backend factory for the common use cases. @@ -107,7 +110,8 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, // BackendFactory implementation. virtual int CreateBackend(NetLog* net_log, disk_cache::Backend** backend, - CompletionCallback* callback); + CompletionCallback* callback, + FilePath** stat_db_path); private: CacheType type_; @@ -378,6 +382,8 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, scoped_ptr playback_cache_map_; + FilePath* stat_db_path_; + DISALLOW_COPY_AND_ASSIGN(HttpCache); }; diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index a12a64f..3fef3a7 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -34,6 +35,8 @@ #include "net/http/http_transaction.h" #include "net/http/http_util.h" #include "net/http/partial_data.h" +#include "net/http/preconnect.h" +#include "net/http/net-plugin-bridge.h" using base::Time; @@ -1643,13 +1646,17 @@ bool HttpCache::Transaction::RequiresValidation() { return true; if (response_.headers->RequiresValidation( - response_.request_time, response_.response_time, Time::Now())) + response_.request_time, response_.response_time, Time::Now())) { + ObserveRevalidation(&response_, request_, cache_); return true; + } // Since Vary header computation is fairly expensive, we save it for last. if (response_.vary_data.is_valid() && - !response_.vary_data.MatchesRequest(*request_, *response_.headers)) + !response_.vary_data.MatchesRequest(*request_, *response_.headers)) { + ObserveRevalidation(&response_, request_, cache_); return true; + } return false; } diff --git a/net/http/http_getzip_bridge.cc b/net/http/http_getzip_bridge.cc new file mode 100644 index 0000000..9395c1e --- /dev/null +++ b/net/http/http_getzip_bridge.cc @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2012, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other *materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **/ + +#include "net/http/http_getzip_bridge.h" +#include "net/http/http_request_headers.h" +#include "net/http/http_response_headers.h" + +namespace net +{ + +void GetNextHttpRequestHeader( void*& it) +{ + if (NULL == it)return; + + HttpRequestHeaders::Iterator* myIt = + (static_cast (it)); + + if (!myIt->GetNext()) + { + delete myIt; + it = NULL; + } +} + +void GetFirstHttpRequestHeader( + net::HttpRequestHeaders& req, void*& it) +{ + //create a new Iterator for the req + it = new net::HttpRequestHeaders::Iterator(req); + return GetNextHttpRequestHeader( it ); +} + +const std::string& GetHttpRequestHeaderName( void*& it ) +{ + net::HttpRequestHeaders::Iterator* myIt = + (static_cast (it)); + return myIt->name(); +} + +const std::string& GetHttpRequestHeaderValue( void*& it ) +{ + net::HttpRequestHeaders::Iterator* myIt = + (static_cast (it)); + return myIt->value(); +} + +bool GetHttpRequestHeaderByValue( + net::HttpRequestHeaders& req, + const std::string& headerName, + std::string* headerValue) +{ + return req.GetHeader(headerName, headerValue); +} + +void SetHttpRequestHeader(net::HttpRequestHeaders& req, + const std::string& headerName, const std::string& value) +{ + req.SetHeader(headerName, value); +} + +void RemoveHttpRequestHeader(net::HttpRequestHeaders& req, + const std::string& headerName) +{ + req.RemoveHeader(headerName); +} + +void RemoveHttpResponseHeader(net::HttpResponseHeaders* res, + const std::string& headerName) +{ + if (NULL == res) + return; + + res->RemoveHeader(headerName); +} + +std::string GetHttpResponseHeaderValue(net::HttpResponseHeaders* res, + const std::string& headerName) +{ + if (NULL == res) + return ""; + std::string value; + + void* iter = NULL; + std::string temp; + while (res->EnumerateHeader(&iter, headerName, &temp)) { + + value.append(temp); + value.append(", "); + } + if(value.size() > 2) + { + value.erase(value.size() - 2); + } + + return value; +} + +int GetHttpResponseCode(net::HttpResponseHeaders* res) +{ + if(NULL == res) return -1; + + return res->response_code(); +} + +bool HasHttpResponseHeader(net::HttpResponseHeaders* res, + const std::string& headerName) +{ + if(NULL == res) return false; + + return res->HasHeader(headerName); +} + +void initBridge(){ } + +}; //end net + diff --git a/net/http/http_getzip_bridge.h b/net/http/http_getzip_bridge.h new file mode 100644 index 0000000..c545b89 --- /dev/null +++ b/net/http/http_getzip_bridge.h @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2012, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other *materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **/ + +#ifndef HTTP_GETZIP_BRIDGE_H_ +#define HTTP_GETZIP_BRIDGE_H_ + + +#include +#include "net/http/http_request_headers.h" +#include "net/http/http_response_headers.h" + +#define EXPORT __attribute__((visibility("default"), used)) + +namespace net +{ + //HttpRequestHeader method delegates + //@argument it - should be initialized to NULL + extern void GetFirstHttpRequestHeader(net::HttpRequestHeaders& req, void*& it) EXPORT; + extern const std::string& GetHttpRequestHeaderName( void*& it ) EXPORT; + extern const std::string& GetHttpRequestHeaderValue( void*& it ) EXPORT; + bool GetHttpRequestHeaderByValue( net::HttpRequestHeaders& req, + const std::string& headerName, + std::string* headerValue) EXPORT; + extern void GetNextHttpRequestHeader( void*& it ) EXPORT; + + extern void SetHttpRequestHeader(net::HttpRequestHeaders& req, const std::string& headerName, + const std::string& value) EXPORT; + extern void RemoveHttpRequestHeader(net::HttpRequestHeaders& req, const std::string& headerName) EXPORT; + + ////HttpResponseHeader method delegates + extern void RemoveHttpResponseHeader(net::HttpResponseHeaders* res, const std::string& headerName) EXPORT; + extern std::string GetHttpResponseHeaderValue(net::HttpResponseHeaders* res, const std::string& headerName) EXPORT; + extern int GetHttpResponseCode(net::HttpResponseHeaders* res) EXPORT; + extern bool HasHttpResponseHeader(net::HttpResponseHeaders* res, const std::string& headerName) EXPORT; + + extern void initBridge(); +}; + + +#endif /* HTTP_GETZIP_BRIDGE_H_ */ diff --git a/net/http/http_getzip_factory.cc b/net/http/http_getzip_factory.cc new file mode 100644 index 0000000..02948d8 --- /dev/null +++ b/net/http/http_getzip_factory.cc @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2012, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other *materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **/ + +#include "net/http/http_getzip_factory.h" +#include "net/socket/client_socket.h" +#include +#include + +namespace net +{ + +HttpGetZipFactory* HttpGetZipFactory::s_pFactory = NULL; + +typedef IGetZipManager* mngr_create_(); + +HttpGetZipFactory::HttpGetZipFactory() : + m_pMngr(NULL), libHandle(NULL) +{ +} + +HttpGetZipFactory::~HttpGetZipFactory() +{ + delete m_pMngr; + m_pMngr = NULL; + + if (NULL != libHandle) + { + ::dlclose(libHandle); + libHandle = NULL; + } +} + +void HttpGetZipFactory::InitGETZipManager() +{ + if (NULL != s_pFactory) + return; + + s_pFactory = new HttpGetZipFactory(); + + s_pFactory->libHandle = ::dlopen("libgetzip.so", RTLD_NOW); + + if (s_pFactory->libHandle) + { + SLOGD("%s: libgetzip.so successfully loaded", __FILE__); + dlerror(); + mngr_create_* mngrCreate = (mngr_create_*) dlsym(s_pFactory->libHandle, + "createGETZipManager"); + + if (mngrCreate) + { + SLOGD("%s,: GETzip initializing method was found in libgetzip.so", + __FILE__); + s_pFactory->m_pMngr = (IGetZipManager*) mngrCreate(); + if( NULL == s_pFactory->m_pMngr) + { + s_pFactory->m_pMngr = new GetZipManager(); + } + return; + } + SLOGD("netstack: Failed to find createGETZipManager sybmol in libgetzip.so"); + ::dlclose(s_pFactory->libHandle); + s_pFactory->libHandle = NULL; + s_pFactory->m_pMngr = new GetZipManager(); + return; + } + + SLOGD("%s: Failed to construct GETzip manager, didn't find the library!", + __FILE__); + s_pFactory->m_pMngr = new GetZipManager(); +} + +IGetZipManager* HttpGetZipFactory::GetGETZipManager() +{ + return s_pFactory->m_pMngr; +} + +void HttpGetZipFactory::StopGETZipManager() +{ + if (libHandle == NULL) + return; + + delete m_pMngr; + m_pMngr = new GetZipManager(); + ::dlclose(libHandle); + libHandle = NULL; +} + +IGetZipManager::IGetZipManager() +{ +} + +IGetZipManager::~IGetZipManager() +{ +} + +GetZipManager::GetZipManager() +{ +} + +} +; //end network diff --git a/net/http/http_getzip_factory.h b/net/http/http_getzip_factory.h new file mode 100644 index 0000000..f7cced0 --- /dev/null +++ b/net/http/http_getzip_factory.h @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2012, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other *materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **/ + +#ifndef HTTP_GETZIP_FACTORY_H_ +#define HTTP_GETZIP_FACTORY_H_ + +#include "net/socket/client_socket.h" +#include +#include "base/basictypes.h" + +namespace net +{ + +//forward declarations +class HttpRequestHeaders; +class HttpResponseHeaders; + +typedef enum +{ + GETZIP_OK = 1, + REQUEST_RETRY_NEEDED = 2, //GETzip failure that requires last request retry + NULL_ARGUMENT = 3, //One of the passed argument was NULL + NO_GETZIP_CONNECTION = 4 //No GETzip connection was found +} GETZipDecompressionStatus; + +//Main GetZip interface +class IGetZipManager +{ +public: + IGetZipManager(); + virtual void CompressRequestHeaders(HttpRequestHeaders&, ClientSocket*) = 0; + virtual GETZipDecompressionStatus + DecompressResponseHeaders(HttpResponseHeaders*, ClientSocket*) = 0; + virtual void StopGetZipConnection(ClientSocket*) = 0; + virtual void OpenGetZipConnection(ClientSocket*) = 0; + virtual ~IGetZipManager() = 0; + +private: + DISALLOW_COPY_AND_ASSIGN(IGetZipManager); +}; + +//Simple, non private GetZip manager implementation +class GetZipManager: public IGetZipManager +{ +public: + + GetZipManager(); + virtual ~GetZipManager() + { + } + ; + + virtual void CompressRequestHeaders(HttpRequestHeaders&, ClientSocket*) + { + } + ; + virtual GETZipDecompressionStatus DecompressResponseHeaders(HttpResponseHeaders*, ClientSocket*) + { + return NO_GETZIP_CONNECTION; + } + ; + virtual void StopGetZipConnection(ClientSocket*) + { + } + ; + virtual void OpenGetZipConnection(ClientSocket*) + { + } + ; + +private: + DISALLOW_COPY_AND_ASSIGN(GetZipManager); +}; + +//This class is used to initialize GetZip manager +//First tries to initialize GetZipManager from proprietary library, +//if the library does not exist, creates GetZipManager +//Note: In the current implementation of network stack all the actions +//related to GetZipManager and GetZipFactory are carried out via IOThread +//hence, the implementation is not synchronized (this might change in the future). +class HttpGetZipFactory +{ + +public: + + //GetZipManager is kept within HttpGetZipFactory, + //which is singleton. + //This method is used to access the GetZipManager + //Don't use it before initializing HttpGetZipFactory object. + static IGetZipManager* GetGETZipManager(); + + //Initialization must be called before accessing + //GetZipManager for the first time. + static void InitGETZipManager(); + + void StopGETZipManager(); + +private: + IGetZipManager* m_pMngr; + static HttpGetZipFactory* s_pFactory; + + void* libHandle; + + HttpGetZipFactory(); + ~HttpGetZipFactory(); + + DISALLOW_COPY_AND_ASSIGN(HttpGetZipFactory); +}; + +}; //end network +#endif /* HTTP_GETZIP_FACTORY_H_ */ diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc index 8253eac..5e212b2 100644 --- a/net/http/http_network_layer.cc +++ b/net/http/http_network_layer.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,6 +11,7 @@ #include "base/string_util.h" #include "net/http/http_network_session.h" #include "net/http/http_network_transaction.h" +#include "net/http/http_getzip_factory.h" #include "net/spdy/spdy_framer.h" #include "net/spdy/spdy_session.h" #include "net/spdy/spdy_session_pool.h" @@ -21,6 +23,7 @@ HttpNetworkLayer::HttpNetworkLayer(HttpNetworkSession* session) : session_(session), suspended_(false) { DCHECK(session_.get()); + HttpGetZipFactory::InitGETZipManager(); } HttpNetworkLayer::~HttpNetworkLayer() { diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index d13ec97..d36f22a 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -39,7 +40,8 @@ HttpNetworkSession::HttpNetworkSession(const Params& params) params.dns_cert_checker, params.ssl_host_info_factory, params.proxy_service, - params.ssl_config_service), + params.ssl_config_service, + this), spdy_session_pool_(params.host_resolver, params.ssl_config_service), ALLOW_THIS_IN_INITIALIZER_LIST(http_stream_factory_( new HttpStreamFactoryImpl(this))) { diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 7f0ac4f..7ef80f7 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -54,6 +55,7 @@ #include "net/spdy/spdy_http_stream.h" #include "net/spdy/spdy_session.h" #include "net/spdy/spdy_session_pool.h" +#include using base::Time; @@ -245,8 +247,17 @@ int HttpNetworkTransaction::RestartWithAuth( void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { DCHECK(HaveAuth(target)); - DCHECK(!stream_request_.get()); + PrepareForRetry(true); +} + +void HttpNetworkTransaction::PrepareForGetZipRetry() +{ + PrepareForRetry(false); +} +void HttpNetworkTransaction::PrepareForRetry(bool isForAuthentication) +{ + DCHECK(!stream_request_.get()); bool keep_alive = false; // Even if the server says the connection is keep-alive, we have to be // able to find the end of each response in order to reuse the connection. @@ -254,8 +265,10 @@ void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { stream_->CanFindEndOfResponse()) { // If the response body hasn't been completely read, we need to drain // it first. + // goes to drain body first!!! if (!stream_->IsResponseBodyComplete()) { - next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; + next_state_ = isForAuthentication ? STATE_DRAIN_BODY_FOR_AUTH_RESTART: + STATE_DRAIN_BODY_FOR_GETZIP_RETRY; read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket. read_buf_len_ = kDrainBodyBufferSize; return; @@ -265,35 +278,58 @@ void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { // We don't need to drain the response body, so we act as if we had drained // the response body. - DidDrainBodyForAuthRestart(keep_alive); + isForAuthentication ? + DidDrainBodyForAuthRestart(keep_alive): + DidDrainBodyForGetZipRetry(keep_alive); } -void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { - DCHECK(!stream_request_.get()); +void HttpNetworkTransaction::DidDrainBodyForAuthRestart( bool keep_alive ) + { - if (stream_.get()) { + DidDrainBodyForRetry( keep_alive ); + // Reset the other member variables. + ResetStateForAuthRestart(); + } + +void HttpNetworkTransaction::DidDrainBodyForGetZipRetry( bool keep_alive ) +{ + DidDrainBodyForRetry( keep_alive ); + read_buf_ = NULL; + read_buf_len_ = 0; + headers_valid_ = false; + request_headers_.Clear(); + response_ = HttpResponseInfo(); +} + +void HttpNetworkTransaction::DidDrainBodyForRetry( bool keep_alive ) +{ + DCHECK( !stream_request_.get() ); + + if ( stream_.get() ) + { HttpStream* new_stream = NULL; - if (keep_alive && stream_->IsConnectionReusable()) { + if ( keep_alive && stream_->IsConnectionReusable() ) + { // We should call connection_->set_idle_time(), but this doesn't occur // often enough to be worth the trouble. stream_->SetConnectionReused(); new_stream = stream_->RenewStreamForAuth(); } - if (!new_stream) { + if ( !new_stream ) + { // Close the stream and mark it as not_reusable. Even in the // keep_alive case, we've determined that the stream_ is not // reusable if new_stream is NULL. - stream_->Close(true); + stream_->Close( true ); next_state_ = STATE_CREATE_STREAM; - } else { + } + else + { next_state_ = STATE_INIT_STREAM; } - stream_.reset(new_stream); + stream_.reset( new_stream ); } - - // Reset the other member variables. - ResetStateForAuthRestart(); } bool HttpNetworkTransaction::IsReadyToRestartForAuth() { @@ -559,6 +595,13 @@ int HttpNetworkTransaction::DoLoop(int result) { net_log_.EndEventWithNetErrorCode( NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, rv); break; + case STATE_DRAIN_BODY_FOR_GETZIP_RETRY: + DCHECK_EQ(OK, rv); + rv = DoDrainBodyForGetZipRetry(); + break; + case STATE_DRAIN_BODY_FOR_GETZIP_RETRY_COMPLETE: + rv = DoDrainBodyForGetZipRetryComplete(rv); + break; case STATE_DRAIN_BODY_FOR_AUTH_RESTART: DCHECK_EQ(OK, rv); net_log_.BeginEvent( @@ -963,9 +1006,28 @@ int HttpNetworkTransaction::DoDrainBodyForAuthRestart() { return rv; } +int HttpNetworkTransaction::DoDrainBodyForGetZipRetry() { + int rv = DoReadBody(); + DCHECK(next_state_ == STATE_READ_BODY_COMPLETE); + next_state_ = STATE_DRAIN_BODY_FOR_GETZIP_RETRY_COMPLETE; + return rv; +} + +int HttpNetworkTransaction::DoDrainBodyForGetZipRetryComplete(int result) { + DoDrainBodyForRetryComplete( result, false ); + return OK; +} + // TODO(wtc): This method and the DoReadBodyComplete method are almost // the same. Figure out a good way for these two methods to share code. int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) { + DoDrainBodyForRetryComplete( result, true ); + return OK; +} + +void HttpNetworkTransaction::DoDrainBodyForRetryComplete( int result, + bool isForAuthentication ) +{ // keep_alive defaults to true because the very reason we're draining the // response body is to reuse the connection for auth restart. bool done = false, keep_alive = true; @@ -978,13 +1040,15 @@ int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) { } if (done) { - DidDrainBodyForAuthRestart(keep_alive); + isForAuthentication ? + DidDrainBodyForAuthRestart(keep_alive): + DidDrainBodyForGetZipRetry(keep_alive); } else { // Keep draining. - next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; + next_state_ = isForAuthentication ? + STATE_DRAIN_BODY_FOR_AUTH_RESTART : + STATE_DRAIN_BODY_FOR_GETZIP_RETRY ; } - - return OK; } void HttpNetworkTransaction::LogTransactionConnectedMetrics() { @@ -1190,8 +1254,12 @@ int HttpNetworkTransaction::HandleIOError(int error) { // cause SSL handshake errors to be delayed until the first or second Write // (Snap Start) or the first Read (False & Snap Start) on the underlying // connection. - error = HandleSSLHandshakeError(error); - + if(error != ERR_GETZIP) + error = HandleSSLHandshakeError(error); + else + { + SLOGD("%s:%s:: SHUTR protocol failure", __FILE__, __FUNCTION__); + } switch (error) { // If we try to reuse a connection that the server is in the process of // closing, we may end up successfully writing out our request (or a @@ -1209,6 +1277,10 @@ int HttpNetworkTransaction::HandleIOError(int error) { ResetConnectionAndRequestForResend(); error = OK; break; + case ERR_GETZIP: + PrepareForGetZipRetry(); + error = OK; + break; } return error; } @@ -1338,6 +1410,8 @@ std::string HttpNetworkTransaction::DescribeState(State state) { STATE_CASE(STATE_READ_HEADERS_COMPLETE); STATE_CASE(STATE_READ_BODY); STATE_CASE(STATE_READ_BODY_COMPLETE); + STATE_CASE(STATE_DRAIN_BODY_FOR_GETZIP_RETRY); + STATE_CASE(STATE_DRAIN_BODY_FOR_GETZIP_RETRY_COMPLETE); STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART); STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE); STATE_CASE(STATE_NONE); diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 00e9a65..7abfcf9 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -102,6 +103,8 @@ class HttpNetworkTransaction : public HttpTransaction, STATE_READ_HEADERS_COMPLETE, STATE_READ_BODY, STATE_READ_BODY_COMPLETE, + STATE_DRAIN_BODY_FOR_GETZIP_RETRY, + STATE_DRAIN_BODY_FOR_GETZIP_RETRY_COMPLETE, STATE_DRAIN_BODY_FOR_AUTH_RESTART, STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE, STATE_NONE @@ -137,6 +140,9 @@ class HttpNetworkTransaction : public HttpTransaction, int DoReadBodyComplete(int result); int DoDrainBodyForAuthRestart(); int DoDrainBodyForAuthRestartComplete(int result); + int DoDrainBodyForGetZipRetry(); + int DoDrainBodyForGetZipRetryComplete(int result); + void DoDrainBodyForRetryComplete( int result, bool isForAuthentication ); void BuildRequestHeaders(bool using_proxy); @@ -182,10 +188,28 @@ class HttpNetworkTransaction : public HttpTransaction, // Sets up the state machine to restart the transaction with auth. void PrepareForAuthRestart(HttpAuth::Target target); + // Sets up the state machine to restart the transaction if + // GETzip error occurred. + void PrepareForGetZipRetry(); + + // Sets up the state machine to restart the transaction. + void PrepareForRetry(bool isForAuthentication); + // Called when we don't need to drain the response body or have drained it. + // Clears request info for transaction restart for auth. + // Uses DidDrainBodyForRetry to reset connection if needed and to + // set next_state_ + void DidDrainBodyForAuthRestart(bool keep_alive); + + // Called when we don't need to drain the response body or have drained it. + // Clears request info for transaction retry caused by GETzip error. + // Uses DidDrainBodyForRetry to reset connection if needed and to + // set next_state_ + void DidDrainBodyForGetZipRetry(bool keep_alive); + // Resets |connection_| unless |keep_alive| is true, then calls // ResetStateForRestart. Sets |next_state_| appropriately. - void DidDrainBodyForAuthRestart(bool keep_alive); + void DidDrainBodyForRetry( bool keep_alive ); // Resets the members of the transaction so it can be restarted. void ResetStateForRestart(); diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc index c28d0e6..94a51e1 100644 --- a/net/http/http_proxy_client_socket_pool.cc +++ b/net/http/http_proxy_client_socket_pool.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -425,7 +426,8 @@ HttpProxyClientSocketPool::HttpProxyClientSocketPool( HostResolver* host_resolver, TransportClientSocketPool* transport_pool, SSLClientSocketPool* ssl_pool, - NetLog* net_log) + NetLog* net_log, + HttpNetworkSession *network_session) : transport_pool_(transport_pool), ssl_pool_(ssl_pool), base_(max_sockets, max_sockets_per_group, histograms, @@ -435,7 +437,8 @@ HttpProxyClientSocketPool::HttpProxyClientSocketPool( new HttpProxyConnectJobFactory(transport_pool, ssl_pool, host_resolver, - net_log)) {} + net_log), + network_session) {} HttpProxyClientSocketPool::~HttpProxyClientSocketPool() {} diff --git a/net/http/http_proxy_client_socket_pool.h b/net/http/http_proxy_client_socket_pool.h index 2ab331e..c539ede 100644 --- a/net/http/http_proxy_client_socket_pool.h +++ b/net/http/http_proxy_client_socket_pool.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -31,6 +32,7 @@ class SpdySessionPool; class SpdyStream; class TransportClientSocketPool; class TransportSocketParams; +class HttpNetworkSession; // HttpProxySocketParams only needs the socket params for one of the proxy // types. The other param must be NULL. When using an HTTP Proxy, @@ -179,7 +181,8 @@ class HttpProxyClientSocketPool : public ClientSocketPool { HostResolver* host_resolver, TransportClientSocketPool* transport_pool, SSLClientSocketPool* ssl_pool, - NetLog* net_log); + NetLog* net_log, + HttpNetworkSession *network_session); virtual ~HttpProxyClientSocketPool(); diff --git a/net/http/http_request_headers.cc b/net/http/http_request_headers.cc index 9d523c1..9cb3a83 100644 --- a/net/http/http_request_headers.cc +++ b/net/http/http_request_headers.cc @@ -1,4 +1,5 @@ // Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,6 +13,7 @@ namespace net { const char HttpRequestHeaders::kGetMethod[] = "GET"; +const char HttpRequestHeaders::kHeadMethod[] = "HEAD"; const char HttpRequestHeaders::kAcceptCharset[] = "Accept-Charset"; const char HttpRequestHeaders::kAcceptEncoding[] = "Accept-Encoding"; const char HttpRequestHeaders::kAcceptLanguage[] = "Accept-Language"; diff --git a/net/http/http_request_headers.h b/net/http/http_request_headers.h index d574ae4..e130ab1 100644 --- a/net/http/http_request_headers.h +++ b/net/http/http_request_headers.h @@ -1,4 +1,5 @@ // Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -55,6 +56,7 @@ class NET_EXPORT HttpRequestHeaders { }; static const char kGetMethod[]; + static const char kHeadMethod[]; static const char kAcceptCharset[]; static const char kAcceptEncoding[]; diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc index 0649bce..5d0d9ed 100644 --- a/net/http/http_stream_parser.cc +++ b/net/http/http_stream_parser.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,13 +19,15 @@ #include "net/http/http_util.h" #include "net/socket/ssl_client_socket.h" #include "net/socket/client_socket_handle.h" +#include "net/http/http_getzip_factory.h" namespace net { HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, const HttpRequestInfo* request, GrowableIOBuffer* read_buffer, - const BoundNetLog& net_log) + const BoundNetLog& net_log, + bool using_proxy) : io_state_(STATE_NONE), request_(request), request_headers_(NULL), @@ -44,7 +47,10 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, io_callback_(this, &HttpStreamParser::OnIOComplete)), chunk_length_(0), chunk_length_without_encoding_(0), - sent_last_chunk_(false) { + sent_last_chunk_(false), + using_proxy_(using_proxy), + has_to_retry_(false){ + DCHECK_EQ(0, read_buffer->offset()); } @@ -62,7 +68,7 @@ int HttpStreamParser::SendRequest(const std::string& request_line, DCHECK(!user_callback_); DCHECK(callback); DCHECK(response); - + has_to_retry_ = false; if (net_log_.IsLoggingAllEvents()) { net_log_.AddEvent( NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS, @@ -78,6 +84,15 @@ int HttpStreamParser::SendRequest(const std::string& request_line, return result; response_->socket_address = HostPortPair::FromAddrInfo(address.head()); + //Shutr only for GET/HEAD requests + if((!(using_proxy_)) && ((request_line.find(HttpRequestHeaders::kGetMethod) == 0) || + (request_line.find(HttpRequestHeaders::kHeadMethod) == 0))) + { + HttpGetZipFactory::GetGETZipManager()->CompressRequestHeaders( + const_cast(headers), + connection_->socket()); + } + std::string request = request_line + headers.ToString(); scoped_refptr headers_io_buf(new StringIOBuffer(request)); request_headers_ = new DrainableIOBuffer(headers_io_buf, @@ -161,6 +176,11 @@ void HttpStreamParser::OnIOComplete(int result) { if (result != ERR_IO_PENDING && user_callback_) { CompletionCallback* c = user_callback_; user_callback_ = NULL; + if(has_to_retry_ ) + { + result = ERR_GETZIP; + has_to_retry_ = false; + } c->Run(result); } } @@ -201,8 +221,19 @@ int HttpStreamParser::DoLoop(int result) { break; case STATE_READ_HEADERS_COMPLETE: result = DoReadHeadersComplete(result); + if(!using_proxy_) + { + GETZipDecompressionStatus st = + HttpGetZipFactory::GetGETZipManager()->DecompressResponseHeaders( + response_->headers.get(), + connection_->socket()); + if( st == REQUEST_RETRY_NEEDED ) + { + has_to_retry_ = true; + } + } net_log_.EndEventWithNetErrorCode( - NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS, result); + NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS, result); break; case STATE_BODY_PENDING: DCHECK(result != ERR_IO_PENDING); diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h index 2192eff..fa3e6fc 100644 --- a/net/http/http_stream_parser.h +++ b/net/http/http_stream_parser.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -36,7 +37,9 @@ class HttpStreamParser : public ChunkCallback { HttpStreamParser(ClientSocketHandle* connection, const HttpRequestInfo* request, GrowableIOBuffer* read_buffer, - const BoundNetLog& net_log); + const BoundNetLog& net_log, + bool using_proxy = false); + ~HttpStreamParser(); // These functions implement the interface described in HttpStream with @@ -186,6 +189,10 @@ class HttpStreamParser : public ChunkCallback { // The underlying socket. ClientSocketHandle* const connection_; + bool using_proxy_; + + bool has_to_retry_; + BoundNetLog net_log_; // Callback to be used when doing IO. diff --git a/net/http/net-plugin-bridge-exports.h b/net/http/net-plugin-bridge-exports.h new file mode 100644 index 0000000..773602a --- /dev/null +++ b/net/http/net-plugin-bridge-exports.h @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2011, Code Aurora Forum. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// API for the network plug-in +#ifndef NET_HTTP_NET_PLUGIN_BRIDGE_EXPORTS_H_ +#define NET_HTTP_NET_PLUGIN_BRIDGE_EXPORTS_H_ + +// export these functions from libwebcore, may be used by the plug-in +extern bool HeadersIsRedirect(const net::HttpResponseHeaders* h, std::string& s) + __attribute__ ((visibility ("default"), used)); +extern GURL GurlResolveOrigin(const net::HttpRequestInfo* req, std::string& s) + __attribute__ ((visibility ("default"), used)); +extern GURL GurlOrigin(const net::HttpRequestInfo* req) + __attribute__ ((visibility ("default"), used)); +extern void NetPreconnect(net::HttpNetworkSession*, GURL const&) + __attribute__ ((visibility ("default"), used)); + +#endif /* NET_HTTP_NET_PLUGIN_BRIDGE_EXPORTS_H_ */ diff --git a/net/http/net-plugin-bridge.cc b/net/http/net-plugin-bridge.cc new file mode 100644 index 0000000..42019ca --- /dev/null +++ b/net/http/net-plugin-bridge.cc @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "net/http/http_cache_transaction.h" + +#include "build/build_config.h" + +#include + +#include + +#include "base/compiler_specific.h" +#include "net/http/http_response_headers.h" +#include "net/http/preconnect.h" + +#include "net/http/net-plugin-bridge.h" +#include "net/http/net-plugin-bridge-exports.h" +#include +#include + +static void (*DoObserveRevalidation)(const net::HttpResponseInfo* resp, + const net::HttpRequestInfo* req, net::HttpCache* cache) = NULL; + +static void InitOnce() { + static bool initialized = false; + if (!initialized) { + initialized = true; + void* fh = dlopen("qnet-plugin.so", RTLD_LAZY); + if (fh) { + const char *error; + + dlerror(); //see man dlopen + *(void **)(&DoObserveRevalidation) = dlsym(fh, "DoObserveRevalidation"); + if (NULL != (error = dlerror())) { + DoObserveRevalidation = NULL; + } + } + if (NULL == DoObserveRevalidation) { + SLOGD("Failed to load DoObserveRevalidation symbol in qnet-plugin.so"); + } + } +} + +void ObserveRevalidation(const net::HttpResponseInfo* resp, + const net::HttpRequestInfo* req, net::HttpCache* cache) { + InitOnce(); + if (DoObserveRevalidation) { + DoObserveRevalidation(resp, req, cache); + } +} + + +bool HeadersIsRedirect(const net::HttpResponseHeaders* headers, + std::string& location) { + return headers->IsRedirect(&location); +} + +GURL GurlResolveOrigin(const net::HttpRequestInfo* req, + std::string& location) { + return req->url.Resolve(location).GetOrigin(); +} + +GURL GurlOrigin(const net::HttpRequestInfo* req) { + return req->url.GetOrigin(); +} + +void NetPreconnect(net::HttpNetworkSession* session, GURL const& url) { + net::Preconnect::DoPreconnect(session, url); +} diff --git a/net/http/net-plugin-bridge.h b/net/http/net-plugin-bridge.h new file mode 100644 index 0000000..09f45e9 --- /dev/null +++ b/net/http/net-plugin-bridge.h @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2011, Code Aurora Forum. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef NET_HTTP_NET_PLUGIN_BRIDGE_H_ +#define NET_HTTP_NET_PLUGIN_BRIDGE_H_ + +// revalidated cache entries observer +extern void ObserveRevalidation(const net::HttpResponseInfo* resp, + const net::HttpRequestInfo* req, net::HttpCache* cache); + +#endif /* NET_HTTP_NET_PLUGIN_BRIDGE_H_ */ diff --git a/net/http/preconnect.cc b/net/http/preconnect.cc new file mode 100644 index 0000000..929b627 --- /dev/null +++ b/net/http/preconnect.cc @@ -0,0 +1,70 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. 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/http/preconnect.h" + +#include "base/logging.h" +#include "net/proxy/proxy_info.h" +#include "net/http/http_stream_factory.h" +#include "net/http/http_network_session.h" + +namespace net { + + +// static +void Preconnect::DoPreconnect(HttpNetworkSession* session, + const GURL& url, int count, + HttpRequestInfo::RequestMotivation motivation ) { + Preconnect* preconnect = new Preconnect(session); + preconnect->Connect(url, count, motivation); +} + +Preconnect::Preconnect(HttpNetworkSession* session) + : session_(session), + ALLOW_THIS_IN_INITIALIZER_LIST( + io_callback_(this, &Preconnect::OnPreconnectComplete)) {} + +Preconnect::~Preconnect() {} + +void Preconnect::Connect(const GURL& url, int count, + HttpRequestInfo::RequestMotivation motivation) { + + request_info_.reset(new HttpRequestInfo()); + request_info_->url = url; + request_info_->method = "GET"; + // It almost doesn't matter whether we use net::LOWEST or net::HIGHEST + // priority here, as we won't make a request, and will surrender the created + // socket to the pool as soon as we can. However, we would like to mark the + // speculative socket as such, and IF we use a net::LOWEST priority, and if + // a navigation asked for a socket (after us) then it would get our socket, + // and we'd get its later-arriving socket, which might make us record that + // the speculation didn't help :-/. By using net::HIGHEST, we ensure that + // a socket is given to us if "we asked first" and this allows us to mark it + // as speculative, and better detect stats (if it gets used). + // TODO(jar): histogram to see how often we accidentally use a previously- + // unused socket, when a previously used socket was available. + request_info_->priority = HIGHEST; + request_info_->motivation = motivation; + + // Setup the SSL Configuration. + ssl_config_.reset(new SSLConfig()); + session_->ssl_config_service()->GetSSLConfig(ssl_config_.get()); + if (session_->http_stream_factory()->next_protos()) + ssl_config_->next_protos = *session_->http_stream_factory()->next_protos(); + + // All preconnects should perform EV certificate verification. + ssl_config_->verify_ev_cert = true; + + proxy_info_.reset(new ProxyInfo()); + HttpStreamFactory* stream_factory = session_->http_stream_factory(); + stream_factory->PreconnectStreams(count, *(request_info_.get()), + *(ssl_config_.get()), net_log_); +} + +void Preconnect::OnPreconnectComplete(int error_code) { + delete this; +} + +} // namespace net diff --git a/net/http/preconnect.h b/net/http/preconnect.h new file mode 100644 index 0000000..e7e1914 --- /dev/null +++ b/net/http/preconnect.h @@ -0,0 +1,66 @@ +// Copyright (c) 2006-2010 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. + +// A Preconnect instance maintains state while a TCP/IP connection is made, and +// and then released into the pool of available connections for future use. + +#ifndef NET_HTTP_PRECONNECT_H__ +#define NET_HTTP_PRECONNECT_H__ +#pragma once + +#include "base/scoped_ptr.h" +#include "net/base/completion_callback.h" +#include "net/base/net_log.h" +#include "net/http/http_request_info.h" +#include "net/http/http_stream_factory.h" + +namespace net { + +class ProxyInfo; +struct SSLConfig; + +class Preconnect { + public: + // Try to preconnect. Typically used by predictor when a subresource probably + // needs a connection. |count| may be used to request more than one connection + // be established in parallel. + static void DoPreconnect(HttpNetworkSession* session, const GURL& url, + int count = 1, HttpRequestInfo::RequestMotivation motivation = + HttpRequestInfo::PRECONNECT_MOTIVATED); + + private: + explicit Preconnect(HttpNetworkSession* session); + virtual ~Preconnect(); + + void OnPreconnectComplete(int error_code); + + // Request actual connection, via interface that tags request as needed for + // preconnect only (so that they can be merged with connections needed for + // navigations). + void Connect(const GURL& url, int count, + HttpRequestInfo::RequestMotivation motivation); + + HttpNetworkSession * session_; + // HttpRequestInfo used for connecting. + scoped_ptr request_info_; + + // SSLConfig used for connecting. + scoped_ptr ssl_config_; + + // ProxyInfo used for connecting. + scoped_ptr proxy_info_; + + // A net log to use for this preconnect. + BoundNetLog net_log_; + + // Our preconnect. + scoped_ptr stream_request_; + + CompletionCallbackImpl io_callback_; + + DISALLOW_COPY_AND_ASSIGN(Preconnect); +}; +} // namespace net +#endif // NET_HTTP_HTTP_REQUEST_INFO_H__ + diff --git a/net/http/tcp-connections-bridge-exports.h b/net/http/tcp-connections-bridge-exports.h new file mode 100644 index 0000000..3d873cd --- /dev/null +++ b/net/http/tcp-connections-bridge-exports.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// API for the network plug-in +#ifndef NET_HTTP_TCP_CONNECTIONS_BRIDGE_EXPORTS_H_ +#define NET_HTTP_TCP_CONNECTIONS_BRIDGE_EXPORTS_H_ + +// export these functions from libwebcore, may be used by the plug-in +extern void NetPreconnect(net::HttpNetworkSession*, GURL const&, int numOfConnections) + __attribute__ ((visibility ("default"), used)); + +#endif /* NET_HTTP_NET_PLUGIN_BRIDGE_EXPORTS_H_ */ diff --git a/net/http/tcp-connections-bridge.cc b/net/http/tcp-connections-bridge.cc new file mode 100644 index 0000000..3201b3d --- /dev/null +++ b/net/http/tcp-connections-bridge.cc @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011, 2012 Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "build/build_config.h" + +#include + +#include + +#include "base/compiler_specific.h" +#include "net/http/http_response_headers.h" +#include "net/http/preconnect.h" + +#include "net/http/tcp-connections-bridge.h" +#include "net/http/tcp-connections-bridge-exports.h" +#include "net/http/http_network_session.h" +#include +#include + +static void (*DoObserveConnections)( + net::HttpNetworkSession* session, + const GURL& url) = NULL; + +static void InitOnce() { + static bool initialized = false; + if (!initialized) { + initialized = true; + void* fh = dlopen("tcp-connections.so", RTLD_LAZY); + if (fh) { + dlerror(); //see man dlopen + *(void **)(&DoObserveConnections) = dlsym(fh, "DoObserveConnections"); + } + if (NULL == DoObserveConnections) { + SLOGD("Failed to load DoObserveConnections symbol in tcp-connections.so"); + } + } +} + +void ObserveConnections( + net::HttpNetworkSession *session, + const GURL& url +) +{ + InitOnce(); + if (DoObserveConnections) { + DoObserveConnections(session, url); + } +} + +void NetPreconnect(net::HttpNetworkSession* session, GURL const& url, int numOfConnections) { + net::Preconnect::DoPreconnect(session, url, numOfConnections); +} diff --git a/net/http/tcp-connections-bridge.h b/net/http/tcp-connections-bridge.h new file mode 100644 index 0000000..94f5501 --- /dev/null +++ b/net/http/tcp-connections-bridge.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NET_HTTP_TCP_CONNECTIONS_BRIDGE_H_ +#define NET_HTTP_TCP_CONNECTIONS_BRIDGE_H_ + +// revalidated cache entries observer +extern void ObserveConnections +( + net::HttpNetworkSession *session, + const GURL& url +); + +#endif /* NET_HTTP_NET_PLUGIN_BRIDGE_H_ */ diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc index 46cfc45..f0d9c2c 100644 --- a/net/socket/client_socket_pool_base.cc +++ b/net/socket/client_socket_pool_base.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011,2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -15,6 +16,15 @@ #include "net/base/net_log.h" #include "net/base/net_errors.h" #include "net/socket/client_socket_handle.h" +#include "net/http/http_network_session.h" +#include "net/http/preconnect.h" +#include "net/http/tcp-connections-bridge.h" +#include "googleurl/src/gurl.h" +#include +#include + +// Define Log Tag for this source file. +#define LOG_TAG "Socket_Pool" using base::TimeDelta; @@ -34,12 +44,23 @@ bool g_cleanup_timer_enabled = true; // Note: It's important to close idle sockets that have received data as soon // as possible because the received data may cause BSOD on Windows XP under // some conditions. See http://crbug.com/4606. -const int kCleanupInterval = 10; // DO NOT INCREASE THIS TIMEOUT. +int kCleanupInterval = 2; // DO NOT INCREASE THIS TIMEOUT. // Indicate whether or not we should establish a new transport layer connection // after a certain timeout has passed without receiving an ACK. bool g_connect_backup_jobs_enabled = true; +// Indicate whether or not we should close the unused sockets in the next run +// of the reaper cleanup thread. +bool g_close_unused_sockets = false; + +// Called to inform that we should close the unused sockets that resides in +// the idle pool. +extern "C" void SetCloseUnUsedSocketsFlag() +{ + g_close_unused_sockets = true; +} + } // namespace namespace net { @@ -166,7 +187,8 @@ ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper( int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, base::TimeDelta used_idle_socket_timeout, - ConnectJobFactory* connect_job_factory) + ConnectJobFactory* connect_job_factory, + HttpNetworkSession *network_session) : idle_socket_count_(0), connecting_socket_count_(0), handed_out_socket_count_(0), @@ -183,6 +205,31 @@ ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper( DCHECK_LE(max_sockets_per_group, max_sockets); NetworkChangeNotifier::AddIPAddressObserver(this); + + network_session_ = network_session; + + tcp_fin_aggregation = net::TCPFinAggregationFactory::GetTCPFinFactoryInstance(this)->GetTCPFinAggregation(); + if (NULL == tcp_fin_aggregation) { + SLOGD("Failed to create TCP Fin Aggregation interface."); + } else { + int new_cleanup_interval = tcp_fin_aggregation->GetCleanupInterval(kCleanupInterval); + kCleanupInterval = new_cleanup_interval; + } + + close_unused_sockets_enabled = false; + char netCloseUnusedSocketsSystemProperty[PROPERTY_VALUE_MAX]; + if(property_get("net.close.unused.sockets", + netCloseUnusedSocketsSystemProperty, "1")) { + close_unused_sockets_enabled = (bool)atoi(netCloseUnusedSocketsSystemProperty); + } + SLOGD("netstack: CloseUnusedSockets is %s", close_unused_sockets_enabled?"ON":"OFF"); + + char net_statistics_enabled_sys_property[PROPERTY_VALUE_MAX]; + if(property_get("net.statistics", + net_statistics_enabled_sys_property, "0")) { + net_statistics_enabled = (bool)atoi(net_statistics_enabled_sys_property); + SLOGD("netstack: system net.statistics value: %d", net_statistics_enabled); + } } ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { @@ -229,8 +276,9 @@ int ClientSocketPoolBaseHelper::RequestSocket( CHECK(request->handle()); // Cleanup any timed-out idle sockets if no timer is used. - if (!use_cleanup_timer_) + if ((!use_cleanup_timer_) && ((NULL == tcp_fin_aggregation) || (((NULL != tcp_fin_aggregation) && !tcp_fin_aggregation->IsEnabled())))) { CleanupIdleSockets(false); + } request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); Group* group = GetOrCreateGroup(group_name); @@ -242,6 +290,9 @@ int ClientSocketPoolBaseHelper::RequestSocket( delete request; } else { InsertRequestIntoQueue(request, group->mutable_pending_requests()); + if (net_statistics_enabled) { + SLOGD("insertRequestToQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } } return rv; } @@ -254,8 +305,9 @@ void ClientSocketPoolBaseHelper::RequestSockets( DCHECK(!request.handle()); // Cleanup any timed out idle sockets if no timer is used. - if (!use_cleanup_timer_) + if ((!use_cleanup_timer_) && ((NULL == tcp_fin_aggregation) || (((NULL != tcp_fin_aggregation) && !tcp_fin_aggregation->IsEnabled())))) { CleanupIdleSockets(false); + } if (num_sockets > max_sockets_per_group_) { num_sockets = max_sockets_per_group_; @@ -273,7 +325,7 @@ void ClientSocketPoolBaseHelper::RequestSockets( int rv = OK; for (int num_iterations_left = num_sockets; - group->NumActiveSocketSlots() < num_sockets && + group->NumActiveSocketSlots() <= num_sockets && num_iterations_left > 0 ; num_iterations_left--) { rv = RequestSocketInternal(group_name, &request); if (rv < 0 && rv != ERR_IO_PENDING) { @@ -382,6 +434,20 @@ int ClientSocketPoolBaseHelper::RequestSocketInternal( } } + if (!preconnecting) { + std::string url; + const int ssl_sockets_groupname_prefix_length_ = 4; + if (0 == group_name.compare(0, ssl_sockets_groupname_prefix_length_ , "ssl/")) { + url.append("https://"); + }else { + url.append("http://"); + } + url.append(group_name); + GURL gurl = GURL(url); + + ObserveConnections(network_session_, gurl); + } + return rv; } @@ -420,7 +486,7 @@ bool ClientSocketPoolBaseHelper::AssignIdleSocketToGroup( if (idle_socket_it != idle_sockets->end()) { DecrementIdleCount(); base::TimeDelta idle_time = - base::TimeTicks::Now() - idle_socket_it->start_time; + base::Time::Now() - idle_socket_it->start_time; IdleSocket idle_socket = *idle_socket_it; idle_sockets->erase(idle_socket_it); HandOutSocket( @@ -471,6 +537,9 @@ void ClientSocketPoolBaseHelper::CancelRequest( scoped_ptr req(RemoveRequestFromQueue(it, group)); req->net_log().AddEvent(NetLog::TYPE_CANCELLED, NULL); req->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); + if (net_statistics_enabled) { + SLOGD("removeRequestFromQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } // We let the job run, unless we're at the socket limit. if (group->jobs().size() && ReachedMaxSocketsLimit()) { @@ -595,8 +664,8 @@ DictionaryValue* ClientSocketPoolBaseHelper::GetInfoAsValue( return dict; } -bool ClientSocketPoolBaseHelper::IdleSocket::ShouldCleanup( - base::TimeTicks now, +bool IdleSocket::ShouldCleanup( + base::Time now, base::TimeDelta timeout) const { bool timed_out = (now - start_time) >= timeout; if (timed_out) @@ -607,12 +676,13 @@ bool ClientSocketPoolBaseHelper::IdleSocket::ShouldCleanup( } void ClientSocketPoolBaseHelper::CleanupIdleSockets(bool force) { - if (idle_socket_count_ == 0) + if (idle_socket_count_ == 0) { return; + } // Current time value. Retrieving it once at the function start rather than // inside the inner loop, since it shouldn't change by any meaningful amount. - base::TimeTicks now = base::TimeTicks::Now(); + base::Time now = base::Time::Now(); GroupMap::iterator i = group_map_.begin(); while (i != group_map_.end()) { @@ -623,7 +693,8 @@ void ClientSocketPoolBaseHelper::CleanupIdleSockets(bool force) { base::TimeDelta timeout = j->socket->WasEverUsed() ? used_idle_socket_timeout_ : unused_idle_socket_timeout_; - if (force || j->ShouldCleanup(now, timeout)) { + if (force || j->ShouldCleanup(now, timeout) || + ((true == close_unused_sockets_enabled) && (true == g_close_unused_sockets) && !j->socket->WasEverUsed())) { delete j->socket; j = group->mutable_idle_sockets()->erase(j); DecrementIdleCount(); @@ -685,8 +756,21 @@ void ClientSocketPoolBaseHelper::IncrementIdleCount() { } void ClientSocketPoolBaseHelper::DecrementIdleCount() { - if (--idle_socket_count_ == 0) + if (--idle_socket_count_ == 0) { timer_.Stop(); + } +} + +void ClientSocketPoolBaseHelper::OnCleanupTimerFired() +{ + if((NULL != tcp_fin_aggregation) && + (tcp_fin_aggregation->IsEnabled())) { + tcp_fin_aggregation->ReaperCleanup(g_close_unused_sockets); + } + else { + CleanupIdleSockets(false); + } + g_close_unused_sockets = false; } // static @@ -814,6 +898,9 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete( base::TimeDelta(), group, r->net_log()); r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); InvokeUserCallbackLater(r->handle(), r->callback(), result); + if (net_statistics_enabled) { + SLOGD("removeRequestFromQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } } else { AddIdleSocket(socket.release(), group); OnAvailableSocketSlot(group_name, group); @@ -837,6 +924,9 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete( r->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, result); InvokeUserCallbackLater(r->handle(), r->callback(), result); + if (net_statistics_enabled) { + SLOGD("removeRequestFromQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } } else { RemoveConnectJob(job, group); } @@ -897,6 +987,9 @@ void ClientSocketPoolBaseHelper::ProcessPendingRequest( request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); InvokeUserCallbackLater(request->handle(), request->callback(), rv); + if (net_statistics_enabled) { + SLOGD("removeRequestFromQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } } } @@ -933,7 +1026,7 @@ void ClientSocketPoolBaseHelper::AddIdleSocket( DCHECK(socket); IdleSocket idle_socket; idle_socket.socket = socket; - idle_socket.start_time = base::TimeTicks::Now(); + idle_socket.start_time = base::Time::Now(); group->mutable_idle_sockets()->push_back(idle_socket); IncrementIdleCount(); diff --git a/net/socket/client_socket_pool_base.h b/net/socket/client_socket_pool_base.h index bd30a8b..ce759a0 100644 --- a/net/socket/client_socket_pool_base.h +++ b/net/socket/client_socket_pool_base.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011,2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -18,7 +19,6 @@ // implementing ConnectJob::ConnectInternal(). They can control the parameters // passed to each new ConnectJob instance via their ConnectJobFactory subclass // and templated SocketParams parameter. -// #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ #pragma once @@ -44,10 +44,15 @@ #include "net/base/request_priority.h" #include "net/socket/client_socket.h" #include "net/socket/client_socket_pool.h" +#include "net/base/host_resolver.h" +#include "tcp_fin_aggregation.h" +#include "tcp_fin_aggregation_factory.h" namespace net { class ClientSocketHandle; +class HttpNetworkSession; +class ITCPFinAggregation; // ConnectJob provides an abstract interface for "connecting" a socket. // The connection may involve host resolution, tcp connection, ssl connection, @@ -149,6 +154,29 @@ class ConnectJob { namespace internal { + // Entry for a persistent socket which became idle at time |start_time|. + class IdleSocket { + public: + IdleSocket() : socket(NULL) {} + ClientSocket* socket; + base::Time start_time; + + // An idle socket should be removed if it can't be reused, or has been idle + // for too long. |now| is the current time value (TimeTicks::Now()). + // |timeout| is the length of time to wait before timing out an idle socket. + // + // An idle socket can't be reused if it is disconnected or has received + // data unexpectedly (hence no longer idle). The unread data would be + // mistaken for the beginning of the next response if we were to reuse the + // socket for a new request. + bool ShouldCleanup(base::Time now, base::TimeDelta timeout) const; + + base::Time StartTime() const + { + return start_time; + } + }; + // ClientSocketPoolBaseHelper is an internal class that implements almost all // the functionality from ClientSocketPoolBase without using templates. // ClientSocketPoolBase adds templated definitions built on top of @@ -224,7 +252,8 @@ class ClientSocketPoolBaseHelper int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, base::TimeDelta used_idle_socket_timeout, - ConnectJobFactory* connect_job_factory); + ConnectJobFactory* connect_job_factory, + HttpNetworkSession *network_session); ~ClientSocketPoolBaseHelper(); @@ -258,6 +287,18 @@ class ClientSocketPoolBaseHelper return idle_socket_count_; } + // Called when the number of idle sockets changes. + void IncrementIdleCount(); + void DecrementIdleCount(); + + class Group; + typedef std::map GroupMap; + + void RemoveGroup(const std::string& group_name); + void RemoveGroup(GroupMap::iterator it); + + GroupMap group_map_; + // See ClientSocketPool::IdleSocketCountInGroup() for documentation on this // function. int IdleSocketCountInGroup(const std::string& group_name) const; @@ -313,29 +354,9 @@ class ClientSocketPoolBaseHelper // NetworkChangeNotifier::IPAddressObserver methods: virtual void OnIPAddressChanged(); - private: - friend class base::RefCounted; - - // Entry for a persistent socket which became idle at time |start_time|. - struct IdleSocket { - IdleSocket() : socket(NULL) {} - - // An idle socket should be removed if it can't be reused, or has been idle - // for too long. |now| is the current time value (TimeTicks::Now()). - // |timeout| is the length of time to wait before timing out an idle socket. - // - // An idle socket can't be reused if it is disconnected or has received - // data unexpectedly (hence no longer idle). The unread data would be - // mistaken for the beginning of the next response if we were to reuse the - // socket for a new request. - bool ShouldCleanup(base::TimeTicks now, base::TimeDelta timeout) const; - - ClientSocket* socket; - base::TimeTicks start_time; - }; - typedef std::deque RequestQueue; - typedef std::map RequestMap; + + HttpNetworkSession *network_session_; // A Group is allocated per group_name when there are idle sockets or pending // requests. Otherwise, the Group object is removed from the map. @@ -410,7 +431,10 @@ class ClientSocketPoolBaseHelper ScopedRunnableMethodFactory method_factory_; }; - typedef std::map GroupMap; + private: + friend class base::RefCounted; + + typedef std::map RequestMap; typedef std::set ConnectJobSet; @@ -432,12 +456,6 @@ class ClientSocketPoolBaseHelper Group* group); Group* GetOrCreateGroup(const std::string& group_name); - void RemoveGroup(const std::string& group_name); - void RemoveGroup(GroupMap::iterator it); - - // Called when the number of idle sockets changes. - void IncrementIdleCount(); - void DecrementIdleCount(); // Start cleanup timer for idle sockets. void StartIdleSocketTimer(); @@ -450,9 +468,7 @@ class ClientSocketPoolBaseHelper // Called when timer_ fires. This method scans the idle sockets removing // sockets that timed out or can't be reused. - void OnCleanupTimerFired() { - CleanupIdleSockets(false); - } + void OnCleanupTimerFired(); // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL. void RemoveConnectJob(ConnectJob* job, Group* group); @@ -526,8 +542,6 @@ class ClientSocketPoolBaseHelper // in |pending_callback_map_|. void InvokeUserCallback(ClientSocketHandle* handle); - GroupMap group_map_; - // Map of the ClientSocketHandles for which we have a pending Task to invoke a // callback. This is necessary since, before we invoke said callback, it's // possible that the request is cancelled. @@ -552,9 +566,22 @@ class ClientSocketPoolBaseHelper // The maximum number of sockets kept per group. const int max_sockets_per_group_; + // Pointer to ITCPFinAggregation interface that implements + // TCP Fin Aggregation feature. + ITCPFinAggregation* tcp_fin_aggregation; + + // TCP Fin Aggregation feature + bool net_tcp_fin_aggr_feature_enabled_sys_property_; + // Whether to use timer to cleanup idle sockets. bool use_cleanup_timer_; + // Whether statistics is enabled. + bool net_statistics_enabled; + + // Whether unused sockets are closed after page load fnished + bool close_unused_sockets_enabled; + // The time to wait until closing idle sockets. const base::TimeDelta unused_idle_socket_timeout_; const base::TimeDelta used_idle_socket_timeout_; @@ -638,11 +665,13 @@ class ClientSocketPoolBase { ClientSocketPoolHistograms* histograms, base::TimeDelta unused_idle_socket_timeout, base::TimeDelta used_idle_socket_timeout, - ConnectJobFactory* connect_job_factory) + ConnectJobFactory* connect_job_factory, + HttpNetworkSession *network_session) : histograms_(histograms), helper_(max_sockets, max_sockets_per_group, unused_idle_socket_timeout, used_idle_socket_timeout, - new ConnectJobFactoryAdaptor(connect_job_factory)) {} + new ConnectJobFactoryAdaptor(connect_job_factory), + network_session) {} virtual ~ClientSocketPoolBase() {} diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc index 182eb18..0313db4 100644 --- a/net/socket/client_socket_pool_manager.cc +++ b/net/socket/client_socket_pool_manager.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -253,7 +254,8 @@ ClientSocketPoolManager::ClientSocketPoolManager( DnsCertProvenanceChecker* dns_cert_checker, SSLHostInfoFactory* ssl_host_info_factory, ProxyService* proxy_service, - SSLConfigService* ssl_config_service) + SSLConfigService* ssl_config_service, + HttpNetworkSession *network_session) : net_log_(net_log), socket_factory_(socket_factory), host_resolver_(host_resolver), @@ -269,7 +271,8 @@ ClientSocketPoolManager::ClientSocketPoolManager( &transport_pool_histograms_, host_resolver, socket_factory_, - net_log)), + net_log, + network_session)), ssl_pool_histograms_("SSL2"), ssl_socket_pool_(new SSLClientSocketPool( g_max_sockets, g_max_sockets_per_group, @@ -284,7 +287,8 @@ ClientSocketPoolManager::ClientSocketPoolManager( NULL /* no socks proxy */, NULL /* no http proxy */, ssl_config_service, - net_log)), + net_log, + network_session)), transport_for_socks_pool_histograms_("TCPforSOCKS"), socks_pool_histograms_("SOCK"), transport_for_http_proxy_pool_histograms_("TCPforHTTPProxy"), @@ -417,7 +421,8 @@ SOCKSClientSocketPool* ClientSocketPoolManager::GetSocketPoolForSOCKSProxy( &transport_for_socks_pool_histograms_, host_resolver_, socket_factory_, - net_log_))); + net_log_, + NULL))); DCHECK(tcp_ret.second); std::pair ret = @@ -427,7 +432,8 @@ SOCKSClientSocketPool* ClientSocketPoolManager::GetSocketPoolForSOCKSProxy( &socks_pool_histograms_, host_resolver_, tcp_ret.first->second, - net_log_))); + net_log_, + NULL))); return ret.first->second; } @@ -456,7 +462,8 @@ HttpProxyClientSocketPool* ClientSocketPoolManager::GetSocketPoolForHTTPProxy( &transport_for_http_proxy_pool_histograms_, host_resolver_, socket_factory_, - net_log_))); + net_log_, + NULL))); DCHECK(tcp_http_ret.second); std::pair tcp_https_ret = @@ -468,7 +475,8 @@ HttpProxyClientSocketPool* ClientSocketPoolManager::GetSocketPoolForHTTPProxy( &transport_for_https_proxy_pool_histograms_, host_resolver_, socket_factory_, - net_log_))); + net_log_, + NULL))); DCHECK(tcp_https_ret.second); std::pair ssl_https_ret = @@ -487,7 +495,8 @@ HttpProxyClientSocketPool* ClientSocketPoolManager::GetSocketPoolForHTTPProxy( tcp_https_ret.first->second /* https proxy */, NULL /* no socks proxy */, NULL /* no http proxy */, - ssl_config_service_, net_log_))); + ssl_config_service_, net_log_, + NULL))); DCHECK(tcp_https_ret.second); std::pair ret = @@ -500,7 +509,8 @@ HttpProxyClientSocketPool* ClientSocketPoolManager::GetSocketPoolForHTTPProxy( host_resolver_, tcp_http_ret.first->second, ssl_https_ret.first->second, - net_log_))); + net_log_, + NULL))); return ret.first->second; } @@ -525,7 +535,8 @@ SSLClientSocketPool* ClientSocketPoolManager::GetSocketPoolForSSLWithProxy( GetSocketPoolForSOCKSProxy(proxy_server), GetSocketPoolForHTTPProxy(proxy_server), ssl_config_service_, - net_log_); + net_log_, + NULL); std::pair ret = ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server, diff --git a/net/socket/client_socket_pool_manager.h b/net/socket/client_socket_pool_manager.h index 54b13f7..28074c7 100644 --- a/net/socket/client_socket_pool_manager.h +++ b/net/socket/client_socket_pool_manager.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -44,6 +45,7 @@ class SSLClientSocketPool; class SSLConfigService; class SSLHostInfoFactory; class TransportClientSocketPool; +class HttpNetworkSession; struct HttpRequestInfo; struct SSLConfig; @@ -77,7 +79,8 @@ class ClientSocketPoolManager : public base::NonThreadSafe, DnsCertProvenanceChecker* dns_cert_checker, SSLHostInfoFactory* ssl_host_info_factory, ProxyService* proxy_service, - SSLConfigService* ssl_config_service); + SSLConfigService* ssl_config_service, + HttpNetworkSession *network_session); ~ClientSocketPoolManager(); void FlushSocketPools(); @@ -174,6 +177,7 @@ class ClientSocketPoolManager : public base::NonThreadSafe, SSLHostInfoFactory* const ssl_host_info_factory_; const scoped_refptr proxy_service_; const scoped_refptr ssl_config_service_; + HttpNetworkSession *http_network_session_; // Note: this ordering is important. diff --git a/net/socket/socks_client_socket_pool.cc b/net/socket/socks_client_socket_pool.cc index be563c8..dd7dbf7 100644 --- a/net/socket/socks_client_socket_pool.cc +++ b/net/socket/socks_client_socket_pool.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -222,7 +223,8 @@ SOCKSClientSocketPool::SOCKSClientSocketPool( ClientSocketPoolHistograms* histograms, HostResolver* host_resolver, TransportClientSocketPool* transport_pool, - NetLog* net_log) + NetLog* net_log, + HttpNetworkSession *network_session) : transport_pool_(transport_pool), base_(max_sockets, max_sockets_per_group, histograms, base::TimeDelta::FromSeconds( @@ -230,7 +232,8 @@ SOCKSClientSocketPool::SOCKSClientSocketPool( base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout), new SOCKSConnectJobFactory(transport_pool, host_resolver, - net_log)) { + net_log), + network_session) { } SOCKSClientSocketPool::~SOCKSClientSocketPool() {} diff --git a/net/socket/socks_client_socket_pool.h b/net/socket/socks_client_socket_pool.h index 894ee2b..d554815 100644 --- a/net/socket/socks_client_socket_pool.h +++ b/net/socket/socks_client_socket_pool.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -117,7 +118,8 @@ class SOCKSClientSocketPool : public ClientSocketPool { ClientSocketPoolHistograms* histograms, HostResolver* host_resolver, TransportClientSocketPool* transport_pool, - NetLog* net_log); + NetLog* net_log, + HttpNetworkSession *network_session); virtual ~SOCKSClientSocketPool(); diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc index 52554f8..66146a9 100644 --- a/net/socket/ssl_client_socket_pool.cc +++ b/net/socket/ssl_client_socket_pool.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -505,7 +506,8 @@ SSLClientSocketPool::SSLClientSocketPool( SOCKSClientSocketPool* socks_pool, HttpProxyClientSocketPool* http_proxy_pool, SSLConfigService* ssl_config_service, - NetLog* net_log) + NetLog* net_log, + HttpNetworkSession *network_session) : transport_pool_(transport_pool), socks_pool_(socks_pool), http_proxy_pool_(http_proxy_pool), @@ -522,7 +524,8 @@ SSLClientSocketPool::SSLClientSocketPool( dnsrr_resolver, dns_cert_checker, ssl_host_info_factory, - net_log)), + net_log), + network_session), ssl_config_service_(ssl_config_service) { if (ssl_config_service_) ssl_config_service_->AddObserver(this); diff --git a/net/socket/ssl_client_socket_pool.h b/net/socket/ssl_client_socket_pool.h index 3f2efc3..558b373 100644 --- a/net/socket/ssl_client_socket_pool.h +++ b/net/socket/ssl_client_socket_pool.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -194,7 +195,8 @@ class SSLClientSocketPool : public ClientSocketPool, SOCKSClientSocketPool* socks_pool, HttpProxyClientSocketPool* http_proxy_pool, SSLConfigService* ssl_config_service, - NetLog* net_log); + NetLog* net_log, + HttpNetworkSession *network_session); virtual ~SSLClientSocketPool(); diff --git a/net/socket/tcp_client_socket_libevent.cc b/net/socket/tcp_client_socket_libevent.cc index f820955..da3e1a0 100644 --- a/net/socket/tcp_client_socket_libevent.cc +++ b/net/socket/tcp_client_socket_libevent.cc @@ -1,4 +1,5 @@ // Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,6 +27,7 @@ #include "net/base/net_log.h" #include "net/base/net_util.h" #include "net/base/network_change_notifier.h" +#include "net/http/http_getzip_factory.h" #if defined(USE_SYSTEM_LIBEVENT) #include #else @@ -125,6 +127,7 @@ TCPClientSocketLibevent::TCPClientSocketLibevent( , calling_uid_(0) #endif { + HttpGetZipFactory::GetGETZipManager()->OpenGetZipConnection( ((ClientSocket*)this) ); scoped_refptr params; if (source.is_valid()) params = new NetLogSourceParameter("source_dependency", source); @@ -135,6 +138,7 @@ TCPClientSocketLibevent::TCPClientSocketLibevent( } TCPClientSocketLibevent::~TCPClientSocketLibevent() { + HttpGetZipFactory::GetGETZipManager()->StopGetZipConnection( ((ClientSocket*)this) ); Disconnect(); net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); } diff --git a/net/socket/tcp_client_socket_pool.cc b/net/socket/tcp_client_socket_pool.cc index 735f498..a4c43e4 100644 --- a/net/socket/tcp_client_socket_pool.cc +++ b/net/socket/tcp_client_socket_pool.cc @@ -1,4 +1,5 @@ // Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -247,13 +248,15 @@ TCPClientSocketPool::TCPClientSocketPool( ClientSocketPoolHistograms* histograms, HostResolver* host_resolver, ClientSocketFactory* client_socket_factory, - NetLog* net_log) + NetLog* net_log, + HttpNetworkSession *network_session) : base_(max_sockets, max_sockets_per_group, histograms, base::TimeDelta::FromSeconds( ClientSocketPool::unused_idle_socket_timeout()), base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout), new TCPConnectJobFactory(client_socket_factory, - host_resolver, net_log)) { + host_resolver, net_log), + network_session) { base_.EnableConnectBackupJobs(); } diff --git a/net/socket/tcp_client_socket_pool.h b/net/socket/tcp_client_socket_pool.h index cb671db..1537cf4 100644 --- a/net/socket/tcp_client_socket_pool.h +++ b/net/socket/tcp_client_socket_pool.h @@ -1,4 +1,5 @@ // Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -126,7 +127,8 @@ class TCPClientSocketPool : public ClientSocketPool { ClientSocketPoolHistograms* histograms, HostResolver* host_resolver, ClientSocketFactory* client_socket_factory, - NetLog* net_log); + NetLog* net_log, + HttpNetworkSession *network_session); virtual ~TCPClientSocketPool(); diff --git a/net/socket/tcp_fin_aggregation.h b/net/socket/tcp_fin_aggregation.h new file mode 100644 index 0000000..26ab3f8 --- /dev/null +++ b/net/socket/tcp_fin_aggregation.h @@ -0,0 +1,52 @@ +// Copyright (c) 2011,2012 Code Aurora Forum. All rights reserved. + +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Code Aurora Forum, Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef TCP_FIN_AGGREGATION_H_ +#define TCP_FIN_AGGREGATION_H_ + +#include "base/basictypes.h" +#include "client_socket_pool_base.h" + +namespace net { + +class ITCPFinAggregation { + +public: + ITCPFinAggregation() {}; + virtual ~ITCPFinAggregation() {}; + + virtual bool IsEnabled() = 0; + virtual void ReaperCleanup(bool close_unused_socket) = 0; + virtual int GetCleanupInterval(int current_interval) = 0; + +private: + DISALLOW_COPY_AND_ASSIGN(ITCPFinAggregation); +}; + +} // namespace net + +#endif /* TCP_FIN_AGGREGATION_H_ */ diff --git a/net/socket/tcp_fin_aggregation_bridge.h b/net/socket/tcp_fin_aggregation_bridge.h new file mode 100644 index 0000000..071832a --- /dev/null +++ b/net/socket/tcp_fin_aggregation_bridge.h @@ -0,0 +1,46 @@ +// Copyright (c) 2011, Code Aurora Forum. All rights reserved. + +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Code Aurora Forum, Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef TCP_FIN_AGGREGATION_BRIDGE_H_ +#define TCP_FIN_AGGREGATION_BRIDGE_H_ + +#include "client_socket_pool_base.h" +#include "time.h" + +namespace net { +namespace internal { + class ClientSocketPoolBaseHelper; + class IdleSocket; +} +}; + +extern void DecrementIdleCount(net::internal::ClientSocketPoolBaseHelper* pool_base_helper) __attribute__((visibility("default"), used)); +extern void RemoveGroup(net::internal::ClientSocketPoolBaseHelper* pool_base_helper, const std::string& group_name) __attribute__((visibility("default"), used)); +extern bool ShouldCleanup(net::internal::IdleSocket* idle_socket, base::Time now, base::TimeDelta timeout) __attribute__((visibility("default"), used)); +extern base::Time GetCurrentTime() __attribute__((visibility("default"), used)); + +#endif /* TCP_FIN_AGGREGATION_BRIDGE_H_ */ diff --git a/net/socket/tcp_fin_aggregation_factory.cc b/net/socket/tcp_fin_aggregation_factory.cc new file mode 100644 index 0000000..0b13243 --- /dev/null +++ b/net/socket/tcp_fin_aggregation_factory.cc @@ -0,0 +1,88 @@ +// Copyright (c) 2011, Code Aurora Forum. All rights reserved. + +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Code Aurora Forum, Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "tcp_fin_aggregation_factory.h" +#include "tcp_fin_aggregation_bridge.h" +#include +#include + +namespace net { + +base::Lock TCPFinAggregationFactory::m_mutex; + +TCPFinAggregationFactory* TCPFinAggregationFactory::s_pFactory = NULL; + +TCPFinAggregationFactory* TCPFinAggregationFactory::GetTCPFinFactoryInstance(internal::ClientSocketPoolBaseHelper* pool_base_helper) { + base::AutoLock myLock(TCPFinAggregationFactory::m_mutex); + if(s_pFactory == NULL) { + s_pFactory = new TCPFinAggregationFactory(pool_base_helper); + } + return s_pFactory; +} + +TCPFinAggregationFactory::TCPFinAggregationFactory(internal::ClientSocketPoolBaseHelper* pool_base_helper):m_pTCPFin(NULL) { + InitTCPFinAggregation(pool_base_helper); +} + +void TCPFinAggregationFactory::InitTCPFinAggregation(internal::ClientSocketPoolBaseHelper* pool_base_helper) { + void* libHandle = dlopen("libtcpfinaggr.so", RTLD_LAZY); + if (!libHandle) + { + SLOGD("dl error message %s", dlerror()); + } + + if(libHandle) { + SLOGD("%s: libtcpfinaggr.so successfully loaded", __FILE__); + *(void **)(&tcpfin_create_) = dlsym(libHandle, "createTCPFinAggregation"); + + if(tcpfin_create_) { + SLOGD("%s,: TCP Fin Aggregation initializing method was found in libtcpfinaggr.so", __FILE__); + m_pTCPFin = tcpfin_create_(pool_base_helper); + return; + } + ::dlclose(libHandle); + SLOGD("Failed to load createTCPFinAggregation symbol in libtcpfinaggr.so"); + } +} +}; // namespace net + +void DecrementIdleCount(net::internal::ClientSocketPoolBaseHelper* pool_base_helper) +{ + pool_base_helper->DecrementIdleCount(); +} +void RemoveGroup(net::internal::ClientSocketPoolBaseHelper* pool_base_helper, const std::string& group_name) +{ + pool_base_helper->RemoveGroup(group_name); +} +bool ShouldCleanup(net::internal::IdleSocket* idle_socket, base::Time now, base::TimeDelta timeout) +{ + return idle_socket->ShouldCleanup(now, timeout); +} +base::Time GetCurrentTime() +{ + return base::Time::Now(); +} diff --git a/net/socket/tcp_fin_aggregation_factory.h b/net/socket/tcp_fin_aggregation_factory.h new file mode 100644 index 0000000..17e61c1 --- /dev/null +++ b/net/socket/tcp_fin_aggregation_factory.h @@ -0,0 +1,71 @@ +// Copyright (c) 2011, Code Aurora Forum. All rights reserved. + +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Code Aurora Forum, Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef TCP_FIN_AGGREGATION_FACTORY_H_ +#define TCP_FIN_AGGREGATION_FACTORY_H_ + +#include "tcp_fin_aggregation.h" +#include "client_socket_pool_base.h" +#include "base/synchronization/lock.h" +#include "tcp_fin_aggregation_bridge.h" + +namespace net { +class ITCPFinAggregation; +namespace internal { + class ClientSocketPoolBaseHelper; +} + +static ITCPFinAggregation* (*tcpfin_create_)(internal::ClientSocketPoolBaseHelper* pool_base_helper) = NULL; + +class TCPFinAggregationFactory { + +public: + + + static TCPFinAggregationFactory* GetTCPFinFactoryInstance(internal::ClientSocketPoolBaseHelper* pool_base_helper); + + ITCPFinAggregation* GetTCPFinAggregation(){ return m_pTCPFin;} + +private: + + ITCPFinAggregation* m_pTCPFin; + + static TCPFinAggregationFactory* s_pFactory; + + static base::Lock m_mutex; + + TCPFinAggregationFactory(internal::ClientSocketPoolBaseHelper* pool_base_helper); + + ~TCPFinAggregationFactory(); + + void InitTCPFinAggregation(internal::ClientSocketPoolBaseHelper* pool_base_helper); + + DISALLOW_COPY_AND_ASSIGN(TCPFinAggregationFactory); +}; + +} // namespace net +#endif diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc index ef02061..d1ac198 100644 --- a/net/socket/transport_client_socket_pool.cc +++ b/net/socket/transport_client_socket_pool.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -425,13 +426,15 @@ TransportClientSocketPool::TransportClientSocketPool( ClientSocketPoolHistograms* histograms, HostResolver* host_resolver, ClientSocketFactory* client_socket_factory, - NetLog* net_log) + NetLog* net_log, + HttpNetworkSession *network_session) : base_(max_sockets, max_sockets_per_group, histograms, base::TimeDelta::FromSeconds( ClientSocketPool::unused_idle_socket_timeout()), base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout), new TransportConnectJobFactory(client_socket_factory, - host_resolver, net_log)) { + host_resolver, net_log), + network_session) { base_.EnableConnectBackupJobs(); } diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h index c1633bb..c6fdce5 100644 --- a/net/socket/transport_client_socket_pool.h +++ b/net/socket/transport_client_socket_pool.h @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -147,7 +148,8 @@ class TransportClientSocketPool : public ClientSocketPool { ClientSocketPoolHistograms* histograms, HostResolver* host_resolver, ClientSocketFactory* client_socket_factory, - NetLog* net_log); + NetLog* net_log, + HttpNetworkSession *network_session); virtual ~TransportClientSocketPool(); diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 95f536f..2818d19 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -1,4 +1,6 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011, Code Aurora Forum. All rights reserved + // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -40,6 +42,7 @@ #include "net/url_request/url_request_redirect_job.h" #include "net/url_request/url_request_throttler_header_adapter.h" #include "net/url_request/url_request_throttler_manager.h" +#include "net/disk_cache/stat_hub_api.h" static const char kAvailDictionaryHeader[] = "Avail-Dictionary"; @@ -285,6 +288,9 @@ void URLRequestHttpJob::NotifyHeadersComplete() { void URLRequestHttpJob::NotifyDone(const URLRequestStatus& status) { RecordCompressionHistograms(); + GURL& url = request_info_.url; + unsigned short url_len = url.spec().length(); + StatHubCmd(INPUT_CMD_CH_URL_REQUEST_DONE, (void*)url.spec().c_str(), url_len+1, NULL, 0); URLRequestJob::NotifyDone(status); } @@ -296,6 +302,11 @@ void URLRequestHttpJob::DestroyTransaction() { context_ = NULL; } +static void updateUrlRequest(const GURL& url, const std::string& headers) { + unsigned short url_len = url.spec().length(); + StatHubCmd(INPUT_CMD_CH_URL_REQUEST, (void*)url.spec().c_str(), url_len+1, (void*)headers.c_str(), headers.length()+1); +} + void URLRequestHttpJob::StartTransaction() { // NOTE: This method assumes that request_info_ is already setup properly. @@ -317,6 +328,7 @@ void URLRequestHttpJob::StartTransaction() { if (rv == OK) { if (!URLRequestThrottlerManager::GetInstance()->enforce_throttling() || !throttling_entry_->IsDuringExponentialBackoff()) { + updateUrlRequest(request_info_.url, request_info_.extra_headers.ToString().c_str()); rv = transaction_->Start( &request_info_, &start_callback_, request_->net_log()); } else { -- cgit v1.1