summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_about_handler.cc14
-rw-r--r--chrome/common/url_constants.cc2
-rw-r--r--chrome/common/url_constants.h2
-rw-r--r--net/net.gyp2
-rw-r--r--net/proxy/proxy_service.h15
-rw-r--r--net/url_request/url_request_job_manager.cc2
-rw-r--r--net/url_request/url_request_view_net_internal_job.cc272
-rw-r--r--net/url_request/url_request_view_net_internal_job.h26
8 files changed, 329 insertions, 6 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc
index d7c14fc..4c8226e 100644
--- a/chrome/browser/browser_about_handler.cc
+++ b/chrome/browser/browser_about_handler.cc
@@ -65,7 +65,6 @@ using base::TimeDelta;
namespace {
// The paths used for the about pages.
-const char kCachePath[] = "cache";
const char kDnsPath[] = "dns";
const char kHistogramsPath[] = "histograms";
const char kObjectsPath[] = "objects";
@@ -783,6 +782,19 @@ bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) {
return true;
}
+ // Handle rewriting net-internal URLs. This allows us to load
+ // about:net-internal.
+ if (StartsWithASCII(url->spec(), chrome::kAboutNetInternalURL, true)) {
+ // Create a mapping from about:net-internal to the view-net-internal:
+ // internal URL.
+ std::string path;
+ size_t split = url->spec().find('/');
+ if (split != std::string::npos)
+ path = url->spec().substr(split + 1);
+ *url = GURL(std::string(chrome::kViewNetInternalScheme) + ":" + path);
+ return true;
+ }
+
// Handle URL to crash the browser process.
if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutBrowserCrash)) {
// Induce an intentional crash in the browser process.
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 03d048f..ed128cd 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -21,12 +21,14 @@ const char kMailToScheme[] = "mailto";
const char kPrintScheme[] = "print";
const char kUserScriptScheme[] = "chrome-user-script";
const char kViewCacheScheme[] = "view-cache";
+const char kViewNetInternalScheme[] = "view-net-internal";
const char kViewSourceScheme[] = "view-source";
const char kStandardSchemeSeparator[] = "://";
const char kAboutBlankURL[] = "about:blank";
const char kAboutCacheURL[] = "about:cache";
+const char kAboutNetInternalURL[] = "about:net-internal";
const char kAboutCrashURL[] = "about:crash";
const char kAboutHangURL[] = "about:hang";
const char kAboutMemoryURL[] = "about:memory";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 5917aaa..c647339 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -25,6 +25,7 @@ extern const char kMailToScheme[];
extern const char kPrintScheme[];
extern const char kUserScriptScheme[];
extern const char kViewCacheScheme[];
+extern const char kViewNetInternalScheme[];
extern const char kViewSourceScheme[];
// Used to separate a standard scheme and the hostname: "://".
@@ -34,6 +35,7 @@ extern const char kStandardSchemeSeparator[];
extern const char kAboutBlankURL[];
extern const char kAboutBrowserCrash[];
extern const char kAboutCacheURL[];
+extern const char kAboutNetInternalURL[];
extern const char kAboutCrashURL[];
extern const char kAboutHangURL[];
extern const char kAboutMemoryURL[];
diff --git a/net/net.gyp b/net/net.gyp
index 376bc1c..da8f4b5 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -357,6 +357,8 @@
'url_request/url_request_test_job.h',
'url_request/url_request_view_cache_job.cc',
'url_request/url_request_view_cache_job.h',
+ 'url_request/url_request_view_net_internal_job.cc',
+ 'url_request/url_request_view_net_internal_job.h',
],
'sources!': [
'build/precompiled_net.h',
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index cd76453..b38938f 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -107,6 +107,16 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService> {
return init_proxy_resolver_log_;
}
+ // Returns true if we have called UpdateConfig() at least once.
+ bool config_has_been_initialized() const {
+ return config_.id() != ProxyConfig::INVALID_ID;
+ }
+
+ // Returns the last configuration fetched from ProxyConfigService.
+ const ProxyConfig& config() {
+ return config_;
+ }
+
// Creates a proxy service using the specified settings. If |pc| is NULL then
// the system's default proxy settings will be used (on Windows this will
// use IE's settings).
@@ -162,11 +172,6 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService> {
// Identifies the proxy configuration.
ProxyConfig::ID config_id() const { return config_.id(); }
- // Returns true if we have called UpdateConfig() at least once.
- bool config_has_been_initialized() const {
- return config_.id() != ProxyConfig::INVALID_ID;
- }
-
// Checks to see if the proxy configuration changed, and then updates config_
// to reference the new configuration.
void UpdateConfig();
diff --git a/net/url_request/url_request_job_manager.cc b/net/url_request/url_request_job_manager.cc
index 0b193c4..241edec 100644
--- a/net/url_request/url_request_job_manager.cc
+++ b/net/url_request/url_request_job_manager.cc
@@ -20,6 +20,7 @@
#endif
#include "net/url_request/url_request_http_job.h"
#include "net/url_request/url_request_view_cache_job.h"
+#include "net/url_request/url_request_view_net_internal_job.h"
// The built-in set of protocol factories
namespace {
@@ -42,6 +43,7 @@ static const SchemeToFactory kBuiltinFactories[] = {
#endif
{ "about", URLRequestAboutJob::Factory },
{ "view-cache", URLRequestViewCacheJob::Factory },
+ { "view-net-internal", URLRequestViewNetInternalJob::Factory },
};
URLRequestJobManager::URLRequestJobManager() {
diff --git a/net/url_request/url_request_view_net_internal_job.cc b/net/url_request/url_request_view_net_internal_job.cc
new file mode 100644
index 0000000..dba83b1
--- /dev/null
+++ b/net/url_request/url_request_view_net_internal_job.cc
@@ -0,0 +1,272 @@
+// Copyright (c) 2009 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 <sstream>
+
+#include "net/url_request/url_request_view_net_internal_job.h"
+
+#include "base/stl_util-inl.h"
+#include "base/string_util.h"
+#include "net/base/escape.h"
+#include "net/base/load_log_util.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_service.h"
+#include "net/url_request/url_request_context.h"
+
+namespace {
+
+//------------------------------------------------------------------------------
+// Format helpers.
+//------------------------------------------------------------------------------
+
+void OutputTextInPre(const std::string& text, std::string* out) {
+ out->append("<pre>");
+ out->append(EscapeForHTML(text));
+ out->append("</pre>");
+}
+
+//------------------------------------------------------------------------------
+// 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()) {
+ // Print the heading.
+ out->append(StringPrintf("<div>"
+ "<span class=subsection_title>%s</span> "
+ "<span class=subsection_name>(about:net-internal/%s)<span>"
+ "</div>",
+ EscapeForHTML(title_).c_str(),
+ EscapeForHTML(GetFullyQualifiedName()).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:
+ ProxyServiceCurrentConfigSubSection(SubSection* parent)
+ : SubSection(parent, "config", "Current configuration") {
+ }
+
+ virtual void OutputBody(URLRequestContext* context, std::string* 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:
+ ProxyServiceLastInitLogSubSection(SubSection* parent)
+ : SubSection(parent, "init_log", "Last initialized load log") {
+ }
+
+ virtual void OutputBody(URLRequestContext* context, std::string* out) {
+ net::ProxyService* proxy_service = context->proxy_service();
+ net::LoadLog* log = proxy_service->init_proxy_resolver_log();
+ if (log) {
+ OutputTextInPre(net::LoadLogUtil::PrettyPrintAsEventTree(log), out);
+ } else {
+ out->append("<i>None.</i>");
+ }
+ }
+};
+
+class ProxyServiceBadProxiesSubSection : public SubSection {
+ public:
+ ProxyServiceBadProxiesSubSection(SubSection* parent)
+ : SubSection(parent, "bad_proxies", "Bad Proxies") {
+ }
+
+ virtual void OutputBody(URLRequestContext* context, std::string* out) {
+ out->append("TODO");
+ }
+};
+
+class ProxyServiceSubSection : public SubSection {
+ public:
+ ProxyServiceSubSection(SubSection* parent)
+ : SubSection(parent, "proxyservice", "ProxyService") {
+ AddSubSection(new ProxyServiceCurrentConfigSubSection(this));
+ AddSubSection(new ProxyServiceLastInitLogSubSection(this));
+ AddSubSection(new ProxyServiceBadProxiesSubSection(this));
+ }
+};
+
+class HostResolverCacheSubSection : public SubSection {
+ public:
+ HostResolverCacheSubSection(SubSection* parent)
+ : SubSection(parent, "hostcache", "HostCache") {
+ }
+
+ virtual void OutputBody(URLRequestContext* context, std::string* out) {
+ out->append("TODO");
+ }
+};
+
+class HostResolverSubSection : public SubSection {
+ public:
+ HostResolverSubSection(SubSection* parent)
+ : SubSection(parent, "hostresolver", "HostResolver") {
+ AddSubSection(new HostResolverCacheSubSection(this));
+ }
+};
+
+class URLRequestSubSection : public SubSection {
+ public:
+ URLRequestSubSection(SubSection* parent)
+ : SubSection(parent, "urlrequest", "URLRequest") {
+ }
+
+ virtual void OutputBody(URLRequestContext* context, std::string* out) {
+ out->append("TODO");
+ }
+};
+
+class AllSubSections : public SubSection {
+ public:
+ AllSubSections() : SubSection(NULL, "", "") {
+ AddSubSection(new ProxyServiceSubSection(this));
+ AddSubSection(new HostResolverSubSection(this));
+ AddSubSection(new URLRequestSubSection(this));
+ }
+};
+
+} // namespace
+
+// static
+URLRequestJob* URLRequestViewNetInternalJob::Factory(
+ URLRequest* request, const std::string& scheme) {
+ return new URLRequestViewNetInternalJob(request);
+}
+
+bool URLRequestViewNetInternalJob::GetData(std::string* mime_type,
+ std::string* charset,
+ std::string* data) const {
+ DCHECK_EQ(std::string("view-net-internal"), request_->url().scheme());
+
+ mime_type->assign("text/html");
+ charset->assign("UTF-8");
+
+ URLRequestContext* context = request_->context();
+ std::string path = request_->url().path();
+
+ data->clear();
+ data->append("<html><head><title>Network internals</title>"
+ "<style>"
+ "body { font-family: sans-serif; }\n"
+ ".subsection_body { margin: 10px 0 10px 2em; }\n"
+ ".subsection_title { font-weight: bold; }\n"
+ ".subsection_name { font-size: 80%; }\n"
+ "</style>"
+ "</head><body>");
+
+ SubSection* all = Singleton<AllSubSections>::get();
+ SubSection* section = all;
+
+ // Display only the subsection tree asked for.
+ if (!path.empty())
+ section = all->FindSubSectionByName(path);
+
+ if (section) {
+ section->OutputRecursive(context, data);
+ } else {
+ data->append("<i>Nothing found for \"");
+ data->append(EscapeForHTML(path));
+ data->append("\"</i>");
+ }
+
+ data->append("</body></html>");
+
+ return true;
+}
+
diff --git a/net/url_request/url_request_view_net_internal_job.h b/net/url_request/url_request_view_net_internal_job.h
new file mode 100644
index 0000000..4044041
--- /dev/null
+++ b/net/url_request/url_request_view_net_internal_job.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2009 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.
+
+#ifndef NET_URL_REQUEST_URL_REQUEST_VIEW_NET_INTERNAL_JOB_H_
+#define NET_URL_REQUEST_URL_REQUEST_VIEW_NET_INTERNAL_JOB_H_
+
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_simple_job.h"
+
+// A job subclass that implements the view-net-internal: protocol, which simply
+// provides a debug view of the various network components.
+class URLRequestViewNetInternalJob : public URLRequestSimpleJob {
+ public:
+ URLRequestViewNetInternalJob(URLRequest* request)
+ : URLRequestSimpleJob(request) {}
+
+ static URLRequest::ProtocolFactory Factory;
+
+ // override from URLRequestSimpleJob
+ virtual bool GetData(std::string* mime_type,
+ std::string* charset,
+ std::string* data) const;
+};
+
+#endif // NET_URL_REQUEST_URL_REQUEST_VIEW_NET_INTERNAL_JOB_H_