OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 // Detecting mime types is a tricky business because we need to balance | 5 // Detecting mime types is a tricky business because we need to balance |
6 // compatibility concerns with security issues. Here is a survey of how other | 6 // compatibility concerns with security issues. Here is a survey of how other |
7 // browsers behave and then a description of how we intend to behave. | 7 // browsers behave and then a description of how we intend to behave. |
8 // | 8 // |
9 // HTML payload, no Content-Type header: | 9 // HTML payload, no Content-Type header: |
10 // * IE 7: Render as HTML | 10 // * IE 7: Render as HTML |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 | 92 |
93 #include "net/base/mime_sniffer.h" | 93 #include "net/base/mime_sniffer.h" |
94 | 94 |
95 #include "base/basictypes.h" | 95 #include "base/basictypes.h" |
96 #include "base/histogram.h" | 96 #include "base/histogram.h" |
97 #include "base/logging.h" | 97 #include "base/logging.h" |
98 #include "base/string_util.h" | 98 #include "base/string_util.h" |
99 #include "googleurl/src/gurl.h" | 99 #include "googleurl/src/gurl.h" |
100 #include "net/base/mime_util.h" | 100 #include "net/base/mime_util.h" |
101 | 101 |
102 namespace { | |
103 | |
104 class SnifferHistogram : public LinearHistogram { | |
105 public: | |
106 SnifferHistogram(const char* name, int array_size) | |
107 : LinearHistogram(name, 0, array_size - 1, array_size) { | |
108 SetFlags(kUmaTargetedHistogramFlag); | |
109 } | |
110 }; | |
111 | |
112 } // namespace | |
113 | |
114 namespace net { | 102 namespace net { |
115 | 103 |
116 // We aren't interested in looking at more than 512 bytes of content | 104 // We aren't interested in looking at more than 512 bytes of content |
117 static const size_t kMaxBytesToSniff = 512; | 105 static const size_t kMaxBytesToSniff = 512; |
118 | 106 |
119 // The number of content bytes we need to use all our magic numbers. Feel free | 107 // The number of content bytes we need to use all our magic numbers. Feel free |
120 // to increase this number if you add a longer magic number. | 108 // to increase this number if you add a longer magic number. |
121 static const size_t kBytesRequiredForMagic = 42; | 109 static const size_t kBytesRequiredForMagic = 42; |
122 | 110 |
123 struct MagicNumber { | 111 struct MagicNumber { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 MAGIC_HTML_TAG("table") // Mozilla | 199 MAGIC_HTML_TAG("table") // Mozilla |
212 MAGIC_HTML_TAG("a") // Mozilla | 200 MAGIC_HTML_TAG("a") // Mozilla |
213 MAGIC_HTML_TAG("style") // Mozilla | 201 MAGIC_HTML_TAG("style") // Mozilla |
214 MAGIC_HTML_TAG("title") // Mozilla | 202 MAGIC_HTML_TAG("title") // Mozilla |
215 MAGIC_HTML_TAG("b") // Mozilla | 203 MAGIC_HTML_TAG("b") // Mozilla |
216 MAGIC_HTML_TAG("body") // Mozilla | 204 MAGIC_HTML_TAG("body") // Mozilla |
217 MAGIC_HTML_TAG("br") | 205 MAGIC_HTML_TAG("br") |
218 MAGIC_HTML_TAG("p") // Mozilla | 206 MAGIC_HTML_TAG("p") // Mozilla |
219 }; | 207 }; |
220 | 208 |
| 209 static scoped_refptr<Histogram> UMASnifferHistogramGet(const char* name, |
| 210 int array_size) { |
| 211 scoped_refptr<Histogram> counter = |
| 212 LinearHistogram::LinearHistogramFactoryGet( |
| 213 name, 1, array_size - 1, array_size); |
| 214 counter->SetFlags(kUmaTargetedHistogramFlag); |
| 215 return counter; |
| 216 } |
| 217 |
221 static bool MatchMagicNumber(const char* content, size_t size, | 218 static bool MatchMagicNumber(const char* content, size_t size, |
222 const MagicNumber* magic_entry, | 219 const MagicNumber* magic_entry, |
223 std::string* result) { | 220 std::string* result) { |
224 const size_t len = magic_entry->magic_len; | 221 const size_t len = magic_entry->magic_len; |
225 | 222 |
226 // Keep kBytesRequiredForMagic honest. | 223 // Keep kBytesRequiredForMagic honest. |
227 DCHECK(len <= kBytesRequiredForMagic); | 224 DCHECK(len <= kBytesRequiredForMagic); |
228 | 225 |
229 // To compare with magic strings, we need to compute strlen(content), but | 226 // To compare with magic strings, we need to compute strlen(content), but |
230 // content might not actually have a null terminator. In that case, we | 227 // content might not actually have a null terminator. In that case, we |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 static bool SniffForHTML(const char* content, size_t size, | 263 static bool SniffForHTML(const char* content, size_t size, |
267 std::string* result) { | 264 std::string* result) { |
268 // We adopt a strategy similar to that used by Mozilla to sniff HTML tags, | 265 // We adopt a strategy similar to that used by Mozilla to sniff HTML tags, |
269 // but with some modifications to better match the HTML5 spec. | 266 // but with some modifications to better match the HTML5 spec. |
270 const char* const end = content + size; | 267 const char* const end = content + size; |
271 const char* pos; | 268 const char* pos; |
272 for (pos = content; pos < end; ++pos) { | 269 for (pos = content; pos < end; ++pos) { |
273 if (!IsAsciiWhitespace(*pos)) | 270 if (!IsAsciiWhitespace(*pos)) |
274 break; | 271 break; |
275 } | 272 } |
276 static SnifferHistogram counter("mime_sniffer.kSniffableTags2", | 273 static scoped_refptr<Histogram> counter = |
277 arraysize(kSniffableTags)); | 274 UMASnifferHistogramGet("mime_sniffer.kSniffableTags2", |
| 275 arraysize(kSniffableTags)); |
278 // |pos| now points to first non-whitespace character (or at end). | 276 // |pos| now points to first non-whitespace character (or at end). |
279 return CheckForMagicNumbers(pos, end - pos, | 277 return CheckForMagicNumbers(pos, end - pos, |
280 kSniffableTags, arraysize(kSniffableTags), | 278 kSniffableTags, arraysize(kSniffableTags), |
281 &counter, result); | 279 counter.get(), result); |
282 } | 280 } |
283 | 281 |
284 static bool SniffForMagicNumbers(const char* content, size_t size, | 282 static bool SniffForMagicNumbers(const char* content, size_t size, |
285 std::string* result) { | 283 std::string* result) { |
286 // Check our big table of Magic Numbers | 284 // Check our big table of Magic Numbers |
287 static SnifferHistogram counter("mime_sniffer.kMagicNumbers2", | 285 static scoped_refptr<Histogram> counter = |
288 arraysize(kMagicNumbers)); | 286 UMASnifferHistogramGet("mime_sniffer.kMagicNumbers2", |
| 287 arraysize(kMagicNumbers)); |
289 return CheckForMagicNumbers(content, size, | 288 return CheckForMagicNumbers(content, size, |
290 kMagicNumbers, arraysize(kMagicNumbers), | 289 kMagicNumbers, arraysize(kMagicNumbers), |
291 &counter, result); | 290 counter.get(), result); |
292 } | 291 } |
293 | 292 |
294 // Byte order marks | 293 // Byte order marks |
295 static const MagicNumber kMagicXML[] = { | 294 static const MagicNumber kMagicXML[] = { |
296 // We want to be very conservative in interpreting text/xml content as | 295 // We want to be very conservative in interpreting text/xml content as |
297 // XHTML -- we just want to sniff enough to make unit tests pass. | 296 // XHTML -- we just want to sniff enough to make unit tests pass. |
298 // So we match explicitly on this, and don't match other ways of writing | 297 // So we match explicitly on this, and don't match other ways of writing |
299 // it in semantically-equivalent ways. | 298 // it in semantically-equivalent ways. |
300 MAGIC_STRING("application/xhtml+xml", | 299 MAGIC_STRING("application/xhtml+xml", |
301 "<html xmlns=\"http://www.w3.org/1999/xhtml\"") | 300 "<html xmlns=\"http://www.w3.org/1999/xhtml\"") |
(...skipping 11 matching lines...) Expand all Loading... |
313 // We allow at most kFirstTagBytes bytes of content before we expect the | 312 // We allow at most kFirstTagBytes bytes of content before we expect the |
314 // opening tag. | 313 // opening tag. |
315 const size_t kFeedAllowedHeaderBytes = 300; | 314 const size_t kFeedAllowedHeaderBytes = 300; |
316 const char* const end = content + std::min(size, kFeedAllowedHeaderBytes); | 315 const char* const end = content + std::min(size, kFeedAllowedHeaderBytes); |
317 const char* pos = content; | 316 const char* pos = content; |
318 | 317 |
319 // This loop iterates through tag-looking offsets in the file. | 318 // This loop iterates through tag-looking offsets in the file. |
320 // We want to skip XML processing instructions (of the form "<?xml ...") | 319 // We want to skip XML processing instructions (of the form "<?xml ...") |
321 // and stop at the first "plain" tag, then make a decision on the mime-type | 320 // and stop at the first "plain" tag, then make a decision on the mime-type |
322 // based on the name (or possibly attributes) of that tag. | 321 // based on the name (or possibly attributes) of that tag. |
323 static SnifferHistogram counter("mime_sniffer.kMagicXML2", | 322 static scoped_refptr<Histogram> counter = |
324 arraysize(kMagicXML)); | 323 UMASnifferHistogramGet("mime_sniffer.kMagicXML2", |
| 324 arraysize(kMagicXML)); |
325 const int kMaxTagIterations = 5; | 325 const int kMaxTagIterations = 5; |
326 for (int i = 0; i < kMaxTagIterations && pos < end; ++i) { | 326 for (int i = 0; i < kMaxTagIterations && pos < end; ++i) { |
327 pos = reinterpret_cast<const char*>(memchr(pos, '<', end - pos)); | 327 pos = reinterpret_cast<const char*>(memchr(pos, '<', end - pos)); |
328 if (!pos) | 328 if (!pos) |
329 return false; | 329 return false; |
330 | 330 |
331 if (base::strncasecmp(pos, "<?xml", sizeof("<?xml")-1) == 0) { | 331 if (base::strncasecmp(pos, "<?xml", sizeof("<?xml")-1) == 0) { |
332 // Skip XML declarations. | 332 // Skip XML declarations. |
333 ++pos; | 333 ++pos; |
334 continue; | 334 continue; |
335 } else if (base::strncasecmp(pos, "<!DOCTYPE", | 335 } else if (base::strncasecmp(pos, "<!DOCTYPE", |
336 sizeof("<!DOCTYPE")-1) == 0) { | 336 sizeof("<!DOCTYPE")-1) == 0) { |
337 // Skip DOCTYPE declarations. | 337 // Skip DOCTYPE declarations. |
338 ++pos; | 338 ++pos; |
339 continue; | 339 continue; |
340 } | 340 } |
341 | 341 |
342 if (CheckForMagicNumbers(pos, end - pos, | 342 if (CheckForMagicNumbers(pos, end - pos, |
343 kMagicXML, arraysize(kMagicXML), | 343 kMagicXML, arraysize(kMagicXML), |
344 &counter, result)) | 344 counter.get(), result)) |
345 return true; | 345 return true; |
346 | 346 |
347 // TODO(evanm): handle RSS 1.0, which is an RDF format and more difficult | 347 // TODO(evanm): handle RSS 1.0, which is an RDF format and more difficult |
348 // to identify. | 348 // to identify. |
349 | 349 |
350 // If we get here, we've hit an initial tag that hasn't matched one of the | 350 // If we get here, we've hit an initial tag that hasn't matched one of the |
351 // above tests. Abort. | 351 // above tests. Abort. |
352 return true; | 352 return true; |
353 } | 353 } |
354 | 354 |
(...skipping 26 matching lines...) Expand all Loading... |
381 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xA0 - 0xAF | 381 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xA0 - 0xAF |
382 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xB0 - 0xBF | 382 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xB0 - 0xBF |
383 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xC0 - 0xCF | 383 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xC0 - 0xCF |
384 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xD0 - 0xDF | 384 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xD0 - 0xDF |
385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xE0 - 0xEF | 385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xE0 - 0xEF |
386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xF0 - 0xFF | 386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xF0 - 0xFF |
387 }; | 387 }; |
388 | 388 |
389 static bool LooksBinary(const char* content, size_t size) { | 389 static bool LooksBinary(const char* content, size_t size) { |
390 // First, we look for a BOM. | 390 // First, we look for a BOM. |
391 static SnifferHistogram counter("mime_sniffer.kByteOrderMark2", | 391 static scoped_refptr<Histogram> counter = |
392 arraysize(kByteOrderMark)); | 392 UMASnifferHistogramGet("mime_sniffer.kByteOrderMark2", |
| 393 arraysize(kByteOrderMark)); |
393 std::string unused; | 394 std::string unused; |
394 if (CheckForMagicNumbers(content, size, | 395 if (CheckForMagicNumbers(content, size, |
395 kByteOrderMark, arraysize(kByteOrderMark), | 396 kByteOrderMark, arraysize(kByteOrderMark), |
396 &counter, &unused)) { | 397 counter.get(), &unused)) { |
397 // If there is BOM, we think the buffer is not binary. | 398 // If there is BOM, we think the buffer is not binary. |
398 return false; | 399 return false; |
399 } | 400 } |
400 | 401 |
401 // Next we look to see if any of the bytes "look binary." | 402 // Next we look to see if any of the bytes "look binary." |
402 for (size_t i = 0; i < size; ++i) { | 403 for (size_t i = 0; i < size; ++i) { |
403 // If we a see a binary-looking byte, we think the content is binary. | 404 // If we a see a binary-looking byte, we think the content is binary. |
404 if (kByteLooksBinary[static_cast<unsigned char>(content[i])]) | 405 if (kByteLooksBinary[static_cast<unsigned char>(content[i])]) |
405 return true; | 406 return true; |
406 } | 407 } |
407 | 408 |
408 // No evidence either way, default to non-binary. | 409 // No evidence either way, default to non-binary. |
409 return false; | 410 return false; |
410 } | 411 } |
411 | 412 |
412 static bool IsUnknownMimeType(const std::string& mime_type) { | 413 static bool IsUnknownMimeType(const std::string& mime_type) { |
413 // TODO(tc): Maybe reuse some code in net/http/http_response_headers.* here. | 414 // TODO(tc): Maybe reuse some code in net/http/http_response_headers.* here. |
414 // If we do, please be careful not to alter the semantics at all. | 415 // If we do, please be careful not to alter the semantics at all. |
415 static const char* kUnknownMimeTypes[] = { | 416 static const char* kUnknownMimeTypes[] = { |
416 // Empty mime types are as unknown as they get. | 417 // Empty mime types are as unknown as they get. |
417 "", | 418 "", |
418 // The unknown/unknown type is popular and uninformative | 419 // The unknown/unknown type is popular and uninformative |
419 "unknown/unknown", | 420 "unknown/unknown", |
420 // The second most popular unknown mime type is application/unknown | 421 // The second most popular unknown mime type is application/unknown |
421 "application/unknown", | 422 "application/unknown", |
422 // Firefox rejects a mime type if it is exactly */* | 423 // Firefox rejects a mime type if it is exactly */* |
423 "*/*", | 424 "*/*", |
424 }; | 425 }; |
425 static SnifferHistogram counter("mime_sniffer.kUnknownMimeTypes2", | 426 static scoped_refptr<Histogram> counter = |
426 arraysize(kUnknownMimeTypes) + 1); | 427 UMASnifferHistogramGet("mime_sniffer.kUnknownMimeTypes2", |
| 428 arraysize(kUnknownMimeTypes) + 1); |
427 for (size_t i = 0; i < arraysize(kUnknownMimeTypes); ++i) { | 429 for (size_t i = 0; i < arraysize(kUnknownMimeTypes); ++i) { |
428 if (mime_type == kUnknownMimeTypes[i]) { | 430 if (mime_type == kUnknownMimeTypes[i]) { |
429 counter.Add(i); | 431 counter->Add(i); |
430 return true; | 432 return true; |
431 } | 433 } |
432 } | 434 } |
433 if (mime_type.find('/') == std::string::npos) { | 435 if (mime_type.find('/') == std::string::npos) { |
434 // Firefox rejects a mime type if it does not contain a slash | 436 // Firefox rejects a mime type if it does not contain a slash |
435 counter.Add(arraysize(kUnknownMimeTypes)); | 437 counter->Add(arraysize(kUnknownMimeTypes)); |
436 return true; | 438 return true; |
437 } | 439 } |
438 return false; | 440 return false; |
439 } | 441 } |
440 | 442 |
441 // Sniff a crx (chrome extension) file. | 443 // Sniff a crx (chrome extension) file. |
442 static bool SniffCRX(const char* content, size_t content_size, const GURL& url, | 444 static bool SniffCRX(const char* content, size_t content_size, const GURL& url, |
443 const std::string& type_hint, std::string* result) { | 445 const std::string& type_hint, std::string* result) { |
444 static SnifferHistogram counter("mime_sniffer.kSniffCRX", 3); | 446 static scoped_refptr<Histogram> counter = |
| 447 UMASnifferHistogramGet("mime_sniffer.kSniffCRX", 3); |
445 | 448 |
446 // Technically, the crx magic number is just Cr24, but the bytes after that | 449 // Technically, the crx magic number is just Cr24, but the bytes after that |
447 // are a version number which changes infrequently. Including it in the | 450 // are a version number which changes infrequently. Including it in the |
448 // sniffing gives us less room for error. If the version number ever changes, | 451 // sniffing gives us less room for error. If the version number ever changes, |
449 // we can just add an entry to this list. | 452 // we can just add an entry to this list. |
450 // | 453 // |
451 // TODO(aa): If we ever have another magic number, we'll want to pass a | 454 // TODO(aa): If we ever have another magic number, we'll want to pass a |
452 // histogram into CheckForMagicNumbers(), below, to see which one matched. | 455 // histogram into CheckForMagicNumbers(), below, to see which one matched. |
453 const struct MagicNumber kCRXMagicNumbers[] = { | 456 const struct MagicNumber kCRXMagicNumbers[] = { |
454 MAGIC_NUMBER("application/x-chrome-extension", "Cr24\x02\x00\x00\x00") | 457 MAGIC_NUMBER("application/x-chrome-extension", "Cr24\x02\x00\x00\x00") |
455 }; | 458 }; |
456 | 459 |
457 // Only consider files that have the extension ".crx". | 460 // Only consider files that have the extension ".crx". |
458 const char kCRXExtension[] = ".crx"; | 461 const char kCRXExtension[] = ".crx"; |
459 const int kExtensionLength = arraysize(kCRXExtension) - 1; // ignore null | 462 const int kExtensionLength = arraysize(kCRXExtension) - 1; // ignore null |
460 if (url.path().rfind(kCRXExtension, std::string::npos, kExtensionLength) == | 463 if (url.path().rfind(kCRXExtension, std::string::npos, kExtensionLength) == |
461 url.path().size() - kExtensionLength) { | 464 url.path().size() - kExtensionLength) { |
462 counter.Add(1); | 465 counter->Add(1); |
463 } else { | 466 } else { |
464 return false; | 467 return false; |
465 } | 468 } |
466 | 469 |
467 if (CheckForMagicNumbers(content, content_size, | 470 if (CheckForMagicNumbers(content, content_size, |
468 kCRXMagicNumbers, arraysize(kCRXMagicNumbers), | 471 kCRXMagicNumbers, arraysize(kCRXMagicNumbers), |
469 NULL, result)) { | 472 NULL, result)) { |
470 counter.Add(2); | 473 counter->Add(2); |
471 } else { | 474 } else { |
472 return false; | 475 return false; |
473 } | 476 } |
474 | 477 |
475 return true; | 478 return true; |
476 } | 479 } |
477 | 480 |
478 bool ShouldSniffMimeType(const GURL& url, const std::string& mime_type) { | 481 bool ShouldSniffMimeType(const GURL& url, const std::string& mime_type) { |
479 static SnifferHistogram should_sniff_counter( | 482 static scoped_refptr<Histogram> should_sniff_counter = |
480 "mime_sniffer.ShouldSniffMimeType2", 3); | 483 UMASnifferHistogramGet("mime_sniffer.ShouldSniffMimeType2", 3); |
481 // We are willing to sniff the mime type for HTTP, HTTPS, and FTP | 484 // We are willing to sniff the mime type for HTTP, HTTPS, and FTP |
482 bool sniffable_scheme = url.is_empty() || | 485 bool sniffable_scheme = url.is_empty() || |
483 url.SchemeIs("http") || | 486 url.SchemeIs("http") || |
484 url.SchemeIs("https") || | 487 url.SchemeIs("https") || |
485 url.SchemeIs("ftp"); | 488 url.SchemeIs("ftp"); |
486 if (!sniffable_scheme) { | 489 if (!sniffable_scheme) { |
487 should_sniff_counter.Add(1); | 490 should_sniff_counter->Add(1); |
488 return false; | 491 return false; |
489 } | 492 } |
490 | 493 |
491 static const char* kSniffableTypes[] = { | 494 static const char* kSniffableTypes[] = { |
492 // Many web servers are misconfigured to send text/plain for many | 495 // Many web servers are misconfigured to send text/plain for many |
493 // different types of content. | 496 // different types of content. |
494 "text/plain", | 497 "text/plain", |
495 // IIS 4.0 and 5.0 send application/octet-stream when serving .xhtml | 498 // IIS 4.0 and 5.0 send application/octet-stream when serving .xhtml |
496 // files. Firefox 2.0 does not sniff xhtml here, but Safari 3, | 499 // files. Firefox 2.0 does not sniff xhtml here, but Safari 3, |
497 // Opera 9, and IE do. | 500 // Opera 9, and IE do. |
498 "application/octet-stream", | 501 "application/octet-stream", |
499 // XHTML and Atom/RSS feeds are often served as plain xml instead of | 502 // XHTML and Atom/RSS feeds are often served as plain xml instead of |
500 // their more specific mime types. | 503 // their more specific mime types. |
501 "text/xml", | 504 "text/xml", |
502 "application/xml", | 505 "application/xml", |
503 }; | 506 }; |
504 static SnifferHistogram counter("mime_sniffer.kSniffableTypes2", | 507 static scoped_refptr<Histogram> counter = |
505 arraysize(kSniffableTypes) + 1); | 508 UMASnifferHistogramGet("mime_sniffer.kSniffableTypes2", |
| 509 arraysize(kSniffableTypes) + 1); |
506 for (size_t i = 0; i < arraysize(kSniffableTypes); ++i) { | 510 for (size_t i = 0; i < arraysize(kSniffableTypes); ++i) { |
507 if (mime_type == kSniffableTypes[i]) { | 511 if (mime_type == kSniffableTypes[i]) { |
508 counter.Add(i); | 512 counter->Add(i); |
509 should_sniff_counter.Add(2); | 513 should_sniff_counter->Add(2); |
510 return true; | 514 return true; |
511 } | 515 } |
512 } | 516 } |
513 if (IsUnknownMimeType(mime_type)) { | 517 if (IsUnknownMimeType(mime_type)) { |
514 // The web server didn't specify a content type or specified a mime | 518 // The web server didn't specify a content type or specified a mime |
515 // type that we ignore. | 519 // type that we ignore. |
516 counter.Add(arraysize(kSniffableTypes)); | 520 counter->Add(arraysize(kSniffableTypes)); |
517 should_sniff_counter.Add(2); | 521 should_sniff_counter->Add(2); |
518 return true; | 522 return true; |
519 } | 523 } |
520 should_sniff_counter.Add(1); | 524 should_sniff_counter->Add(1); |
521 return false; | 525 return false; |
522 } | 526 } |
523 | 527 |
524 bool SniffMimeType(const char* content, size_t content_size, | 528 bool SniffMimeType(const char* content, size_t content_size, |
525 const GURL& url, const std::string& type_hint, | 529 const GURL& url, const std::string& type_hint, |
526 std::string* result) { | 530 std::string* result) { |
527 DCHECK_LT(content_size, 1000000U); // sanity check | 531 DCHECK_LT(content_size, 1000000U); // sanity check |
528 DCHECK(content); | 532 DCHECK(content); |
529 DCHECK(result); | 533 DCHECK(result); |
530 | 534 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 result->assign("text/plain"); | 595 result->assign("text/plain"); |
592 // We could change our mind if a binary-looking byte appears later in | 596 // We could change our mind if a binary-looking byte appears later in |
593 // the content, so we only have enough content if we have the max. | 597 // the content, so we only have enough content if we have the max. |
594 return content_size >= kMaxBytesToSniff; | 598 return content_size >= kMaxBytesToSniff; |
595 } | 599 } |
596 | 600 |
597 return have_enough_content; | 601 return have_enough_content; |
598 } | 602 } |
599 | 603 |
600 } // namespace net | 604 } // namespace net |
OLD | NEW |