| OLD | NEW | 
|    1 // Copyright 2013 The Chromium Authors. All rights reserved. |    1 // Copyright 2013 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "chrome/browser/media/webrtc_log_uploader.h" |    5 #include "chrome/browser/media/webrtc_log_uploader.h" | 
|    6  |    6  | 
|    7 #include "base/file_util.h" |    7 #include "base/file_util.h" | 
|    8 #include "base/files/file_enumerator.h" |    8 #include "base/files/file_enumerator.h" | 
|    9 #include "base/files/file_path.h" |    9 #include "base/files/file_path.h" | 
|   10 #include "base/logging.h" |   10 #include "base/logging.h" | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|   29 const uint32 kIntermediateCompressionBufferBytes = 256 * 1024;  // 256 KB |   29 const uint32 kIntermediateCompressionBufferBytes = 256 * 1024;  // 256 KB | 
|   30 const int kLogListLimitLines = 50; |   30 const int kLogListLimitLines = 50; | 
|   31  |   31  | 
|   32 const char kUploadURL[] = "https://clients2.google.com/cr/report"; |   32 const char kUploadURL[] = "https://clients2.google.com/cr/report"; | 
|   33 const char kUploadContentType[] = "multipart/form-data"; |   33 const char kUploadContentType[] = "multipart/form-data"; | 
|   34 const char kMultipartBoundary[] = |   34 const char kMultipartBoundary[] = | 
|   35     "----**--yradnuoBgoLtrapitluMklaTelgooG--**----"; |   35     "----**--yradnuoBgoLtrapitluMklaTelgooG--**----"; | 
|   36  |   36  | 
|   37 const int kHttpResponseOk = 200; |   37 const int kHttpResponseOk = 200; | 
|   38  |   38  | 
 |   39 // Adds the header section for a gzip file to the multipart |post_data|. | 
 |   40 void AddMultipartFileContentHeader(std::string* post_data, | 
 |   41                                    const std::string& content_name) { | 
 |   42   post_data->append("--"); | 
 |   43   post_data->append(kMultipartBoundary); | 
 |   44   post_data->append("\r\nContent-Disposition: form-data; name=\""); | 
 |   45   post_data->append(content_name); | 
 |   46   post_data->append("\"; filename=\""); | 
 |   47   post_data->append(content_name + ".gz"); | 
 |   48   post_data->append("\"\r\nContent-Type: application/gzip\r\n\r\n"); | 
 |   49 } | 
 |   50  | 
 |   51 // Adds |compressed_log| to |post_data|. | 
 |   52 void AddLogData(std::string* post_data, | 
 |   53                 const std::vector<uint8>& compressed_log) { | 
 |   54   AddMultipartFileContentHeader(post_data, "webrtc_log"); | 
 |   55   post_data->append(reinterpret_cast<const char*>(&compressed_log[0]), | 
 |   56                     compressed_log.size()); | 
 |   57   post_data->append("\r\n"); | 
 |   58 } | 
 |   59  | 
 |   60 // Adds the RTP dump data to |post_data|. | 
 |   61 void AddRtpDumpData(std::string* post_data, | 
 |   62                     const std::string& name, | 
 |   63                     const std::string& dump_data) { | 
 |   64   AddMultipartFileContentHeader(post_data, name); | 
 |   65   post_data->append(dump_data.data(), dump_data.size()); | 
 |   66   post_data->append("\r\n"); | 
 |   67 } | 
 |   68  | 
