Index: chrome/browser/dom_ui/net_internals_ui.cc |
=================================================================== |
--- chrome/browser/dom_ui/net_internals_ui.cc (revision 43515) |
+++ chrome/browser/dom_ui/net_internals_ui.cc (working copy) |
@@ -4,6 +4,8 @@ |
#include "chrome/browser/dom_ui/net_internals_ui.h" |
+#include <sstream> |
+ |
#include "app/resource_bundle.h" |
#include "base/file_util.h" |
#include "base/path_service.h" |
@@ -12,15 +14,25 @@ |
#include "base/string_util.h" |
#include "base/values.h" |
#include "chrome/browser/browser_process.h" |
+#include "chrome/browser/chrome_thread.h" |
#include "chrome/browser/dom_ui/chrome_url_data_manager.h" |
-#include "chrome/browser/chrome_thread.h" |
#include "chrome/browser/io_thread.h" |
#include "chrome/browser/net/chrome_net_log.h" |
+#include "chrome/browser/net/url_request_context_getter.h" |
+#include "chrome/browser/profile.h" |
#include "chrome/common/chrome_paths.h" |
#include "chrome/common/url_constants.h" |
+#include "net/base/escape.h" |
+#include "net/proxy/proxy_service.h" |
+#include "net/url_request/url_request_context.h" |
namespace { |
+// Formats |t| as a decimal number, in milliseconds. |
+std::string TickCountToString(const base::TimeTicks& t) { |
+ return Int64ToString((t - base::TimeTicks()).InMilliseconds()); |
+} |
+ |
// TODO(eroman): Bootstrap the net-internals page using the passively logged |
// data. |
@@ -93,7 +105,8 @@ |
// we need to grab it from the UI thread). |
IOThreadImpl( |
const base::WeakPtr<NetInternalsMessageHandler>& handler, |
- IOThread* io_thread); |
+ IOThread* io_thread, |
+ URLRequestContextGetter* context_getter); |
~IOThreadImpl(); |
@@ -115,6 +128,11 @@ |
// it indicates that the renderer is ready to start receiving captured data. |
void OnRendererReady(const Value* value); |
+ void OnGetProxySettings(const Value* value); |
+ void OnReloadProxySettings(const Value* value); |
+ void OnGetBadProxies(const Value* value); |
+ void OnClearBadProxies(const Value* value); |
+ |
// ChromeNetLog::Observer implementation: |
virtual void OnAddEntry(const net::NetLog::Entry& entry); |
@@ -129,7 +147,6 @@ |
void CallJavascriptFunction(const std::wstring& function_name, |
Value* arg); |
- private: |
// Pointer to the UI-thread message handler. Only access this from |
// the UI thread. |
base::WeakPtr<NetInternalsMessageHandler> handler_; |
@@ -137,6 +154,8 @@ |
// The global IOThread, which contains the global NetLog to observer. |
IOThread* io_thread_; |
+ scoped_refptr<URLRequestContextGetter> context_getter_; |
+ |
// True if we have attached an observer to the NetLog already. |
bool is_observing_log_; |
friend class base::RefCountedThreadSafe<IOThreadImpl>; |
@@ -192,7 +211,15 @@ |
std::string data_string; |
FilePath file_path; |
PathService::Get(chrome::DIR_NET_INTERNALS, &file_path); |
- std::string filename = path.empty() ? "index.html" : path; |
+ std::string filename; |
+ |
+ // The provided "path" may contain a fragment, or query section. We only |
+ // care about the path itself, and will disregard anything else. |
+ filename = GURL(std::string("chrome://net/") + path).path().substr(1); |
+ |
+ if (filename.empty()) |
+ filename = "index.html"; |
+ |
file_path = file_path.AppendASCII(filename); |
if (!file_util::ReadFileToString(file_path, &data_string)) { |
@@ -233,7 +260,8 @@ |
DOMMessageHandler* NetInternalsMessageHandler::Attach(DOMUI* dom_ui) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
- proxy_ = new IOThreadImpl(this->AsWeakPtr(), g_browser_process->io_thread()); |
+ proxy_ = new IOThreadImpl(this->AsWeakPtr(), g_browser_process->io_thread(), |
+ dom_ui->GetProfile()->GetRequestContext()); |
DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui); |
return result; |
} |
@@ -243,6 +271,14 @@ |
dom_ui_->RegisterMessageCallback("notifyReady", |
proxy_->CreateCallback(&IOThreadImpl::OnRendererReady)); |
+ dom_ui_->RegisterMessageCallback("getProxySettings", |
+ proxy_->CreateCallback(&IOThreadImpl::OnGetProxySettings)); |
+ dom_ui_->RegisterMessageCallback("reloadProxySettings", |
+ proxy_->CreateCallback(&IOThreadImpl::OnReloadProxySettings)); |
+ dom_ui_->RegisterMessageCallback("getBadProxies", |
+ proxy_->CreateCallback(&IOThreadImpl::OnGetBadProxies)); |
+ dom_ui_->RegisterMessageCallback("clearBadProxies", |
+ proxy_->CreateCallback(&IOThreadImpl::OnClearBadProxies)); |
} |
void NetInternalsMessageHandler::CallJavascriptFunction( |
@@ -260,9 +296,11 @@ |
NetInternalsMessageHandler::IOThreadImpl::IOThreadImpl( |
const base::WeakPtr<NetInternalsMessageHandler>& handler, |
- IOThread* io_thread) |
+ IOThread* io_thread, |
+ URLRequestContextGetter* context_getter) |
: handler_(handler), |
io_thread_(io_thread), |
+ context_getter_(context_getter), |
is_observing_log_(false) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
} |
@@ -308,7 +346,7 @@ |
static_cast<int>(event_types[i])); |
} |
- CallJavascriptFunction(L"setLogEventTypeConstants", dict); |
+ CallJavascriptFunction(L"g_browser.receivedLogEventTypeConstants", dict); |
} |
// Tell the javascript about the relationship between event phase enums and |
@@ -320,7 +358,7 @@ |
dict->SetInteger(L"PHASE_END", net::NetLog::PHASE_END); |
dict->SetInteger(L"PHASE_NONE", net::NetLog::PHASE_NONE); |
- CallJavascriptFunction(L"setLogEventPhaseConstants", dict); |
+ CallJavascriptFunction(L"g_browser.receivedLogEventPhaseConstants", dict); |
} |
// Tell the javascript about the relationship between source type enums and |
@@ -336,7 +374,7 @@ |
net::NetLog::SOURCE_INIT_PROXY_RESOLVER); |
dict->SetInteger(L"CONNECT_JOB", net::NetLog::SOURCE_CONNECT_JOB); |
- CallJavascriptFunction(L"setLogSourceTypeConstants", dict); |
+ CallJavascriptFunction(L"g_browser.receivedLogSourceTypeConstants", dict); |
} |
// Tell the javascript about the relationship between entry type enums and |
@@ -348,10 +386,101 @@ |
dict->SetInteger(L"TYPE_STRING", net::NetLog::Entry::TYPE_STRING); |
dict->SetInteger(L"TYPE_ERROR_CODE", net::NetLog::Entry::TYPE_ERROR_CODE); |
- CallJavascriptFunction(L"setLogEntryTypeConstants", dict); |
+ CallJavascriptFunction(L"g_browser.receivedLogEntryTypeConstants", dict); |
} |
+ |
+ // Tell the javascript how the "time ticks" values we have given it relate to |
+ // actual system times. (We used time ticks throughout since they are stable |
+ // across system clock changes). |
+ { |
+ int64 cur_time_ms = (base::Time::Now() - base::Time()).InMilliseconds(); |
+ |
+ int64 cur_time_ticks_ms = |
+ (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds(); |
+ |
+ // If we add this number to a time tick value, it gives the timestamp. |
+ int64 tick_to_time_ms = cur_time_ms - cur_time_ticks_ms; |
+ |
+ // Chrome on all platforms stores times using the Windows epoch |
+ // (Jan 1 1601), but the javascript wants a unix epoch. |
+ // TODO(eroman): Getting the timestamp relative the to unix epoch should |
+ // be part of the time library. |
+ const int64 kUnixEpochMs = 11644473600000LL; |
+ int64 tick_to_unix_time_ms = tick_to_time_ms - kUnixEpochMs; |
+ |
+ // Pass it as a string, since it may be too large to fit in an integer. |
+ CallJavascriptFunction(L"g_browser.receivedTimeTickOffset", |
+ Value::CreateStringValue( |
+ Int64ToString(tick_to_unix_time_ms))); |
+ } |
+ |
+ // Notify the client of the basic proxy data. |
+ OnGetProxySettings(NULL); |
+ OnGetBadProxies(NULL); |
} |
+void NetInternalsMessageHandler::IOThreadImpl::OnGetProxySettings( |
+ const Value* value) { |
+ URLRequestContext* context = context_getter_->GetURLRequestContext(); |
+ net::ProxyService* proxy_service = context->proxy_service(); |
+ |
+ // TODO(eroman): send a dictionary rather than a flat string, so client can do |
+ // its own presentation. |
+ std::string settings_string; |
+ |
+ if (proxy_service->config_has_been_initialized()) { |
+ // net::ProxyConfig defines an operator<<. |
+ std::ostringstream stream; |
+ stream << proxy_service->config(); |
+ settings_string = stream.str(); |
+ } |
+ |
+ CallJavascriptFunction(L"g_browser.receivedProxySettings", |
+ Value::CreateStringValue(settings_string)); |
+} |
+ |
+void NetInternalsMessageHandler::IOThreadImpl::OnReloadProxySettings( |
+ const Value* value) { |
+ URLRequestContext* context = context_getter_->GetURLRequestContext(); |
+ context->proxy_service()->ForceReloadProxyConfig(); |
+ |
+ // Cause the renderer to be notified of the new values. |
+ OnGetProxySettings(NULL); |
+} |
+ |
+void NetInternalsMessageHandler::IOThreadImpl::OnGetBadProxies( |
+ const Value* value) { |
+ URLRequestContext* context = context_getter_->GetURLRequestContext(); |
+ |
+ const net::ProxyRetryInfoMap& bad_proxies_map = |
+ context->proxy_service()->proxy_retry_info(); |
+ |
+ ListValue* list = new ListValue(); |
+ |
+ 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; |
+ |
+ DictionaryValue* dict = new DictionaryValue(); |
+ dict->SetString(L"proxy_uri", proxy_uri); |
+ dict->SetString(L"bad_until", TickCountToString(retry_info.bad_until)); |
+ |
+ list->Append(dict); |
+ } |
+ |
+ CallJavascriptFunction(L"g_browser.receivedBadProxies", list); |
+} |
+ |
+void NetInternalsMessageHandler::IOThreadImpl::OnClearBadProxies( |
+ const Value* value) { |
+ URLRequestContext* context = context_getter_->GetURLRequestContext(); |
+ context->proxy_service()->ClearBadProxiesCache(); |
+ |
+ // Cause the renderer to be notified of the new values. |
+ OnGetBadProxies(NULL); |
+} |
+ |
void NetInternalsMessageHandler::IOThreadImpl::OnAddEntry( |
const net::NetLog::Entry& entry) { |
DCHECK(is_observing_log_); |
@@ -368,10 +497,9 @@ |
entry_dict->SetInteger(L"type", static_cast<int>(entry_type)); |
} |
- // Set the entry time. |
- entry_dict->SetInteger( |
- L"time", |
- static_cast<int>((entry.time - base::TimeTicks()).InMilliseconds())); |
+ // Set the entry time. (Note that we send it as a string since integers |
+ // might overflow). |
+ entry_dict->SetString(L"time", TickCountToString(entry.time)); |
// Set the entry source. |
DictionaryValue* source_dict = new DictionaryValue(); |
@@ -402,7 +530,7 @@ |
entry_dict->SetInteger(L"error_code", entry.error_code); |
} |
- CallJavascriptFunction(L"onLogEntryAdded", entry_dict); |
+ CallJavascriptFunction(L"g_browser.receivedLogEntry", entry_dict); |
} |
void NetInternalsMessageHandler::IOThreadImpl::DispatchToMessageHandler( |
@@ -439,7 +567,6 @@ |
// Failed posting the task, avoid leaking. |
delete arg; |
} |
- |
} |
} // namespace |