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 "chrome/browser/net/net_log_temp_file.h"
7 #include "base/files/file_util.h"
8 #include "base/files/scoped_file.h"
9 #include "base/values.h"
10 #include "chrome/browser/net/chrome_net_log.h"
11 #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "net/log/write_to_file_net_log_observer.h"
15 using content::BrowserThread
;
17 // Path of logs relative to base::GetTempDir(). Must be kept in sync
18 // with chrome/android/java/res/xml/file_paths.xml
19 base::FilePath::CharType kLogRelativePath
[] =
20 FILE_PATH_LITERAL("net-export/chrome-net-export-log.json");
22 // Old path used by net-export. Used to delete old files.
23 // TODO(mmenke): Should remove at some point. Added in M46.
24 base::FilePath::CharType kOldLogRelativePath
[] =
25 FILE_PATH_LITERAL("chrome-net-export-log.json");
27 NetLogTempFile::~NetLogTempFile() {
28 if (write_to_file_observer_
)
29 write_to_file_observer_
->StopObserving(nullptr);
32 void NetLogTempFile::ProcessCommand(Command command
) {
33 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
38 case DO_START_LOG_BYTES
:
39 StartNetLog(LOG_TYPE_LOG_BYTES
);
42 StartNetLog(LOG_TYPE_NORMAL
);
44 case DO_START_STRIP_PRIVATE_DATA
:
45 StartNetLog(LOG_TYPE_STRIP_PRIVATE_DATA
);
56 bool NetLogTempFile::GetFilePath(base::FilePath
* path
) {
57 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
58 if (log_type_
== LOG_TYPE_NONE
|| state_
== STATE_LOGGING
)
61 if (!NetExportLogExists())
64 DCHECK(!log_path_
.empty());
66 // Users, group and others can read, write and traverse.
67 int mode
= base::FILE_PERMISSION_MASK
;
68 base::SetPosixFilePermissions(log_path_
, mode
);
69 #endif // defined(OS_POSIX)
75 base::DictionaryValue
* NetLogTempFile::GetState() {
76 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
77 base::DictionaryValue
* dict
= new base::DictionaryValue
;
82 dict
->SetString("file", log_path_
.LossyDisplayName());
86 case STATE_NOT_LOGGING
:
87 dict
->SetString("state", "NOT_LOGGING");
90 dict
->SetString("state", "LOGGING");
92 case STATE_UNINITIALIZED
:
93 dict
->SetString("state", "UNINITIALIZED");
99 dict
->SetString("logType", "NONE");
101 case LOG_TYPE_UNKNOWN
:
102 dict
->SetString("logType", "UNKNOWN");
104 case LOG_TYPE_LOG_BYTES
:
105 dict
->SetString("logType", "LOG_BYTES");
107 case LOG_TYPE_NORMAL
:
108 dict
->SetString("logType", "NORMAL");
110 case LOG_TYPE_STRIP_PRIVATE_DATA
:
111 dict
->SetString("logType", "STRIP_PRIVATE_DATA");
118 NetLogTempFile::NetLogTempFile(ChromeNetLog
* chrome_net_log
)
119 : state_(STATE_UNINITIALIZED
),
120 log_type_(LOG_TYPE_NONE
),
121 chrome_net_log_(chrome_net_log
) {
124 bool NetLogTempFile::GetNetExportLogBaseDirectory(
125 base::FilePath
* path
) const {
126 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
127 return base::GetTempDir(path
);
130 net::NetLogCaptureMode
NetLogTempFile::GetCaptureModeForLogType(
133 case LOG_TYPE_LOG_BYTES
:
134 return net::NetLogCaptureMode::IncludeSocketBytes();
135 case LOG_TYPE_NORMAL
:
136 return net::NetLogCaptureMode::IncludeCookiesAndCredentials();
137 case LOG_TYPE_STRIP_PRIVATE_DATA
:
138 return net::NetLogCaptureMode::Default();
140 case LOG_TYPE_UNKNOWN
:
143 return net::NetLogCaptureMode::Default();
146 bool NetLogTempFile::EnsureInit() {
147 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
148 if (state_
!= STATE_UNINITIALIZED
)
151 if (!SetUpNetExportLogPath())
154 state_
= STATE_NOT_LOGGING
;
155 if (NetExportLogExists())
156 log_type_
= LOG_TYPE_UNKNOWN
;
158 log_type_
= LOG_TYPE_NONE
;
163 void NetLogTempFile::StartNetLog(LogType log_type
) {
164 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
165 if (state_
== STATE_LOGGING
)
168 DCHECK_NE(STATE_UNINITIALIZED
, state_
);
169 DCHECK(!log_path_
.empty());
171 // Try to make sure we can create the file.
172 // TODO(rtenneti): Find a better for doing the following. Surface some error
173 // to the user if we couldn't create the file.
174 base::ScopedFILE
file(base::OpenFile(log_path_
, "w"));
178 log_type_
= log_type
;
179 state_
= STATE_LOGGING
;
181 scoped_ptr
<base::Value
> constants(NetInternalsUI::GetConstants());
182 write_to_file_observer_
.reset(new net::WriteToFileNetLogObserver());
183 write_to_file_observer_
->set_capture_mode(GetCaptureModeForLogType(log_type
));
184 write_to_file_observer_
->StartObserving(chrome_net_log_
, file
.Pass(),
185 constants
.get(), nullptr);
188 void NetLogTempFile::StopNetLog() {
189 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
190 if (state_
!= STATE_LOGGING
)
193 write_to_file_observer_
->StopObserving(nullptr);
194 write_to_file_observer_
.reset();
195 state_
= STATE_NOT_LOGGING
;
198 bool NetLogTempFile::SetUpNetExportLogPath() {
199 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
200 base::FilePath temp_dir
;
201 if (!GetNetExportLogBaseDirectory(&temp_dir
))
204 // Delete log file at old location, if present.
205 DeleteFile(temp_dir
.Append(kOldLogRelativePath
), false);
207 base::FilePath log_path
= temp_dir
.Append(kLogRelativePath
);
209 if (!base::CreateDirectoryAndGetError(log_path
.DirName(),
214 log_path_
= log_path
;
218 bool NetLogTempFile::NetExportLogExists() const {
219 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING
);
220 DCHECK(!log_path_
.empty());
221 return base::PathExists(log_path_
);