How to properly override Content-Type header in Firefox Web Extension?
Asked Answered
F

1

6

Suppose HTML files coming from a server have these headers:

Content-Type: application/octet-stream
Content-Disposition: attachment;

I would like to alter the headers in a web extension (so that the HTML file is displayed as a regular web page):

Content-Type: text/html; charset=utf-8
(Removed Content-Disposition)

In Google Chrome, the web extension successfully changes the headers and the HTML file is displayed as a normal web page. In Firefox (48), although the headers are changed, I am prompted to download the HTML file. Am I doing something wrong or is this a known bug?

Example of request: localhost:8000/test.html

Code below.


Web extension - manifest.json:

{
    "description": "Change content type",
    "manifest_version": 2,
    "name": "change-content-type",
    "version": "1.0",

    "permissions": [
        "webRequest", "webRequestBlocking", "http://localhost/*"
    ],

    "background": {
        "scripts": ["background.js"]
    }
}

Web extension - Background.js looks as follows:

function setHeader(headers, name, value) {
    for (var header of headers) {
        if (header.name.toLowerCase() == name.toLowerCase()) {
            header.value = value;
            return;
        }
    }

    headers.push({ name : name, value : value });
}

function removeHeader(headers, name) {
    for (var i = 0; i < headers.length; i++) {
        if (headers[i].name.toLowerCase() == name.toLowerCase()) {
            headers.splice(i, 1);
            return;
        }
    }
}

function changeResponseHeaders(details) {
    removeHeader(details.responseHeaders, "Content-Disposition");
    setHeader(details.responseHeaders, "Content-Type", "text/html; charset=utf-8");

    return {
        responseHeaders: details.responseHeaders
    };
}

chrome.webRequest.onHeadersReceived.addListener(
    changeResponseHeaders, {
        urls: ["http://localhost/*"],
        types: ["main_frame", "sub_frame"]
    }, ["blocking", "responseHeaders"]
)

A tiny web server (as an example):

import SimpleHTTPServer

class MyHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def guess_type(self, path):
        return 'application/octet-stream';

    def end_headers(self):
        self.send_my_headers()
        SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)

    def send_my_headers(self):
        self.send_header("Content-Disposition", "attachment;")

if __name__ == '__main__':
    SimpleHTTPServer.test(HandlerClass=MyHTTPRequestHandler)

And a sample HTML file:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Test</title>
</head>
<body>
    <div>Test</div>
</body>
</html>
Fuzz answered 20/9, 2016 at 14:27 Comment(2)
Filed a bug here.Fuzz
I would appreciate if you would post an answer to this, mentioning the bug - especially since it's already fixed in the dev version, so that it doesn't hang unanswered.Chaldea
F
4

This was a bug and it has been fixed. The fix seems to be planned for Mozilla Firefox 52.

I do not have knowledge on the implementation, thus I cannot provide further details.

Fuzz answered 26/9, 2016 at 17:17 Comment(1)
It's seemingly fixed in 51, see bugzilla.mozilla.org/show_bug.cgi?id=1304331#c13Otherness

© 2022 - 2024 — McMap. All rights reserved.