2 * (C) Copyright 2008 Jeremy Maitin-Shepard
4 * Portions of this file are derived from the "Open in Browser" extension,
5 * (C) Copyright 2006 Sylvain Pasche.
7 * Use, modification, and distribution are subject to the terms specified in the
12 * This module was inspired by the "Open in Browser" extension by Sylvain
13 * Pasche, available at http://www.spasche.net/mozilla/.
15 * This module implements (in a somewhat hacky way) overriding of the
16 * server-specified mime type for specified URLs. It works by registering an
17 * observer for the "http-on-examine-response" and
18 * "http-on-examine-merged-response" topics and changes the response MIME type
19 * of the nsIHTTPChannel object passed as the subject, as well as clearing any
20 * "Content-disposition" header.
22 * Unfortunately, due to the design, this hack does not work for FTP.
26 let EXAMINE_TOPIC
= "http-on-examine-response";
27 let EXAMINE_MERGED_TOPIC
= "http-on-examine-merged-response";
29 let table
= new string_hashmap();
31 let timeout
= 10000; // 10000 milliseconds = 10 seconds
35 // uri must be an instance of nsIURI
36 function can_override_mime_type_for_uri(uri
) {
37 return uri
.schemeIs("http") || uri
.schemeIs("https");
40 const cache_service
= Cc
["@mozilla.org/network/cache-service;1"].getService(Ci
.nsICacheService
);
42 function clear_http_cache_entry(uri_string
) {
43 var http_cache_session
= cache_service
.createSession("HTTP", 0, true);
44 http_cache_session
.doomEntriesIfExpired
= false;
46 // Remove the ref component of the URL
47 var cache_key
= uri_string
.replace(/#.*$/, "");
48 var entry
= http_cache_session
.openCacheEntry(cacheKey
, Ci
.nsICache
.ACCESS_READ
, false);
54 let clear_override = function(uri_string
) {
55 table
.remove(uri_string
);
58 if (table_size
== 0) {
59 observer_service
.removeObserver(observer
, EXAMINE_TOPIC
);
60 observer_service
.removeObserver(observer
, EXAMINE_MERGED_TOPIC
);
65 observe: function (subject
, topic
, data
) {
66 if (topic
!= EXAMINE_TOPIC
&& topic
!= EXAMINE_MERGED_TOPIC
)
69 subject
.QueryInterface(Ci
.nsIHttpChannel
);
71 var uri_string
= subject
.originalURI
.spec
;
72 var obj
= table
.get(uri_string
);
78 subject
.contentType
= obj
.mime_type
;
80 // drop content-disposition header
81 subject
.setResponseHeader("Content-Disposition", "", false);
83 clear_override(uri_string
);
89 // uri must be an instance of nsIURI and can_override_mime_type_for_uri must
90 // return true for the passed uri.
92 // mime_type must be a string
93 function override_mime_type_for_next_load(uri
, mime_type
) {
95 clear_http_cache_entry(uri
.spec
);
97 var obj
= table
.get(uri
.spec
);
103 obj
= { mime_type
: mime_type
};
105 obj
.timer
= call_after_timeout(function () {
106 clear_override(uri
.spec
);
109 if (table_size
== 1) {
110 observer_service
.addObserver(observer
, EXAMINE_TOPIC
, false);
111 observer_service
.addObserver(observer
, EXAMINE_MERGED_TOPIC
, false);
113 table
.put(uri
.spec
, obj
);