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

Side by Side Diff: chrome/browser/chromeos/policy/upload_job_impl.cc

Issue 1547593002: Introducing a net::GenerateMimeMultipartBoundary helper. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Self-review. Created 5 years 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
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 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/chromeos/policy/upload_job_impl.h" 5 #include "chrome/browser/chromeos/policy/upload_job_impl.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/rand_util.h"
11 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
12 #include "google_apis/gaia/gaia_constants.h" 11 #include "google_apis/gaia/gaia_constants.h"
13 #include "google_apis/gaia/google_service_auth_error.h" 12 #include "google_apis/gaia/google_service_auth_error.h"
13 #include "net/base/mime_util.h"
14 #include "net/http/http_status_code.h" 14 #include "net/http/http_status_code.h"
15 #include "net/url_request/url_request_status.h" 15 #include "net/url_request/url_request_status.h"
16 16
17 namespace policy { 17 namespace policy {
18 18
19 namespace { 19 namespace {
20 20
21 // Defines the characters that might appear in strings generated by
22 // GenerateRandomString().
23 const char kAlphaNum[] =
24 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
25
26 // Format for bearer tokens in HTTP requests to access OAuth 2.0 protected 21 // Format for bearer tokens in HTTP requests to access OAuth 2.0 protected
27 // resources. 22 // resources.
28 const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; 23 const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s";
29 24
30 // Prefix added to a randomly generated string when choosing the MIME boundary.
31 const char kMultipartBoundaryPrefix[] = "----**--";
32
33 // Postfix added to a randomly generated string when choosing the MIME boundary.
34 const char kMultipartBoundaryPostfix[] = "--**----";
35
36 // Value the "Content-Type" field will be set to in the POST request. 25 // Value the "Content-Type" field will be set to in the POST request.
37 const char kUploadContentType[] = "multipart/form-data"; 26 const char kUploadContentType[] = "multipart/form-data";
38 27
39 // Number of retries when randomly generating a MIME boundary. 28 // Number of retries when randomly generating a MIME boundary.
40 const int kMimeBoundaryRetries = 3; 29 const int kMimeBoundaryRetries = 3;
41 30
42 // Length of the random string for the MIME boundary.
43 const int kMimeBoundarySize = 32;
44
45 // Number of upload retries. 31 // Number of upload retries.
46 const int kMaxRetries = 1; 32 const int kMaxRetries = 1;
47 33
48 // Generates a random alphanumeric string of length |length|. 34 // Max size of MIME boundary according to RFC 1341, section 7.2.1.
49 std::string GenerateRandomString(size_t length) { 35 const size_t kMaxMimeBoundarySize = 70;
50 std::string random;
51 random.reserve(length);
52 for (size_t i = 0; i < length; i++)
53 random.push_back(kAlphaNum[base::RandGenerator(sizeof(kAlphaNum) - 1)]);
54 return random;
55 }
56 36
57 } // namespace 37 } // namespace
58 38
59 UploadJobImpl::Delegate::~Delegate() { 39 UploadJobImpl::Delegate::~Delegate() {
60 } 40 }
61 41
62 UploadJobImpl::MimeBoundaryGenerator::~MimeBoundaryGenerator() { 42 UploadJobImpl::MimeBoundaryGenerator::~MimeBoundaryGenerator() {
63 } 43 }
64 44
65 UploadJobImpl::RandomMimeBoundaryGenerator::~RandomMimeBoundaryGenerator() { 45 UploadJobImpl::RandomMimeBoundaryGenerator::~RandomMimeBoundaryGenerator() {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 bool DataSegment::CheckIfDataContains(const std::string& chunk) { 118 bool DataSegment::CheckIfDataContains(const std::string& chunk) {
139 DCHECK(data_); 119 DCHECK(data_);
140 return data_->find(chunk) != std::string::npos; 120 return data_->find(chunk) != std::string::npos;
141 } 121 }
142 122
143 size_t DataSegment::GetDataSize() const { 123 size_t DataSegment::GetDataSize() const {
144 DCHECK(data_); 124 DCHECK(data_);
145 return data_->size(); 125 return data_->size();
146 } 126 }
147 127
148 std::string UploadJobImpl::RandomMimeBoundaryGenerator::GenerateBoundary( 128 std::string UploadJobImpl::RandomMimeBoundaryGenerator::GenerateBoundary()
149 size_t length) const { 129 const {
150 std::string boundary; 130 return net::GenerateMimeMultipartBoundary();
151 boundary.reserve(length);
152 DCHECK_GT(length, sizeof(kMultipartBoundaryPrefix) +
153 sizeof(kMultipartBoundaryPostfix));
154 const size_t random_part_length = length - sizeof(kMultipartBoundaryPrefix) -
155 sizeof(kMultipartBoundaryPostfix);
156 boundary.append(kMultipartBoundaryPrefix);
157 boundary.append(GenerateRandomString(random_part_length));
158 boundary.append(kMultipartBoundaryPostfix);
159 return boundary;
160 } 131 }
161 132
162 UploadJobImpl::UploadJobImpl( 133 UploadJobImpl::UploadJobImpl(
163 const GURL& upload_url, 134 const GURL& upload_url,
164 const std::string& account_id, 135 const std::string& account_id,
165 OAuth2TokenService* token_service, 136 OAuth2TokenService* token_service,
166 scoped_refptr<net::URLRequestContextGetter> url_context_getter, 137 scoped_refptr<net::URLRequestContextGetter> url_context_getter,
167 Delegate* delegate, 138 Delegate* delegate,
168 scoped_ptr<MimeBoundaryGenerator> boundary_generator) 139 scoped_ptr<MimeBoundaryGenerator> boundary_generator)
169 : OAuth2TokenService::Consumer("cros_upload_job"), 140 : OAuth2TokenService::Consumer("cros_upload_job"),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 return false; 205 return false;
235 } 206 }
236 207
237 // Generates random MIME boundaries and tests if they appear in any of the 208 // Generates random MIME boundaries and tests if they appear in any of the
238 // data segments. Tries up to |kMimeBoundaryRetries| times to find a MIME 209 // data segments. Tries up to |kMimeBoundaryRetries| times to find a MIME
239 // boundary that does not appear within any data segment. 210 // boundary that does not appear within any data segment.
240 bool found = false; 211 bool found = false;
241 int retry = 0; 212 int retry = 0;
242 do { 213 do {
243 found = true; 214 found = true;
244 mime_boundary_.reset(new std::string( 215 mime_boundary_.reset(
245 boundary_generator_->GenerateBoundary(kMimeBoundarySize))); 216 new std::string(boundary_generator_->GenerateBoundary()));
246 for (const auto& data_segment : data_segments_) { 217 for (const auto& data_segment : data_segments_) {
247 if (data_segment->CheckIfDataContains(*mime_boundary_)) { 218 if (data_segment->CheckIfDataContains(*mime_boundary_)) {
248 found = false; 219 found = false;
249 break; 220 break;
250 } 221 }
251 } 222 }
252 ++retry; 223 ++retry;
253 } while (!found && retry <= kMimeBoundaryRetries); 224 } while (!found && retry <= kMimeBoundaryRetries);
Ryan Sleevi 2015/12/28 23:30:00 This seems overly conservative/unnecessary with yo
Łukasz Anforowicz 2015/12/29 18:53:19 Done. I think you have a good point wrt removing
254 225
255 // Notify the delegate that content encoding failed. 226 // Notify the delegate that content encoding failed.
256 if (!found) { 227 if (!found) {
257 delegate_->OnFailure(CONTENT_ENCODING_ERROR); 228 delegate_->OnFailure(CONTENT_ENCODING_ERROR);
258 mime_boundary_.reset(); 229 mime_boundary_.reset();
259 return false; 230 return false;
260 } 231 }
261 232
262 // Estimate an upper bound for the total message size to make memory 233 // Estimate an upper bound for the total message size to make memory
263 // allocation more efficient. It is not an error if this turns out to be too 234 // allocation more efficient. It is not an error if this turns out to be too
264 // small as std::string will take care of the realloc. 235 // small as std::string will take care of the realloc.
265 size_t size = 0; 236 size_t size = 0;
266 for (const auto& data_segment : data_segments_) { 237 for (const auto& data_segment : data_segments_) {
267 for (const auto& entry : data_segment->GetHeaderEntries()) 238 for (const auto& entry : data_segment->GetHeaderEntries())
268 size += entry.first.size() + entry.second.size(); 239 size += entry.first.size() + entry.second.size();
269 size += kMimeBoundarySize + data_segment->GetName().size() + 240 size += kMaxMimeBoundarySize + data_segment->GetName().size() +
270 data_segment->GetFilename().size() + data_segment->GetDataSize(); 241 data_segment->GetFilename().size() + data_segment->GetDataSize();
271 // Add some extra space for all the constants and control characters. 242 // Add some extra space for all the constants and control characters.
272 size += 128; 243 size += 128;
273 } 244 }
274 245
275 // Allocate memory of the expected size. 246 // Allocate memory of the expected size.
276 post_data_.reset(new std::string); 247 post_data_.reset(new std::string);
277 post_data_->reserve(size); 248 post_data_->reserve(size);
278 249
279 for (const auto& data_segment : data_segments_) { 250 for (const auto& data_segment : data_segments_) {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 if (success) { 373 if (success) {
403 state_ = SUCCESS; 374 state_ = SUCCESS;
404 delegate_->OnSuccess(); 375 delegate_->OnSuccess();
405 } else { 376 } else {
406 state_ = ERROR; 377 state_ = ERROR;
407 delegate_->OnFailure(SERVER_ERROR); 378 delegate_->OnFailure(SERVER_ERROR);
408 } 379 }
409 } 380 }
410 381
411 } // namespace policy 382 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698