[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / utils / Mime.cpp
blob576e499a1d02604ad649982b16066304c615c436
1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "Mime.h"
11 #include "FileItem.h"
12 #include "URIUtils.h"
13 #include "URL.h"
14 #include "filesystem/CurlFile.h"
15 #include "music/tags/MusicInfoTag.h"
16 #include "utils/StringUtils.h"
17 #include "video/VideoInfoTag.h"
19 #include <algorithm>
21 const std::map<std::string, std::string> CMime::m_mimetypes = {
22 {{"3dm", "x-world/x-3dmf"},
23 {"3dmf", "x-world/x-3dmf"},
24 {"3fr", "image/3fr"},
25 {"a", "application/octet-stream"},
26 {"aab", "application/x-authorware-bin"},
27 {"aam", "application/x-authorware-map"},
28 {"aas", "application/x-authorware-seg"},
29 {"abc", "text/vnd.abc"},
30 {"acgi", "text/html"},
31 {"afl", "video/animaflex"},
32 {"ai", "application/postscript"},
33 {"aif", "audio/aiff"},
34 {"aifc", "audio/x-aiff"},
35 {"aiff", "audio/aiff"},
36 {"aim", "application/x-aim"},
37 {"aip", "text/x-audiosoft-intra"},
38 {"ani", "application/x-navi-animation"},
39 {"aos", "application/x-nokia-9000-communicator-add-on-software"},
40 {"apng", "image/apng"},
41 {"aps", "application/mime"},
42 {"arc", "application/octet-stream"},
43 {"arj", "application/arj"},
44 {"art", "image/x-jg"},
45 {"arw", "image/arw"},
46 {"asf", "video/x-ms-asf"},
47 {"asm", "text/x-asm"},
48 {"asp", "text/asp"},
49 {"asx", "video/x-ms-asf"},
50 {"au", "audio/basic"},
51 {"avi", "video/avi"},
52 {"avs", "video/avs-video"},
53 {"bcpio", "application/x-bcpio"},
54 {"bin", "application/octet-stream"},
55 {"bm", "image/bmp"},
56 {"bmp", "image/bmp"},
57 {"boo", "application/book"},
58 {"book", "application/book"},
59 {"boz", "application/x-bzip2"},
60 {"bsh", "application/x-bsh"},
61 {"bz", "application/x-bzip"},
62 {"bz2", "application/x-bzip2"},
63 {"c", "text/plain"},
64 {"c++", "text/plain"},
65 {"cat", "application/vnd.ms-pki.seccat"},
66 {"cc", "text/plain"},
67 {"ccad", "application/clariscad"},
68 {"cco", "application/x-cocoa"},
69 {"cdf", "application/cdf"},
70 {"cer", "application/pkix-cert"},
71 {"cer", "application/x-x509-ca-cert"},
72 {"cha", "application/x-chat"},
73 {"chat", "application/x-chat"},
74 {"class", "application/java"},
75 {"com", "application/octet-stream"},
76 {"conf", "text/plain"},
77 {"cpio", "application/x-cpio"},
78 {"cpp", "text/x-c"},
79 {"cpt", "application/x-cpt"},
80 {"crl", "application/pkcs-crl"},
81 {"crt", "application/pkix-cert"},
82 {"cr2", "image/cr2"},
83 {"crw", "image/crw"},
84 {"csh", "application/x-csh"},
85 {"css", "text/css"},
86 {"cxx", "text/plain"},
87 {"dcr", "application/x-director"},
88 {"deepv", "application/x-deepv"},
89 {"def", "text/plain"},
90 {"der", "application/x-x509-ca-cert"},
91 {"dif", "video/x-dv"},
92 {"dir", "application/x-director"},
93 {"dl", "video/dl"},
94 {"divx", "video/x-msvideo"},
95 {"dng", "image/dng"},
96 {"doc", "application/msword"},
97 {"docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
98 {"dot", "application/msword"},
99 {"dp", "application/commonground"},
100 {"drw", "application/drafting"},
101 {"dump", "application/octet-stream"},
102 {"dv", "video/x-dv"},
103 {"dvi", "application/x-dvi"},
104 {"dwf", "model/vnd.dwf"},
105 {"dwg", "image/vnd.dwg"},
106 {"dxf", "image/vnd.dwg"},
107 {"dxr", "application/x-director"},
108 {"el", "text/x-script.elisp"},
109 {"elc", "application/x-elc"},
110 {"env", "application/x-envoy"},
111 {"eps", "application/postscript"},
112 {"erf", "image/erf"},
113 {"es", "application/x-esrehber"},
114 {"etx", "text/x-setext"},
115 {"evy", "application/envoy"},
116 {"exe", "application/octet-stream"},
117 {"f", "text/x-fortran"},
118 {"f77", "text/x-fortran"},
119 {"f90", "text/x-fortran"},
120 {"fdf", "application/vnd.fdf"},
121 {"fif", "image/fif"},
122 {"flac", "audio/flac"},
123 {"fli", "video/fli"},
124 {"flo", "image/florian"},
125 {"flv", "video/x-flv"},
126 {"flx", "text/vnd.fmi.flexstor"},
127 {"fmf", "video/x-atomic3d-feature"},
128 {"for", "text/plain"},
129 {"for", "text/x-fortran"},
130 {"fpx", "image/vnd.fpx"},
131 {"frl", "application/freeloader"},
132 {"funk", "audio/make"},
133 {"g", "text/plain"},
134 {"g3", "image/g3fax"},
135 {"gif", "image/gif"},
136 {"gl", "video/x-gl"},
137 {"gsd", "audio/x-gsm"},
138 {"gsm", "audio/x-gsm"},
139 {"gsp", "application/x-gsp"},
140 {"gss", "application/x-gss"},
141 {"gtar", "application/x-gtar"},
142 {"gz", "application/x-compressed"},
143 {"gzip", "application/x-gzip"},
144 {"h", "text/plain"},
145 {"hdf", "application/x-hdf"},
146 {"heic", "image/heic"},
147 {"heif", "image/heif"},
148 {"help", "application/x-helpfile"},
149 {"hgl", "application/vnd.hp-hpgl"},
150 {"hh", "text/plain"},
151 {"hlb", "text/x-script"},
152 {"hlp", "application/hlp"},
153 {"hpg", "application/vnd.hp-hpgl"},
154 {"hpgl", "application/vnd.hp-hpgl"},
155 {"hqx", "application/binhex"},
156 {"hta", "application/hta"},
157 {"htc", "text/x-component"},
158 {"htm", "text/html"},
159 {"html", "text/html"},
160 {"htmls", "text/html"},
161 {"htt", "text/webviewhtml"},
162 {"htx", "text/html"},
163 {"ice", "x-conference/x-cooltalk"},
164 {"ico", "image/x-icon"},
165 {"idc", "text/plain"},
166 {"ief", "image/ief"},
167 {"iefs", "image/ief"},
168 {"iges", "application/iges"},
169 {"igs", "application/iges"},
170 {"ima", "application/x-ima"},
171 {"imap", "application/x-httpd-imap"},
172 {"inf", "application/inf"},
173 {"ins", "application/x-internet-signup"},
174 {"ip", "application/x-ip2"},
175 {"isu", "video/x-isvideo"},
176 {"it", "audio/it"},
177 {"iv", "application/x-inventor"},
178 {"ivr", "i-world/i-vrml"},
179 {"ivy", "application/x-livescreen"},
180 {"jam", "audio/x-jam"},
181 {"jav", "text/x-java-source"},
182 {"java", "text/x-java-source"},
183 {"jcm", "application/x-java-commerce"},
184 {"jfif", "image/jpeg"},
185 {"jp2", "image/jp2"},
186 {"jfif-tbnl", "image/jpeg"},
187 {"jpe", "image/jpeg"},
188 {"jpeg", "image/jpeg"},
189 {"jpg", "image/jpeg"},
190 {"jps", "image/x-jps"},
191 {"js", "application/javascript"},
192 {"json", "application/json"},
193 {"jut", "image/jutvision"},
194 {"kar", "music/x-karaoke"},
195 {"kdc", "image/kdc"},
196 {"ksh", "text/x-script.ksh"},
197 {"la", "audio/nspaudio"},
198 {"lam", "audio/x-liveaudio"},
199 {"latex", "application/x-latex"},
200 {"lha", "application/lha"},
201 {"lhx", "application/octet-stream"},
202 {"list", "text/plain"},
203 {"lma", "audio/nspaudio"},
204 {"log", "text/plain"},
205 {"lsp", "application/x-lisp"},
206 {"lst", "text/plain"},
207 {"lsx", "text/x-la-asf"},
208 {"ltx", "application/x-latex"},
209 {"lzh", "application/x-lzh"},
210 {"lzx", "application/lzx"},
211 {"m", "text/x-m"},
212 {"m1v", "video/mpeg"},
213 {"m2a", "audio/mpeg"},
214 {"m2v", "video/mpeg"},
215 {"m3u", "audio/x-mpegurl"},
216 {"man", "application/x-troff-man"},
217 {"map", "application/x-navimap"},
218 {"mar", "text/plain"},
219 {"mbd", "application/mbedlet"},
220 {"mc$", "application/x-magic-cap-package-1.0"},
221 {"mcd", "application/x-mathcad"},
222 {"mcf", "text/mcf"},
223 {"mcp", "application/netmc"},
224 {"mdc", "image/mdc"},
225 {"me", "application/x-troff-me"},
226 {"mef", "image/mef"},
227 {"mht", "message/rfc822"},
228 {"mhtml", "message/rfc822"},
229 {"mid", "audio/midi"},
230 {"midi", "audio/midi"},
231 {"mif", "application/x-mif"},
232 {"mime", "message/rfc822"},
233 {"mjf", "audio/x-vnd.audioexplosion.mjuicemediafile"},
234 {"mjpg", "video/x-motion-jpeg"},
235 {"mka", "audio/x-matroska"},
236 {"mkv", "video/x-matroska"},
237 {"mk3d", "video/x-matroska-3d"},
238 {"mm", "application/x-meme"},
239 {"mme", "application/base64"},
240 {"mod", "audio/mod"},
241 {"moov", "video/quicktime"},
242 {"mov", "video/quicktime"},
243 {"movie", "video/x-sgi-movie"},
244 {"mos", "image/mos"},
245 {"mp2", "audio/mpeg"},
246 {"mp3", "audio/mpeg3"},
247 {"mp4", "video/mp4"},
248 {"mpa", "audio/mpeg"},
249 {"mpc", "application/x-project"},
250 {"mpe", "video/mpeg"},
251 {"mpeg", "video/mpeg"},
252 {"mpg", "video/mpeg"},
253 {"mpga", "audio/mpeg"},
254 {"mpp", "application/vnd.ms-project"},
255 {"mpt", "application/x-project"},
256 {"mpv", "application/x-project"},
257 {"mpx", "application/x-project"},
258 {"mrc", "application/marc"},
259 {"mrw", "image/mrw"},
260 {"ms", "application/x-troff-ms"},
261 {"mv", "video/x-sgi-movie"},
262 {"my", "audio/make"},
263 {"mzz", "application/x-vnd.audioexplosion.mzz"},
264 {"nap", "image/naplps"},
265 {"naplps", "image/naplps"},
266 {"nc", "application/x-netcdf"},
267 {"ncm", "application/vnd.nokia.configuration-message"},
268 {"nef", "image/nef"},
269 {"nfo", "text/xml"},
270 {"nif", "image/x-niff"},
271 {"niff", "image/x-niff"},
272 {"nix", "application/x-mix-transfer"},
273 {"nrw", "image/nrw"},
274 {"nsc", "application/x-conference"},
275 {"nvd", "application/x-navidoc"},
276 {"o", "application/octet-stream"},
277 {"oda", "application/oda"},
278 {"ogg", "audio/ogg"},
279 {"omc", "application/x-omc"},
280 {"omcd", "application/x-omcdatamaker"},
281 {"omcr", "application/x-omcregerator"},
282 {"orf", "image/orf"},
283 {"p", "text/x-pascal"},
284 {"p10", "application/pkcs10"},
285 {"p12", "application/pkcs-12"},
286 {"p7a", "application/x-pkcs7-signature"},
287 {"p7c", "application/pkcs7-mime"},
288 {"p7m", "application/pkcs7-mime"},
289 {"p7r", "application/x-pkcs7-certreqresp"},
290 {"p7s", "application/pkcs7-signature"},
291 {"part", "application/pro_eng"},
292 {"pas", "text/pascal"},
293 {"pbm", "image/x-portable-bitmap"},
294 {"pcl", "application/vnd.hp-pcl"},
295 {"pct", "image/x-pict"},
296 {"pcx", "image/x-pcx"},
297 {"pdb", "chemical/x-pdb"},
298 {"pdf", "application/pdf"},
299 {"pef", "image/pef"},
300 {"pfunk", "audio/make.my.funk"},
301 {"pgm", "image/x-portable-greymap"},
302 {"pic", "image/pict"},
303 {"pict", "image/pict"},
304 {"pkg", "application/x-newton-compatible-pkg"},
305 {"pko", "application/vnd.ms-pki.pko"},
306 {"pl", "text/x-script.perl"},
307 {"plx", "application/x-pixclscript"},
308 {"pm", "text/x-script.perl-module"},
309 {"pm4", "application/x-pagemaker"},
310 {"pm5", "application/x-pagemaker"},
311 {"png", "image/png"},
312 {"pnm", "application/x-portable-anymap"},
313 {"pot", "application/vnd.ms-powerpoint"},
314 {"pov", "model/x-pov"},
315 {"ppa", "application/vnd.ms-powerpoint"},
316 {"ppm", "image/x-portable-pixmap"},
317 {"pps", "application/mspowerpoint"},
318 {"ppt", "application/mspowerpoint"},
319 {"ppz", "application/mspowerpoint"},
320 {"pre", "application/x-freelance"},
321 {"prt", "application/pro_eng"},
322 {"ps", "application/postscript"},
323 {"psd", "application/octet-stream"},
324 {"pvu", "paleovu/x-pv"},
325 {"pwz", "application/vnd.ms-powerpoint"},
326 {"py", "text/x-script.python"},
327 {"pyc", "application/x-bytecode.python"},
328 {"qcp", "audio/vnd.qcelp"},
329 {"qd3", "x-world/x-3dmf"},
330 {"qd3d", "x-world/x-3dmf"},
331 {"qif", "image/x-quicktime"},
332 {"qt", "video/quicktime"},
333 {"qtc", "video/x-qtc"},
334 {"qti", "image/x-quicktime"},
335 {"qtif", "image/x-quicktime"},
336 {"ra", "audio/x-realaudio"},
337 {"raf", "image/raf"},
338 {"ram", "audio/x-pn-realaudio"},
339 {"ras", "image/cmu-raster"},
340 {"rast", "image/cmu-raster"},
341 {"raw", "image/raw"},
342 {"rexx", "text/x-script.rexx"},
343 {"rf", "image/vnd.rn-realflash"},
344 {"rgb", "image/x-rgb"},
345 {"rm", "audio/x-pn-realaudio"},
346 {"rmi", "audio/mid"},
347 {"rmm", "audio/x-pn-realaudio"},
348 {"rmp", "audio/x-pn-realaudio"},
349 {"rng", "application/ringing-tones"},
350 {"rnx", "application/vnd.rn-realplayer"},
351 {"roff", "application/x-troff"},
352 {"rp", "image/vnd.rn-realpix"},
353 {"rpm", "audio/x-pn-realaudio-plugin"},
354 {"rt", "text/richtext"},
355 {"rtf", "text/richtext"},
356 {"rtx", "text/richtext"},
357 {"rv", "video/vnd.rn-realvideo"},
358 {"rw2", "image/rw2"},
359 {"s", "text/x-asm"},
360 {"s3m", "audio/s3m"},
361 {"saveme", "application/octet-stream"},
362 {"sbk", "application/x-tbook"},
363 {"scm", "video/x-scm"},
364 {"sdml", "text/plain"},
365 {"sdp", "application/sdp"},
366 {"sdr", "application/sounder"},
367 {"sea", "application/sea"},
368 {"set", "application/set"},
369 {"sgm", "text/sgml"},
370 {"sgml", "text/sgml"},
371 {"sh", "text/x-script.sh"},
372 {"shar", "application/x-bsh"},
373 {"shtml", "text/x-server-parsed-html"},
374 {"sid", "audio/x-psid"},
375 {"sit", "application/x-stuffit"},
376 {"skd", "application/x-koan"},
377 {"skm", "application/x-koan"},
378 {"skp", "application/x-koan"},
379 {"skt", "application/x-koan"},
380 {"sl", "application/x-seelogo"},
381 {"smi", "application/smil"},
382 {"smil", "application/smil"},
383 {"snd", "audio/basic"},
384 {"sol", "application/solids"},
385 {"spc", "text/x-speech"},
386 {"spl", "application/futuresplash"},
387 {"spr", "application/x-sprite"},
388 {"sprite", "application/x-sprite"},
389 {"src", "application/x-wais-source"},
390 {"srw", "image/srw"},
391 {"ssi", "text/x-server-parsed-html"},
392 {"ssm", "application/streamingmedia"},
393 {"sst", "application/vnd.ms-pki.certstore"},
394 {"step", "application/step"},
395 {"stl", "application/sla"},
396 {"stp", "application/step"},
397 {"sup", "application/x-pgs"},
398 {"sv4cpio", "application/x-sv4cpio"},
399 {"sv4crc", "application/x-sv4crc"},
400 {"svf", "image/vnd.dwg"},
401 {"svg", "image/svg+xml"},
402 {"svr", "application/x-world"},
403 {"swf", "application/x-shockwave-flash"},
404 {"t", "application/x-troff"},
405 {"talk", "text/x-speech"},
406 {"tar", "application/x-tar"},
407 {"tbk", "application/toolbook"},
408 {"tcl", "text/x-script.tcl"},
409 {"tcsh", "text/x-script.tcsh"},
410 {"tex", "application/x-tex"},
411 {"texi", "application/x-texinfo"},
412 {"texinfo", "application/x-texinfo"},
413 {"text", "text/plain"},
414 {"tgz", "application/x-compressed"},
415 {"tif", "image/tiff"},
416 {"tiff", "image/tiff"},
417 {"tr", "application/x-troff"},
418 {"ts", "video/mp2t"},
419 {"tsi", "audio/tsp-audio"},
420 {"tsp", "audio/tsplayer"},
421 {"tsv", "text/tab-separated-values"},
422 {"turbot", "image/florian"},
423 {"txt", "text/plain"},
424 {"uil", "text/x-uil"},
425 {"uni", "text/uri-list"},
426 {"unis", "text/uri-list"},
427 {"unv", "application/i-deas"},
428 {"uri", "text/uri-list"},
429 {"uris", "text/uri-list"},
430 {"ustar", "application/x-ustar"},
431 {"uu", "text/x-uuencode"},
432 {"uue", "text/x-uuencode"},
433 {"vcd", "application/x-cdlink"},
434 {"vcs", "text/x-vcalendar"},
435 {"vda", "application/vda"},
436 {"vdo", "video/vdo"},
437 {"vew", "application/groupwise"},
438 {"viv", "video/vivo"},
439 {"vivo", "video/vivo"},
440 {"vmd", "application/vocaltec-media-desc"},
441 {"vmf", "application/vocaltec-media-file"},
442 {"voc", "audio/voc"},
443 {"vos", "video/vosaic"},
444 {"vox", "audio/voxware"},
445 {"vqe", "audio/x-twinvq-plugin"},
446 {"vqf", "audio/x-twinvq"},
447 {"vql", "audio/x-twinvq-plugin"},
448 {"vrml", "application/x-vrml"},
449 {"vrt", "x-world/x-vrt"},
450 {"vsd", "application/x-visio"},
451 {"vst", "application/x-visio"},
452 {"vsw", "application/x-visio"},
453 {"vtt", "text/vtt"},
454 {"w60", "application/wordperfect6.0"},
455 {"w61", "application/wordperfect6.1"},
456 {"w6w", "application/msword"},
457 {"wav", "audio/wav"},
458 {"wb1", "application/x-qpro"},
459 {"wbmp", "image/vnd.wap.wbmp"},
460 {"web", "application/vnd.xara"},
461 {"webp", "image/webp"},
462 {"wiz", "application/msword"},
463 {"wk1", "application/x-123"},
464 {"wma", "audio/x-ms-wma"},
465 {"wmf", "windows/metafile"},
466 {"wml", "text/vnd.wap.wml"},
467 {"wmlc", "application/vnd.wap.wmlc"},
468 {"wmls", "text/vnd.wap.wmlscript"},
469 {"wmlsc", "application/vnd.wap.wmlscriptc"},
470 {"wmv", "video/x-ms-wmv"},
471 {"word", "application/msword"},
472 {"wp", "application/wordperfect"},
473 {"wp5", "application/wordperfect"},
474 {"wp6", "application/wordperfect"},
475 {"wpd", "application/wordperfect"},
476 {"wq1", "application/x-lotus"},
477 {"wri", "application/mswrite"},
478 {"wrl", "model/vrml"},
479 {"wrz", "model/vrml"},
480 {"wsc", "text/scriplet"},
481 {"wsrc", "application/x-wais-source"},
482 {"wtk", "application/x-wintalk"},
483 {"x3f", "image/x3f"},
484 {"xbm", "image/xbm"},
485 {"xdr", "video/x-amt-demorun"},
486 {"xgz", "xgl/drawing"},
487 {"xif", "image/vnd.xiff"},
488 {"xl", "application/excel"},
489 {"xla", "application/excel"},
490 {"xlb", "application/excel"},
491 {"xlc", "application/excel"},
492 {"xld", "application/excel"},
493 {"xlk", "application/excel"},
494 {"xll", "application/excel"},
495 {"xlm", "application/excel"},
496 {"xls", "application/excel"},
497 {"xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
498 {"xlt", "application/excel"},
499 {"xlv", "application/excel"},
500 {"xlw", "application/excel"},
501 {"xm", "audio/xm"},
502 {"xml", "text/xml"},
503 {"xmz", "xgl/movie"},
504 {"xpix", "application/x-vnd.ls-xpix"},
505 {"xpm", "image/xpm"},
506 {"x-png", "image/png"},
507 {"xspf", "application/xspf+xml"},
508 {"xsr", "video/x-amt-showrun"},
509 {"xvid", "video/x-msvideo"},
510 {"xwd", "image/x-xwd"},
511 {"xyz", "chemical/x-pdb"},
512 {"z", "application/x-compressed"},
513 {"zip", "application/zip"},
514 {"zoo", "application/octet-stream"},
515 {"zsh", "text/x-script.zsh"}}};
517 std::string CMime::GetMimeType(const std::string &extension)
519 if (extension.empty())
520 return "";
522 std::string ext = extension;
523 size_t posNotPoint = ext.find_first_not_of('.');
524 if (posNotPoint != std::string::npos && posNotPoint > 0)
525 ext = extension.substr(posNotPoint);
526 transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
528 std::map<std::string, std::string>::const_iterator it = m_mimetypes.find(ext);
529 if (it != m_mimetypes.end())
530 return it->second;
532 return "";
535 std::string CMime::GetMimeType(const CFileItem &item)
537 std::string path = item.GetDynPath();
538 if (item.HasVideoInfoTag() && !item.GetVideoInfoTag()->GetPath().empty())
539 path = item.GetVideoInfoTag()->GetPath();
540 else if (item.HasMusicInfoTag() && !item.GetMusicInfoTag()->GetURL().empty())
541 path = item.GetMusicInfoTag()->GetURL();
543 return GetMimeType(URIUtils::GetExtension(path));
546 std::string CMime::GetMimeType(const CURL &url, bool lookup)
549 std::string strMimeType;
551 if( url.IsProtocol("shout") || url.IsProtocol("http") || url.IsProtocol("https"))
553 // If lookup is false, bail out early to leave mime type empty
554 if (!lookup)
555 return strMimeType;
557 std::string strmime;
558 XFILE::CCurlFile::GetMimeType(url, strmime);
560 // try to get mime-type again but with an NSPlayer User-Agent
561 // in order for server to provide correct mime-type. Allows us
562 // to properly detect an MMS stream
563 if (StringUtils::StartsWithNoCase(strmime, "video/x-ms-"))
564 XFILE::CCurlFile::GetMimeType(url, strmime, "NSPlayer/11.00.6001.7000");
566 // make sure there are no options set in mime-type
567 // mime-type can look like "video/x-ms-asf ; charset=utf8"
568 size_t i = strmime.find(';');
569 if(i != std::string::npos)
570 strmime.erase(i, strmime.length() - i);
571 StringUtils::Trim(strmime);
572 strMimeType = strmime;
574 else
575 strMimeType = GetMimeType(url.GetFileType());
577 // if it's still empty set to an unknown type
578 if (strMimeType.empty())
579 strMimeType = "application/octet-stream";
581 return strMimeType;
584 CMime::EFileType CMime::GetFileTypeFromMime(const std::string& mimeType)
586 // based on http://mimesniff.spec.whatwg.org/
588 std::string type, subtype;
589 if (!parseMimeType(mimeType, type, subtype))
590 return FileTypeUnknown;
592 if (type == "application")
594 if (subtype == "zip")
595 return FileTypeZip;
596 if (subtype == "x-gzip")
597 return FileTypeGZip;
598 if (subtype == "x-rar-compressed")
599 return FileTypeRar;
601 if (subtype == "xml")
602 return FileTypeXml;
604 else if (type == "text")
606 if (subtype == "xml")
607 return FileTypeXml;
608 if (subtype == "html")
609 return FileTypeHtml;
610 if (subtype == "plain")
611 return FileTypePlainText;
613 else if (type == "image")
615 if (subtype == "bmp")
616 return FileTypeBmp;
617 if (subtype == "gif")
618 return FileTypeGif;
619 if (subtype == "png")
620 return FileTypePng;
621 if (subtype == "jpeg" || subtype == "pjpeg")
622 return FileTypeJpeg;
625 if (StringUtils::EndsWith(subtype, "+zip"))
626 return FileTypeZip;
627 if (StringUtils::EndsWith(subtype, "+xml"))
628 return FileTypeXml;
630 return FileTypeUnknown;
633 CMime::EFileType CMime::GetFileTypeFromContent(const std::string& fileContent)
635 // based on http://mimesniff.spec.whatwg.org/#matching-a-mime-type-pattern
637 const size_t len = fileContent.length();
638 if (len < 2)
639 return FileTypeUnknown;
641 const unsigned char* const b = (const unsigned char*)fileContent.c_str();
643 //! @todo add detection for text types
645 // check image types
646 if (b[0] == 'B' && b[1] == 'M')
647 return FileTypeBmp;
648 if (len >= 6 && b[0] == 'G' && b[1] == 'I' && b[2] == 'F' && b[3] == '8' && (b[4] == '7' || b[4] == '9') && b[5] == 'a')
649 return FileTypeGif;
650 if (len >= 8 && b[0] == 0x89 && b[1] == 'P' && b[2] == 'N' && b[3] == 'G' && b[4] == 0x0D && b[5] == 0x0A && b[6] == 0x1A && b[7] == 0x0A)
651 return FileTypePng;
652 if (len >= 3 && b[0] == 0xFF && b[1] == 0xD8 && b[2] == 0xFF)
653 return FileTypeJpeg;
655 // check archive types
656 if (len >= 3 && b[0] == 0x1F && b[1] == 0x8B && b[2] == 0x08)
657 return FileTypeGZip;
658 if (len >= 4 && b[0] == 'P' && b[1] == 'K' && b[2] == 0x03 && b[3] == 0x04)
659 return FileTypeZip;
660 if (len >= 7 && b[0] == 'R' && b[1] == 'a' && b[2] == 'r' && b[3] == ' ' && b[4] == 0x1A && b[5] == 0x07 && b[6] == 0x00)
661 return FileTypeRar;
663 //! @todo add detection for other types if required
665 return FileTypeUnknown;
668 bool CMime::parseMimeType(const std::string& mimeType, std::string& type, std::string& subtype)
670 static const char* const whitespaceChars = "\x09\x0A\x0C\x0D\x20"; // tab, LF, FF, CR and space
672 type.clear();
673 subtype.clear();
675 const size_t slashPos = mimeType.find('/');
676 if (slashPos == std::string::npos)
677 return false;
679 type.assign(mimeType, 0, slashPos);
680 subtype.assign(mimeType, slashPos + 1, std::string::npos);
682 const size_t semicolonPos = subtype.find(';');
683 if (semicolonPos != std::string::npos)
684 subtype.erase(semicolonPos);
686 StringUtils::Trim(type, whitespaceChars);
687 StringUtils::Trim(subtype, whitespaceChars);
689 if (type.empty() || subtype.empty())
691 type.clear();
692 subtype.clear();
693 return false;
696 StringUtils::ToLower(type);
697 StringUtils::ToLower(subtype);
699 return true;