Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <iterator> | 6 #include <iterator> |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/base64.h" | |
| 10 #include "base/containers/hash_tables.h" | 11 #include "base/containers/hash_tables.h" |
| 11 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/rand_util.h" | |
| 13 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 14 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_split.h" | 17 #include "base/strings/string_split.h" |
| 16 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 18 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 19 #include "net/base/mime_util.h" | 21 #include "net/base/mime_util.h" |
| 20 #include "net/base/platform_mime_util.h" | 22 #include "net/base/platform_mime_util.h" |
| 21 #include "net/http/http_util.h" | 23 #include "net/http/http_util.h" |
| 22 | 24 |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 504 template<class T> | 506 template<class T> |
| 505 void HashSetToVector(base::hash_set<T>* source, std::vector<T>* target) { | 507 void HashSetToVector(base::hash_set<T>* source, std::vector<T>* target) { |
| 506 size_t old_target_size = target->size(); | 508 size_t old_target_size = target->size(); |
| 507 target->resize(old_target_size + source->size()); | 509 target->resize(old_target_size + source->size()); |
| 508 size_t i = 0; | 510 size_t i = 0; |
| 509 for (typename base::hash_set<T>::iterator iter = source->begin(); | 511 for (typename base::hash_set<T>::iterator iter = source->begin(); |
| 510 iter != source->end(); ++iter, ++i) | 512 iter != source->end(); ++iter, ++i) |
| 511 (*target)[old_target_size + i] = *iter; | 513 (*target)[old_target_size + i] = *iter; |
| 512 } | 514 } |
| 513 | 515 |
| 516 // Characters to be used for mime multipart boundary. | |
| 517 // The RFC 2046 spec says the alphanumeric characters plus the | |
| 518 // following characters are legal for boundaries: '()+_,-./:=? | |
| 519 // However the following characters, though legal, cause some sites | |
| 520 // to fail: (),./:=+ | |
|
Ryan Sleevi
2016/01/08 19:55:04
Sorry, I've been at a conference this week and hav
| |
| 521 const char kMimeBoundaryCharacters[] = | |
| 522 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
| 523 | |
| 524 // Size of mime multipart boundary. | |
| 525 const size_t kMimeBoundarySize = 69; | |
| 526 | |
| 514 } // namespace | 527 } // namespace |
| 515 | 528 |
| 516 void GetExtensionsForMimeType( | 529 void GetExtensionsForMimeType( |
| 517 const std::string& unsafe_mime_type, | 530 const std::string& unsafe_mime_type, |
| 518 std::vector<base::FilePath::StringType>* extensions) { | 531 std::vector<base::FilePath::StringType>* extensions) { |
| 519 if (unsafe_mime_type == "*/*" || unsafe_mime_type == "*") | 532 if (unsafe_mime_type == "*/*" || unsafe_mime_type == "*") |
| 520 return; | 533 return; |
| 521 | 534 |
| 522 const std::string mime_type = base::ToLowerASCII(unsafe_mime_type); | 535 const std::string mime_type = base::ToLowerASCII(unsafe_mime_type); |
| 523 base::hash_set<base::FilePath::StringType> unique_extensions; | 536 base::hash_set<base::FilePath::StringType> unique_extensions; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 550 &unique_extensions); | 563 &unique_extensions); |
| 551 | 564 |
| 552 GetExtensionsFromHardCodedMappings(kSecondaryMappings, | 565 GetExtensionsFromHardCodedMappings(kSecondaryMappings, |
| 553 arraysize(kSecondaryMappings), mime_type, | 566 arraysize(kSecondaryMappings), mime_type, |
| 554 &unique_extensions); | 567 &unique_extensions); |
| 555 } | 568 } |
| 556 | 569 |
| 557 HashSetToVector(&unique_extensions, extensions); | 570 HashSetToVector(&unique_extensions, extensions); |
| 558 } | 571 } |
| 559 | 572 |
| 573 NET_EXPORT std::string GenerateMimeMultipartBoundary() { | |
| 574 // Based on RFC 1341, section "7.2.1 Multipart: The common syntax": | |
| 575 // Because encapsulation boundaries must not appear in the body parts being | |
| 576 // encapsulated, a user agent must exercise care to choose a unique | |
| 577 // boundary. The boundary in the example above could have been the result of | |
| 578 // an algorithm designed to produce boundaries with a very low probability | |
| 579 // of already existing in the data to be encapsulated without having to | |
| 580 // prescan the data. | |
| 581 // [...] | |
| 582 // the boundary parameter [...] consists of 1 to 70 characters from a set of | |
| 583 // characters known to be very robust through email gateways, and NOT ending | |
| 584 // with white space. | |
| 585 // [...] | |
| 586 // boundary := 0*69<bchars> bcharsnospace | |
| 587 // bchars := bcharsnospace / " " | |
| 588 // bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / "+" / | |
| 589 // "_" / "," / "-" / "." / "/" / ":" / "=" / "?" | |
| 590 | |
| 591 std::string result; | |
| 592 result.reserve(kMimeBoundarySize); | |
| 593 result.append("----MultipartBoundary--"); | |
| 594 while (result.size() < (kMimeBoundarySize - 4)) { | |
| 595 // Subtract 2 from the array size to 1) exclude '\0', and 2) turn the size | |
| 596 // into the last index. | |
| 597 const int last_char_index = sizeof(kMimeBoundaryCharacters) - 2; | |
| 598 char c = kMimeBoundaryCharacters[base::RandInt(0, last_char_index)]; | |
| 599 result.push_back(c); | |
| 600 } | |
| 601 result.append("----"); | |
| 602 | |
| 603 // Not a strict requirement - documentation only. | |
| 604 DCHECK_EQ(kMimeBoundarySize, result.size()); | |
| 605 | |
| 606 return result; | |
| 607 } | |
| 608 | |
| 560 void AddMultipartValueForUpload(const std::string& value_name, | 609 void AddMultipartValueForUpload(const std::string& value_name, |
| 561 const std::string& value, | 610 const std::string& value, |
| 562 const std::string& mime_boundary, | 611 const std::string& mime_boundary, |
| 563 const std::string& content_type, | 612 const std::string& content_type, |
| 564 std::string* post_data) { | 613 std::string* post_data) { |
| 565 DCHECK(post_data); | 614 DCHECK(post_data); |
| 566 // First line is the boundary. | 615 // First line is the boundary. |
| 567 post_data->append("--" + mime_boundary + "\r\n"); | 616 post_data->append("--" + mime_boundary + "\r\n"); |
| 568 // Next line is the Content-disposition. | 617 // Next line is the Content-disposition. |
| 569 post_data->append("Content-Disposition: form-data; name=\"" + | 618 post_data->append("Content-Disposition: form-data; name=\"" + |
| 570 value_name + "\"\r\n"); | 619 value_name + "\"\r\n"); |
| 571 if (!content_type.empty()) { | 620 if (!content_type.empty()) { |
| 572 // If Content-type is specified, the next line is that. | 621 // If Content-type is specified, the next line is that. |
| 573 post_data->append("Content-Type: " + content_type + "\r\n"); | 622 post_data->append("Content-Type: " + content_type + "\r\n"); |
| 574 } | 623 } |
| 575 // Leave an empty line and append the value. | 624 // Leave an empty line and append the value. |
| 576 post_data->append("\r\n" + value + "\r\n"); | 625 post_data->append("\r\n" + value + "\r\n"); |
| 577 } | 626 } |
| 578 | 627 |
| 579 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary, | 628 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary, |
| 580 std::string* post_data) { | 629 std::string* post_data) { |
| 581 DCHECK(post_data); | 630 DCHECK(post_data); |
| 582 post_data->append("--" + mime_boundary + "--\r\n"); | 631 post_data->append("--" + mime_boundary + "--\r\n"); |
| 583 } | 632 } |
| 584 | 633 |
| 585 } // namespace net | 634 } // namespace net |
| OLD | NEW |