| 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // => Chrome: Render as GIF | 66 // => Chrome: Render as GIF |
| 67 // | 67 // |
| 68 // GIF payload, Content-Type: "application/octet-stream": | 68 // GIF payload, Content-Type: "application/octet-stream": |
| 69 // * IE 7: Render as GIF | 69 // * IE 7: Render as GIF |
| 70 // * Firefox 2: Download as application/octet-stream (Note: Firefox will | 70 // * Firefox 2: Download as application/octet-stream (Note: Firefox will |
| 71 // Download as GIF if the URL has an GIF extension) | 71 // Download as GIF if the URL has an GIF extension) |
| 72 // * Safari 3: Download as Unknown (Note: Safari will Render as GIF if the | 72 // * Safari 3: Download as Unknown (Note: Safari will Render as GIF if the |
| 73 // URL has an GIF extension) | 73 // URL has an GIF extension) |
| 74 // * Opera 9: Render as GIF | 74 // * Opera 9: Render as GIF |
| 75 // | 75 // |
| 76 // Given our previous decisions, this decision is more or less clear. | 76 // We used to render as GIF here, but the problem is that some sites want to |
| 77 // => Chrome: Render as GIF | 77 // trigger downloads by sending application/octet-stream (even though they |
| 78 // should be sending Content-Disposition: attachment). Although it is safe |
| 79 // to render as GIF from a security perspective, we actually get better |
| 80 // compatibility if we don't sniff from application/octet stream at all. |
| 81 // => Chrome: Download as application/octet-stream |
| 78 // | 82 // |
| 79 // XHTML payload, Content-Type: "text/xml": | 83 // XHTML payload, Content-Type: "text/xml": |
| 80 // * IE 7: Render as XML | 84 // * IE 7: Render as XML |
| 81 // * Firefox 2: Render as HTML | 85 // * Firefox 2: Render as HTML |
| 82 // * Safari 3: Render as HTML | 86 // * Safari 3: Render as HTML |
| 83 // * Opera 9: Render as HTML | 87 // * Opera 9: Render as HTML |
| 84 // The layout tests rely on us rendering this as HTML. | 88 // The layout tests rely on us rendering this as HTML. |
| 85 // But we're conservative in XHTML detection, as this runs afoul of the | 89 // But we're conservative in XHTML detection, as this runs afoul of the |
| 86 // "don't detect dangerous mime types" rule. | 90 // "don't detect dangerous mime types" rule. |
| 87 // | 91 // |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 url.SchemeIs("ftp"); | 489 url.SchemeIs("ftp"); |
| 486 if (!sniffable_scheme) { | 490 if (!sniffable_scheme) { |
| 487 should_sniff_counter.Add(1); | 491 should_sniff_counter.Add(1); |
| 488 return false; | 492 return false; |
| 489 } | 493 } |
| 490 | 494 |
| 491 static const char* kSniffableTypes[] = { | 495 static const char* kSniffableTypes[] = { |
| 492 // Many web servers are misconfigured to send text/plain for many | 496 // Many web servers are misconfigured to send text/plain for many |
| 493 // different types of content. | 497 // different types of content. |
| 494 "text/plain", | 498 "text/plain", |
| 495 // IIS 4.0 and 5.0 send application/octet-stream when serving .xhtml | 499 // We want to sniff application/octet-stream for |
| 496 // files. Firefox 2.0 does not sniff xhtml here, but Safari 3, | 500 // application/x-chrome-extension, but nothing else. |
| 497 // 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 SnifferHistogram counter("mime_sniffer.kSniffableTypes2", |
| 505 arraysize(kSniffableTypes) + 1); | 508 arraysize(kSniffableTypes) + 1); |
| 506 for (size_t i = 0; i < arraysize(kSniffableTypes); ++i) { | 509 for (size_t i = 0; i < arraysize(kSniffableTypes); ++i) { |
| 507 if (mime_type == kSniffableTypes[i]) { | 510 if (mime_type == kSniffableTypes[i]) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 if (SniffXML(content, content_size, result)) | 573 if (SniffXML(content, content_size, result)) |
| 571 return true; | 574 return true; |
| 572 return content_size >= kMaxBytesToSniff; | 575 return content_size >= kMaxBytesToSniff; |
| 573 } | 576 } |
| 574 | 577 |
| 575 // CRX files (chrome extensions) have a special sniffing algorithm. It is | 578 // CRX files (chrome extensions) have a special sniffing algorithm. It is |
| 576 // tighter than the others because we don't have to match legacy behavior. | 579 // tighter than the others because we don't have to match legacy behavior. |
| 577 if (SniffCRX(content, content_size, url, type_hint, result)) | 580 if (SniffCRX(content, content_size, url, type_hint, result)) |
| 578 return true; | 581 return true; |
| 579 | 582 |
| 583 // We're not interested in sniffing for magic numbers when the type_hint |
| 584 // is application/octet-stream. Time to bail out. |
| 585 if (type_hint == "application/octet-stream") |
| 586 return have_enough_content; |
| 587 |
| 580 // Now we look in our large table of magic numbers to see if we can find | 588 // Now we look in our large table of magic numbers to see if we can find |
| 581 // anything that matches the content. | 589 // anything that matches the content. |
| 582 if (SniffForMagicNumbers(content, content_size, result)) | 590 if (SniffForMagicNumbers(content, content_size, result)) |
| 583 return true; // We've matched a magic number. No more content needed. | 591 return true; // We've matched a magic number. No more content needed. |
| 584 | 592 |
| 585 // Having failed thus far, we're willing to override unknown mime types and | 593 // Having failed thus far, we're willing to override unknown mime types and |
| 586 // text/plain. | 594 // text/plain. |
| 587 if (hint_is_unknown_mime_type || hint_is_text_plain) { | 595 if (hint_is_unknown_mime_type || hint_is_text_plain) { |
| 588 if (looks_binary) | 596 if (looks_binary) |
| 589 result->assign("application/octet-stream"); | 597 result->assign("application/octet-stream"); |
| 590 else | 598 else |
| 591 result->assign("text/plain"); | 599 result->assign("text/plain"); |
| 592 // We could change our mind if a binary-looking byte appears later in | 600 // 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. | 601 // the content, so we only have enough content if we have the max. |
| 594 return content_size >= kMaxBytesToSniff; | 602 return content_size >= kMaxBytesToSniff; |
| 595 } | 603 } |
| 596 | 604 |
| 597 return have_enough_content; | 605 return have_enough_content; |
| 598 } | 606 } |
| 599 | 607 |
| 600 } // namespace net | 608 } // namespace net |
| OLD | NEW |