Bug 1619583 Comment 6 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

When we right click the file and choose "save link as", we make a request to determine the mimetype, and end up in https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/browser/base/content/nsContextMenu.js#1429 . This passes the mimetype (which is text/html).

::DoContent then [calls `CreateListener`](https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/uriloader/exthandler/nsExternalHelperAppService.cpp#821-822), which [calls `GetFromTypeAndExtension`](https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/uriloader/exthandler/nsExternalHelperAppService.cpp#766-767), having deduced the `.exe` file extension from the URL.

So we end up in platform-specific `GetMIMEInfoFromOS`, [called from the above](https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/uriloader/exthandler/nsExternalHelperAppService.cpp#2460).

On Windows, that starts by asking, [is this mimetype any use](https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/uriloader/exthandler/win/nsOSHelperAppService.cpp#433-442)? `application/octet-stream`, for instance, really isn't. The `text/html` that the server sends in this case passes this check.

Then, given that we have a good mimetype, we look up a file extension for that mimetype, and find the `.html` extension in the registry.

Now things get messy. Windows determines how to open files based on the file extension. It has no real concept of mimetypes and they are not associated/determined from files when determining how to open them. So we generate an nsIMIMEInfo object based on the file extension. This guarantees that the file ends up with a file extension that gets it opened how the website would expect based on the mimetype. So we defer to the mimetype to determine what file extension that should be, because the extension we determine from the URL is often bogus (it's either missing or could be "php" or whatever) - on the web, mimetypes rule the roost.

For .html, on Windows we almost certainly find a mimetype because of course Firefox itself has registered as a handler to open these files.

On mac, I had a brief look but it seems that the implementation of `GetMIMEInfoFromOS` is a bit non-committal, and just returns a mime info object for `text/html`, without any extensions listed (!?) and then the JS code or the streamlistener must later decide "oh well, we'll use whatever we got given then".

If theory, I'd argue that the behaviour of Chrome, and our mac/linux implementation is wrong. ".exe" is not a valid extension for an HTML file, and the website claims this is an HTML file, so we should probably treat it like one (which we do on Windows).

In practice, I'm curious about why Chrome behaves as they do. It's possible they treat text/html with a download content-disposition or something the same way we treat `application/octet-stream`. Either way the practical fix here is to fix the mimetype sent by the server...
If Google have a reason for having it this way, or if we think we need to use safebrowsing to mark the download based on the file extension rather than the mimetype, to be honest I'm not 100% sure how we'd get to that place, because I'm not familiar with how we "normally" invoke safebrowsing.

Does that help? :-)
When we right click the file and choose "save link as", we make a request to determine the mimetype, and end up in https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/browser/base/content/nsContextMenu.js#1429 . This passes the mimetype (which is text/html).

::DoContent then [calls `CreateListener`](https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/uriloader/exthandler/nsExternalHelperAppService.cpp#821-822), which [calls `GetFromTypeAndExtension`](https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/uriloader/exthandler/nsExternalHelperAppService.cpp#766-767), having deduced the `.exe` file extension from the URL.

So we end up in platform-specific `GetMIMEInfoFromOS`, [called from the above](https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/uriloader/exthandler/nsExternalHelperAppService.cpp#2460).

On Windows, that starts by asking, [is this mimetype any use](https://searchfox.org/mozilla-central/rev/c79c0d65a183d9d38676855f455a5c6a7f7dadd3/uriloader/exthandler/win/nsOSHelperAppService.cpp#433-442)? `application/octet-stream`, for instance, really isn't. The `text/html` that the server sends in this case passes this check.

Then, given that we have a good mimetype, we look up a file extension for that mimetype, and find the `.html` extension in the registry.

Now things get messy. Windows determines how to open files based on the file extension. It has no real concept of mimetypes and they are not associated/determined from files when determining how to open them. So we generate an nsIMIMEInfo object based on the file extension. This guarantees that the file ends up with a file extension that gets it opened how the website would expect based on the mimetype. So we defer to the mimetype to determine what file extension that should be, because the extension we determine from the URL is often bogus (it's either missing or could be "php" or whatever) - on the web, mimetypes rule the roost.

For .html, on Windows we almost certainly find registry information on how to open it, because of course Firefox itself has registered as a handler to open these files.

On mac, I had a brief look but it seems that the implementation of `GetMIMEInfoFromOS` is a bit non-committal, and just returns a mime info object for `text/html`, without any extensions listed (!?) and then the JS code or the streamlistener must later decide "oh well, we'll use whatever we got given then".

If theory, I'd argue that the behaviour of Chrome, and our mac/linux implementation is wrong. ".exe" is not a valid extension for an HTML file, and the website claims this is an HTML file, so we should probably treat it like one (which we do on Windows).

In practice, I'm curious about why Chrome behaves as they do. It's possible they treat text/html with a download content-disposition or something the same way we treat `application/octet-stream`. Either way the practical fix here is to fix the mimetype sent by the server...
If Google have a reason for having it this way, or if we think we need to use safebrowsing to mark the download based on the file extension rather than the mimetype, to be honest I'm not 100% sure how we'd get to that place, because I'm not familiar with how we "normally" invoke safebrowsing.

Does that help? :-)

Back to Bug 1619583 Comment 6