2018-06-19 01:45:58 +00:00
|
|
|
// Copyright (c) 2018 GitHub, Inc.
|
|
|
|
// Use of this source code is governed by the MIT license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "atom/browser/api/atom_api_net_log.h"
|
2018-09-13 00:25:56 +00:00
|
|
|
|
|
|
|
#include <utility>
|
|
|
|
|
2018-10-04 18:08:56 +00:00
|
|
|
#include "atom/browser/atom_browser_context.h"
|
2019-01-12 01:00:43 +00:00
|
|
|
#include "atom/browser/net/system_network_context_manager.h"
|
2018-06-19 01:45:58 +00:00
|
|
|
#include "atom/common/native_mate_converters/callback.h"
|
|
|
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
2019-03-12 00:13:43 +00:00
|
|
|
#include "atom/common/node_includes.h"
|
2018-10-04 18:08:56 +00:00
|
|
|
#include "base/command_line.h"
|
2018-11-07 13:23:09 +00:00
|
|
|
#include "chrome/browser/browser_process.h"
|
2018-10-04 18:08:56 +00:00
|
|
|
#include "components/net_log/chrome_net_log.h"
|
|
|
|
#include "content/public/browser/storage_partition.h"
|
2018-06-19 01:45:58 +00:00
|
|
|
#include "native_mate/dictionary.h"
|
|
|
|
#include "native_mate/handle.h"
|
2018-10-04 18:08:56 +00:00
|
|
|
#include "net/url_request/url_request_context_getter.h"
|
2018-06-19 01:45:58 +00:00
|
|
|
|
2019-02-19 10:48:27 +00:00
|
|
|
namespace {
|
|
|
|
|
2019-02-21 12:32:44 +00:00
|
|
|
void OnGetFilePathToCompletedLog(const atom::util::CopyablePromise& promise,
|
2019-02-19 10:48:27 +00:00
|
|
|
const base::FilePath& file_path) {
|
2019-02-21 12:32:44 +00:00
|
|
|
promise.GetPromise().Resolve(file_path);
|
2019-02-19 10:48:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2018-06-19 01:45:58 +00:00
|
|
|
namespace atom {
|
|
|
|
|
|
|
|
namespace api {
|
|
|
|
|
2018-10-04 18:08:56 +00:00
|
|
|
NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
|
|
|
: browser_context_(browser_context) {
|
2018-06-19 01:45:58 +00:00
|
|
|
Init(isolate);
|
|
|
|
|
2019-01-12 01:00:43 +00:00
|
|
|
net_log_writer_ = g_browser_process->system_network_context_manager()
|
|
|
|
->GetNetExportFileWriter();
|
2018-10-04 18:08:56 +00:00
|
|
|
net_log_writer_->AddObserver(this);
|
2018-06-19 01:45:58 +00:00
|
|
|
}
|
|
|
|
|
2018-10-04 18:08:56 +00:00
|
|
|
NetLog::~NetLog() {
|
|
|
|
net_log_writer_->RemoveObserver(this);
|
2018-06-19 01:45:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void NetLog::StartLogging(mate::Arguments* args) {
|
|
|
|
base::FilePath log_path;
|
|
|
|
if (!args->GetNext(&log_path) || log_path.empty()) {
|
|
|
|
args->ThrowError("The first parameter must be a valid string");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-10-04 18:08:56 +00:00
|
|
|
auto* network_context =
|
|
|
|
content::BrowserContext::GetDefaultStoragePartition(browser_context_)
|
|
|
|
->GetNetworkContext();
|
|
|
|
|
|
|
|
// TODO(deepak1556): Provide more flexibility to this module
|
|
|
|
// by allowing customizations on the capturing options.
|
|
|
|
net_log_writer_->StartNetLog(
|
|
|
|
log_path, net::NetLogCaptureMode::Default(),
|
|
|
|
net_log::NetExportFileWriter::kNoLimit /* file size limit */,
|
|
|
|
base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
|
|
|
|
std::string(), network_context);
|
2018-06-19 01:45:58 +00:00
|
|
|
}
|
|
|
|
|
2018-10-04 18:08:56 +00:00
|
|
|
std::string NetLog::GetLoggingState() const {
|
|
|
|
if (!net_log_state_)
|
|
|
|
return std::string();
|
|
|
|
const base::Value* current_log_state =
|
|
|
|
net_log_state_->FindKeyOfType("state", base::Value::Type::STRING);
|
|
|
|
if (!current_log_state)
|
|
|
|
return std::string();
|
|
|
|
return current_log_state->GetString();
|
2018-06-19 01:45:58 +00:00
|
|
|
}
|
|
|
|
|
2018-10-04 18:08:56 +00:00
|
|
|
bool NetLog::IsCurrentlyLogging() const {
|
|
|
|
const std::string log_state = GetLoggingState();
|
|
|
|
return (log_state == "STARTING_LOG") || (log_state == "LOGGING");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string NetLog::GetCurrentlyLoggingPath() const {
|
|
|
|
// Net log exporter has a default path which will be used
|
|
|
|
// when no log path is provided, but since we don't allow
|
|
|
|
// net log capture without user provided file path, this
|
|
|
|
// check is completely safe.
|
|
|
|
if (IsCurrentlyLogging()) {
|
|
|
|
const base::Value* current_log_path =
|
|
|
|
net_log_state_->FindKeyOfType("file", base::Value::Type::STRING);
|
|
|
|
if (current_log_path)
|
|
|
|
return current_log_path->GetString();
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::string();
|
2018-06-19 01:45:58 +00:00
|
|
|
}
|
|
|
|
|
2019-02-19 10:48:27 +00:00
|
|
|
v8::Local<v8::Promise> NetLog::StopLogging(mate::Arguments* args) {
|
2019-02-21 12:32:44 +00:00
|
|
|
util::Promise promise(isolate());
|
|
|
|
v8::Local<v8::Promise> handle = promise.GetHandle();
|
2018-06-19 01:45:58 +00:00
|
|
|
|
2018-10-04 18:08:56 +00:00
|
|
|
if (IsCurrentlyLogging()) {
|
2019-02-21 12:32:44 +00:00
|
|
|
stop_callback_queue_.emplace_back(std::move(promise));
|
2018-10-04 18:08:56 +00:00
|
|
|
net_log_writer_->StopNetLog(nullptr);
|
|
|
|
} else {
|
2019-02-21 12:32:44 +00:00
|
|
|
promise.Resolve(base::FilePath());
|
2018-10-04 18:08:56 +00:00
|
|
|
}
|
2019-02-19 10:48:27 +00:00
|
|
|
|
2019-02-21 12:32:44 +00:00
|
|
|
return handle;
|
2018-10-04 18:08:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void NetLog::OnNewState(const base::DictionaryValue& state) {
|
|
|
|
net_log_state_ = state.CreateDeepCopy();
|
|
|
|
|
|
|
|
if (stop_callback_queue_.empty())
|
|
|
|
return;
|
|
|
|
|
2018-10-10 05:49:31 +00:00
|
|
|
if (GetLoggingState() == "NOT_LOGGING") {
|
2019-02-19 10:48:27 +00:00
|
|
|
for (auto& promise : stop_callback_queue_) {
|
2019-02-21 12:32:44 +00:00
|
|
|
// TODO(zcbenz): Remove the use of CopyablePromise when the
|
|
|
|
// GetFilePathToCompletedLog API accepts OnceCallback.
|
|
|
|
net_log_writer_->GetFilePathToCompletedLog(base::Bind(
|
|
|
|
&OnGetFilePathToCompletedLog, util::CopyablePromise(promise)));
|
2018-10-04 18:08:56 +00:00
|
|
|
}
|
|
|
|
stop_callback_queue_.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
mate::Handle<NetLog> NetLog::Create(v8::Isolate* isolate,
|
|
|
|
AtomBrowserContext* browser_context) {
|
|
|
|
return mate::CreateHandle(isolate, new NetLog(isolate, browser_context));
|
2018-06-19 01:45:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
void NetLog::BuildPrototype(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::FunctionTemplate> prototype) {
|
|
|
|
prototype->SetClassName(mate::StringToV8(isolate, "NetLog"));
|
|
|
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
|
|
|
.SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging)
|
|
|
|
.SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath)
|
|
|
|
.SetMethod("startLogging", &NetLog::StartLogging)
|
2018-10-04 18:08:56 +00:00
|
|
|
.SetMethod("stopLogging", &NetLog::StopLogging);
|
2018-06-19 01:45:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace api
|
|
|
|
|
|
|
|
} // namespace atom
|