diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-10 23:13:56 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-10 23:13:56 +0000 |
commit | 6e76d8d105739f3b40274dd0247a75ea44e46a89 (patch) | |
tree | d3b8ba9605783f4ef28cfe2726b9c38b0e57eb23 /chrome/browser/net | |
parent | 02e7a01ff83e7e6aa637809ca43cff5da5dbe1c0 (diff) | |
download | chromium_src-6e76d8d105739f3b40274dd0247a75ea44e46a89.zip chromium_src-6e76d8d105739f3b40274dd0247a75ea44e46a89.tar.gz chromium_src-6e76d8d105739f3b40274dd0247a75ea44e46a89.tar.bz2 |
Replace about:net-internals with the javascript-based frontend.
(DNS request tracing is the only feature lost in this transition; it needs to be added back under the new framework).
BUG=37421
Review URL: http://codereview.chromium.org/2008007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46868 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/net')
-rw-r--r-- | chrome/browser/net/view_http_cache_job_factory.cc | 62 | ||||
-rw-r--r-- | chrome/browser/net/view_http_cache_job_factory.h (renamed from chrome/browser/net/view_net_internals_job_factory.h) | 8 | ||||
-rw-r--r-- | chrome/browser/net/view_net_internals_job_factory.cc | 875 |
3 files changed, 66 insertions, 879 deletions
diff --git a/chrome/browser/net/view_http_cache_job_factory.cc b/chrome/browser/net/view_http_cache_job_factory.cc new file mode 100644 index 0000000..ce10ff1 --- /dev/null +++ b/chrome/browser/net/view_http_cache_job_factory.cc @@ -0,0 +1,62 @@ +// Copyright (c) 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. + +#include "chrome/browser/net/view_http_cache_job_factory.h" + +#include "chrome/common/url_constants.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_simple_job.h" +#include "net/url_request/view_cache_helper.h" + +namespace { + +// A job subclass that dumps an HTTP cache entry. +class ViewHttpCacheJob : public URLRequestSimpleJob { + public: + explicit ViewHttpCacheJob(URLRequest* request) + : URLRequestSimpleJob(request) {} + + // URLRequestSimpleJob methods: + virtual bool GetData(std::string* mime_type, + std::string* charset, + std::string* data) const; + + private: + ~ViewHttpCacheJob() {} +}; + +bool ViewHttpCacheJob::GetData(std::string* mime_type, + std::string* charset, + std::string* data) const { + mime_type->assign("text/html"); + charset->assign("UTF-8"); + + data->clear(); + + std::string cache_key; + cache_key = + request_->url().spec().substr(strlen(chrome::kNetworkViewCacheURL)); + ViewCacheHelper::GetEntryInfoHTML(cache_key, + request_->context(), + chrome::kNetworkViewCacheURL, + data); + + return true; +} + +} // namespace + +// static +bool ViewHttpCacheJobFactory::IsSupportedURL(const GURL& url) { + return StartsWithASCII(url.spec(), + chrome::kNetworkViewCacheURL, + true /*case_sensitive*/); +} + +// static +URLRequestJob* ViewHttpCacheJobFactory::CreateJobForRequest( + URLRequest* request) { + return new ViewHttpCacheJob(request); +} diff --git a/chrome/browser/net/view_net_internals_job_factory.h b/chrome/browser/net/view_http_cache_job_factory.h index a694c93..e3fa152 100644 --- a/chrome/browser/net/view_net_internals_job_factory.h +++ b/chrome/browser/net/view_http_cache_job_factory.h @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_NET_VIEW_NET_INTERNALS_JOB_FACTORY_H_ -#define CHROME_BROWSER_NET_VIEW_NET_INTERNALS_JOB_FACTORY_H_ +#ifndef CHROME_BROWSER_NET_VIEW_HTTP_CACHE_JOB_FACTORY_H_ +#define CHROME_BROWSER_NET_VIEW_HTTP_CACHE_JOB_FACTORY_H_ class GURL; class URLRequest; class URLRequestJob; -class ViewNetInternalsJobFactory { +class ViewHttpCacheJobFactory { public: static bool IsSupportedURL(const GURL& url); static URLRequestJob* CreateJobForRequest(URLRequest* request); }; -#endif // CHROME_BROWSER_NET_VIEW_NET_INTERNALS_JOB_FACTORY_H_ +#endif // CHROME_BROWSER_NET_VIEW_HTTP_CACHE_JOB_FACTORY_H_ diff --git a/chrome/browser/net/view_net_internals_job_factory.cc b/chrome/browser/net/view_net_internals_job_factory.cc deleted file mode 100644 index 213ae5f..0000000 --- a/chrome/browser/net/view_net_internals_job_factory.cc +++ /dev/null @@ -1,875 +0,0 @@ -// Copyright (c) 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. - -#include "chrome/browser/net/view_net_internals_job_factory.h" - -#include <sstream> - -#include "base/format_macros.h" -#include "base/stl_util-inl.h" -#include "base/string_util.h" -#include "chrome/browser/net/chrome_net_log.h" -#include "chrome/browser/net/chrome_url_request_context.h" -#include "chrome/browser/net/passive_log_collector.h" -#include "chrome/common/url_constants.h" -#include "net/base/escape.h" -#include "net/base/host_resolver_impl.h" -#include "net/base/net_errors.h" -#include "net/base/net_log_util.h" -#include "net/base/net_util.h" -#include "net/base/sys_addrinfo.h" -#include "net/proxy/proxy_service.h" -#include "net/socket_stream/socket_stream.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_simple_job.h" -#include "net/url_request/view_cache_helper.h" - -namespace { - -const char kViewHttpCacheSubPath[] = "view-cache"; - -// TODO(eroman): Delete this file. It should be replaced by -// chrome/browser/dom_ui/net_internals_ui.cc once the porting is -// complete. - -PassiveLogCollector* GetPassiveLogCollector(URLRequestContext* context) { - // Really this is the same as: - // g_browser_process->io_thread()->globals()-> - // net_log.get() - // (But we can't access g_browser_process from the IO thread). - ChromeNetLog* chrome_net_log = static_cast<ChromeNetLog*>( - static_cast<ChromeURLRequestContext*>(context)->net_log()); - return chrome_net_log->passive_collector(); -} - -PassiveLogCollector::RequestTracker* GetURLRequestTracker( - URLRequestContext* context) { - return GetPassiveLogCollector(context)->url_request_tracker(); -} - -PassiveLogCollector::RequestTracker* GetSocketStreamTracker( - URLRequestContext* context) { - return GetPassiveLogCollector(context)->socket_stream_tracker(); -} - -PassiveLogCollector::InitProxyResolverTracker* GetInitProxyResolverTracker( - URLRequestContext* context) { - return GetPassiveLogCollector(context)->init_proxy_resolver_tracker(); -} - -std::string GetDetails(const GURL& url) { - DCHECK(ViewNetInternalsJobFactory::IsSupportedURL(url)); - size_t start = strlen(chrome::kNetworkViewInternalsURL); - if (start >= url.spec().size()) - return std::string(); - return url.spec().substr(start); -} - -GURL MakeURL(const std::string& details) { - return GURL(std::string(chrome::kNetworkViewInternalsURL) + details); -} - -// Converts a PassiveLogCollector::EntryList to a CapturingNetLog::EntryList. -// -// They are basically the same thing, except PassiveLogCollector has an extra -// "order" field which we will drop. -net::CapturingNetLog::EntryList ConvertEntryList( - const PassiveLogCollector::EntryList& input) { - net::CapturingNetLog::EntryList result; - for (size_t i = 0; i < input.size(); ++i) { - result.push_back( - net::CapturingNetLog::Entry( - input[i].type, - input[i].time, - input[i].source, - input[i].phase, - input[i].extra_parameters)); - } - return result; -} - -// A job subclass that implements a protocol to inspect the internal -// state of the network stack. -class ViewNetInternalsJob : public URLRequestSimpleJob { - public: - - explicit ViewNetInternalsJob(URLRequest* request) - : URLRequestSimpleJob(request) {} - - // URLRequestSimpleJob methods: - virtual bool GetData(std::string* mime_type, - std::string* charset, - std::string* data) const; - - // Overridden methods from URLRequestJob: - virtual bool IsRedirectResponse(GURL* location, int* http_status_code); - - private: - ~ViewNetInternalsJob() {} - - // Returns true if the current request is for a "view-cache" URL. - // If it is, then |key| is assigned the particular cache URL of the request. - bool GetViewCacheKeyForRequest(std::string* key) const; -}; - -//------------------------------------------------------------------------------ -// Format helpers. -//------------------------------------------------------------------------------ - -void OutputTextInPre(const std::string& text, std::string* out) { - out->append("<pre>"); - out->append(EscapeForHTML(text)); - out->append("</pre>"); -} - -// Appends an input button to |data| with text |title| that sends the command -// string |command| back to the browser, and then refreshes the page. -void DrawCommandButton(const std::string& title, - const std::string& command, - std::string* data) { - StringAppendF(data, "<input type=\"button\" value=\"%s\" " - "onclick=\"DoCommand('%s')\" />", - title.c_str(), - command.c_str()); -} - -//------------------------------------------------------------------------------ -// URLRequestContext helpers. -//------------------------------------------------------------------------------ - -net::HostResolverImpl* GetHostResolverImpl(URLRequestContext* context) { - return context->host_resolver()->GetAsHostResolverImpl(); -} - -net::HostCache* GetHostCache(URLRequestContext* context) { - if (GetHostResolverImpl(context)) - return GetHostResolverImpl(context)->cache(); - return NULL; -} - -//------------------------------------------------------------------------------ -// Subsection definitions. -//------------------------------------------------------------------------------ - -class SubSection { - public: - // |name| is the URL path component for this subsection. - // |title| is the textual description. - SubSection(SubSection* parent, const char* name, const char* title) - : parent_(parent), - name_(name), - title_(title) { - } - - virtual ~SubSection() { - STLDeleteContainerPointers(children_.begin(), children_.end()); - } - - // Outputs the subsection's contents to |out|. - virtual void OutputBody(URLRequestContext* context, std::string* out) {} - - // Outputs this subsection, and all of its children. - void OutputRecursive(URLRequestContext* context, std::string* out) { - if (!is_root()) { - // Canonicalizing the URL escapes characters which cause problems in HTML. - std::string section_url = MakeURL(GetFullyQualifiedName()).spec(); - - // Print the heading. - StringAppendF( - out, - "<div>" - "<span class=subsection_title>%s</span> " - "<span class=subsection_name>(<a href='%s'>%s</a>)<span>" - "</div>", - EscapeForHTML(title_).c_str(), - section_url.c_str(), - EscapeForHTML(section_url).c_str()); - - out->append("<div class=subsection_body>"); - } - - OutputBody(context, out); - - for (size_t i = 0; i < children_.size(); ++i) - children_[i]->OutputRecursive(context, out); - - if (!is_root()) - out->append("</div>"); - } - - // Returns the SubSection contained by |this| with fully qualified name - // |dotted_name|, or NULL if none was found. - SubSection* FindSubSectionByName(const std::string& dotted_name) { - if (dotted_name == "") - return this; - - std::string child_name; - std::string child_sub_name; - - size_t split_pos = dotted_name.find('.'); - if (split_pos == std::string::npos) { - child_name = dotted_name; - child_sub_name = std::string(); - } else { - child_name = dotted_name.substr(0, split_pos); - child_sub_name = dotted_name.substr(split_pos + 1); - } - - for (size_t i = 0; i < children_.size(); ++i) { - if (children_[i]->name_ == child_name) - return children_[i]->FindSubSectionByName(child_sub_name); - } - - return NULL; // Not found. - } - - std::string GetFullyQualifiedName() { - if (!parent_) - return name_; - - std::string parent_name = parent_->GetFullyQualifiedName(); - if (parent_name.empty()) - return name_; - - return parent_name + "." + name_; - } - - bool is_root() const { - return parent_ == NULL; - } - - protected: - typedef std::vector<SubSection*> SubSectionList; - - void AddSubSection(SubSection* subsection) { - children_.push_back(subsection); - } - - SubSection* parent_; - std::string name_; - std::string title_; - - SubSectionList children_; -}; - -class ProxyServiceCurrentConfigSubSection : public SubSection { - public: - explicit ProxyServiceCurrentConfigSubSection(SubSection* parent) - : SubSection(parent, "config", "Current configuration") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - DrawCommandButton("Force reload", "reload-proxy-config", out); - - net::ProxyService* proxy_service = context->proxy_service(); - if (proxy_service->config_has_been_initialized()) { - // net::ProxyConfig defines an operator<<. - std::ostringstream stream; - stream << proxy_service->config(); - OutputTextInPre(stream.str(), out); - } else { - out->append("<i>Not yet initialized</i>"); - } - } -}; - -class ProxyServiceLastInitLogSubSection : public SubSection { - public: - explicit ProxyServiceLastInitLogSubSection(SubSection* parent) - : SubSection(parent, "init_log", "Last initialized load log") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - OutputTextInPre( - net::NetLogUtil::PrettyPrintAsEventTree( - ConvertEntryList(GetInitProxyResolverTracker(context)->entries()), - 0), - out); - } -}; - -class ProxyServiceBadProxiesSubSection : public SubSection { - public: - explicit ProxyServiceBadProxiesSubSection(SubSection* parent) - : SubSection(parent, "bad_proxies", "Bad Proxies") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - net::ProxyService* proxy_service = context->proxy_service(); - const net::ProxyRetryInfoMap& bad_proxies_map = - proxy_service->proxy_retry_info(); - - DrawCommandButton("Clear", "clear-badproxies", out); - - out->append("<table border=1>"); - out->append("<tr><th>Bad proxy server</th>" - "<th>Remaining time until retry (ms)</th></tr>"); - - for (net::ProxyRetryInfoMap::const_iterator it = bad_proxies_map.begin(); - it != bad_proxies_map.end(); ++it) { - const std::string& proxy_uri = it->first; - const net::ProxyRetryInfo& retry_info = it->second; - - // Note that ttl_ms may be negative, for the cases where entries have - // expired but not been garbage collected yet. - int ttl_ms = static_cast<int>( - (retry_info.bad_until - base::TimeTicks::Now()).InMilliseconds()); - - // Color expired entries blue. - if (ttl_ms > 0) - out->append("<tr>"); - else - out->append("<tr style='color:blue'>"); - - StringAppendF(out, "<td>%s</td><td>%d</td>", - EscapeForHTML(proxy_uri).c_str(), - ttl_ms); - - out->append("</tr>"); - } - out->append("</table>"); - } -}; - -class ProxyServiceSubSection : public SubSection { - public: - explicit ProxyServiceSubSection(SubSection* parent) - : SubSection(parent, "proxyservice", "ProxyService") { - AddSubSection(new ProxyServiceCurrentConfigSubSection(this)); - AddSubSection(new ProxyServiceLastInitLogSubSection(this)); - AddSubSection(new ProxyServiceBadProxiesSubSection(this)); - } -}; - -class HostResolverCacheSubSection : public SubSection { - public: - explicit HostResolverCacheSubSection(SubSection* parent) - : SubSection(parent, "hostcache", "HostCache") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - const net::HostCache* host_cache = GetHostCache(context); - - if (!host_cache || host_cache->caching_is_disabled()) { - out->append("<i>Caching is disabled.</i>"); - return; - } - - DrawCommandButton("Clear", "clear-hostcache", out); - - StringAppendF( - out, - "<ul><li>Size: %" PRIuS "</li>" - "<li>Capacity: %" PRIuS "</li>" - "<li>Time to live (ms) for success entries: %" PRId64"</li>" - "<li>Time to live (ms) for failure entries: %" PRId64"</li></ul>", - host_cache->size(), - host_cache->max_entries(), - host_cache->success_entry_ttl().InMilliseconds(), - host_cache->failure_entry_ttl().InMilliseconds()); - - out->append("<table border=1>" - "<tr>" - "<th>Host</th>" - "<th>Address family</th>" - "<th>Address list</th>" - "<th>Canonical name</th>" - "<th>Time to live (ms)</th>" - "</tr>"); - - for (net::HostCache::EntryMap::const_iterator it = - host_cache->entries().begin(); - it != host_cache->entries().end(); - ++it) { - const net::HostCache::Key& key = it->first; - const net::HostCache::Entry* entry = it->second.get(); - - std::string address_family_str = - AddressFamilyToString(key.address_family); - - // Note that ttl_ms may be negative, for the cases where entries have - // expired but not been garbage collected yet. - int ttl_ms = static_cast<int>( - (entry->expiration - base::TimeTicks::Now()).InMilliseconds()); - - // Color expired entries blue. - if (ttl_ms > 0) { - out->append("<tr>"); - } else { - out->append("<tr style='color:blue'>"); - } - - // Stringify all of the addresses in the address list, separated - // by newlines (br). - std::string address_list_html; - std::string canonical_name_html; - - if (entry->error != net::OK) { - address_list_html = "<span style='font-weight: bold; color:red'>" + - EscapeForHTML(net::ErrorToString(entry->error)) + - "</span>"; - } else { - const struct addrinfo* current_address = entry->addrlist.head(); - while (current_address) { - if (!address_list_html.empty()) - address_list_html += "<br>"; - address_list_html += EscapeForHTML( - net::NetAddressToString(current_address)); - current_address = current_address->ai_next; - } - std::string canonical_name; - if (entry->addrlist.GetCanonicalName(&canonical_name)) - canonical_name_html = EscapeForHTML(canonical_name); - } - - StringAppendF(out, - "<td>%s</td><td>%s</td><td>%s</td>" - "<td>%s</td><td>%d</td></tr>", - EscapeForHTML(key.hostname).c_str(), - EscapeForHTML(address_family_str).c_str(), - address_list_html.c_str(), - canonical_name_html.c_str(), - ttl_ms); - } - - out->append("</table>"); - } - - static std::string AddressFamilyToString(net::AddressFamily address_family) { - switch (address_family) { - case net::ADDRESS_FAMILY_IPV4: - return "IPV4"; - case net::ADDRESS_FAMILY_IPV6: - return "IPV6"; - case net::ADDRESS_FAMILY_UNSPECIFIED: - return "UNSPECIFIED"; - default: - NOTREACHED(); - return "???"; - } - } -}; - -class HostResolverTraceSubSection : public SubSection { - public: - explicit HostResolverTraceSubSection(SubSection* parent) - : SubSection(parent, "trace", "Trace of requests") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - net::HostResolverImpl* resolver = GetHostResolverImpl(context); - if (!resolver) { - out->append("<i>Tracing is not supported by this resolver.</i>"); - return; - } - - DrawCommandButton("Clear", "clear-hostresolver-trace", out); - - if (resolver->IsRequestsTracingEnabled()) { - DrawCommandButton("Disable tracing", "hostresolver-trace-disable", out); - } else { - DrawCommandButton("Enable tracing", "hostresolver-trace-enable", out); - } - - net::CapturingNetLog::EntryList entries; - if (resolver->GetRequestsTrace(&entries)) { - out->append( - "<p>To make sense of this trace, process it with the Python script " - "formatter.py at " - "<a href='http://src.chromium.org/viewvc/chrome/trunk/src/net/tools/" - "dns_trace_formatter/'>net/tools/dns_trace_formatter</a></p>"); - OutputTextInPre(net::NetLogUtil::PrettyPrintAsEventTree(entries, 0), - out); - } else { - out->append("<p><i>No trace information, must enable tracing.</i></p>"); - } - } -}; - -class HostResolverSubSection : public SubSection { - public: - explicit HostResolverSubSection(SubSection* parent) - : SubSection(parent, "hostresolver", "HostResolver") { - AddSubSection(new HostResolverCacheSubSection(this)); - AddSubSection(new HostResolverTraceSubSection(this)); - } -}; - -// Helper for the URLRequest "outstanding" and "live" sections. -void OutputURLAndLoadLog(const PassiveLogCollector::RequestInfo& request, - std::string* out) { - out->append("<li>"); - out->append("<nobr>"); - out->append(EscapeForHTML(request.url)); - out->append("</nobr>"); - OutputTextInPre( - net::NetLogUtil::PrettyPrintAsEventTree( - ConvertEntryList(request.entries), - request.num_entries_truncated), - out); - out->append("</li>"); -} - -class URLRequestLiveSubSection : public SubSection { - public: - explicit URLRequestLiveSubSection(SubSection* parent) - : SubSection(parent, "outstanding", "Outstanding requests") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - PassiveLogCollector::RequestInfoList requests = - GetURLRequestTracker(context)->GetLiveRequests(); - - out->append("<ol>"); - for (size_t i = 0; i < requests.size(); ++i) { - // Reverse the list order, so we display from most recent to oldest. - size_t index = requests.size() - i - 1; - OutputURLAndLoadLog(requests[index], out); - } - out->append("</ol>"); - } -}; - -class URLRequestRecentSubSection : public SubSection { - public: - explicit URLRequestRecentSubSection(SubSection* parent) - : SubSection(parent, "recent", "Recently completed requests") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - PassiveLogCollector::RequestInfoList recent = - GetURLRequestTracker(context)->GetRecentlyDeceased(); - - DrawCommandButton("Clear", "clear-urlrequest-graveyard", out); - - out->append("<ol>"); - for (size_t i = 0; i < recent.size(); ++i) { - // Reverse the list order, so we dispay from most recent to oldest. - size_t index = recent.size() - i - 1; - OutputURLAndLoadLog(recent[index], out); - } - out->append("</ol>"); - } -}; - -class URLRequestSubSection : public SubSection { - public: - explicit URLRequestSubSection(SubSection* parent) - : SubSection(parent, "urlrequest", "URLRequest") { - AddSubSection(new URLRequestLiveSubSection(this)); - AddSubSection(new URLRequestRecentSubSection(this)); - } -}; - -class HttpCacheStatsSubSection : public SubSection { - public: - explicit HttpCacheStatsSubSection(SubSection* parent) - : SubSection(parent, "stats", "Statistics") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - ViewCacheHelper::GetStatisticsHTML(context, out); - } -}; - -class HttpCacheSection : public SubSection { - public: - explicit HttpCacheSection(SubSection* parent) - : SubSection(parent, "httpcache", "HttpCache") { - AddSubSection(new HttpCacheStatsSubSection(this)); - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - // Advertise the view-cache URL (too much data to inline it). - out->append("<p><a href='/"); - out->append(kViewHttpCacheSubPath); - out->append("'>View all cache entries</a></p>"); - } -}; - -class SocketStreamLiveSubSection : public SubSection { - public: - explicit SocketStreamLiveSubSection(SubSection* parent) - : SubSection(parent, "live", "Live SocketStreams") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - PassiveLogCollector::RequestInfoList sockets = - GetSocketStreamTracker(context)->GetLiveRequests(); - - out->append("<ol>"); - for (size_t i = 0; i < sockets.size(); ++i) { - // Reverse the list order, so we dispay from most recent to oldest. - size_t index = sockets.size() - i - 1; - OutputURLAndLoadLog(sockets[index], out); - } - out->append("</ol>"); - } -}; - -class SocketStreamRecentSubSection : public SubSection { - public: - explicit SocketStreamRecentSubSection(SubSection* parent) - : SubSection(parent, "recent", "Recently completed SocketStreams") { - } - - virtual void OutputBody(URLRequestContext* context, std::string* out) { - PassiveLogCollector::RequestInfoList recent = - GetSocketStreamTracker(context)->GetRecentlyDeceased(); - - DrawCommandButton("Clear", "clear-socketstream-graveyard", out); - - out->append("<ol>"); - for (size_t i = 0; i < recent.size(); ++i) { - // Reverse the list order, so we dispay from most recent to oldest. - size_t index = recent.size() - i - 1; - OutputURLAndLoadLog(recent[index], out); - } - out->append("</ol>"); - } -}; - -class SocketStreamSubSection : public SubSection { - public: - explicit SocketStreamSubSection(SubSection* parent) - : SubSection(parent, "socketstream", "SocketStream") { - AddSubSection(new SocketStreamLiveSubSection(this)); - AddSubSection(new SocketStreamRecentSubSection(this)); - } -}; - -class AllSubSections : public SubSection { - public: - AllSubSections() : SubSection(NULL, "", "") { - AddSubSection(new ProxyServiceSubSection(this)); - AddSubSection(new HostResolverSubSection(this)); - AddSubSection(new URLRequestSubSection(this)); - AddSubSection(new HttpCacheSection(this)); - AddSubSection(new SocketStreamSubSection(this)); - } -}; - -bool HandleCommand(const std::string& command, - URLRequestContext* context) { - if (StartsWithASCII(command, "full-logging-", true)) { - bool enable_full_logging = (command == "full-logging-enable"); - GetURLRequestTracker(context)->SetUnbounded(enable_full_logging); - GetSocketStreamTracker(context)->SetUnbounded(enable_full_logging); - return true; - } - - if (StartsWithASCII(command, "hostresolver-trace-", true)) { - bool enable_tracing = (command == "hostresolver-trace-enable"); - if (GetHostResolverImpl(context)) { - GetHostResolverImpl(context)->EnableRequestsTracing(enable_tracing); - } - } - - if (command == "clear-urlrequest-graveyard") { - GetURLRequestTracker(context)->ClearRecentlyDeceased(); - return true; - } - - if (command == "clear-socketstream-graveyard") { - GetSocketStreamTracker(context)->ClearRecentlyDeceased(); - return true; - } - - if (command == "clear-hostcache") { - net::HostCache* host_cache = GetHostCache(context); - if (host_cache) - host_cache->clear(); - return true; - } - - if (command == "clear-badproxies") { - context->proxy_service()->ClearBadProxiesCache(); - return true; - } - - if (command == "clear-hostresolver-trace") { - if (GetHostResolverImpl(context)) - GetHostResolverImpl(context)->ClearRequestsTrace(); - } - - if (command == "reload-proxy-config") { - context->proxy_service()->ForceReloadProxyConfig(); - return true; - } - - return false; -} - -// Process any query strings in the request (for actions like toggling -// full logging. -void ProcessQueryStringCommands(URLRequestContext* context, - const std::string& query) { - if (!StartsWithASCII(query, "commands=", true)) { - // Not a recognized format. - return; - } - - std::string commands_str = query.substr(strlen("commands=")); - commands_str = UnescapeURLComponent(commands_str, UnescapeRule::NORMAL); - - // The command list is comma-separated. - std::vector<std::string> commands; - SplitString(commands_str, ',', &commands); - - for (size_t i = 0; i < commands.size(); ++i) - HandleCommand(commands[i], context); -} - -// Appends some HTML controls to |data| that allow the user to enable full -// logging, and clear some of the already logged data. -void DrawControlsHeader(URLRequestContext* context, std::string* data) { - bool is_full_logging_enabled = - GetURLRequestTracker(context)->is_unbounded() && - GetSocketStreamTracker(context)->is_unbounded(); - - data->append("<div style='margin-bottom: 10px'>"); - - if (is_full_logging_enabled) { - DrawCommandButton("Disable full logging", "full-logging-disable", data); - } else { - DrawCommandButton("Enable full logging", "full-logging-enable", data); - } - - DrawCommandButton("Clear all data", - // Send a list of comma separated commands: - "clear-badproxies," - "clear-hostcache," - "clear-urlrequest-graveyard," - "clear-socketstream-graveyard," - "clear-hostresolver-trace", - data); - - data->append("</div>"); -} - -bool ViewNetInternalsJob::GetData(std::string* mime_type, - std::string* charset, - std::string* data) const { - mime_type->assign("text/html"); - charset->assign("UTF-8"); - - URLRequestContext* context = - static_cast<URLRequestContext*>(request_->context()); - - data->clear(); - - // Use a different handler for "view-cache/*" subpaths. - std::string cache_key; - if (GetViewCacheKeyForRequest(&cache_key)) { - GURL url = MakeURL(kViewHttpCacheSubPath + std::string("/")); - ViewCacheHelper::GetEntryInfoHTML(cache_key, context, url.spec(), data); - return true; - } - - // Handle any query arguments as a command request, then redirect back to - // the same URL stripped of query parameters. The redirect happens as part - // of IsRedirectResponse(). - if (request_->url().has_query()) { - ProcessQueryStringCommands(context, request_->url().query()); - return true; - } - - std::string details = GetDetails(request_->url()); - - data->append("<!DOCTYPE HTML>" - "<html><head><title>Network internals</title>" - "<style>" - "body { font-family: sans-serif; font-size: 0.8em; }\n" - "tt, code, pre { font-family: WebKitHack, monospace; }\n" - ".subsection_body { margin: 10px 0 10px 2em; }\n" - ".subsection_title { font-weight: bold; }\n" - "</style>" - "<script>\n" - - // Unfortunately we can't do XHR from chrome://net-internals - // because the chrome:// protocol restricts access. - // - // So instead, we will send commands by doing a form - // submission (which as a side effect will reload the page). - "function DoCommand(command) {\n" - " document.getElementById('cmd').value = command;\n" - " document.getElementById('cmdsender').submit();\n" - "}\n" - - "</script>\n" - "</head><body>" - "<form action='' method=GET id=cmdsender>" - "<input type='hidden' id=cmd name='commands'>" - "</form>" - "<p><a href='http://dev.chromium.org/" - "developers/design-documents/view-net-internals'>" - "Help: how do I use this?</a></p>"); - - DrawControlsHeader(context, data); - - SubSection* all = Singleton<AllSubSections>::get(); - SubSection* section = all; - - // Display only the subsection tree asked for. - if (!details.empty()) - section = all->FindSubSectionByName(details); - - if (section) { - section->OutputRecursive(context, data); - } else { - data->append("<i>Nothing found for \""); - data->append(EscapeForHTML(details)); - data->append("\"</i>"); - } - - data->append("</body></html>"); - - return true; -} - -bool ViewNetInternalsJob::IsRedirectResponse(GURL* location, - int* http_status_code) { - if (request_->url().has_query() && !GetViewCacheKeyForRequest(NULL)) { - // Strip the query parameters. - GURL::Replacements replacements; - replacements.ClearQuery(); - *location = request_->url().ReplaceComponents(replacements); - *http_status_code = 307; - return true; - } - return false; -} - -bool ViewNetInternalsJob::GetViewCacheKeyForRequest( - std::string* key) const { - std::string path = GetDetails(request_->url()); - if (!StartsWithASCII(path, kViewHttpCacheSubPath, true)) - return false; - - if (path.size() > strlen(kViewHttpCacheSubPath) && - path[strlen(kViewHttpCacheSubPath)] != '/') - return false; - - if (key && path.size() > strlen(kViewHttpCacheSubPath) + 1) - *key = path.substr(strlen(kViewHttpCacheSubPath) + 1); - - return true; -} - -} // namespace - -// static -bool ViewNetInternalsJobFactory::IsSupportedURL(const GURL& url) { - // Note that kNetworkViewInternalsURL is terminated by a '/'. - return StartsWithASCII(url.spec(), - chrome::kNetworkViewInternalsURL, - true /*case_sensitive*/); -} - -// static -URLRequestJob* ViewNetInternalsJobFactory::CreateJobForRequest( - URLRequest* request) { - return new ViewNetInternalsJob(request); -} |