summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc3
-rw-r--r--chrome/browser/chromeos/policy/upload_job.h1
-rw-r--r--chrome/browser/chromeos/policy/upload_job_impl.cc82
-rw-r--r--chrome/browser/chromeos/policy/upload_job_impl.h7
-rw-r--r--chrome/browser/chromeos/policy/upload_job_unittest.cc5
-rw-r--r--chrome/common/cloud_print/cloud_print_helpers.cc8
-rw-r--r--chrome/common/cloud_print/cloud_print_helpers.h3
-rw-r--r--chrome/service/cloud_print/cloud_print_connector.cc6
-rw-r--r--chrome/service/cloud_print/printer_job_handler.cc3
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_requester.cc7
-rw-r--r--components/search_engines/template_url.cc8
-rw-r--r--content/browser/download/mhtml_generation_manager.cc25
-rw-r--r--google_apis/drive/base_requests.cc17
-rw-r--r--google_apis/drive/drive_api_requests_unittest.cc2
-rw-r--r--net/base/mime_util.cc49
-rw-r--r--net/base/mime_util.h4
-rw-r--r--net/base/mime_util_unittest.cc28
-rw-r--r--third_party/WebKit/Source/platform/network/FormDataEncoder.cpp1
18 files changed, 108 insertions, 151 deletions
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc
index f719de7..1f373f5 100644
--- a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc
+++ b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc
@@ -124,9 +124,6 @@ void DeviceCommandScreenshotJob::OnFailure(UploadJob::ErrorCode error_code) {
case UploadJob::SERVER_ERROR:
result_code = FAILURE_SERVER;
break;
- case UploadJob::CONTENT_ENCODING_ERROR:
- result_code = FAILURE_CLIENT;
- break;
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
diff --git a/chrome/browser/chromeos/policy/upload_job.h b/chrome/browser/chromeos/policy/upload_job.h
index 9702d12..1df7573 100644
--- a/chrome/browser/chromeos/policy/upload_job.h
+++ b/chrome/browser/chromeos/policy/upload_job.h
@@ -30,7 +30,6 @@ class UploadJob {
// If the upload fails, the Delegate's OnFailure() method is invoked with
// one of these error codes.
enum ErrorCode {
- CONTENT_ENCODING_ERROR = 0, // Failed to encode content.
NETWORK_ERROR = 1, // Network failure.
AUTHENTICATION_ERROR = 2, // Authentication failure.
SERVER_ERROR = 3 // Server returned error or malformed reply.
diff --git a/chrome/browser/chromeos/policy/upload_job_impl.cc b/chrome/browser/chromeos/policy/upload_job_impl.cc
index f1a4783..97a379e 100644
--- a/chrome/browser/chromeos/policy/upload_job_impl.cc
+++ b/chrome/browser/chromeos/policy/upload_job_impl.cc
@@ -4,15 +4,16 @@
#include "chrome/browser/chromeos/policy/upload_job_impl.h"
+#include <stddef.h>
#include <set>
#include <utility>
#include "base/logging.h"
#include "base/macros.h"
-#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/google_service_auth_error.h"
+#include "net/base/mime_util.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_request_status.h"
@@ -20,41 +21,18 @@ namespace policy {
namespace {
-// Defines the characters that might appear in strings generated by
-// GenerateRandomString().
-const char kAlphaNum[] =
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
// Format for bearer tokens in HTTP requests to access OAuth 2.0 protected
// resources.
const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s";
-// Prefix added to a randomly generated string when choosing the MIME boundary.
-const char kMultipartBoundaryPrefix[] = "----**--";
-
-// Postfix added to a randomly generated string when choosing the MIME boundary.
-const char kMultipartBoundaryPostfix[] = "--**----";
-
// Value the "Content-Type" field will be set to in the POST request.
const char kUploadContentType[] = "multipart/form-data";
-// Number of retries when randomly generating a MIME boundary.
-const int kMimeBoundaryRetries = 3;
-
-// Length of the random string for the MIME boundary.
-const int kMimeBoundarySize = 32;
-
// Number of upload retries.
const int kMaxRetries = 1;
-// Generates a random alphanumeric string of length |length|.
-std::string GenerateRandomString(size_t length) {
- std::string random;
- random.reserve(length);
- for (size_t i = 0; i < length; i++)
- random.push_back(kAlphaNum[base::RandGenerator(sizeof(kAlphaNum) - 1)]);
- return random;
-}
+// Max size of MIME boundary according to RFC 1341, section 7.2.1.
+const size_t kMaxMimeBoundarySize = 70;
} // namespace
@@ -95,10 +73,6 @@ class DataSegment {
// Returns the size in bytes of the blob in |data_|.
size_t GetDataSize() const;
- // Helper method that performs a substring match of |chunk| in |data_|.
- // Returns |true| if |chunk| matches a substring, |false| otherwise.
- bool CheckIfDataContains(const std::string& chunk);
-
private:
const std::string name_;
const std::string filename_;
@@ -137,28 +111,14 @@ scoped_ptr<std::string> DataSegment::GetData() {
return std::move(data_);
}
-bool DataSegment::CheckIfDataContains(const std::string& chunk) {
- DCHECK(data_);
- return data_->find(chunk) != std::string::npos;
-}
-
size_t DataSegment::GetDataSize() const {
DCHECK(data_);
return data_->size();
}
-std::string UploadJobImpl::RandomMimeBoundaryGenerator::GenerateBoundary(
- size_t length) const {
- std::string boundary;
- boundary.reserve(length);
- DCHECK_GT(length, sizeof(kMultipartBoundaryPrefix) +
- sizeof(kMultipartBoundaryPostfix));
- const size_t random_part_length = length - sizeof(kMultipartBoundaryPrefix) -
- sizeof(kMultipartBoundaryPostfix);
- boundary.append(kMultipartBoundaryPrefix);
- boundary.append(GenerateRandomString(random_part_length));
- boundary.append(kMultipartBoundaryPostfix);
- return boundary;
+std::string UploadJobImpl::RandomMimeBoundaryGenerator::GenerateBoundary()
+ const {
+ return net::GenerateMimeMultipartBoundary();
}
UploadJobImpl::UploadJobImpl(
@@ -236,30 +196,8 @@ bool UploadJobImpl::SetUpMultipart() {
return false;
}
- // Generates random MIME boundaries and tests if they appear in any of the
- // data segments. Tries up to |kMimeBoundaryRetries| times to find a MIME
- // boundary that does not appear within any data segment.
- bool found = false;
- int retry = 0;
- do {
- found = true;
- mime_boundary_.reset(new std::string(
- boundary_generator_->GenerateBoundary(kMimeBoundarySize)));
- for (const auto& data_segment : data_segments_) {
- if (data_segment->CheckIfDataContains(*mime_boundary_)) {
- found = false;
- break;
- }
- }
- ++retry;
- } while (!found && retry <= kMimeBoundaryRetries);
-
- // Notify the delegate that content encoding failed.
- if (!found) {
- delegate_->OnFailure(CONTENT_ENCODING_ERROR);
- mime_boundary_.reset();
- return false;
- }
+ mime_boundary_.reset(
+ new std::string(boundary_generator_->GenerateBoundary()));
// Estimate an upper bound for the total message size to make memory
// allocation more efficient. It is not an error if this turns out to be too
@@ -268,7 +206,7 @@ bool UploadJobImpl::SetUpMultipart() {
for (const auto& data_segment : data_segments_) {
for (const auto& entry : data_segment->GetHeaderEntries())
size += entry.first.size() + entry.second.size();
- size += kMimeBoundarySize + data_segment->GetName().size() +
+ size += kMaxMimeBoundarySize + data_segment->GetName().size() +
data_segment->GetFilename().size() + data_segment->GetDataSize();
// Add some extra space for all the constants and control characters.
size += 128;
diff --git a/chrome/browser/chromeos/policy/upload_job_impl.h b/chrome/browser/chromeos/policy/upload_job_impl.h
index 958eef3..7c7106f 100644
--- a/chrome/browser/chromeos/policy/upload_job_impl.h
+++ b/chrome/browser/chromeos/policy/upload_job_impl.h
@@ -5,8 +5,6 @@
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_UPLOAD_JOB_IMPL_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_UPLOAD_JOB_IMPL_H_
-#include <stddef.h>
-
#include <map>
#include <string>
@@ -36,7 +34,7 @@ class UploadJobImpl : public UploadJob,
public:
virtual ~MimeBoundaryGenerator();
- virtual std::string GenerateBoundary(size_t length) const = 0;
+ virtual std::string GenerateBoundary() const = 0;
private:
DISALLOW_ASSIGN(MimeBoundaryGenerator);
@@ -48,8 +46,7 @@ class UploadJobImpl : public UploadJob,
public:
~RandomMimeBoundaryGenerator() override;
- std::string GenerateBoundary(
- size_t length) const override; // MimeBoundaryGenerator
+ std::string GenerateBoundary() const override; // MimeBoundaryGenerator
};
UploadJobImpl(const GURL& upload_url,
diff --git a/chrome/browser/chromeos/policy/upload_job_unittest.cc b/chrome/browser/chromeos/policy/upload_job_unittest.cc
index 85f88cb..bc5f5a9 100644
--- a/chrome/browser/chromeos/policy/upload_job_unittest.cc
+++ b/chrome/browser/chromeos/policy/upload_job_unittest.cc
@@ -51,8 +51,9 @@ class RepeatingMimeBoundaryGenerator
~RepeatingMimeBoundaryGenerator() override {}
// MimeBoundaryGenerator:
- std::string GenerateBoundary(size_t length) const override {
- return std::string(length, character_);
+ std::string GenerateBoundary() const override {
+ const int kMimeBoundarySize = 32;
+ return std::string(kMimeBoundarySize, character_);
}
private:
diff --git a/chrome/common/cloud_print/cloud_print_helpers.cc b/chrome/common/cloud_print/cloud_print_helpers.cc
index 406c54b..6fcd8bd 100644
--- a/chrome/common/cloud_print/cloud_print_helpers.cc
+++ b/chrome/common/cloud_print/cloud_print_helpers.cc
@@ -12,7 +12,6 @@
#include "base/logging.h"
#include "base/md5.h"
#include "base/memory/scoped_ptr.h"
-#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "base/values.h"
@@ -207,13 +206,6 @@ std::string GetMultipartMimeType(const std::string& mime_boundary) {
return std::string("multipart/form-data; boundary=") + mime_boundary;
}
-// Create a MIME boundary marker (27 '-' characters followed by 16 hex digits).
-void CreateMimeBoundaryForUpload(std::string* out) {
- int r1 = base::RandInt(0, std::numeric_limits<int32_t>::max());
- int r2 = base::RandInt(0, std::numeric_limits<int32_t>::max());
- base::SStringPrintf(out, "---------------------------%08X%08X", r1, r2);
-}
-
std::string GetHashOfPrinterTags(const PrinterTags& printer_tags) {
return HashPrinterTags(PreparePrinterTags(printer_tags));
}
diff --git a/chrome/common/cloud_print/cloud_print_helpers.h b/chrome/common/cloud_print/cloud_print_helpers.h
index 273e6d4..009fab6 100644
--- a/chrome/common/cloud_print/cloud_print_helpers.h
+++ b/chrome/common/cloud_print/cloud_print_helpers.h
@@ -70,9 +70,6 @@ scoped_ptr<base::DictionaryValue> ParseResponseJSON(
// Returns the MIME type of multipart with |mime_boundary|.
std::string GetMultipartMimeType(const std::string& mime_boundary);
-// Create a MIME boundary marker (27 '-' characters followed by 16 hex digits).
-void CreateMimeBoundaryForUpload(std::string *out);
-
// Returns an MD5 hash for |printer_tags| and the default required tags.
std::string GetHashOfPrinterTags(const PrinterTags& printer_tags);
diff --git a/chrome/service/cloud_print/cloud_print_connector.cc b/chrome/service/cloud_print/cloud_print_connector.cc
index 731d9c9..1bec7b08 100644
--- a/chrome/service/cloud_print/cloud_print_connector.cc
+++ b/chrome/service/cloud_print/cloud_print_connector.cc
@@ -362,8 +362,7 @@ void CloudPrintConnector::ReportUserMessage(const std::string& message_id,
const std::string& failure_msg) {
// This is a fire and forget type of function.
// Result of this request will be ignored.
- std::string mime_boundary;
- CreateMimeBoundaryForUpload(&mime_boundary);
+ std::string mime_boundary = net::GenerateMimeMultipartBoundary();
GURL url = GetUrlForUserMessage(settings_.server_url(), message_id);
std::string post_data;
net::AddMultipartValueForUpload(kMessageTextValue, failure_msg, mime_boundary,
@@ -609,8 +608,7 @@ void CloudPrintConnector::OnReceivePrinterCaps(
const printing::PrinterBasicInfo& info = pending_tasks_.front().printer_info;
DCHECK(IsSamePrinter(info.printer_name, printer_name));
- std::string mime_boundary;
- CreateMimeBoundaryForUpload(&mime_boundary);
+ std::string mime_boundary = net::GenerateMimeMultipartBoundary();
std::string post_data;
net::AddMultipartValueForUpload(kProxyIdValue,
diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc
index 2f255f9..a720d5e 100644
--- a/chrome/service/cloud_print/printer_job_handler.cc
+++ b/chrome/service/cloud_print/printer_job_handler.cc
@@ -684,8 +684,7 @@ void PrinterJobHandler::OnReceivePrinterCaps(
printer_watcher_->GetCurrentPrinterInfo(&printer_info);
std::string post_data;
- std::string mime_boundary;
- CreateMimeBoundaryForUpload(&mime_boundary);
+ std::string mime_boundary = net::GenerateMimeMultipartBoundary();
if (succeeded) {
std::string caps_hash =
diff --git a/cloud_print/gcp20/prototype/cloud_print_requester.cc b/cloud_print/gcp20/prototype/cloud_print_requester.cc
index b32456c..ccae344 100644
--- a/cloud_print/gcp20/prototype/cloud_print_requester.cc
+++ b/cloud_print/gcp20/prototype/cloud_print_requester.cc
@@ -12,7 +12,6 @@
#include "base/json/json_writer.h"
#include "base/md5.h"
#include "base/message_loop/message_loop.h"
-#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.h"
#include "google_apis/google_api_keys.h"
@@ -125,11 +124,7 @@ void CloudPrintRequester::StartRegistration(const std::string& proxy_id,
const std::string& user,
const LocalSettings& settings,
const std::string& cdd) {
- std::string mime_boundary;
- int r1 = base::RandInt(0, std::numeric_limits<int32_t>::max());
- int r2 = base::RandInt(0, std::numeric_limits<int32_t>::max());
- base::SStringPrintf(&mime_boundary,
- "---------------------------%08X%08X", r1, r2);
+ std::string mime_boundary = net::GenerateMimeMultipartBoundary();
std::string data;
std::string data_mimetype;
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc
index a75779b..dcf45f8 100644
--- a/components/search_engines/template_url.cc
+++ b/components/search_engines/template_url.cc
@@ -14,7 +14,6 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/field_trial.h"
-#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
@@ -277,12 +276,9 @@ bool TemplateURLRef::EncodeFormData(const PostParams& post_params,
return false;
const char kUploadDataMIMEType[] = "multipart/form-data; boundary=";
- const char kMultipartBoundary[] = "----+*+----%016" PRIx64 "----+*+----";
// Each name/value pair is stored in a body part which is preceded by a
- // boundary delimiter line. Uses random number generator here to create
- // a unique boundary delimiter for form data encoding.
- std::string boundary = base::StringPrintf(kMultipartBoundary,
- base::RandUint64());
+ // boundary delimiter line.
+ std::string boundary = net::GenerateMimeMultipartBoundary();
// Sets the content MIME type.
post_content->first = kUploadDataMIMEType;
post_content->first += boundary;
diff --git a/content/browser/download/mhtml_generation_manager.cc b/content/browser/download/mhtml_generation_manager.cc
index 792e019..ef92023 100644
--- a/content/browser/download/mhtml_generation_manager.cc
+++ b/content/browser/download/mhtml_generation_manager.cc
@@ -12,10 +12,8 @@
#include "base/files/file.h"
#include "base/guid.h"
#include "base/macros.h"
-#include "base/rand_util.h"
#include "base/scoped_observer.h"
#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "content/browser/bad_message.h"
#include "content/browser/frame_host/frame_tree_node.h"
@@ -26,6 +24,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/web_contents.h"
+#include "net/base/mime_util.h"
namespace content {
@@ -73,7 +72,6 @@ class MHTMLGenerationManager::Job : public RenderProcessHostObserver {
void RenderProcessHostDestroyed(RenderProcessHost* host) override;
private:
- static std::string GenerateMHTMLBoundaryMarker();
static int64_t CloseFileOnFileThread(base::File file);
void AddFrame(RenderFrameHost* render_frame_host);
@@ -124,7 +122,7 @@ MHTMLGenerationManager::Job::Job(int job_id,
GenerateMHTMLCallback callback)
: job_id_(job_id),
frame_tree_node_id_of_busy_frame_(FrameTreeNode::kFrameTreeNodeInvalidId),
- mhtml_boundary_marker_(GenerateMHTMLBoundaryMarker()),
+ mhtml_boundary_marker_(net::GenerateMimeMultipartBoundary()),
salt_(base::GenerateGUID()),
callback_(callback),
observed_renderer_process_host_(this) {
@@ -280,25 +278,6 @@ int64_t MHTMLGenerationManager::Job::CloseFileOnFileThread(base::File file) {
return file_size;
}
-// static
-std::string MHTMLGenerationManager::Job::GenerateMHTMLBoundaryMarker() {
- // TODO(lukasza): Introduce and use a shared helper function in
- // net/base/mime_util.h instead of having the ad-hoc code below.
-
- // Trying to generate random boundaries similar to IE/UnMHT
- // (ex: ----=_NextPart_000_001B_01CC157B.96F808A0).
- uint8_t random_values[10];
- base::RandBytes(random_values, sizeof(random_values));
-
- std::string result("----=_NextPart_000_");
- result += base::HexEncode(random_values + 0, 2);
- result += '_';
- result += base::HexEncode(random_values + 2, 4);
- result += '.';
- result += base::HexEncode(random_values + 6, 4);
- return result;
-}
-
MHTMLGenerationManager* MHTMLGenerationManager::GetInstance() {
return base::Singleton<MHTMLGenerationManager>::get();
}
diff --git a/google_apis/drive/base_requests.cc b/google_apis/drive/base_requests.cc
index 3e5b0d1..8a4e38b 100644
--- a/google_apis/drive/base_requests.cc
+++ b/google_apis/drive/base_requests.cc
@@ -12,7 +12,6 @@
#include "base/json/json_writer.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/rand_util.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
@@ -27,6 +26,7 @@
#include "net/base/elements_upload_data_stream.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
+#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_data_stream.h"
@@ -76,13 +76,6 @@ const char kMultipartItemHeaderFormat[] = "--%s\nContent-Type: %s\n\n";
// Footer for whole multipart message.
const char kMultipartFooterFormat[] = "--%s--";
-// Characters to be used for multipart/related boundary.
-const char kBoundaryCharacters[] =
- "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-// Size of multipart/related's boundary.
-const char kBoundarySize = 70;
-
// Parses JSON passed in |json| on |blocking_task_runner|. Runs |callback| on
// the calling thread when finished with either success or failure.
// The callback must not be null.
@@ -227,13 +220,7 @@ void GenerateMultipartBody(MultipartType multipart_type,
// Generate random boundary.
if (predetermined_boundary.empty()) {
while (true) {
- boundary.resize(kBoundarySize);
- for (int i = 0; i < kBoundarySize; ++i) {
- // Subtract 2 from the array size to exclude '\0', and to turn the size
- // into the last index.
- const int last_char_index = arraysize(kBoundaryCharacters) - 2;
- boundary[i] = kBoundaryCharacters[base::RandInt(0, last_char_index)];
- }
+ boundary = net::GenerateMimeMultipartBoundary();
bool conflict_with_content = false;
for (auto& part : parts) {
if (part.data.find(boundary, 0) != std::string::npos) {
diff --git a/google_apis/drive/drive_api_requests_unittest.cc b/google_apis/drive/drive_api_requests_unittest.cc
index 0912d61..3200339 100644
--- a/google_apis/drive/drive_api_requests_unittest.cc
+++ b/google_apis/drive/drive_api_requests_unittest.cc
@@ -2141,7 +2141,7 @@ TEST_F(DriveApiRequestsTest, BatchUploadRequestProgress) {
new TestBatchableDelegate(GURL("http://example.com/test"),
"application/binary", std::string(0, 'c'),
base::Bind(&EmptyClosure))};
- const size_t kExpectedUploadDataPosition[] = {208, 517, 776};
+ const size_t kExpectedUploadDataPosition[] = {207, 515, 773};
const size_t kExpectedUploadDataSize = 851;
request->AddRequest(requests[0]);
request->AddRequest(requests[1]);
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index d1e202b..3e8d615 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -7,9 +7,11 @@
#include <map>
#include <string>
+#include "base/base64.h"
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -511,6 +513,17 @@ void HashSetToVector(base::hash_set<T>* source, std::vector<T>* target) {
(*target)[old_target_size + i] = *iter;
}
+// Characters to be used for mime multipart boundary.
+// The RFC 2046 spec says the alphanumeric characters plus the
+// following characters are legal for boundaries: '()+_,-./:=?
+// However the following characters, though legal, cause some sites
+// to fail: (),./:=+
+const char kMimeBoundaryCharacters[] =
+ "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+// Size of mime multipart boundary.
+const size_t kMimeBoundarySize = 69;
+
} // namespace
void GetExtensionsForMimeType(
@@ -557,6 +570,42 @@ void GetExtensionsForMimeType(
HashSetToVector(&unique_extensions, extensions);
}
+NET_EXPORT std::string GenerateMimeMultipartBoundary() {
+ // Based on RFC 1341, section "7.2.1 Multipart: The common syntax":
+ // Because encapsulation boundaries must not appear in the body parts being
+ // encapsulated, a user agent must exercise care to choose a unique
+ // boundary. The boundary in the example above could have been the result of
+ // an algorithm designed to produce boundaries with a very low probability
+ // of already existing in the data to be encapsulated without having to
+ // prescan the data.
+ // [...]
+ // the boundary parameter [...] consists of 1 to 70 characters from a set of
+ // characters known to be very robust through email gateways, and NOT ending
+ // with white space.
+ // [...]
+ // boundary := 0*69<bchars> bcharsnospace
+ // bchars := bcharsnospace / " "
+ // bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / "+" /
+ // "_" / "," / "-" / "." / "/" / ":" / "=" / "?"
+
+ std::string result;
+ result.reserve(kMimeBoundarySize);
+ result.append("----MultipartBoundary--");
+ while (result.size() < (kMimeBoundarySize - 4)) {
+ // Subtract 2 from the array size to 1) exclude '\0', and 2) turn the size
+ // into the last index.
+ const int last_char_index = sizeof(kMimeBoundaryCharacters) - 2;
+ char c = kMimeBoundaryCharacters[base::RandInt(0, last_char_index)];
+ result.push_back(c);
+ }
+ result.append("----");
+
+ // Not a strict requirement - documentation only.
+ DCHECK_EQ(kMimeBoundarySize, result.size());
+
+ return result;
+}
+
void AddMultipartValueForUpload(const std::string& value_name,
const std::string& value,
const std::string& mime_boundary,
diff --git a/net/base/mime_util.h b/net/base/mime_util.h
index d58ddb0..48b9a64 100644
--- a/net/base/mime_util.h
+++ b/net/base/mime_util.h
@@ -100,6 +100,10 @@ enum CertificateMimeType {
CERTIFICATE_MIME_TYPE_PKCS12_ARCHIVE,
};
+// Generates a random MIME multipart boundary.
+// The returned string is guaranteed to be at most 70 characters long.
+NET_EXPORT std::string GenerateMimeMultipartBoundary();
+
// Prepares one value as part of a multi-part upload request.
NET_EXPORT void AddMultipartValueForUpload(const std::string& value_name,
const std::string& value,
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc
index 8bc61bc..0787d8c 100644
--- a/net/base/mime_util_unittest.cc
+++ b/net/base/mime_util_unittest.cc
@@ -273,6 +273,34 @@ TEST(MimeUtilTest, TestGetExtensionsForMimeType) {
}
}
+TEST(MimeUtilTest, TestGenerateMimeMultipartBoundary) {
+ std::string boundary1 = GenerateMimeMultipartBoundary();
+ std::string boundary2 = GenerateMimeMultipartBoundary();
+
+ // RFC 1341 says: the boundary parameter [...] consists of 1 to 70 characters.
+ EXPECT_GE(70u, boundary1.size());
+ EXPECT_GE(70u, boundary2.size());
+
+ // RFC 1341 asks to: exercise care to choose a unique boundary.
+ EXPECT_NE(boundary1, boundary2);
+ ASSERT_LE(16u, boundary1.size());
+ ASSERT_LE(16u, boundary2.size());
+
+ // Expect that we don't pick '\0' character from the array/string
+ // where we take the characters from.
+ EXPECT_EQ(std::string::npos, boundary1.find('\0'));
+ EXPECT_EQ(std::string::npos, boundary2.find('\0'));
+
+ // Asserts below are not RFC 1341 requirements, but are here
+ // to improve readability of generated MIME documents and to
+ // try to preserve some aspects of the old boundary generation code.
+ EXPECT_EQ("--", boundary1.substr(0, 2));
+ EXPECT_EQ("--", boundary2.substr(0, 2));
+ EXPECT_NE(std::string::npos, boundary1.find("MultipartBoundary"));
+ EXPECT_NE(std::string::npos, boundary2.find("MultipartBoundary"));
+ EXPECT_EQ("--", boundary1.substr(boundary1.size() - 2, 2));
+ EXPECT_EQ("--", boundary2.substr(boundary2.size() - 2, 2));
+}
TEST(MimeUtilTest, TestAddMultipartValueForUpload) {
const char ref_output[] =
diff --git a/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp b/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp
index e66bf81..0b73501 100644
--- a/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp
+++ b/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp
@@ -99,6 +99,7 @@ WTF::TextEncoding FormDataEncoder::encodingFromAcceptCharset(const String& accep
return charset;
}
+// TODO(lukasza): Reuse net::GenerateMimeMultipartBoundary instead.
Vector<char> FormDataEncoder::generateUniqueBoundaryString()
{
Vector<char> boundary;