|   39 }  // namespace |   69 }  // namespace | 
|   40  |   70  | 
|   41 WebRtcLogUploadDoneData::WebRtcLogUploadDoneData() {} |   71 WebRtcLogUploadDoneData::WebRtcLogUploadDoneData() {} | 
|   42  |   72  | 
|   43 WebRtcLogUploadDoneData::~WebRtcLogUploadDoneData() {} |   73 WebRtcLogUploadDoneData::~WebRtcLogUploadDoneData() {} | 
|   44  |   74  | 
|   45 WebRtcLogUploader::WebRtcLogUploader() |   75 WebRtcLogUploader::WebRtcLogUploader() | 
|   46     : log_count_(0), |   76     : log_count_(0), | 
|   47       post_data_(NULL), |   77       post_data_(NULL), | 
|   48       shutting_down_(false) { |   78       shutting_down_(false) { | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|   62   DCHECK(!shutting_down_); |   92   DCHECK(!shutting_down_); | 
|   63   int response_code = source->GetResponseCode(); |   93   int response_code = source->GetResponseCode(); | 
|   64   UploadDoneDataMap::iterator it = upload_done_data_.find(source); |   94   UploadDoneDataMap::iterator it = upload_done_data_.find(source); | 
|   65   if (it != upload_done_data_.end()) { |   95   if (it != upload_done_data_.end()) { | 
|   66     // The log path can be empty here if we failed getting it before. We still |   96     // The log path can be empty here if we failed getting it before. We still | 
|   67     // upload the log if that's the case. |   97     // upload the log if that's the case. | 
|   68     std::string report_id; |   98     std::string report_id; | 
|   69     if (response_code == kHttpResponseOk && |   99     if (response_code == kHttpResponseOk && | 
|   70         source->GetResponseAsString(&report_id) && |  100         source->GetResponseAsString(&report_id) && | 
|   71         !it->second.log_path.empty()) { |  101         !it->second.log_path.empty()) { | 
 |  102       // TODO(jiayl): Add the RTP dump records to chrome://webrtc-logs. | 
|   72       base::FilePath log_list_path = |  103       base::FilePath log_list_path = | 
|   73           WebRtcLogList::GetWebRtcLogListFileForDirectory(it->second.log_path); |  104           WebRtcLogList::GetWebRtcLogListFileForDirectory(it->second.log_path); | 
|   74       content::BrowserThread::PostTask( |  105       content::BrowserThread::PostTask( | 
|   75           content::BrowserThread::FILE, |  106           content::BrowserThread::FILE, | 
|   76           FROM_HERE, |  107           FROM_HERE, | 
|   77           base::Bind(&WebRtcLogUploader::AddUploadedLogInfoToUploadListFile, |  108           base::Bind(&WebRtcLogUploader::AddUploadedLogInfoToUploadListFile, | 
|   78                      base::Unretained(this), |  109                      base::Unretained(this), | 
|   79                      log_list_path, |  110                      log_list_path, | 
|   80                      it->second.local_log_id, |  111                      it->second.local_log_id, | 
|   81                      report_id)); |  112                      report_id)); | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  132     base::FilePath log_list_path = |  163     base::FilePath log_list_path = | 
|  133         WebRtcLogList::GetWebRtcLogListFileForDirectory( |  164         WebRtcLogList::GetWebRtcLogListFileForDirectory( | 
|  134             upload_done_data.log_path); |  165             upload_done_data.log_path); | 
|  135     AddLocallyStoredLogInfoToUploadListFile(log_list_path, local_log_id); |  166     AddLocallyStoredLogInfoToUploadListFile(log_list_path, local_log_id); | 
|  136   } |  167   } | 
|  137  |  168  | 
|  138   WebRtcLogUploadDoneData upload_done_data_with_log_id = upload_done_data; |  169   WebRtcLogUploadDoneData upload_done_data_with_log_id = upload_done_data; | 
|  139   upload_done_data_with_log_id.local_log_id = local_log_id; |  170   upload_done_data_with_log_id.local_log_id = local_log_id; | 
|  140  |  171  | 
|  141   scoped_ptr<std::string> post_data(new std::string()); |  172   scoped_ptr<std::string> post_data(new std::string()); | 
|  142   SetupMultipart(post_data.get(), compressed_log, meta_data); |  173   SetupMultipart(post_data.get(), | 
 |  174                  compressed_log, | 
 |  175                  upload_done_data.incoming_rtp_dump, | 
 |  176                  upload_done_data.outgoing_rtp_dump, | 
 |  177                  meta_data); | 
|  143  |  178  | 
|  144   // If a test has set the test string pointer, write to it and skip uploading. |  179   // If a test has set the test string pointer, write to it and skip uploading. | 
|  145   // Still fire the upload callback so that we can run an extension API test |  180   // Still fire the upload callback so that we can run an extension API test | 
|  146   // using the test framework for that without hanging. |  181   // using the test framework for that without hanging. | 
|  147   // TODO(grunell): Remove this when the api test for this feature is fully |  182   // TODO(grunell): Remove this when the api test for this feature is fully | 
|  148   // implemented according to the test plan. http://crbug.com/257329. |  183   // implemented according to the test plan. http://crbug.com/257329. | 
|  149   if (post_data_) { |  184   if (post_data_) { | 
|  150     *post_data_ = *post_data; |  185     *post_data_ = *post_data; | 
|  151     NotifyUploadDone(kHttpResponseOk, "", upload_done_data_with_log_id); |  186     NotifyUploadDone(kHttpResponseOk, "", upload_done_data_with_log_id); | 
|  152     return; |  187     return; | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|  174        ++it) { |  209        ++it) { | 
|  175     delete it->first; |  210     delete it->first; | 
|  176   } |  211   } | 
|  177   upload_done_data_.clear(); |  212   upload_done_data_.clear(); | 
|  178   shutting_down_ = true; |  213   shutting_down_ = true; | 
|  179 } |  214 } | 
|  180  |  215  | 
|  181 void WebRtcLogUploader::SetupMultipart( |  216 void WebRtcLogUploader::SetupMultipart( | 
|  182     std::string* post_data, |  217     std::string* post_data, | 
|  183     const std::vector<uint8>& compressed_log, |  218     const std::vector<uint8>& compressed_log, | 
 |  219     const base::FilePath& incoming_rtp_dump, | 
 |  220     const base::FilePath& outgoing_rtp_dump, | 
|  184     const std::map<std::string, std::string>& meta_data) { |  221     const std::map<std::string, std::string>& meta_data) { | 
|  185 #if defined(OS_WIN) |  222 #if defined(OS_WIN) | 
|  186   const char product[] = "Chrome"; |  223   const char product[] = "Chrome"; | 
|  187 #elif defined(OS_MACOSX) |  224 #elif defined(OS_MACOSX) | 
|  188   const char product[] = "Chrome_Mac"; |  225   const char product[] = "Chrome_Mac"; | 
|  189 #elif defined(OS_LINUX) |  226 #elif defined(OS_LINUX) | 
|  190 #if !defined(ADDRESS_SANITIZER) |  227 #if !defined(ADDRESS_SANITIZER) | 
|  191   const char product[] = "Chrome_Linux"; |  228   const char product[] = "Chrome_Linux"; | 
|  192 #else |  229 #else | 
|  193   const char product[] = "Chrome_Linux_ASan"; |  230   const char product[] = "Chrome_Linux_ASan"; | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  210                                   "", post_data); |  247                                   "", post_data); | 
|  211  |  248  | 
|  212   // Add custom meta data. |  249   // Add custom meta data. | 
|  213   std::map<std::string, std::string>::const_iterator it = meta_data.begin(); |  250   std::map<std::string, std::string>::const_iterator it = meta_data.begin(); | 
|  214   for (; it != meta_data.end(); ++it) { |  251   for (; it != meta_data.end(); ++it) { | 
|  215     net::AddMultipartValueForUpload(it->first, it->second, kMultipartBoundary, |  252     net::AddMultipartValueForUpload(it->first, it->second, kMultipartBoundary, | 
|  216                                     "", post_data); |  253                                     "", post_data); | 
|  217   } |  254   } | 
|  218  |  255  | 
|  219   AddLogData(post_data, compressed_log); |  256   AddLogData(post_data, compressed_log); | 
 |  257  | 
 |  258   // Add the rtp dumps if they exist. | 
 |  259   base::FilePath rtp_dumps[2] = {incoming_rtp_dump, outgoing_rtp_dump}; | 
 |  260   static const char* kRtpDumpNames[2] = {"rtpdump_recv", "rtpdump_send"}; | 
 |  261  | 
 |  262   for (size_t i = 0; i < 2; ++i) { | 
 |  263     if (!rtp_dumps[i].empty() && base::PathExists(rtp_dumps[i])) { | 
 |  264       std::string dump_data; | 
 |  265       if (base::ReadFileToString(rtp_dumps[i], &dump_data)) | 
 |  266         AddRtpDumpData(post_data, kRtpDumpNames[i], dump_data); | 
 |  267     } | 
 |  268   } | 
 |  269  | 
|  220   net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data); |  270   net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data); | 
|  221 } |  271 } | 
|  222  |  272  | 
|  223 void WebRtcLogUploader::AddLogData(std::string* post_data, |  | 
|  224                                    const std::vector<uint8>& compressed_log) { |  | 
|  225   post_data->append("--"); |  | 
|  226   post_data->append(kMultipartBoundary); |  | 
|  227   post_data->append("\r\n"); |  | 
|  228   post_data->append("Content-Disposition: form-data; name=\"webrtc_log\""); |  | 
|  229   post_data->append("; filename=\"webrtc_log.gz\"\r\n"); |  | 
|  230   post_data->append("Content-Type: application/gzip\r\n\r\n"); |  | 
|  231   post_data->append(reinterpret_cast<const char*>(&compressed_log[0]), |  | 
|  232                     compressed_log.size()); |  | 
|  233   post_data->append("\r\n"); |  | 
|  234 } |  | 
|  235  |  | 
|  236 void WebRtcLogUploader::CompressLog(std::vector<uint8>* compressed_log, |  273 void WebRtcLogUploader::CompressLog(std::vector<uint8>* compressed_log, | 
|  237                                     uint8* input, |  274                                     uint8* input, | 
|  238                                     uint32 input_size) { |  275                                     uint32 input_size) { | 
|  239   PartialCircularBuffer read_pcb(input, input_size); |  276   PartialCircularBuffer read_pcb(input, input_size); | 
|  240  |  277  | 
|  241   z_stream stream = {0}; |  278   z_stream stream = {0}; | 
|  242   int result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, |  279   int result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, | 
|  243                             // windowBits = 15 is default, 16 is added to |  280                             // windowBits = 15 is default, 16 is added to | 
|  244                             // produce a gzip header + trailer. |  281                             // produce a gzip header + trailer. | 
|  245                             15 + 16, |  282                             15 + 16, | 
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  417     if (!success) { |  454     if (!success) { | 
|  418       error_message = "Uploading failed, response code: " + |  455       error_message = "Uploading failed, response code: " + | 
|  419                       base::IntToString(response_code); |  456                       base::IntToString(response_code); | 
|  420     } |  457     } | 
|  421     content::BrowserThread::PostTask( |  458     content::BrowserThread::PostTask( | 
|  422         content::BrowserThread::UI, FROM_HERE, |  459         content::BrowserThread::UI, FROM_HERE, | 
|  423         base::Bind(upload_done_data.callback, success, report_id, |  460         base::Bind(upload_done_data.callback, success, report_id, | 
|  424                    error_message)); |  461                    error_message)); | 
|  425   } |  462   } | 
|  426 } |  463 } | 
| OLD | NEW |