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 |