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"
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());
37 case DO_START_LOG_BYTES
:
38 StartNetLog(LOG_TYPE_LOG_BYTES
);
41 StartNetLog(LOG_TYPE_NORMAL
);
43 case DO_START_STRIP_PRIVATE_DATA
:
44 StartNetLog(LOG_TYPE_STRIP_PRIVATE_DATA
);
55 bool NetLogTempFile::GetFilePath(base::FilePath
* path
) {
56 DCHECK(thread_checker_
.CalledOnValidThread());
57 if (log_type_
== LOG_TYPE_NONE
|| state_
== STATE_LOGGING
)
60 if (!NetExportLogExists())
63 DCHECK(!log_path_
.empty());
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)
74 base::DictionaryValue
* NetLogTempFile::GetState() {
75 DCHECK(thread_checker_
.CalledOnValidThread());
76 base::DictionaryValue
* dict
= new base::DictionaryValue
;
81 dict
->SetString("file", log_path_
.LossyDisplayName());
85 case STATE_NOT_LOGGING
:
86 dict
->SetString("state", "NOT_LOGGING");
89 dict
->SetString("state", "LOGGING");
91 case STATE_UNINITIALIZED
:
92 dict
->SetString("state", "UNINITIALIZED");
98 dict
->SetString("logType", "NONE");
100 case LOG_TYPE_UNKNOWN
:
101 dict
->SetString("logType", "UNKNOWN");
103 case LOG_TYPE_LOG_BYTES
:
104 dict
->SetString("logType", "LOG_BYTES");
106 case LOG_TYPE_NORMAL
:
107 dict
->SetString("logType", "NORMAL");
109 case LOG_TYPE_STRIP_PRIVATE_DATA
:
110 dict
->SetString("logType", "STRIP_PRIVATE_DATA");
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(
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();
145 case LOG_TYPE_UNKNOWN
:
148 return net::NetLogCaptureMode::Default();
151 bool NetLogTempFile::EnsureInit() {
152 DCHECK(thread_checker_
.CalledOnValidThread());
153 if (state_
!= STATE_UNINITIALIZED
)
156 if (!SetUpNetExportLogPath())
159 state_
= STATE_NOT_LOGGING
;
160 if (NetExportLogExists())
161 log_type_
= LOG_TYPE_UNKNOWN
;
163 log_type_
= LOG_TYPE_NONE
;
168 void NetLogTempFile::StartNetLog(LogType log_type
) {
169 DCHECK(thread_checker_
.CalledOnValidThread());
170 if (state_
== STATE_LOGGING
)
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"));
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
)
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
))
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)) {
219 log_path_
= log_path
;
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