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 "net/http/http_content_disposition.h" | 5 #include "net/http/http_content_disposition.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/i18n/icu_string_conversions.h" | 8 #include "base/i18n/icu_string_conversions.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/strings/string_tokenizer.h" |
11 #include "base/sys_string_conversions.h" | 12 #include "base/sys_string_conversions.h" |
12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
13 #include "net/base/net_util.h" | 14 #include "net/base/net_util.h" |
14 #include "net/http/http_util.h" | 15 #include "net/http/http_util.h" |
15 #include "third_party/icu/public/common/unicode/ucnv.h" | 16 #include "third_party/icu/public/common/unicode/ucnv.h" |
16 | 17 |
17 namespace { | 18 namespace { |
18 | 19 |
19 enum RFC2047EncodingType { | 20 enum RFC2047EncodingType { |
20 Q_ENCODING, | 21 Q_ENCODING, |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 125 |
125 // RFC 2047 : one of encoding methods supported by Firefox and relatively | 126 // RFC 2047 : one of encoding methods supported by Firefox and relatively |
126 // widely used by web servers. | 127 // widely used by web servers. |
127 // =?charset?<E>?<encoded string>?= where '<E>' is either 'B' or 'Q'. | 128 // =?charset?<E>?<encoded string>?= where '<E>' is either 'B' or 'Q'. |
128 // We don't care about the length restriction (72 bytes) because | 129 // We don't care about the length restriction (72 bytes) because |
129 // many web servers generate encoded words longer than the limit. | 130 // many web servers generate encoded words longer than the limit. |
130 std::string decoded_word; | 131 std::string decoded_word; |
131 *is_rfc2047 = true; | 132 *is_rfc2047 = true; |
132 int part_index = 0; | 133 int part_index = 0; |
133 std::string charset; | 134 std::string charset; |
134 StringTokenizer t(encoded_word, "?"); | 135 base::StringTokenizer t(encoded_word, "?"); |
135 RFC2047EncodingType enc_type = Q_ENCODING; | 136 RFC2047EncodingType enc_type = Q_ENCODING; |
136 while (*is_rfc2047 && t.GetNext()) { | 137 while (*is_rfc2047 && t.GetNext()) { |
137 std::string part = t.token(); | 138 std::string part = t.token(); |
138 switch (part_index) { | 139 switch (part_index) { |
139 case 0: | 140 case 0: |
140 if (part != "=") { | 141 if (part != "=") { |
141 *is_rfc2047 = false; | 142 *is_rfc2047 = false; |
142 break; | 143 break; |
143 } | 144 } |
144 ++part_index; | 145 ++part_index; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 // strings. Non-ASCII strings are interpreted based on |referrer_charset|. | 230 // strings. Non-ASCII strings are interpreted based on |referrer_charset|. |
230 bool DecodeFilenameValue(const std::string& input, | 231 bool DecodeFilenameValue(const std::string& input, |
231 const std::string& referrer_charset, | 232 const std::string& referrer_charset, |
232 std::string* output, | 233 std::string* output, |
233 int* parse_result_flags) { | 234 int* parse_result_flags) { |
234 int current_parse_result_flags = 0; | 235 int current_parse_result_flags = 0; |
235 std::string decoded_value; | 236 std::string decoded_value; |
236 bool is_previous_token_rfc2047 = true; | 237 bool is_previous_token_rfc2047 = true; |
237 | 238 |
238 // Tokenize with whitespace characters. | 239 // Tokenize with whitespace characters. |
239 StringTokenizer t(input, " \t\n\r"); | 240 base::StringTokenizer t(input, " \t\n\r"); |
240 t.set_options(StringTokenizer::RETURN_DELIMS); | 241 t.set_options(base::StringTokenizer::RETURN_DELIMS); |
241 while (t.GetNext()) { | 242 while (t.GetNext()) { |
242 if (t.token_is_delim()) { | 243 if (t.token_is_delim()) { |
243 // If the previous non-delimeter token is not RFC2047-encoded, | 244 // If the previous non-delimeter token is not RFC2047-encoded, |
244 // put in a space in its place. Otheriwse, skip over it. | 245 // put in a space in its place. Otheriwse, skip over it. |
245 if (!is_previous_token_rfc2047) | 246 if (!is_previous_token_rfc2047) |
246 decoded_value.push_back(' '); | 247 decoded_value.push_back(' '); |
247 continue; | 248 continue; |
248 } | 249 } |
249 // We don't support a single multibyte character split into | 250 // We don't support a single multibyte character split into |
250 // adjacent encoded words. Some broken mail clients emit headers | 251 // adjacent encoded words. Some broken mail clients emit headers |
(...skipping 11 matching lines...) Expand all Loading... |
262 *parse_result_flags |= current_parse_result_flags; | 263 *parse_result_flags |= current_parse_result_flags; |
263 return true; | 264 return true; |
264 } | 265 } |
265 | 266 |
266 // Parses the charset and value-chars out of an ext-value string. | 267 // Parses the charset and value-chars out of an ext-value string. |
267 // | 268 // |
268 // ext-value = charset "'" [ language ] "'" value-chars | 269 // ext-value = charset "'" [ language ] "'" value-chars |
269 bool ParseExtValueComponents(const std::string& input, | 270 bool ParseExtValueComponents(const std::string& input, |
270 std::string* charset, | 271 std::string* charset, |
271 std::string* value_chars) { | 272 std::string* value_chars) { |
272 StringTokenizer t(input, "'"); | 273 base::StringTokenizer t(input, "'"); |
273 t.set_options(StringTokenizer::RETURN_DELIMS); | 274 t.set_options(base::StringTokenizer::RETURN_DELIMS); |
274 std::string temp_charset; | 275 std::string temp_charset; |
275 std::string temp_value; | 276 std::string temp_value; |
276 int numDelimsSeen = 0; | 277 int numDelimsSeen = 0; |
277 while (t.GetNext()) { | 278 while (t.GetNext()) { |
278 if (t.token_is_delim()) { | 279 if (t.token_is_delim()) { |
279 ++numDelimsSeen; | 280 ++numDelimsSeen; |
280 continue; | 281 continue; |
281 } else { | 282 } else { |
282 switch (numDelimsSeen) { | 283 switch (numDelimsSeen) { |
283 case 0: | 284 case 0: |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 | 447 |
447 if (!ext_filename.empty()) | 448 if (!ext_filename.empty()) |
448 filename_ = ext_filename; | 449 filename_ = ext_filename; |
449 else if (!filename.empty()) | 450 else if (!filename.empty()) |
450 filename_ = filename; | 451 filename_ = filename; |
451 else | 452 else |
452 filename_ = name; | 453 filename_ = name; |
453 } | 454 } |
454 | 455 |
455 } // namespace net | 456 } // namespace net |
OLD | NEW |