mime_sniffer/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! ## mime-sniffer: Detecting mime types base on content sniffer.
//!
//! ***The detection workflow was copied from
//! [Chromium](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/net/base/mime_sniffer.cc)***
//!
//! Detecting mime types is a tricky business because we need to balance
//! compatibility concerns with security issues.  Here is a survey of how other
//! browsers behave and then a description of how we intend to behave.
//!
//! ### HTML payload, no Content-Type header:
//! * IE 7: Render as HTML
//! * Firefox 2: Render as HTML
//! * Safari 3: Render as HTML
//! * Opera 9: Render as HTML
//!
//! Here the choice seems clear:
//! => Chrome: Render as HTML
//!
//! ### HTML payload, Content-Type: "text/plain":
//! * IE 7: Render as HTML
//! * Firefox 2: Render as text
//! * Safari 3: Render as text (Note: Safari will Render as HTML if the URL
//!                                   has an HTML extension)
//! * Opera 9: Render as text
//!
//! Here we choose to follow the majority (and break some compatibility with IE).
//! Many folks dislike IE's behavior here.
//! => Chrome: Render as text
//! We generalize this as follows.  If the Content-Type header is text/plain
//! we won't detect dangerous mime types (those that can execute script).
//!
//! ### HTML payload, Content-Type: "application/octet-stream":
//! * IE 7: Render as HTML
//! * Firefox 2: Download as application/octet-stream
//! * Safari 3: Render as HTML
//! * Opera 9: Render as HTML
//!
//! We follow Firefox.
//! => Chrome: Download as application/octet-stream
//! One factor in this decision is that IIS 4 and 5 will send
//! application/octet-stream for .xhtml files (because they don't recognize
//! the extension).  We did some experiments and it looks like this doesn't occur
//! very often on the web.  We choose the more secure option.
//!
//! ### GIF payload, no Content-Type header:
//! * IE 7: Render as GIF
//! * Firefox 2: Render as GIF
//! * Safari 3: Download as Unknown (Note: Safari will Render as GIF if the
//!                                        URL has an GIF extension)
//! * Opera 9: Render as GIF
//!
//! The choice is clear.
//! => Chrome: Render as GIF
//! Once we decide to render HTML without a Content-Type header, there isn't much
//! reason not to render GIFs.
//!
//! ### GIF payload, Content-Type: "text/plain":
//! * IE 7: Render as GIF
//! * Firefox 2: Download as application/octet-stream (Note: Firefox will
//!                              Download as GIF if the URL has an GIF extension)
//! * Safari 3: Download as Unknown (Note: Safari will Render as GIF if the
//!                                        URL has an GIF extension)
//! * Opera 9: Render as GIF
//!
//! Displaying as text/plain makes little sense as the content will look like
//! gibberish.  Here, we could change our minds and download.
//! => Chrome: Render as GIF
//!
//! ### GIF payload, Content-Type: "application/octet-stream":
//! * IE 7: Render as GIF
//! * Firefox 2: Download as application/octet-stream (Note: Firefox will
//!                              Download as GIF if the URL has an GIF extension)
//! * Safari 3: Download as Unknown (Note: Safari will Render as GIF if the
//!                                        URL has an GIF extension)
//! * Opera 9: Render as GIF
//!
//! We used to render as GIF here, but the problem is that some sites want to
//! trigger downloads by sending application/octet-stream (even though they
//! should be sending Content-Disposition: attachment).  Although it is safe
//! to render as GIF from a security perspective, we actually get better
//! compatibility if we don't sniff from application/octet stream at all.
//! => Chrome: Download as application/octet-stream
//!
//! Note that our definition of HTML payload is much stricter than IE's
//! definition and roughly the same as Firefox's definition.
//!
//! # Examples
//!
//! ```rust
//! use mime_sniffer::MimeTypeSniffer;
//!
//! assert_eq!(Some("application/pdf"), b"%PDF-1.5".sniff_mime_type());
//! ```
//!
//! ```rust
//! #[macro_use]
//! extern crate mime;
//! extern crate mime_sniffer;
//!
//! use mime_sniffer::{HttpRequest, MimeTypeSniffer, MimeTypeSnifferExt};
//!
//! fn main() {
//!     let req = HttpRequest {
//!         content: b"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1",
//!         url: &"http://localhost/notes.ppt",
//!         type_hint: "text/plain",
//!     };
//!
//!     assert_eq!(req.sniff_mime_type(), Some("application/vnd.ms-powerpoint"));
//!     assert_eq!(req.sniff_mime_type_ext().unwrap().type_(), mime::APPLICATION);
//! }
//! ```
extern crate mime;
extern crate url;

mod api;
mod magic;

pub use api::{HttpRequest, MimeTypeSniffable, MimeTypeSniffer, MimeTypeSnifferExt};