diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-13 03:20:06 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-13 03:20:06 +0000 |
commit | 4634dfa6cd9128f1aad2b455a43e802ad82510a5 (patch) | |
tree | 70ae1a309395f51d27e43656d0fc9ca684ddc18b /net | |
parent | 5ac843ca1cd19a5eab6efc3adb22560dd40f1756 (diff) | |
download | chromium_src-4634dfa6cd9128f1aad2b455a43e802ad82510a5.zip chromium_src-4634dfa6cd9128f1aad2b455a43e802ad82510a5.tar.gz chromium_src-4634dfa6cd9128f1aad2b455a43e802ad82510a5.tar.bz2 |
Miscellaneous tweaks to the about:net-internals page.
* Display the time to live of negative host cache entries (and don't make the whole line red).
* Generalize the buttons, so each subsection can specify their own; to that end, adds a button to clear the hostcache, url request recent requests, socket stream recent requests. (I intend to add a button to force refetching of proxy config as well).
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/548021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36084 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/url_request/url_request_view_net_internals_job.cc | 182 |
1 files changed, 123 insertions, 59 deletions
diff --git a/net/url_request/url_request_view_net_internals_job.cc b/net/url_request/url_request_view_net_internals_job.cc index 733be40..7ee7d7f 100644 --- a/net/url_request/url_request_view_net_internals_job.cc +++ b/net/url_request/url_request_view_net_internals_job.cc @@ -35,6 +35,19 @@ void OutputTextInPre(const std::string& text, std::string* out) { 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) { + data->append( + StringPrintf("<input type=\"button\" value=\"%s\" " + "onclick=\"DoCommand('%s')\" />", + title.c_str(), + command.c_str())); +} + + //------------------------------------------------------------------------------ // Subsection definitions. //------------------------------------------------------------------------------ @@ -148,6 +161,7 @@ class ProxyServiceCurrentConfigSubSection : public SubSection { } virtual void OutputBody(URLRequestContext* context, std::string* out) { + // TODO(eroman): add a button to force reloading the proxy config. net::ProxyService* proxy_service = context->proxy_service(); if (proxy_service->config_has_been_initialized()) { // net::ProxyConfig defines an operator<<. @@ -212,6 +226,8 @@ class HostResolverCacheSubSection : public SubSection { return; } + DrawCommandButton("Clear", "clear-hostcache", out); + out->append(StringPrintf( "<ul><li>Size: %" PRIuS "</li>" "<li>Capacity: %" PRIuS "</li>" @@ -240,22 +256,27 @@ class HostResolverCacheSubSection : public SubSection { std::string address_family_str = AddressFamilyToString(key.address_family); - if (entry->error == net::OK) { - // 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'>"); - } + // 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()); - // Stringify all of the addresses in the address list, separated - // by newlines (br). - std::string address_list_html; + // 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; + + 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()) @@ -264,23 +285,14 @@ class HostResolverCacheSubSection : public SubSection { net::NetAddressToString(current_address)); current_address = current_address->ai_next; } - - out->append(StringPrintf("<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(), - ttl_ms)); - } else { - // This was an entry that failed to be resolved. - // Color negative entries red. - out->append(StringPrintf( - "<tr style='color:red'><td>%s</td><td>%s</td>" - "<td colspan=2>%s</td></tr>", - EscapeForHTML(key.hostname).c_str(), - EscapeForHTML(address_family_str).c_str(), - EscapeForHTML(net::ErrorToString(entry->error)).c_str())); } + + out->append(StringPrintf("<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(), + ttl_ms)); } out->append("</table>"); @@ -354,6 +366,8 @@ class URLRequestRecentSubSection : public SubSection { RequestTracker<URLRequest>::RecentRequestInfoList recent = context->url_request_tracker()->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. @@ -432,6 +446,8 @@ class SocketStreamRecentSubSection : public SubSection { RequestTracker<net::SocketStream>::RecentRequestInfoList recent = context->socket_stream_tracker()->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. @@ -480,49 +496,77 @@ bool GetViewCacheKeyFromPath(const std::string path, return true; } -// Process any query strings in the request (for actions like toggling -// full logging. As a side-effect, also append some status text to the HTML -// describing what we did. -void ProcessQueryStringCommands(URLRequestContext* context, - const std::string& query, - std::string* data) { - if (StartsWithASCII(query, "logging=", true)) { - bool enable_unbounded = StartsWithASCII(query, "logging=E", true); - context->url_request_tracker()->SetUnbounded(enable_unbounded); - context->socket_stream_tracker()->SetUnbounded(enable_unbounded); - - if (enable_unbounded) - data->append("<i>Enabled full logging for this session.</i>\n"); - else - data->append("<i>Disabled full logging, and cleared the recent " - "requests</i>\n"); - - } else if (StartsWithASCII(query, "data=Clear", true)) { +bool HandleCommand(const std::string& command, URLRequestContext* context) { + if (StartsWithASCII(command, "full-logging-", true)) { + bool enable_full_logging = (command == "full-logging-enable"); + context->url_request_tracker()->SetUnbounded(enable_full_logging); + context->socket_stream_tracker()->SetUnbounded(enable_full_logging); + return true; + } + + if (command == "clear-urlrequest-graveyard") { context->url_request_tracker()->ClearRecentlyDeceased(); + return true; + } + + if (command == "clear-socketstream-graveyard") { context->socket_stream_tracker()->ClearRecentlyDeceased(); + return true; + } + + if (command == "clear-hostcache") { + net::HostCache* host_cache = context->host_resolver()->GetHostCache(); + if (host_cache) + host_cache->clear(); + return true; + } - data->append("<i>Cleared the recent request logs</i>\n"); + 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); } -// Append some HTML controls to |data| that allow the user to enable full +// 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 = context->url_request_tracker()->IsUnbounded() && context->socket_stream_tracker()->IsUnbounded(); - data->append("<form action='' method=GET style='margin-bottom: 10px'>\n"); + data->append("<div style='margin-bottom: 10px'>"); + if (is_full_logging_enabled) { - data->append( - "<input type=submit name=logging value='Disable full logging' />"); + DrawCommandButton("Disable full logging", "full-logging-disable", data); } else { - data->append( - "<input type=submit name=logging value='Enable full logging' />"); + DrawCommandButton("Enable full logging", "full-logging-enable", data); } - data->append("<input type=submit name=data value='Clear recent requests' />"); - data->append("</form>\n"); + DrawCommandButton("Clear all data", + // Send a list of comma separated commands: + "clear-hostcache," + "clear-urlrequest-graveyard," + "clear-socketstream-graveyard", + data); + + data->append("</div>"); } } // namespace @@ -564,12 +608,32 @@ bool URLRequestViewNetInternalsJob::GetData(std::string* mime_type, ".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>"); - ProcessQueryStringCommands(context, query, data); + // TODO(eroman): do a redirect after processing the commands, to clear the + // URL of the command string (otherwise if you refresh the page you + // re-execute the command, which can be confusing when that command was to + // clear all the data!). + ProcessQueryStringCommands(context, query); DrawControlsHeader(context, data); SubSection* all = Singleton<AllSubSections>::get(); |