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 // NOTE: based loosely on mozilla's nsDataChannel.cpp | 5 // NOTE: based loosely on mozilla's nsDataChannel.cpp |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "net/base/data_url.h" | 9 #include "net/base/data_url.h" |
10 | 10 |
11 #include "base/base64.h" | 11 #include "base/base64.h" |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "net/base/escape.h" | 15 #include "net/base/escape.h" |
16 #include "url/gurl.h" | 16 #include "url/gurl.h" |
17 | 17 |
18 namespace net { | 18 namespace net { |
19 | 19 |
20 // static | 20 // static |
21 bool DataURL::Parse(const GURL& url, std::string* mime_type, | 21 bool DataURL::Parse(const GURL& url, |
22 std::string* charset, std::string* data) { | 22 std::string* mime_type, |
| 23 std::string* charset, |
| 24 std::string* data) { |
23 DCHECK(mime_type->empty()); | 25 DCHECK(mime_type->empty()); |
24 DCHECK(charset->empty()); | 26 DCHECK(charset->empty()); |
25 std::string::const_iterator begin = url.spec().begin(); | 27 std::string::const_iterator begin = url.spec().begin(); |
26 std::string::const_iterator end = url.spec().end(); | 28 std::string::const_iterator end = url.spec().end(); |
27 | 29 |
28 std::string::const_iterator after_colon = std::find(begin, end, ':'); | 30 std::string::const_iterator after_colon = std::find(begin, end, ':'); |
29 if (after_colon == end) | 31 if (after_colon == end) |
30 return false; | 32 return false; |
31 ++after_colon; | 33 ++after_colon; |
32 | 34 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 // (Spaces in a data URL should be escaped, which is handled below, so any | 78 // (Spaces in a data URL should be escaped, which is handled below, so any |
77 // spaces now are wrong. People expect to be able to enter them in the URL | 79 // spaces now are wrong. People expect to be able to enter them in the URL |
78 // bar for text, and it can't hurt, so we allow it.) | 80 // bar for text, and it can't hurt, so we allow it.) |
79 std::string temp_data = std::string(comma + 1, end); | 81 std::string temp_data = std::string(comma + 1, end); |
80 | 82 |
81 // For base64, we may have url-escaped whitespace which is not part | 83 // For base64, we may have url-escaped whitespace which is not part |
82 // of the data, and should be stripped. Otherwise, the escaped whitespace | 84 // of the data, and should be stripped. Otherwise, the escaped whitespace |
83 // could be part of the payload, so don't strip it. | 85 // could be part of the payload, so don't strip it. |
84 if (base64_encoded) { | 86 if (base64_encoded) { |
85 temp_data = UnescapeURLComponent(temp_data, | 87 temp_data = UnescapeURLComponent(temp_data, |
86 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS | | 88 UnescapeRule::SPACES | |
87 UnescapeRule::CONTROL_CHARS); | 89 UnescapeRule::URL_SPECIAL_CHARS | |
| 90 UnescapeRule::CONTROL_CHARS); |
88 } | 91 } |
89 | 92 |
90 // Strip whitespace. | 93 // Strip whitespace. |
91 if (base64_encoded || !(mime_type->compare(0, 5, "text/") == 0 || | 94 if (base64_encoded || |
92 mime_type->find("xml") != std::string::npos)) { | 95 !(mime_type->compare(0, 5, "text/") == 0 || |
93 temp_data.erase(std::remove_if(temp_data.begin(), temp_data.end(), | 96 mime_type->find("xml") != std::string::npos)) { |
94 IsAsciiWhitespace<wchar_t>), | 97 temp_data.erase( |
95 temp_data.end()); | 98 std::remove_if( |
| 99 temp_data.begin(), temp_data.end(), IsAsciiWhitespace<wchar_t>), |
| 100 temp_data.end()); |
96 } | 101 } |
97 | 102 |
98 if (!base64_encoded) { | 103 if (!base64_encoded) { |
99 temp_data = UnescapeURLComponent(temp_data, | 104 temp_data = UnescapeURLComponent(temp_data, |
100 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS | | 105 UnescapeRule::SPACES | |
101 UnescapeRule::CONTROL_CHARS); | 106 UnescapeRule::URL_SPECIAL_CHARS | |
| 107 UnescapeRule::CONTROL_CHARS); |
102 } | 108 } |
103 | 109 |
104 if (base64_encoded) { | 110 if (base64_encoded) { |
105 size_t length = temp_data.length(); | 111 size_t length = temp_data.length(); |
106 size_t padding_needed = 4 - (length % 4); | 112 size_t padding_needed = 4 - (length % 4); |
107 // If the input wasn't padded, then we pad it as necessary until we have a | 113 // If the input wasn't padded, then we pad it as necessary until we have a |
108 // length that is a multiple of 4 as required by our decoder. We don't | 114 // length that is a multiple of 4 as required by our decoder. We don't |
109 // correct if the input was incorrectly padded. If |padding_needed| == 3, | 115 // correct if the input was incorrectly padded. If |padding_needed| == 3, |
110 // then the input isn't well formed and decoding will fail with or without | 116 // then the input isn't well formed and decoding will fail with or without |
111 // padding. | 117 // padding. |
112 if ((padding_needed == 1 || padding_needed == 2) && | 118 if ((padding_needed == 1 || padding_needed == 2) && |
113 temp_data[length - 1] != '=') { | 119 temp_data[length - 1] != '=') { |
114 temp_data.resize(length + padding_needed, '='); | 120 temp_data.resize(length + padding_needed, '='); |
115 } | 121 } |
116 return base::Base64Decode(temp_data, data); | 122 return base::Base64Decode(temp_data, data); |
117 } | 123 } |
118 | 124 |
119 temp_data.swap(*data); | 125 temp_data.swap(*data); |
120 return true; | 126 return true; |
121 } | 127 } |
122 | 128 |
123 } // namespace net | 129 } // namespace net |
OLD | NEW |