1use std::ffi::OsStr;
4use std::fs;
5use std::io::BufRead;
6use std::io::{Read, Write};
7use std::net::TcpListener;
8use std::path::Path;
9use std::str;
10use std::thread;
11
12#[cfg(feature = "reload")]
13mod reload;
14
15pub fn read_header<T: Read + Write>(stream: &mut T) -> Vec<u8> {
16 let mut buffer = Vec::new();
17 let mut reader = std::io::BufReader::new(stream);
18 loop {
19 reader.read_until(b'\n', &mut buffer).unwrap();
20 if buffer.ends_with(b"\r\n\r\n") {
22 break;
23 }
24 }
25 buffer
26}
27
28#[allow(unused)]
29fn handle_client<T: Read + Write>(mut stream: T, root_path: &str, reload: bool, headers: &str) {
30 let buffer = read_header(&mut stream);
31 let request_string = str::from_utf8(&buffer).unwrap();
32
33 if request_string.is_empty() {
34 return;
35 }
36
37 let mut parts = request_string.split(' ');
39
40 let _method = parts.next().unwrap().trim();
41 let mut path = parts.next().unwrap().trim();
42 let _http_version = parts.next().unwrap().trim();
43
44 if let Some(parameters_index) = path.find('?') {
46 path = &path[..parameters_index];
47 }
48
49 let path = path.replace("../", "").replace("%20", " ");
51 let path = if path.ends_with('/') {
52 Path::new(root_path).join(Path::new(&format!(
53 "{}{}",
54 path.trim_start_matches('/'),
55 "index.html"
56 )))
57 } else {
58 Path::new(root_path).join(path.trim_matches('/'))
59 };
60
61 let extension = path.extension().and_then(OsStr::to_str);
62
63 let (file_contents, extension) = if extension.is_some() {
64 (fs::read(&path), extension)
65 } else {
66 if let Ok(file_contents) = fs::read(&path) {
68 println!("WARNING: Serving file without extension: [ {} ] with media type 'application/octet-stream'", &path.to_str().unwrap());
69 (Ok(file_contents), None)
70 } else {
71 let file = fs::read(path.with_extension("html"));
74 (file, Some("html"))
75 }
76 };
77
78 if let Ok(mut file_contents) = file_contents {
79 let content_type = extension_to_mime_impl(extension);
81
82 #[allow(unused_mut)]
83 let mut content_length = file_contents.len();
84
85 #[cfg(feature = "reload")]
87 let reload_append = include_bytes!("reload.html");
88 #[cfg(feature = "reload")]
89 {
90 if extension == Some("html") && reload {
91 content_length += reload_append.len();
92 }
93 }
94
95 let response = format!(
96 "HTTP/1.1 200 OK\r\nContent-type: {}\r\nContent-Length: {}{}\r\n\r\n",
97 content_type, content_length, headers
98 );
99
100 let mut bytes = response.as_bytes().to_vec();
101 bytes.append(&mut file_contents);
102 stream.write_all(&bytes).unwrap();
103
104 #[cfg(feature = "reload")]
106 {
107 if extension == Some("html") && reload {
108 stream.write_all(reload_append).unwrap();
110 }
111 }
112
113 stream.flush().unwrap();
114 } else {
115 let response = "HTTP/1.1 404 NOT FOUND\r\n\r\n";
117 stream.write_all(response.as_bytes()).unwrap();
118 stream.flush().unwrap();
119 }
120}
121
122pub fn run(address: &str, port: u32, path: &str, reload: bool, headers: &str) {
123 #[cfg(feature = "reload")]
124 {
125 if reload {
126 let address = address.to_owned();
127 let path = path.to_owned();
128 thread::spawn(move || {
129 reload::watch_for_reloads(&address, &path);
130 });
131 }
132 }
133
134 let address_with_port = format!("{}:{:?}", address, port);
135 let listener = TcpListener::bind(address_with_port).unwrap();
136 for stream in listener.incoming() {
137 if let Ok(stream) = stream as Result<std::net::TcpStream, std::io::Error> {
138 let path = path.to_owned();
139 let headers = headers.to_owned();
140 thread::spawn(move || {
141 handle_client(stream, &path, reload, &headers);
142 });
143 }
144 }
145}
146
147fn extension_to_mime_impl(extension: Option<&str>) -> &'static str {
151 match extension {
154 Some("323") => "text/h323; charset=utf8",
155 Some("3g2") => "video/3gpp2",
156 Some("3gp") => "video/3gpp",
157 Some("3gp2") => "video/3gpp2",
158 Some("3gpp") => "video/3gpp",
159 Some("7z") => "application/x-7z-compressed",
160 Some("aa") => "audio/audible",
161 Some("aac") => "audio/aac",
162 Some("aaf") => "application/octet-stream",
163 Some("aax") => "audio/vnd.audible.aax",
164 Some("ac3") => "audio/ac3",
165 Some("aca") => "application/octet-stream",
166 Some("accda") => "application/msaccess.addin",
167 Some("accdb") => "application/msaccess",
168 Some("accdc") => "application/msaccess.cab",
169 Some("accde") => "application/msaccess",
170 Some("accdr") => "application/msaccess.runtime",
171 Some("accdt") => "application/msaccess",
172 Some("accdw") => "application/msaccess.webapplication",
173 Some("accft") => "application/msaccess.ftemplate",
174 Some("acx") => "application/internet-property-stream",
175 Some("addin") => "application/xml",
176 Some("ade") => "application/msaccess",
177 Some("adobebridge") => "application/x-bridge-url",
178 Some("adp") => "application/msaccess",
179 Some("adt") => "audio/vnd.dlna.adts",
180 Some("adts") => "audio/aac",
181 Some("afm") => "application/octet-stream",
182 Some("ai") => "application/postscript",
183 Some("aif") => "audio/x-aiff",
184 Some("aifc") => "audio/aiff",
185 Some("aiff") => "audio/aiff",
186 Some("air") => "application/vnd.adobe.air-application-installer-package+zip",
187 Some("amc") => "application/x-mpeg",
188 Some("application") => "application/x-ms-application",
189 Some("art") => "image/x-jg",
190 Some("asa") => "application/xml",
191 Some("asax") => "application/xml",
192 Some("ascx") => "application/xml",
193 Some("asd") => "application/octet-stream",
194 Some("asf") => "video/x-ms-asf",
195 Some("ashx") => "application/xml",
196 Some("asi") => "application/octet-stream",
197 Some("asm") => "text/plain; charset=utf8",
198 Some("asmx") => "application/xml",
199 Some("aspx") => "application/xml",
200 Some("asr") => "video/x-ms-asf",
201 Some("asx") => "video/x-ms-asf",
202 Some("atom") => "application/atom+xml",
203 Some("au") => "audio/basic",
204 Some("avi") => "video/x-msvideo",
205 Some("axs") => "application/olescript",
206 Some("bas") => "text/plain; charset=utf8",
207 Some("bcpio") => "application/x-bcpio",
208 Some("bin") => "application/octet-stream",
209 Some("bmp") => "image/bmp",
210 Some("c") => "text/plain; charset=utf8",
211 Some("cab") => "application/octet-stream",
212 Some("caf") => "audio/x-caf",
213 Some("calx") => "application/vnd.ms-office.calx",
214 Some("cat") => "application/vnd.ms-pki.seccat",
215 Some("cc") => "text/plain; charset=utf8",
216 Some("cd") => "text/plain; charset=utf8",
217 Some("cdda") => "audio/aiff",
218 Some("cdf") => "application/x-cdf",
219 Some("cer") => "application/x-x509-ca-cert",
220 Some("chm") => "application/octet-stream",
221 Some("class") => "application/x-java-applet",
222 Some("clp") => "application/x-msclip",
223 Some("cmx") => "image/x-cmx",
224 Some("cnf") => "text/plain; charset=utf8",
225 Some("cod") => "image/cis-cod",
226 Some("config") => "application/xml",
227 Some("contact") => "text/x-ms-contact; charset=utf8",
228 Some("coverage") => "application/xml",
229 Some("cpio") => "application/x-cpio",
230 Some("cpp") => "text/plain; charset=utf8",
231 Some("crd") => "application/x-mscardfile",
232 Some("crl") => "application/pkix-crl",
233 Some("crt") => "application/x-x509-ca-cert",
234 Some("cs") => "text/plain; charset=utf8",
235 Some("csdproj") => "text/plain; charset=utf8",
236 Some("csh") => "application/x-csh",
237 Some("csproj") => "text/plain; charset=utf8",
238 Some("css") => "text/css; charset=utf8",
239 Some("csv") => "text/csv; charset=utf8",
240 Some("cur") => "application/octet-stream",
241 Some("cxx") => "text/plain; charset=utf8",
242 Some("dat") => "application/octet-stream",
243 Some("datasource") => "application/xml",
244 Some("dbproj") => "text/plain; charset=utf8",
245 Some("dcr") => "application/x-director",
246 Some("def") => "text/plain; charset=utf8",
247 Some("deploy") => "application/octet-stream",
248 Some("der") => "application/x-x509-ca-cert",
249 Some("dgml") => "application/xml",
250 Some("dib") => "image/bmp",
251 Some("dif") => "video/x-dv",
252 Some("dir") => "application/x-director",
253 Some("disco") => "application/xml",
254 Some("dll") => "application/x-msdownload",
255 Some("dll.config") => "application/xml",
256 Some("dlm") => "text/dlm; charset=utf8",
257 Some("doc") => "application/msword",
258 Some("docm") => "application/vnd.ms-word.document.macroEnabled.12",
259 Some("docx") => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
260 Some("dot") => "application/msword",
261 Some("dotm") => "application/vnd.ms-word.template.macroEnabled.12",
262 Some("dotx") => "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
263 Some("dsp") => "application/octet-stream",
264 Some("dsw") => "text/plain; charset=utf8",
265 Some("dtd") => "application/xml",
266 Some("dtsConfig") => "application/xml",
267 Some("dv") => "video/x-dv",
268 Some("dvi") => "application/x-dvi",
269 Some("dwf") => "drawing/x-dwf",
270 Some("dwp") => "application/octet-stream",
271 Some("dxr") => "application/x-director",
272 Some("eml") => "message/rfc822",
273 Some("emz") => "application/octet-stream",
274 Some("eot") => "application/vnd.ms-fontobject",
275 Some("eps") => "application/postscript",
276 Some("etl") => "application/etl",
277 Some("etx") => "text/x-setext; charset=utf8",
278 Some("evy") => "application/envoy",
279 Some("exe") => "application/octet-stream",
280 Some("exe.config") => "application/xml",
281 Some("fdf") => "application/vnd.fdf",
282 Some("fif") => "application/fractals",
283 Some("filters") => "Application/xml",
284 Some("fla") => "application/octet-stream",
285 Some("flr") => "x-world/x-vrml",
286 Some("flv") => "video/x-flv",
287 Some("fsscript") => "application/fsharp-script",
288 Some("fsx") => "application/fsharp-script",
289 Some("generictest") => "application/xml",
290 Some("gif") => "image/gif",
291 Some("group") => "text/x-ms-group; charset=utf8",
292 Some("gsm") => "audio/x-gsm",
293 Some("gtar") => "application/x-gtar",
294 Some("gz") => "application/x-gzip",
295 Some("h") => "text/plain; charset=utf8",
296 Some("hdf") => "application/x-hdf",
297 Some("hdml") => "text/x-hdml; charset=utf8",
298 Some("hhc") => "application/x-oleobject",
299 Some("hhk") => "application/octet-stream",
300 Some("hhp") => "application/octet-stream",
301 Some("hlp") => "application/winhlp",
302 Some("hpp") => "text/plain; charset=utf8",
303 Some("hqx") => "application/mac-binhex40",
304 Some("hta") => "application/hta",
305 Some("htc") => "text/x-component; charset=utf8",
306 Some("htm") => "text/html; charset=utf8",
307 Some("html") => "text/html; charset=utf8",
308 Some("htt") => "text/webviewhtml; charset=utf8",
309 Some("hxa") => "application/xml",
310 Some("hxc") => "application/xml",
311 Some("hxd") => "application/octet-stream",
312 Some("hxe") => "application/xml",
313 Some("hxf") => "application/xml",
314 Some("hxh") => "application/octet-stream",
315 Some("hxi") => "application/octet-stream",
316 Some("hxk") => "application/xml",
317 Some("hxq") => "application/octet-stream",
318 Some("hxr") => "application/octet-stream",
319 Some("hxs") => "application/octet-stream",
320 Some("hxt") => "text/html; charset=utf8",
321 Some("hxv") => "application/xml",
322 Some("hxw") => "application/octet-stream",
323 Some("hxx") => "text/plain; charset=utf8",
324 Some("i") => "text/plain; charset=utf8",
325 Some("ico") => "image/x-icon",
326 Some("ics") => "application/octet-stream",
327 Some("idl") => "text/plain; charset=utf8",
328 Some("ief") => "image/ief",
329 Some("iii") => "application/x-iphone",
330 Some("inc") => "text/plain; charset=utf8",
331 Some("inf") => "application/octet-stream",
332 Some("inl") => "text/plain; charset=utf8",
333 Some("ins") => "application/x-internet-signup",
334 Some("ipa") => "application/x-itunes-ipa",
335 Some("ipg") => "application/x-itunes-ipg",
336 Some("ipproj") => "text/plain; charset=utf8",
337 Some("ipsw") => "application/x-itunes-ipsw",
338 Some("iqy") => "text/x-ms-iqy; charset=utf8",
339 Some("isp") => "application/x-internet-signup",
340 Some("ite") => "application/x-itunes-ite",
341 Some("itlp") => "application/x-itunes-itlp",
342 Some("itms") => "application/x-itunes-itms",
343 Some("itpc") => "application/x-itunes-itpc",
344 Some("ivf") => "video/x-ivf",
345 Some("jar") => "application/java-archive",
346 Some("java") => "application/octet-stream",
347 Some("jck") => "application/liquidmotion",
348 Some("jcz") => "application/liquidmotion",
349 Some("jfif") => "image/pjpeg",
350 Some("jnlp") => "application/x-java-jnlp-file",
351 Some("jpb") => "application/octet-stream",
352 Some("jpe") => "image/jpeg",
353 Some("jpeg") => "image/jpeg",
354 Some("jpg") => "image/jpeg",
355 Some("js") => "application/javascript",
356 Some("json") => "application/json",
357 Some("jsx") => "text/jscript; charset=utf8",
358 Some("jsxbin") => "text/plain; charset=utf8",
359 Some("latex") => "application/x-latex",
360 Some("library-ms") => "application/windows-library+xml",
361 Some("lit") => "application/x-ms-reader",
362 Some("loadtest") => "application/xml",
363 Some("lpk") => "application/octet-stream",
364 Some("lsf") => "video/x-la-asf",
365 Some("lst") => "text/plain; charset=utf8",
366 Some("lsx") => "video/x-la-asf",
367 Some("lzh") => "application/octet-stream",
368 Some("m13") => "application/x-msmediaview",
369 Some("m14") => "application/x-msmediaview",
370 Some("m1v") => "video/mpeg",
371 Some("m2t") => "video/vnd.dlna.mpeg-tts",
372 Some("m2ts") => "video/vnd.dlna.mpeg-tts",
373 Some("m2v") => "video/mpeg",
374 Some("m3u") => "audio/x-mpegurl",
375 Some("m3u8") => "audio/x-mpegurl",
376 Some("m4a") => "audio/m4a",
377 Some("m4b") => "audio/m4b",
378 Some("m4p") => "audio/m4p",
379 Some("m4r") => "audio/x-m4r",
380 Some("m4v") => "video/x-m4v",
381 Some("mac") => "image/x-macpaint",
382 Some("mak") => "text/plain; charset=utf8",
383 Some("man") => "application/x-troff-man",
384 Some("manifest") => "application/x-ms-manifest",
385 Some("map") => "text/plain; charset=utf8",
386 Some("master") => "application/xml",
387 Some("mda") => "application/msaccess",
388 Some("mdb") => "application/x-msaccess",
389 Some("mde") => "application/msaccess",
390 Some("mdp") => "application/octet-stream",
391 Some("me") => "application/x-troff-me",
392 Some("mfp") => "application/x-shockwave-flash",
393 Some("mht") => "message/rfc822",
394 Some("mhtml") => "message/rfc822",
395 Some("mid") => "audio/mid",
396 Some("midi") => "audio/mid",
397 Some("mix") => "application/octet-stream",
398 Some("mjs") => "application/javascript",
399 Some("mk") => "text/plain; charset=utf8",
400 Some("mmf") => "application/x-smaf",
401 Some("mno") => "application/xml",
402 Some("mny") => "application/x-msmoney",
403 Some("mod") => "video/mpeg",
404 Some("mov") => "video/quicktime",
405 Some("movie") => "video/x-sgi-movie",
406 Some("mp2") => "video/mpeg",
407 Some("mp2v") => "video/mpeg",
408 Some("mp3") => "audio/mpeg",
409 Some("mp4") => "video/mp4",
410 Some("mp4v") => "video/mp4",
411 Some("mpa") => "video/mpeg",
412 Some("mpe") => "video/mpeg",
413 Some("mpeg") => "video/mpeg",
414 Some("mpf") => "application/vnd.ms-mediapackage",
415 Some("mpg") => "video/mpeg",
416 Some("mpp") => "application/vnd.ms-project",
417 Some("mpv2") => "video/mpeg",
418 Some("mqv") => "video/quicktime",
419 Some("ms") => "application/x-troff-ms",
420 Some("msi") => "application/octet-stream",
421 Some("mso") => "application/octet-stream",
422 Some("mts") => "video/vnd.dlna.mpeg-tts",
423 Some("mtx") => "application/xml",
424 Some("mvb") => "application/x-msmediaview",
425 Some("mvc") => "application/x-miva-compiled",
426 Some("mxp") => "application/x-mmxp",
427 Some("nc") => "application/x-netcdf",
428 Some("nsc") => "video/x-ms-asf",
429 Some("nws") => "message/rfc822",
430 Some("ocx") => "application/octet-stream",
431 Some("oda") => "application/oda",
432 Some("odc") => "text/x-ms-odc; charset=utf8",
433 Some("odh") => "text/plain; charset=utf8",
434 Some("odl") => "text/plain; charset=utf8",
435 Some("odp") => "application/vnd.oasis.opendocument.presentation",
436 Some("ods") => "application/oleobject",
437 Some("odt") => "application/vnd.oasis.opendocument.text",
438 Some("ogg") => "application/ogg",
439 Some("one") => "application/onenote",
440 Some("onea") => "application/onenote",
441 Some("onepkg") => "application/onenote",
442 Some("onetmp") => "application/onenote",
443 Some("onetoc") => "application/onenote",
444 Some("onetoc2") => "application/onenote",
445 Some("orderedtest") => "application/xml",
446 Some("osdx") => "application/opensearchdescription+xml",
447 Some("otf") => "application/x-font-opentype",
448 Some("p10") => "application/pkcs10",
449 Some("p12") => "application/x-pkcs12",
450 Some("p7b") => "application/x-pkcs7-certificates",
451 Some("p7c") => "application/pkcs7-mime",
452 Some("p7m") => "application/pkcs7-mime",
453 Some("p7r") => "application/x-pkcs7-certreqresp",
454 Some("p7s") => "application/pkcs7-signature",
455 Some("pbm") => "image/x-portable-bitmap",
456 Some("pcast") => "application/x-podcast",
457 Some("pct") => "image/pict",
458 Some("pcx") => "application/octet-stream",
459 Some("pcz") => "application/octet-stream",
460 Some("pdf") => "application/pdf",
461 Some("pfb") => "application/octet-stream",
462 Some("pfm") => "application/octet-stream",
463 Some("pfx") => "application/x-pkcs12",
464 Some("pgm") => "image/x-portable-graymap",
465 Some("pic") => "image/pict",
466 Some("pict") => "image/pict",
467 Some("pkgdef") => "text/plain; charset=utf8",
468 Some("pkgundef") => "text/plain; charset=utf8",
469 Some("pko") => "application/vnd.ms-pki.pko",
470 Some("pls") => "audio/scpls",
471 Some("pma") => "application/x-perfmon",
472 Some("pmc") => "application/x-perfmon",
473 Some("pml") => "application/x-perfmon",
474 Some("pmr") => "application/x-perfmon",
475 Some("pmw") => "application/x-perfmon",
476 Some("png") => "image/png",
477 Some("pnm") => "image/x-portable-anymap",
478 Some("pnt") => "image/x-macpaint",
479 Some("pntg") => "image/x-macpaint",
480 Some("pnz") => "image/png",
481 Some("pot") => "application/vnd.ms-powerpoint",
482 Some("potm") => "application/vnd.ms-powerpoint.template.macroEnabled.12",
483 Some("potx") => "application/vnd.openxmlformats-officedocument.presentationml.template",
484 Some("ppa") => "application/vnd.ms-powerpoint",
485 Some("ppam") => "application/vnd.ms-powerpoint.addin.macroEnabled.12",
486 Some("ppm") => "image/x-portable-pixmap",
487 Some("pps") => "application/vnd.ms-powerpoint",
488 Some("ppsm") => "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
489 Some("ppsx") => "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
490 Some("ppt") => "application/vnd.ms-powerpoint",
491 Some("pptm") => "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
492 Some("pptx") => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
493 Some("prf") => "application/pics-rules",
494 Some("prm") => "application/octet-stream",
495 Some("prx") => "application/octet-stream",
496 Some("ps") => "application/postscript",
497 Some("psc1") => "application/PowerShell",
498 Some("psd") => "application/octet-stream",
499 Some("psess") => "application/xml",
500 Some("psm") => "application/octet-stream",
501 Some("psp") => "application/octet-stream",
502 Some("pub") => "application/x-mspublisher",
503 Some("pwz") => "application/vnd.ms-powerpoint",
504 Some("qht") => "text/x-html-insertion; charset=utf8",
505 Some("qhtm") => "text/x-html-insertion; charset=utf8",
506 Some("qt") => "video/quicktime",
507 Some("qti") => "image/x-quicktime",
508 Some("qtif") => "image/x-quicktime",
509 Some("qtl") => "application/x-quicktimeplayer",
510 Some("qxd") => "application/octet-stream",
511 Some("ra") => "audio/x-pn-realaudio",
512 Some("ram") => "audio/x-pn-realaudio",
513 Some("rar") => "application/octet-stream",
514 Some("ras") => "image/x-cmu-raster",
515 Some("rat") => "application/rat-file",
516 Some("rc") => "text/plain; charset=utf8",
517 Some("rc2") => "text/plain; charset=utf8",
518 Some("rct") => "text/plain; charset=utf8",
519 Some("rdlc") => "application/xml",
520 Some("resx") => "application/xml",
521 Some("rf") => "image/vnd.rn-realflash",
522 Some("rgb") => "image/x-rgb",
523 Some("rgs") => "text/plain; charset=utf8",
524 Some("rm") => "application/vnd.rn-realmedia",
525 Some("rmi") => "audio/mid",
526 Some("rmp") => "application/vnd.rn-rn_music_package",
527 Some("roff") => "application/x-troff",
528 Some("rpm") => "audio/x-pn-realaudio-plugin",
529 Some("rqy") => "text/x-ms-rqy; charset=utf8",
530 Some("rtf") => "application/rtf",
531 Some("rtx") => "text/richtext; charset=utf8",
532 Some("ruleset") => "application/xml",
533 Some("s") => "text/plain; charset=utf8",
534 Some("safariextz") => "application/x-safari-safariextz",
535 Some("scd") => "application/x-msschedule",
536 Some("sct") => "text/scriptlet; charset=utf8",
537 Some("sd2") => "audio/x-sd2",
538 Some("sdp") => "application/sdp",
539 Some("sea") => "application/octet-stream",
540 Some("searchConnector-ms") => "application/windows-search-connector+xml",
541 Some("setpay") => "application/set-payment-initiation",
542 Some("setreg") => "application/set-registration-initiation",
543 Some("settings") => "application/xml",
544 Some("sfnt") => "application/font-sfnt",
545 Some("sgimb") => "application/x-sgimb",
546 Some("sgml") => "text/sgml; charset=utf8",
547 Some("sh") => "application/x-sh",
548 Some("shar") => "application/x-shar",
549 Some("shtml") => "text/html; charset=utf8",
550 Some("sit") => "application/x-stuffit",
551 Some("sitemap") => "application/xml",
552 Some("skin") => "application/xml",
553 Some("sldm") => "application/vnd.ms-powerpoint.slide.macroEnabled.12",
554 Some("sldx") => "application/vnd.openxmlformats-officedocument.presentationml.slide",
555 Some("slk") => "application/vnd.ms-excel",
556 Some("sln") => "text/plain; charset=utf8",
557 Some("slupkg-ms") => "application/x-ms-license",
558 Some("smd") => "audio/x-smd",
559 Some("smi") => "application/octet-stream",
560 Some("smx") => "audio/x-smd",
561 Some("smz") => "audio/x-smd",
562 Some("snd") => "audio/basic",
563 Some("snippet") => "application/xml",
564 Some("snp") => "application/octet-stream",
565 Some("sol") => "text/plain; charset=utf8",
566 Some("sor") => "text/plain; charset=utf8",
567 Some("spc") => "application/x-pkcs7-certificates",
568 Some("spl") => "application/futuresplash",
569 Some("src") => "application/x-wais-source",
570 Some("srf") => "text/plain; charset=utf8",
571 Some("ssisdeploymentmanifest") => "application/xml",
572 Some("ssm") => "application/streamingmedia",
573 Some("sst") => "application/vnd.ms-pki.certstore",
574 Some("stl") => "application/vnd.ms-pki.stl",
575 Some("sv4cpio") => "application/x-sv4cpio",
576 Some("sv4crc") => "application/x-sv4crc",
577 Some("svc") => "application/xml",
578 Some("svg") => "image/svg+xml",
579 Some("swf") => "application/x-shockwave-flash",
580 Some("t") => "application/x-troff",
581 Some("tar") => "application/x-tar",
582 Some("tcl") => "application/x-tcl",
583 Some("testrunconfig") => "application/xml",
584 Some("testsettings") => "application/xml",
585 Some("tex") => "application/x-tex",
586 Some("texi") => "application/x-texinfo",
587 Some("texinfo") => "application/x-texinfo",
588 Some("tgz") => "application/x-compressed",
589 Some("thmx") => "application/vnd.ms-officetheme",
590 Some("thn") => "application/octet-stream",
591 Some("tif") => "image/tiff",
592 Some("tiff") => "image/tiff",
593 Some("tlh") => "text/plain; charset=utf8",
594 Some("tli") => "text/plain; charset=utf8",
595 Some("toc") => "application/octet-stream",
596 Some("tr") => "application/x-troff",
597 Some("trm") => "application/x-msterminal",
598 Some("trx") => "application/xml",
599 Some("ts") => "video/vnd.dlna.mpeg-tts",
600 Some("tsv") => "text/tab-separated-values; charset=utf8",
601 Some("ttf") => "application/x-font-ttf",
602 Some("tts") => "video/vnd.dlna.mpeg-tts",
603 Some("txt") => "text/plain; charset=utf8",
604 Some("u32") => "application/octet-stream",
605 Some("uls") => "text/iuls; charset=utf8",
606 Some("user") => "text/plain; charset=utf8",
607 Some("ustar") => "application/x-ustar",
608 Some("vb") => "text/plain; charset=utf8",
609 Some("vbdproj") => "text/plain; charset=utf8",
610 Some("vbk") => "video/mpeg",
611 Some("vbproj") => "text/plain; charset=utf8",
612 Some("vbs") => "text/vbscript; charset=utf8",
613 Some("vcf") => "text/x-vcard; charset=utf8",
614 Some("vcproj") => "Application/xml",
615 Some("vcs") => "text/plain; charset=utf8",
616 Some("vcxproj") => "Application/xml",
617 Some("vddproj") => "text/plain; charset=utf8",
618 Some("vdp") => "text/plain; charset=utf8",
619 Some("vdproj") => "text/plain; charset=utf8",
620 Some("vdx") => "application/vnd.ms-visio.viewer",
621 Some("vml") => "application/xml",
622 Some("vscontent") => "application/xml",
623 Some("vsct") => "application/xml",
624 Some("vsd") => "application/vnd.visio",
625 Some("vsi") => "application/ms-vsi",
626 Some("vsix") => "application/vsix",
627 Some("vsixlangpack") => "application/xml",
628 Some("vsixmanifest") => "application/xml",
629 Some("vsmdi") => "application/xml",
630 Some("vspscc") => "text/plain; charset=utf8",
631 Some("vss") => "application/vnd.visio",
632 Some("vsscc") => "text/plain; charset=utf8",
633 Some("vssettings") => "application/xml",
634 Some("vssscc") => "text/plain; charset=utf8",
635 Some("vst") => "application/vnd.visio",
636 Some("vstemplate") => "application/xml",
637 Some("vsto") => "application/x-ms-vsto",
638 Some("vsw") => "application/vnd.visio",
639 Some("vsx") => "application/vnd.visio",
640 Some("vtx") => "application/vnd.visio",
641 Some("wasm") => "application/wasm",
642 Some("wav") => "audio/wav",
643 Some("wave") => "audio/wav",
644 Some("wax") => "audio/x-ms-wax",
645 Some("wbk") => "application/msword",
646 Some("wbmp") => "image/vnd.wap.wbmp",
647 Some("wcm") => "application/vnd.ms-works",
648 Some("wdb") => "application/vnd.ms-works",
649 Some("wdp") => "image/vnd.ms-photo",
650 Some("webarchive") => "application/x-safari-webarchive",
651 Some("webtest") => "application/xml",
652 Some("wiq") => "application/xml",
653 Some("wiz") => "application/msword",
654 Some("wks") => "application/vnd.ms-works",
655 Some("wlmp") => "application/wlmoviemaker",
656 Some("wlpginstall") => "application/x-wlpg-detect",
657 Some("wlpginstall3") => "application/x-wlpg3-detect",
658 Some("wm") => "video/x-ms-wm",
659 Some("wma") => "audio/x-ms-wma",
660 Some("wmd") => "application/x-ms-wmd",
661 Some("wmf") => "application/x-msmetafile",
662 Some("wml") => "text/vnd.wap.wml; charset=utf8",
663 Some("wmlc") => "application/vnd.wap.wmlc",
664 Some("wmls") => "text/vnd.wap.wmlscript; charset=utf8",
665 Some("wmlsc") => "application/vnd.wap.wmlscriptc",
666 Some("wmp") => "video/x-ms-wmp",
667 Some("wmv") => "video/x-ms-wmv",
668 Some("wmx") => "video/x-ms-wmx",
669 Some("wmz") => "application/x-ms-wmz",
670 Some("woff") => "application/font-woff",
671 Some("woff2") => "application/font-woff2",
672 Some("wpl") => "application/vnd.ms-wpl",
673 Some("wps") => "application/vnd.ms-works",
674 Some("wri") => "application/x-mswrite",
675 Some("wrl") => "x-world/x-vrml",
676 Some("wrz") => "x-world/x-vrml",
677 Some("wsc") => "text/scriptlet; charset=utf8",
678 Some("wsdl") => "application/xml",
679 Some("wvx") => "video/x-ms-wvx",
680 Some("x") => "application/directx",
681 Some("xaf") => "x-world/x-vrml",
682 Some("xaml") => "application/xaml+xml",
683 Some("xap") => "application/x-silverlight-app",
684 Some("xbap") => "application/x-ms-xbap",
685 Some("xbm") => "image/x-xbitmap",
686 Some("xdr") => "text/plain; charset=utf8",
687 Some("xht") => "application/xhtml+xml",
688 Some("xhtml") => "application/xhtml+xml",
689 Some("xla") => "application/vnd.ms-excel",
690 Some("xlam") => "application/vnd.ms-excel.addin.macroEnabled.12",
691 Some("xlc") => "application/vnd.ms-excel",
692 Some("xld") => "application/vnd.ms-excel",
693 Some("xlk") => "application/vnd.ms-excel",
694 Some("xll") => "application/vnd.ms-excel",
695 Some("xlm") => "application/vnd.ms-excel",
696 Some("xls") => "application/vnd.ms-excel",
697 Some("xlsb") => "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
698 Some("xlsm") => "application/vnd.ms-excel.sheet.macroEnabled.12",
699 Some("xlsx") => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
700 Some("xlt") => "application/vnd.ms-excel",
701 Some("xltm") => "application/vnd.ms-excel.template.macroEnabled.12",
702 Some("xltx") => "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
703 Some("xlw") => "application/vnd.ms-excel",
704 Some("xml") => "application/xml",
705 Some("xmta") => "application/xml",
706 Some("xof") => "x-world/x-vrml",
707 Some("xoml") => "text/plain; charset=utf8",
708 Some("xpm") => "image/x-xpixmap",
709 Some("xps") => "application/vnd.ms-xpsdocument",
710 Some("xrm-ms") => "application/xml",
711 Some("xsc") => "application/xml",
712 Some("xsd") => "application/xml",
713 Some("xsf") => "application/xml",
714 Some("xsl") => "application/xml",
715 Some("xslt") => "application/xslt+xml",
716 Some("xsn") => "application/octet-stream",
717 Some("xss") => "application/xml",
718 Some("xtp") => "application/octet-stream",
719 Some("xwd") => "image/x-xwindowdump",
720 Some("z") => "application/x-compress",
721 Some("zip") => "application/zip",
722 _ => "application/octet-stream",
723 }
724}