12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/net/net_log_temp_file.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/net/chrome_net_log.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/ui/webui/net_internals/net_internals_ui.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/net_log_logger.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NetLogTempFile::NetLogTempFile(ChromeNetLog* chrome_net_log) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : state_(STATE_UNINITIALIZED), 1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_type_(LOG_TYPE_NONE), 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) log_filename_(FILE_PATH_LITERAL("chrome-net-export-log.json")), 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome_net_log_(chrome_net_log) { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NetLogTempFile::~NetLogTempFile() { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (net_log_logger_) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_logger_->StopObserving(); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetLogTempFile::ProcessCommand(Command command) { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!EnsureInit()) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (command) { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case DO_START: 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StartNetLog(false); 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case DO_START_STRIP_PRIVATE_DATA: 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StartNetLog(true); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case DO_STOP: 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopNetLog(); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* NetLogTempFile::GetState() { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureInit(); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetString("file", log_path_.LossyDisplayName()); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // NDEBUG 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (state_) { 6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case STATE_NOT_LOGGING: 6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) dict->SetString("state", "NOT_LOGGING"); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case STATE_LOGGING: 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) dict->SetString("state", "LOGGING"); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case STATE_UNINITIALIZED: 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetString("state", "UNINITIALIZED"); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) switch (log_type_) { 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case LOG_TYPE_NONE: 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) dict->SetString("logType", "NONE"); 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case LOG_TYPE_UNKNOWN: 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) dict->SetString("logType", "UNKNOWN"); 7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case LOG_TYPE_NORMAL: 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) dict->SetString("logType", "NORMAL"); 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case LOG_TYPE_STRIP_PRIVATE_DATA: 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) dict->SetString("logType", "STRIP_PRIVATE_DATA"); 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dict; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetLogTempFile::EnsureInit() { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (state_ != STATE_UNINITIALIZED) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetNetExportLog()) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state_ = STATE_NOT_LOGGING; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NetExportLogExists()) 9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_type_ = LOG_TYPE_UNKNOWN; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_type_ = LOG_TYPE_NONE; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void NetLogTempFile::StartNetLog(bool strip_private_data) { 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (state_ == STATE_LOGGING) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(STATE_UNINITIALIZED, state_); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!log_path_.empty()); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Try to make sure we can create the file. 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(rtenneti): Find a better for doing the following. Surface some error 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the user if we couldn't create the file. 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FILE* file = base::OpenFile(log_path_, "w"); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (file == NULL) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::Value> constants(NetInternalsUI::GetConstants()); 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log_logger_.reset(new net::NetLogLogger(file, *constants)); 12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (strip_private_data) { 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) net_log_logger_->set_log_level(net::NetLog::LOG_STRIP_PRIVATE_DATA); 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_type_ = LOG_TYPE_STRIP_PRIVATE_DATA; 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_type_ = LOG_TYPE_NORMAL; 12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_logger_->StartObserving(chrome_net_log_); 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state_ = STATE_LOGGING; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetLogTempFile::StopNetLog() { 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (state_ != STATE_LOGGING) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_logger_->StopObserving(); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_logger_.reset(); 14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state_ = STATE_NOT_LOGGING; 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetLogTempFile::GetFilePath(base::FilePath* path) { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (log_type_ == LOG_TYPE_NONE || state_ == STATE_LOGGING) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!NetExportLogExists()) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!log_path_.empty()); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_POSIX) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Users, group and others can read, write and traverse. 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int mode = base::FILE_PERMISSION_MASK; 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::SetPosixFilePermissions(log_path_, mode); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(OS_POSIX) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *path = log_path_; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetLogTempFile::GetNetExportLog() { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath temp_dir; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetNetExportLogDirectory(&temp_dir)) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) log_path_ = temp_dir.Append(log_filename_); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetLogTempFile::GetNetExportLogDirectory(base::FilePath* path) { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::GetTempDir(path); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetLogTempFile::NetExportLogExists() { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!log_path_.empty()); 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return base::PathExists(log_path_); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 182