atom_api_net_log.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (c) 2018 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/browser/api/atom_api_net_log.h"
  5. #include <utility>
  6. #include "atom/browser/atom_browser_context.h"
  7. #include "atom/browser/net/system_network_context_manager.h"
  8. #include "atom/common/native_mate_converters/callback.h"
  9. #include "atom/common/native_mate_converters/file_path_converter.h"
  10. #include "atom/common/node_includes.h"
  11. #include "base/command_line.h"
  12. #include "chrome/browser/browser_process.h"
  13. #include "components/net_log/chrome_net_log.h"
  14. #include "content/public/browser/storage_partition.h"
  15. #include "native_mate/dictionary.h"
  16. #include "native_mate/handle.h"
  17. #include "net/url_request/url_request_context_getter.h"
  18. namespace atom {
  19. namespace api {
  20. NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
  21. : browser_context_(browser_context) {
  22. Init(isolate);
  23. net_log_writer_ = g_browser_process->system_network_context_manager()
  24. ->GetNetExportFileWriter();
  25. net_log_writer_->AddObserver(this);
  26. }
  27. NetLog::~NetLog() {
  28. net_log_writer_->RemoveObserver(this);
  29. }
  30. void NetLog::StartLogging(mate::Arguments* args) {
  31. base::FilePath log_path;
  32. if (!args->GetNext(&log_path) || log_path.empty()) {
  33. args->ThrowError("The first parameter must be a valid string");
  34. return;
  35. }
  36. auto* network_context =
  37. content::BrowserContext::GetDefaultStoragePartition(browser_context_)
  38. ->GetNetworkContext();
  39. // TODO(deepak1556): Provide more flexibility to this module
  40. // by allowing customizations on the capturing options.
  41. net_log_writer_->StartNetLog(
  42. log_path, net::NetLogCaptureMode::Default(),
  43. net_log::NetExportFileWriter::kNoLimit /* file size limit */,
  44. base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
  45. std::string(), network_context);
  46. }
  47. std::string NetLog::GetLoggingState() const {
  48. if (!net_log_state_)
  49. return std::string();
  50. const base::Value* current_log_state =
  51. net_log_state_->FindKeyOfType("state", base::Value::Type::STRING);
  52. if (!current_log_state)
  53. return std::string();
  54. return current_log_state->GetString();
  55. }
  56. bool NetLog::IsCurrentlyLogging() const {
  57. const std::string log_state = GetLoggingState();
  58. return (log_state == "STARTING_LOG") || (log_state == "LOGGING");
  59. }
  60. std::string NetLog::GetCurrentlyLoggingPath() const {
  61. // Net log exporter has a default path which will be used
  62. // when no log path is provided, but since we don't allow
  63. // net log capture without user provided file path, this
  64. // check is completely safe.
  65. if (IsCurrentlyLogging()) {
  66. const base::Value* current_log_path =
  67. net_log_state_->FindKeyOfType("file", base::Value::Type::STRING);
  68. if (current_log_path)
  69. return current_log_path->GetString();
  70. }
  71. return std::string();
  72. }
  73. v8::Local<v8::Promise> NetLog::StopLogging(mate::Arguments* args) {
  74. util::Promise promise(isolate());
  75. v8::Local<v8::Promise> handle = promise.GetHandle();
  76. if (IsCurrentlyLogging()) {
  77. stop_callback_queue_.emplace_back(std::move(promise));
  78. net_log_writer_->StopNetLog(nullptr);
  79. } else {
  80. promise.Resolve(base::FilePath());
  81. }
  82. return handle;
  83. }
  84. void NetLog::OnNewState(const base::DictionaryValue& state) {
  85. net_log_state_ = state.CreateDeepCopy();
  86. if (stop_callback_queue_.empty())
  87. return;
  88. if (GetLoggingState() == "NOT_LOGGING") {
  89. for (auto& promise : stop_callback_queue_) {
  90. // TODO(zcbenz): Remove the use of CopyablePromise when the
  91. // GetFilePathToCompletedLog API accepts OnceCallback.
  92. net_log_writer_->GetFilePathToCompletedLog(base::Bind(
  93. util::CopyablePromise::ResolveCopyablePromise<const base::FilePath&>,
  94. util::CopyablePromise(promise)));
  95. }
  96. stop_callback_queue_.clear();
  97. }
  98. }
  99. // static
  100. mate::Handle<NetLog> NetLog::Create(v8::Isolate* isolate,
  101. AtomBrowserContext* browser_context) {
  102. return mate::CreateHandle(isolate, new NetLog(isolate, browser_context));
  103. }
  104. // static
  105. void NetLog::BuildPrototype(v8::Isolate* isolate,
  106. v8::Local<v8::FunctionTemplate> prototype) {
  107. prototype->SetClassName(mate::StringToV8(isolate, "NetLog"));
  108. mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
  109. .SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging)
  110. .SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath)
  111. .SetMethod("startLogging", &NetLog::StartLogging)
  112. .SetMethod("stopLogging", &NetLog::StopLogging);
  113. }
  114. } // namespace api
  115. } // namespace atom