I have a web app where the user needs to upload a .zip file. On the server-side, I am checking the mime type of the uploaded file, to make sure it is application/x-zip-compressed
or application/zip
.
This worked fine for me on Firefox and IE. However, when a coworker tested it, it failed for him on Firefox (sent mime type was something like "application/octet-stream
") but worked on Internet Explorer. Our setups seem to be identical: IE8, FF 3.5.1 with all add-ons disabled, Win XP SP3, WinRAR installed as native .zip file handler (not sure if that's relevant).
So my question is: How does the browser determine what mime type to send?
Please note: I know that the mime type is sent by the browser and, therefore, unreliable. I am just checking it as a convenience–mainly to give a more friendly error message than the ones you get by trying to open a non-zip file as a zip file, and to avoid loading the (presumably heavy) zip file libraries.
Best Answer
Chrome
Chrome (version 38 as of writing) has 3 ways to determine the MIME type and does so in a certain order. The snippet below is from file
src/net/base/mime_util.cc
, methodMimeUtil::GetMimeTypeFromExtensionHelper
.The hard-coded lists come a bit earlier in the file: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 (
kPrimaryMappings
andkSecondaryMappings
).An example: when uploading a CSV file from a Windows system with Microsoft Excel installed, Chrome will report this as
application/vnd.ms-excel
. This is because.csv
is not specified in the first hard-coded list, so the browser falls back to the system registry.HKEY_CLASSES_ROOT\.csv
has a value namedContent Type
that is set toapplication/vnd.ms-excel
.Internet Explorer
Again using the same example, the browser will report
application/vnd.ms-excel
. I think it's reasonable to assume Internet Explorer (version 11 as of writing) uses the registry. Possibly it also makes use of a hard-coded list like Chrome and Firefox, but its closed source nature makes it hard to verify.Firefox
As indicated in the Chrome code, Firefox (version 32 as of writing) works in a similar way. Snippet from file
uriloader\exthandler\nsExternalHelperAppService.cpp
, methodnsExternalHelperAppService::GetTypeFromExtension
The hard-coded lists come earlier in the file, somewhere near line 441. You're looking for
defaultMimeEntries
andextraMimeEntries
.With my current profile, the browser will report
text/csv
because there's an entry for it inmimeTypes.rdf
(item 2 in the list above). With a fresh profile, which does not have this entry, the browser will reportapplication/vnd.ms-excel
(item 3 in the list).Summary
The hard-coded lists in the browsers are pretty limited. Often, the MIME type sent by the browser will be the one reported by the OS. And this is exactly why, as stated in the question, the MIME type reported by the browser is unreliable.