Disable PDF tests that are failing after combining PDF plugin into chrome.
[chromium-blink-merge.git] / content / browser / tracing / trace_uploader.cc
blob37ccb883ea083b8b06d0bedf5ae65583003a5b6e
1 // Copyright 2014 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 "content/browser/tracing/trace_uploader.h"
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/memory/shared_memory.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/time/time.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "net/base/mime_util.h"
15 #include "net/base/network_delegate.h"
16 #include "net/proxy/proxy_config.h"
17 #include "net/proxy/proxy_config_service.h"
18 #include "net/url_request/url_fetcher.h"
19 #include "net/url_request/url_request_context.h"
20 #include "net/url_request/url_request_context_builder.h"
21 #include "net/url_request/url_request_context_getter.h"
22 #include "third_party/zlib/zlib.h"
23 #include "url/gurl.h"
25 using std::string;
27 namespace content {
28 namespace {
29 const char kUploadContentType[] = "multipart/form-data";
30 const char kMultipartBoundary[] =
31 "----**--yradnuoBgoLtrapitluMklaTelgooG--**----";
33 const int kHttpResponseOk = 200;
35 } // namespace
37 TraceUploader::TraceUploader(const std::string& product,
38 const std::string& version,
39 const std::string& upload_url,
40 net::URLRequestContextGetter* request_context)
41 : product_(product),
42 version_(version),
43 upload_url_(upload_url),
44 request_context_(request_context) {
45 DCHECK(!product_.empty());
46 DCHECK(!version_.empty());
47 DCHECK(!upload_url_.empty());
50 TraceUploader::~TraceUploader() {
51 DCHECK_CURRENTLY_ON(BrowserThread::UI);
54 void TraceUploader::OnURLFetchComplete(const net::URLFetcher* source) {
55 DCHECK_CURRENTLY_ON(BrowserThread::UI);
56 DCHECK_EQ(source, url_fetcher_.get());
57 int response_code = source->GetResponseCode();
58 string report_id;
59 string error_message;
60 bool success = (response_code == kHttpResponseOk);
61 if (success) {
62 source->GetResponseAsString(&report_id);
63 } else {
64 error_message = "Uploading failed, response code: " +
65 base::IntToString(response_code);
68 BrowserThread::PostTask(
69 content::BrowserThread::UI,
70 FROM_HERE,
71 base::Bind(done_callback_, success, report_id, error_message));
72 url_fetcher_.reset();
75 void TraceUploader::OnURLFetchUploadProgress(
76 const net::URLFetcher* source, int64 current, int64 total) {
77 DCHECK(url_fetcher_.get());
79 LOG(WARNING) << "Upload progress: " << current << " of " << total;
80 BrowserThread::PostTask(
81 content::BrowserThread::UI,
82 FROM_HERE,
83 base::Bind(progress_callback_, current, total));
86 void TraceUploader::DoUpload(
87 const std::string& file_contents,
88 UploadProgressCallback progress_callback,
89 UploadDoneCallback done_callback) {
90 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
91 DCHECK(!url_fetcher_.get());
93 progress_callback_ = progress_callback;
94 done_callback_ = done_callback;
96 if (url_fetcher_.get()) {
97 OnUploadError("Already uploading.");
100 scoped_ptr<char[]> compressed_contents(new char[kMaxUploadBytes]);
101 int compressed_bytes;
102 if (!Compress(file_contents, kMaxUploadBytes, compressed_contents.get(),
103 &compressed_bytes)) {
104 OnUploadError("Compressing file failed.");
105 return;
108 std::string post_data;
109 SetupMultipart("trace.json.gz",
110 std::string(compressed_contents.get(), compressed_bytes),
111 &post_data);
113 content::BrowserThread::PostTask(
114 content::BrowserThread::UI, FROM_HERE,
115 base::Bind(&TraceUploader::CreateAndStartURLFetcher,
116 base::Unretained(this),
117 post_data));
120 void TraceUploader::OnUploadError(std::string error_message) {
121 LOG(ERROR) << error_message;
122 content::BrowserThread::PostTask(
123 content::BrowserThread::UI,
124 FROM_HERE,
125 base::Bind(done_callback_, false, "", error_message));
128 void TraceUploader::SetupMultipart(const std::string& trace_filename,
129 const std::string& trace_contents,
130 std::string* post_data) {
131 net::AddMultipartValueForUpload("prod", product_, kMultipartBoundary, "",
132 post_data);
133 net::AddMultipartValueForUpload("ver", version_ + "-trace",
134 kMultipartBoundary, "", post_data);
135 net::AddMultipartValueForUpload("guid", "0", kMultipartBoundary,
136 "", post_data);
137 net::AddMultipartValueForUpload("type", "trace", kMultipartBoundary,
138 "", post_data);
139 // No minidump means no need for crash to process the report.
140 net::AddMultipartValueForUpload("should_process", "false", kMultipartBoundary,
141 "", post_data);
143 AddTraceFile(trace_filename, trace_contents, post_data);
145 net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data);
148 void TraceUploader::AddTraceFile(const std::string& trace_filename,
149 const std::string& trace_contents,
150 std::string* post_data) {
151 post_data->append("--");
152 post_data->append(kMultipartBoundary);
153 post_data->append("\r\n");
154 post_data->append("Content-Disposition: form-data; name=\"trace\"");
155 post_data->append("; filename=\"");
156 post_data->append(trace_filename);
157 post_data->append("\"\r\n");
158 post_data->append("Content-Type: application/gzip\r\n\r\n");
159 post_data->append(trace_contents);
160 post_data->append("\r\n");
163 bool TraceUploader::Compress(std::string input,
164 int max_compressed_bytes,
165 char* compressed,
166 int* compressed_bytes) {
167 DCHECK(compressed);
168 DCHECK(compressed_bytes);
169 z_stream stream = {0};
170 int result = deflateInit2(&stream,
171 Z_DEFAULT_COMPRESSION,
172 Z_DEFLATED,
173 // 16 is added to produce a gzip header + trailer.
174 MAX_WBITS + 16,
175 8, // memLevel = 8 is default.
176 Z_DEFAULT_STRATEGY);
177 DCHECK_EQ(Z_OK, result);
178 stream.next_in = reinterpret_cast<uint8*>(&input[0]);
179 stream.avail_in = input.size();
180 stream.next_out = reinterpret_cast<uint8*>(compressed);
181 stream.avail_out = max_compressed_bytes;
182 // Do a one-shot compression. This will return Z_STREAM_END only if |output|
183 // is large enough to hold all compressed data.
184 result = deflate(&stream, Z_FINISH);
185 bool success = (result == Z_STREAM_END);
186 result = deflateEnd(&stream);
187 DCHECK(result == Z_OK || result == Z_DATA_ERROR);
189 if (success)
190 *compressed_bytes = max_compressed_bytes - stream.avail_out;
192 LOG(WARNING) << "input size: " << input.size()
193 << ", output size: " << *compressed_bytes;
194 return success;
197 void TraceUploader::CreateAndStartURLFetcher(const std::string& post_data) {
198 DCHECK_CURRENTLY_ON(BrowserThread::UI);
199 DCHECK(!url_fetcher_.get());
201 std::string content_type = kUploadContentType;
202 content_type.append("; boundary=");
203 content_type.append(kMultipartBoundary);
205 url_fetcher_.reset(
206 net::URLFetcher::Create(GURL(upload_url_), net::URLFetcher::POST, this));
207 url_fetcher_->SetRequestContext(request_context_);
208 url_fetcher_->SetUploadData(content_type, post_data);
209 url_fetcher_->Start();
212 } // namespace content