Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: components/webrtc_log_uploader/webrtc_log_uploader.cc

Issue 14329020: Implementing uploading of a WebRTC diagnostic log. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review, added url and app session id, rebase Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/webrtc_log_uploader/webrtc_log_uploader.h"
6
7 #include "base/logging.h"
8 #include "base/memory/partial_circular_buffer.h"
9 #include "base/shared_memory.h"
10 #include "base/stringprintf.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "net/base/mime_util.h"
13 #include "net/base/network_delegate.h"
14 #include "net/proxy/proxy_config.h"
15 #include "net/proxy/proxy_config_service.h"
16 #include "net/url_request/url_fetcher.h"
17 #include "net/url_request/url_request_context.h"
18 #include "net/url_request/url_request_context_builder.h"
19 #include "net/url_request/url_request_context_getter.h"
20 #include "third_party/zlib/zlib.h"
21
22 // TODO(grunell): Temporary. Send product and version info with the UploadLog
23 // call or in ctor. Not necessary if this file is moved to chrome/ (TBD).
24 #include "chrome/common/chrome_version_info.h"
25
26 namespace components {
27
28 namespace {
29
30 const int kLogCountLimit = 5;
31 const uint32 kIntermediateCompressionBufferBytes = 256 * 1024; // 256 KB
32
33 const char kUploadURL[] = "https://clients2.google.com/cr/report";
34 const char kUploadContentType[] = "multipart/form-data";
35 const char kMultipartBoundary[] =
36 "----**--yradnuoBgoLtrapitluMklaTelgooG--**----";
37
38 } // namespace
39
40 WebRtcLogUploader::WebRtcLogUploader()
41 : log_count_(0) {
42 }
43
44 WebRtcLogUploader::~WebRtcLogUploader() {
45 }
46
47 void WebRtcLogUploader::OnURLFetchComplete(
48 const net::URLFetcher* source) {
49 }
50
51 void WebRtcLogUploader::OnURLFetchUploadProgress(
52 const net::URLFetcher* source, int64 current, int64 total) {
53 }
54
55 bool WebRtcLogUploader::ApplyForStartLogging() {
56 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
57 if (log_count_ < kLogCountLimit) {
58 ++log_count_;
59 return true;
60 }
61 return false;
62 }
63
64 void WebRtcLogUploader::UploadLog(net::URLRequestContextGetter* request_context,
65 scoped_ptr<base::SharedMemory> shared_memory,
66 uint32 length,
67 const std::string& app_session_id,
68 const std::string& app_url) {
69 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
70 DCHECK(shared_memory);
71 DCHECK(shared_memory->memory());
72
73 std::string post_data;
74 SetupMultipart(&post_data, reinterpret_cast<uint8*>(shared_memory->memory()),
75 length, app_session_id, app_url);
76
77 std::string content_type = kUploadContentType;
78 content_type.append("; boundary=");
79 content_type.append(kMultipartBoundary);
80
81 net::URLFetcher* url_fetcher =
82 net::URLFetcher::Create(GURL(kUploadURL), net::URLFetcher::POST, this);
83 url_fetcher->SetRequestContext(request_context);
84 url_fetcher->SetUploadData(content_type, post_data);
85 url_fetcher->Start();
86
87 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
88 base::Bind(&WebRtcLogUploader::DecreaseLogCount, base::Unretained(this)));
89 }
90
91 void WebRtcLogUploader::SetupMultipart(std::string* post_data,
92 uint8* log_buffer,
93 uint32 log_buffer_length,
94 const std::string& app_session_id,
95 const std::string& app_url) {
96 #if defined(OS_WIN)
Jói 2013/05/24 21:14:06 This logic for determining the product name for Cr
Henrik Grunell 2013/05/27 13:00:32 Yes, I've checked this with cpu@ and there isn't.
97 const char product[] = "Chrome";
98 #elif defined(OS_MACOSX)
99 const char product[] = "Chrome_Mac";
100 #elif defined(OS_LINUX)
101 #if !defined(ADDRESS_SANITIZER)
102 const char product[] = "Chrome_Linux";
103 #else
104 const char product[] = "Chrome_Linux_ASan";
105 #endif
106 #elif defined(OS_ANDROID)
107 const char product[] = "Chrome_Android";
108 #elif defined(OS_CHROMEOS)
109 const char product[] = "Chrome_ChromeOS";
110 #else
111 // This file should not be compiled for other platforms.
112 COMPILE_ASSERT(false);
113 #endif
114 net::AddMultipartValueForUpload("prod", product, kMultipartBoundary,
115 "", post_data);
116 chrome::VersionInfo version_info;
117 net::AddMultipartValueForUpload("ver", version_info.Version(),
118 kMultipartBoundary, "", post_data);
119 net::AddMultipartValueForUpload("guid", "0", kMultipartBoundary,
120 "", post_data);
121 net::AddMultipartValueForUpload("type", "webrtc_log", kMultipartBoundary,
122 "", post_data);
123 net::AddMultipartValueForUpload("app_session_id", app_session_id,
124 kMultipartBoundary, "", post_data);
125 net::AddMultipartValueForUpload("url", app_url, kMultipartBoundary,
126 "", post_data);
127 AddLogData(post_data, log_buffer, log_buffer_length);
128 net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data);
129 }
130
131 void WebRtcLogUploader::AddLogData(std::string* post_data,
132 uint8* log_buffer,
133 uint32 log_buffer_length) {
134 post_data->append("--");
135 post_data->append(kMultipartBoundary);
136 post_data->append("\r\n");
137 post_data->append("Content-Disposition: form-data; name=\"log\"");
138 post_data->append("; filename=\"log.gz\"\r\n");
139 post_data->append("Content-Type: application/gzip\r\n\r\n");
140
141 CompressLog(post_data, log_buffer, log_buffer_length);
142
143 post_data->append("\r\n");
144 }
145
146 void WebRtcLogUploader::CompressLog(std::string* post_data,
147 uint8* input,
148 uint32 input_size) {
149 base::PartialCircularBuffer read_pcb(input, input_size);
150
151 z_stream stream = {0};
152 int result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
153 // windowBits = 15 is default, 16 is added to
154 // produce a gzip header + trailer.
155 15 + 16,
156 8, // memLevel = 8 is default.
157 Z_DEFAULT_STRATEGY);
158 DCHECK_EQ(Z_OK, result);
159
160 scoped_ptr<uint8[]> intermediate_buffer(
Jói 2013/05/24 21:14:06 As far as I can tell, this can be stack-allocated
Henrik Grunell 2013/05/27 13:00:32 OK, done.
161 new uint8[kIntermediateCompressionBufferBytes]);
162 memset(intermediate_buffer.get(), 0, kIntermediateCompressionBufferBytes);
163
164 IncreaseMultipartBufferSize(post_data, &stream);
Jói 2013/05/24 21:14:06 A better name might indicate that this sets stream
Henrik Grunell 2013/05/27 13:00:32 Agree. I thing the suggested name is fine. Done.
165 uint32 read = 0;
166
167 do {
168 if (stream.avail_in == 0) {
169 read = read_pcb.Read(&intermediate_buffer.get()[0],
170 kIntermediateCompressionBufferBytes);
171 stream.next_in = &intermediate_buffer.get()[0];
172 stream.avail_in = read;
173 if (read != kIntermediateCompressionBufferBytes)
174 break;
175 }
176 result = deflate(&stream, Z_SYNC_FLUSH);
177 DCHECK_EQ(Z_OK, result);
178 if (stream.avail_out == 0)
179 IncreaseMultipartBufferSize(post_data, &stream);
180 } while (true);
181
182 // Ensure we have enough room in the output buffer. Easier to always just do a
183 // resize than looping around and resize if needed.
184 if (stream.avail_out < kIntermediateCompressionBufferBytes)
185 IncreaseMultipartBufferSize(post_data, &stream);
186
187 result = deflate(&stream, Z_FINISH);
Jói 2013/05/24 21:14:06 Will this be OK if (stream.avail_in == 0)? Seems l
Henrik Grunell 2013/05/27 13:00:32 Yes, this is OK. If there's no more input it will
188 DCHECK_EQ(Z_STREAM_END, result);
189 result = deflateEnd(&stream);
190 DCHECK_EQ(Z_OK, result);
191
192 post_data->resize(post_data->size() - stream.avail_out);
193 }
194
195 void WebRtcLogUploader::IncreaseMultipartBufferSize(std::string* post_data,
196 z_stream* stream) {
197 size_t old_size = post_data->size() - stream->avail_out;
198 post_data->resize(old_size + kIntermediateCompressionBufferBytes);
199 stream->next_out = reinterpret_cast<uint8*>(&(*post_data)[old_size]);
200 stream->avail_out = kIntermediateCompressionBufferBytes;
201 }
202
203 void WebRtcLogUploader::DecreaseLogCount() {
204 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
205 --log_count_;
206 }
207
208 } // namespace components
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698