removed one error message
[k8imago.git] / code / modules / httpobserver.js
blobf8b883e7f132bdf4df9d0b57ba081a54a515944c
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.
9 */
10 // http observer
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
33 let btoa = null;
35 registerWindowHook("load", function (win) {
36 btoa = win.btoa;
37 });
39 registerWindowHook("unload", function (win) {
40 btoa = null;
41 });
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;
67 if (!ctype) return;
68 if (!imagectRE.test(ctype) /*&& ctype !== "application/octet-stream"*/) {
69 //conlog("ctype: ", ctype);
70 return;
73 let dw = getDomWindowForChannel(httpChannel), bro = null;
74 if (dw) {
75 bro = getBrowserForDomWindow(dw);
76 if (bro) {
77 if (PREFS.debugLog) conlog("[", httpChannel.URI.spec, "] browser: ", bro.currentURI.spec);
78 } else {
79 if (PREFS.debugLog) conlog("*** [", httpChannel.URI.spec, "] NO browser");
80 return;
82 } else {
83 if (PREFS.debugLog) conlog("*** [", httpChannel.URI.spec, "] NO dom window");
84 return;
87 // intercept and count
88 if (Math.floor(httpChannel.responseStatus/100) === 2) {
89 let isoctet = false/*ctype === "application/octet-stream"*/;
90 // whitelisted?
91 if (isUnblockedImage(httpChannel.URI)) return;
92 // blacklisted?
93 let blacklisted = (isBlockedImage(httpChannel.URI));
94 // global black/white lists
95 if (!blacklisted) {
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];
101 // check rules
102 if (!blacklisted) {
103 if (PREFS.debugLog) conlog("*** [", httpChannel.URI.spec, "] searching for rule...");
104 let rule = getRuleForURI(httpChannel.URI);
105 if (rule) {
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!");
110 blacklisted = true;
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...
131 try {
132 if (tldsvc.getBaseDomain(bro.currentURI) === tldsvc.getBaseDomain(httpChannel.URI)) {
133 if (PREFS.debugLog) conlog(httpChannel.URI.spec, ": first-party!");
134 return;
136 } catch (e) {}
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);
142 nlst.inited();
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);
146 } else {
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);