Roll src/third_party/WebKit 9f7fb92:f103b33 (svn 202621:202622)
[chromium-blink-merge.git] / components / net_log / net_log_temp_file.cc
bloba8073dd50b88cfd917e199c99a2ba1a14c4c1578
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/net_log/net_log_temp_file.h"
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/files/scoped_file.h"
10 #include "base/values.h"
11 #include "components/net_log/chrome_net_log.h"
12 #include "net/log/write_to_file_net_log_observer.h"
14 namespace net_log {
16 // Path of logs relative to base::GetTempDir(). Must be kept in sync
17 // with chrome/android/java/res/xml/file_paths.xml
18 base::FilePath::CharType kLogRelativePath[] =
19 FILE_PATH_LITERAL("net-export/chrome-net-export-log.json");
21 // Old path used by net-export. Used to delete old files.
22 // TODO(mmenke): Should remove at some point. Added in M46.
23 base::FilePath::CharType kOldLogRelativePath[] =
24 FILE_PATH_LITERAL("chrome-net-export-log.json");
26 NetLogTempFile::~NetLogTempFile() {
27 if (write_to_file_observer_)
28 write_to_file_observer_->StopObserving(nullptr);
31 void NetLogTempFile::ProcessCommand(Command command) {
32 DCHECK(thread_checker_.CalledOnValidThread());
33 if (!EnsureInit())
34 return;
36 switch (command) {
37 case DO_START_LOG_BYTES:
38 StartNetLog(LOG_TYPE_LOG_BYTES);
39 break;
40 case DO_START:
41 StartNetLog(LOG_TYPE_NORMAL);
42 break;
43 case DO_START_STRIP_PRIVATE_DATA:
44 StartNetLog(LOG_TYPE_STRIP_PRIVATE_DATA);
45 break;
46 case DO_STOP:
47 StopNetLog();
48 break;
49 default:
50 NOTREACHED();
51 break;
55 bool NetLogTempFile::GetFilePath(base::FilePath* path) {
56 DCHECK(thread_checker_.CalledOnValidThread());
57 if (log_type_ == LOG_TYPE_NONE || state_ == STATE_LOGGING)
58 return false;
60 if (!NetExportLogExists())
61 return false;
63 DCHECK(!log_path_.empty());
64 #if defined(OS_POSIX)
65 // Users, group and others can read, write and traverse.
66 int mode = base::FILE_PERMISSION_MASK;
67 base::SetPosixFilePermissions(log_path_, mode);
68 #endif // defined(OS_POSIX)
70 *path = log_path_;
71 return true;
74 base::DictionaryValue* NetLogTempFile::GetState() {
75 DCHECK(thread_checker_.CalledOnValidThread());
76 base::DictionaryValue* dict = new base::DictionaryValue;
78 EnsureInit();
80 #ifndef NDEBUG
81 dict->SetString("file", log_path_.LossyDisplayName());
82 #endif // NDEBUG
84 switch (state_) {
85 case STATE_NOT_LOGGING:
86 dict->SetString("state", "NOT_LOGGING");
87 break;
88 case STATE_LOGGING:
89 dict->SetString("state", "LOGGING");
90 break;
91 case STATE_UNINITIALIZED:
92 dict->SetString("state", "UNINITIALIZED");
93 break;
96 switch (log_type_) {
97 case LOG_TYPE_NONE:
98 dict->SetString("logType", "NONE");
99 break;
100 case LOG_TYPE_UNKNOWN:
101 dict->SetString("logType", "UNKNOWN");
102 break;
103 case LOG_TYPE_LOG_BYTES:
104 dict->SetString("logType", "LOG_BYTES");
105 break;
106 case LOG_TYPE_NORMAL:
107 dict->SetString("logType", "NORMAL");
108 break;
109 case LOG_TYPE_STRIP_PRIVATE_DATA:
110 dict->SetString("logType", "STRIP_PRIVATE_DATA");
111 break;
114 return dict;
117 NetLogTempFile::NetLogTempFile(
118 ChromeNetLog* chrome_net_log,
119 const base::CommandLine::StringType& command_line_string,
120 const std::string& channel_string)
121 : state_(STATE_UNINITIALIZED),
122 log_type_(LOG_TYPE_NONE),
123 chrome_net_log_(chrome_net_log),
124 command_line_string_(command_line_string),
125 channel_string_(channel_string) {
126 // NetLogTempFile can be created on one thread and used on another.
127 thread_checker_.DetachFromThread();
130 bool NetLogTempFile::GetNetExportLogBaseDirectory(base::FilePath* path) const {
131 DCHECK(thread_checker_.CalledOnValidThread());
132 return base::GetTempDir(path);
135 net::NetLogCaptureMode NetLogTempFile::GetCaptureModeForLogType(
136 LogType log_type) {
137 switch (log_type) {
138 case LOG_TYPE_LOG_BYTES:
139 return net::NetLogCaptureMode::IncludeSocketBytes();
140 case LOG_TYPE_NORMAL:
141 return net::NetLogCaptureMode::IncludeCookiesAndCredentials();
142 case LOG_TYPE_STRIP_PRIVATE_DATA:
143 return net::NetLogCaptureMode::Default();
144 case LOG_TYPE_NONE:
145 case LOG_TYPE_UNKNOWN:
146 NOTREACHED();
148 return net::NetLogCaptureMode::Default();
151 bool NetLogTempFile::EnsureInit() {
152 DCHECK(thread_checker_.CalledOnValidThread());
153 if (state_ != STATE_UNINITIALIZED)
154 return true;
156 if (!SetUpNetExportLogPath())
157 return false;
159 state_ = STATE_NOT_LOGGING;
160 if (NetExportLogExists())
161 log_type_ = LOG_TYPE_UNKNOWN;
162 else
163 log_type_ = LOG_TYPE_NONE;
165 return true;
168 void NetLogTempFile::StartNetLog(LogType log_type) {
169 DCHECK(thread_checker_.CalledOnValidThread());
170 if (state_ == STATE_LOGGING)
171 return;
173 DCHECK_NE(STATE_UNINITIALIZED, state_);
174 DCHECK(!log_path_.empty());
176 // Try to make sure we can create the file.
177 // TODO(rtenneti): Find a better for doing the following. Surface some error
178 // to the user if we couldn't create the file.
179 base::ScopedFILE file(base::OpenFile(log_path_, "w"));
180 if (!file)
181 return;
183 log_type_ = log_type;
184 state_ = STATE_LOGGING;
186 scoped_ptr<base::Value> constants(
187 ChromeNetLog::GetConstants(command_line_string_, channel_string_));
188 write_to_file_observer_.reset(new net::WriteToFileNetLogObserver());
189 write_to_file_observer_->set_capture_mode(GetCaptureModeForLogType(log_type));
190 write_to_file_observer_->StartObserving(chrome_net_log_, file.Pass(),
191 constants.get(), nullptr);
194 void NetLogTempFile::StopNetLog() {
195 DCHECK(thread_checker_.CalledOnValidThread());
196 if (state_ != STATE_LOGGING)
197 return;
199 write_to_file_observer_->StopObserving(nullptr);
200 write_to_file_observer_.reset();
201 state_ = STATE_NOT_LOGGING;
204 bool NetLogTempFile::SetUpNetExportLogPath() {
205 DCHECK(thread_checker_.CalledOnValidThread());
206 base::FilePath temp_dir;
207 if (!GetNetExportLogBaseDirectory(&temp_dir))
208 return false;
210 // Delete log file at old location, if present.
211 DeleteFile(temp_dir.Append(kOldLogRelativePath), false);
213 base::FilePath log_path = temp_dir.Append(kLogRelativePath);
215 if (!base::CreateDirectoryAndGetError(log_path.DirName(), nullptr)) {
216 return false;
219 log_path_ = log_path;
220 return true;
223 bool NetLogTempFile::NetExportLogExists() const {
224 DCHECK(thread_checker_.CalledOnValidThread());
225 DCHECK(!log_path_.empty());
226 return base::PathExists(log_path_);
229 } // namespace net_log