1 /* coded by Ketmar // Invisible Vector (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software. It comes without any warranty, to
5 * the extent permitted by applicable law. You can redistribute it
6 * and/or modify it under the terms of the Do What The Fuck You Want
7 * To Public License, Version 2, as published by Sam Hocevar. See
8 * http://www.wtfpl.net/txt/copying/ for more details.
11 let EXPORTED_SYMBOLS
= [
14 const {utils
:Cu
, classes
:Cc
, interfaces
:Ci
, results
:Cr
} = Components
;
17 //////////////////////////////////////////////////////////////////////////////
18 Cu
.import("resource://gre/modules/Services.jsm");
20 //////////////////////////////////////////////////////////////////////////////
21 Cu
.import("chrome://k8-imago-code/content/modules/utils.js");
22 Cu
.import(MODULE_PATH
+"debuglog.js");
23 Cu
.import(MODULE_PATH
+"prefs.js");
24 Cu
.import(MODULE_PATH
+"tamper.js");
25 Cu
.import(MODULE_PATH
+"stoplist.js");
26 Cu
.import(MODULE_PATH
+"imgreload.js");
27 Cu
.import(MODULE_PATH
+"hazard.js");
28 Cu
.import(MODULE_PATH
+"rule-engine.js");
31 //////////////////////////////////////////////////////////////////////////////
32 // init some functions from window
35 registerWindowHook("load", function (win
) {
39 registerWindowHook("unload", function (win
) {
44 //////////////////////////////////////////////////////////////////////////////
45 const tldsvc
= Cc
["@mozilla.org/network/effective-tld-service;1"].getService(Ci
.nsIEffectiveTLDService
);
48 //////////////////////////////////////////////////////////////////////////////
49 const imagectRE
= /^image\//;
52 let httpRequestObserver
= {
53 QueryInterface: function (aIID
) {
54 if (aIID
.equals(Ci
.nsIObserver
) || aIID
.equals(Ci
.nsISupports
)) return this;
55 throw Components
.results
.NS_NOINTERFACE
;
58 observe: function (aSubject
, aTopic
, aData
) {
59 if (!(aSubject
instanceof Ci
.nsIHttpChannel
)) return;
61 if (aTopic
=== "http-on-examine-response") {
62 // aSubject is request object
64 let httpChannel
= aSubject
.QueryInterface(Ci
.nsIHttpChannel
);
66 let ctype
= httpChannel
.contentType
;
68 if (!imagectRE
.test(ctype
) /*&& ctype !== "application/octet-stream"*/) {
69 //conlog("ctype: ", ctype);
73 let dw = getDomWindowForChannel(httpChannel), bro = null;
75 bro = getBrowserForDomWindow(dw);
77 if (PREFS.debugLog) conlog("[", httpChannel.URI.spec, "] browser: ", bro.currentURI.spec);
79 if (PREFS.debugLog) conlog("*** [", httpChannel.URI.spec, "] NO browser");
83 if (PREFS.debugLog) conlog("*** [", httpChannel.URI.spec, "] NO dom window");
87 // intercept and count
88 if (Math.floor(httpChannel.responseStatus/100) === 2) {
89 let isoctet = false/*ctype === "application/octet-stream"*/;
91 if (isUnblockedImage(httpChannel.URI)) return;
93 let blacklisted = (isBlockedImage(httpChannel.URI));
94 // global black/white lists
96 //TODO: list priorities
97 let host = httpChannel.URI.host;
98 if (WHITE_HOSTS[host]) return; // whitelisted
99 if (host in BLACK_HOSTS) blacklisted = BLACK_HOSTS[host];
103 if (PREFS.debugLog) conlog("*** [", httpChannel.URI.spec, "] searching for rule...");
104 let rule = getRuleForURI(httpChannel.URI);
106 if (PREFS.debugLog) conlog("*** [", httpChannel.URI.spec, "] rule: ", rule);
107 if (rule.stopAction) {
108 if (rule.action === "deny") {
109 if (PREFS.debugLog) conlog("*** [", httpChannel.URI.spec, "] blocked by 'deny' rule!");
115 get minWidth () ("minWidth" in this.options ? this.options.minWidth : PREFS.minWidth),
116 get minHeight () ("minHeight" in this.options ? this.options.minHeight : PREFS.minHeight),
117 get maxWidth () ("maxWidth" in this.options ? this.options.maxWidth : PREFS.maxWidth),
118 get maxHeight () ("maxHeight" in this.options ? this.options.maxHeight : PREFS.maxHeight),
119 get showPlaceholder () ("showPlaceholder" in this.options ? this.options.showPlaceholder : PREFS.showPlaceholder),
120 get allowUnknownFormats () ("allowUnknownFormats" in this.options ? this.options.allowUnknownFormats : PREFS.allowUnknownFormats),
121 get maxLength () ("maxLength" in this.options ? this.options.maxLength : PREFS.maxLength),
122 get allowFirstPartyImages () ("allowFirstPartyImages" in this.options ? this.options.allowFirstPartyImages : PREFS.allowFirstPartyImages),
123 get action () (this.options.stopAction ? this.options.action : "allow"),
124 get stopAction () this.options.stopAction,
127 //conlog("bl: [", httpChannel.URI.spec, "]: ", blacklisted);
128 // check for 1st-party images
129 if (!blacklisted
&& PREFS
.allowFirstPartyImages
&& !bro
.currentURI
.equals(httpChannel
.URI
)) {
130 // i've seen "Error: NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIURI.host]" there, so...
132 if (tldsvc
.getBaseDomain(bro
.currentURI
) === tldsvc
.getBaseDomain(httpChannel
.URI
)) {
133 if (PREFS
.debugLog
) conlog(httpChannel
.URI
.spec
, ": first-party!");
138 //if (PREFS.debugLog) conlog("counting: ", httpChannel.URI.spec);
139 let nlst
= new ImgDetectListener(isoctet
, blacklisted
);
140 aSubject
.QueryInterface(Ci
.nsITraceableChannel
);
141 nlst
.olst
= aSubject
.setNewListener(nlst
);
143 // onStartRequest() and onStopRequest() will be called anyway, and
144 // our tamper will process that correctly for blacklisted images
145 if (blacklisted
) aSubject
.cancel(Cr
.NS_BINDING_ABORTED
);
147 //if (PREFS.debugLog) conlog("WTF: ", httpChannel.URI.spec, " (", httpChannel.responseStatus, ")");
148 //aSubject.cancel(Cr.NS_BINDING_ABORTED);
150 } else if (aTopic
=== "http-on-modify-request") {
151 let httpChannel
= aSubject
.QueryInterface(Ci
.nsIHttpChannel
);
152 let url
= httpChannel
.URI
.spec
;
153 if (url
in reloadUrlList
) {
154 // ah, ok, i took time from rfc
155 httpChannel
.setRequestHeader("If-Modified-Since", "Sat, 29 Oct 1994 19:43:31 GMT", false);
156 httpChannel
.setRequestHeader("ETag", "", false);
157 delete reloadUrlList
[url
];
164 //////////////////////////////////////////////////////////////////////////////
165 let osvc
= Cc
["@mozilla.org/observer-service;1"].getService(Ci
.nsIObserverService
);
166 osvc
.addObserver(httpRequestObserver
, "http-on-examine-response", false);
167 osvc
.addObserver(httpRequestObserver
, "http-on-modify-request", false);