Index: chrome/browser/net/view_http_cache_job_factory.cc |
=================================================================== |
--- chrome/browser/net/view_http_cache_job_factory.cc (revision 46824) |
+++ chrome/browser/net/view_http_cache_job_factory.cc (working copy) |
@@ -2,25 +2,9 @@ |
// 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 "chrome/browser/net/view_http_cache_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" |
@@ -28,74 +12,10 @@ |
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 { |
+// A job subclass that dumps an HTTP cache entry. |
+class ViewHttpCacheJob : public URLRequestSimpleJob { |
public: |
- |
- explicit ViewNetInternalsJob(URLRequest* request) |
+ explicit ViewHttpCacheJob(URLRequest* request) |
: URLRequestSimpleJob(request) {} |
// URLRequestSimpleJob methods: |
@@ -103,773 +23,40 @@ |
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; |
+ ~ViewHttpCacheJob() {} |
}; |
-//------------------------------------------------------------------------------ |
-// 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 { |
+bool ViewHttpCacheJob::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; |
- } |
+ cache_key = |
+ request_->url().spec().substr(strlen(chrome::kNetworkViewCacheURL)); |
+ ViewCacheHelper::GetEntryInfoHTML(cache_key, |
+ request_->context(), |
+ chrome::kNetworkViewCacheURL, |
+ data); |
- // 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 '/'. |
+bool ViewHttpCacheJobFactory::IsSupportedURL(const GURL& url) { |
return StartsWithASCII(url.spec(), |
- chrome::kNetworkViewInternalsURL, |
+ chrome::kNetworkViewCacheURL, |
true /*case_sensitive*/); |
} |
// static |
-URLRequestJob* ViewNetInternalsJobFactory::CreateJobForRequest( |
+URLRequestJob* ViewHttpCacheJobFactory::CreateJobForRequest( |
URLRequest* request) { |
- return new ViewNetInternalsJob(request); |
+ return new ViewHttpCacheJob(request); |
} |