Skip to content

Commit bc8a0e7

Browse files
committed
Towards a functioning Applicable Rules list
1 parent d27c975 commit bc8a0e7

File tree

4 files changed

+127
-25
lines changed

4 files changed

+127
-25
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// An ApplicableList is a structure used to keep track of which rulesets
2+
// were applied, and which ones weren't but might have been, to the contents
3+
// of a given page (top level nsIDOMWindow)
4+
5+
function ApplicableList(logger) {
6+
this.log = logger;
7+
};
8+
9+
ApplicableList.prototype = {
10+
active: {},
11+
inactive: {},
12+
13+
active_rule: function(ruleset) {
14+
this.log(WARN,"active rule" + ruleset);
15+
this.active[ruleset.name] = ruleset;
16+
},
17+
18+
inactive_rule: function(ruleset) {
19+
this.log(WARN,"inactive rule" + ruleset);
20+
this.inactive[ruleset.name] = ruleset;
21+
},
22+
23+
show_applicable: function() {
24+
this.log(WARN,"showing rules");
25+
for (var x in this.active) {
26+
this.log(WARN,"Active: " + x.name);
27+
}
28+
for (x in this.inactive) {
29+
this.log(WARN,"Inctive: " + x.name);
30+
}
31+
}
32+
};
33+

src/chrome/content/code/HTTPS.js

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
INCLUDE('Cookie');
1+
INCLUDE('Cookie','ApplicableList');
22
// XXX: Disable STS for now.
33
var STS = {
44
isSTSURI : function(uri) {
@@ -28,8 +28,8 @@ const HTTPS = {
2828
httpsForcedExceptions: null,
2929
httpsRewrite: null,
3030

31-
replaceChannel: function(channel) {
32-
var uri = HTTPSRules.rewrittenURI(channel.URI);
31+
replaceChannel: function(applicable_list, channel) {
32+
var uri = HTTPSRules.rewrittenURI(applicable_list, channel.URI);
3333
if (!uri) {
3434
HTTPS.log(INFO,
3535
"Got replace channel with no applicable rules for URI "
@@ -80,12 +80,51 @@ const HTTPS = {
8080
return true;
8181
},
8282

83+
getApplicableListForContext: function(ctx, uri) {
84+
var alist = null;
85+
var domWinOrNode = null;
86+
if (!ctx) {
87+
this.log(WARN, "No context loading " + uri.spec);
88+
return null;
89+
}
90+
91+
try {
92+
domWinOrNode = ctx.QueryInterface(CI.nsIDOMWindow);
93+
domWinOrNode = domWinOrNode.top;
94+
} catch (e) {
95+
try {
96+
domWinOrNode = ctx.QueryInterface(CI.nsIDOMNode);
97+
} catch(e) {
98+
this.log(WARN, "Context coercion failure for " + uri.spec);
99+
return null;
100+
}
101+
}
102+
103+
if ("https_everywhere_applicable_rules" in domWinOrNode) {
104+
alist = domWinOrNode.https_everywhere_applicable_rules;
105+
} else {
106+
// Usually onLocationChange should have put this in here for us, in some
107+
// cases perhaps we have to make it here...
108+
alist = new ApplicableList(this.log);
109+
domWinOrNode.https_everywhere_applicable_rules = alist;
110+
this.log(WARN, "had to generate applicable list in forceURI for " +
111+
uri.spec + ", " + alist);
112+
}
113+
this.log(WARN, "Successfully returning " + alist);
114+
return alist;
115+
},
116+
83117
forceURI: function(uri, fallback, ctx) {
84118
// Switch some uris to https; ctx is either nsIDOMNode or nsIDOMWindow as
85119
// per the ContentPolicy API.
86120
// Returns true if everything worked out (either correct replacement or no
87121
// replacement needed). Retun False if all attempts to rewrite failed.
88-
var newuri = HTTPSRules.rewrittenURI(uri);
122+
123+
// first of all we need to get the applicable rules list to keep track of
124+
// what rulesets might have applied to this page
125+
this.log(WARN, "Context is " + ctx);
126+
var alist = this.getApplicableListForContext(ctx, uri);
127+
var newuri = HTTPSRules.rewrittenURI(alist, uri);
89128
if (!newuri) return true; // no applicable rule
90129

91130
try {

src/chrome/content/code/HTTPSRules.js

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,8 @@ function RuleSet(name, match_rule, default_off) {
2121
this.name = name;
2222
this.ruleset_match = match_rule;
2323
this.notes = "";
24-
if (match_rule) {
25-
this.ruleset_match_c = new RegExp(match_rule);
26-
} else {
27-
this.ruleset_match_c = null;
28-
}
24+
if (match_rule) this.ruleset_match_c = new RegExp(match_rule)
25+
else this.ruleset_match_c = null;
2926
if (default_off) {
3027
// Perhaps problematically, this currently ignores the actual content of
3128
// the default_off XML attribute. Ideally we'd like this attribute to be
@@ -50,11 +47,10 @@ function RuleSet(name, match_rule, default_off) {
5047

5148
RuleSet.prototype = {
5249
_apply: function(urispec) {
50+
// return 0 would have applied but is inactive, null if it does not apply
51+
// and the new url if it does apply
5352
var i;
5453
var returl = null;
55-
if (!this.active) {
56-
return null;
57-
}
5854
// If a rulset has a match_rule and it fails, go no further
5955
if (this.ruleset_match_c && !this.ruleset_match_c.test(urispec)) {
6056
this.log(VERB, "ruleset_match_c excluded " + urispec);
@@ -69,10 +65,10 @@ RuleSet.prototype = {
6965
}
7066
// Okay, now find the first rule that triggers
7167
for(i = 0; i < this.rules.length; ++i) {
72-
returl = urispec.replace(this.rules[i].from_c,
73-
this.rules[i].to);
68+
returl = urispec.replace(this.rules[i].from_c, this.rules[i].to);
7469
if (returl != urispec) {
75-
return returl;
70+
if (this.active) return returl
71+
else return 0;
7672
}
7773
}
7874
if (this.ruleset_match_c) {
@@ -88,11 +84,14 @@ RuleSet.prototype = {
8884
},
8985

9086
transformURI: function(uri) {
91-
// If no rule applies, return null; otherwise, return a fresh uri instance
87+
// If no rule applies, return null; if a rule would have applied but was
88+
// inactive, return 0; otherwise, return a fresh uri instance
9289
// for the target
9390
var newurl = this._apply(uri.spec);
9491
if (null == newurl)
9592
return null;
93+
if (0 == newurl)
94+
return 0;
9695
var newuri = Components.classes["@mozilla.org/network/standard-url;1"].
9796
createInstance(CI.nsIStandardURL);
9897
newuri.init(CI.nsIStandardURL.URLTYPE_STANDARD, 80,
@@ -313,13 +312,26 @@ const HTTPSRules = {
313312
}
314313
},
315314

316-
rewrittenURI: function(uri) {
315+
rewrittenURI: function(applicable_list, uri) {
317316
var i = 0;
318317
var newuri = null
319318
var rs = this.applicableRulesets(uri.host);
319+
if (!applicable_list)
320+
this.log(DBUG, "No applicable list rewriting " + uri.spec);
320321
for(i = 0; i < rs.length; ++i) {
321-
if ((newuri = rs[i].transformURI(uri)))
322+
newuri = rs[i].transformURI(uri);
323+
if (newuri) {
324+
if (applicable_list) {
325+
applicable_list.active_rule(rs[i]);
326+
applicable_list.show_applicable();
327+
}
322328
return newuri;
329+
} else if (0 == newuri) {
330+
if (applicable_list) {
331+
applicable_list.inactive_rule(rs[i]);
332+
applicable_list.show_applicable();
333+
}
334+
}
323335
}
324336
return null;
325337
},

src/components/https-everywhere.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ function xpcom_checkInterfaces(iid,iids,ex) {
115115
throw ex;
116116
}
117117

118-
INCLUDE('IOUtil', 'HTTPSRules', 'HTTPS', 'Thread');
118+
INCLUDE('IOUtil', 'HTTPSRules', 'HTTPS', 'Thread', 'ApplicableList');
119119

120120
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
121121

@@ -211,15 +211,16 @@ HTTPSEverywhere.prototype = {
211211
},
212212

213213
// We use onLocationChange to make a fresh list of rulesets that could have
214-
// applied to the content in the current page. This will be appended to as
215-
// various content is embedded / requested by JavaScript
214+
// applied to the content in the current page (the "applicable list" is used
215+
// for the context menu in the UI). This will be appended to as various
216+
// content is embedded / requested by JavaScript.
216217
onLocationChange: function(wp, req, uri) {
217218
this.log(WARN,"onLocationChange");
218219
if (wp instanceof CI.nsIWebProgress) {
219220
var x = wp.DOMWindow;
220221
if (x instanceof CI.nsIDOMWindow) {
221222
var top_window = x.top; // climb out of iframes
222-
top_window.https_everywhere_applicable_rules = {};
223+
top_window.https_everywhere_applicable_rules = new ApplicableList(this.log);
223224
} else {
224225
this.log(WARN,"onLocationChange: no nsIDOMWindow");
225226
}
@@ -228,6 +229,22 @@ HTTPSEverywhere.prototype = {
228229
}
229230
},
230231

232+
// the lists get made when the urlbar is loading something new, but they
233+
// need to be appended to with reference only to the channel
234+
getApplicableListForChannel: function(channel) {
235+
var nc = channel.notificationCallbacks ? channel.notificationCallbacks : channel.loadGroup.notificationCallbacks;
236+
if (!nc) {
237+
this.log(WARN, "no window for " + channel.URI.spec);
238+
return null;
239+
} else {
240+
var domWin = nc.getInterface(CI.nsIDOMWindow);
241+
this.log(WARN, "list of rules is " + domWin.https_everywhere_applicable_rules);
242+
this.log(WARN, "list of rules is " +
243+
domWin.https_everywhere_applicable_rules.show_applicable());
244+
}
245+
return domWin.https_everywhere_applicable_rules;
246+
},
247+
231248
observe: function(subject, topic, data) {
232249
// Top level glue for the nsIObserver API
233250
var channel = subject;
@@ -240,7 +257,8 @@ HTTPSEverywhere.prototype = {
240257
this.log(DBUG, "Avoiding blacklisted " + channel.URI.spec);
241258
return;
242259
}
243-
HTTPS.replaceChannel(channel);
260+
var lst = this.getApplicableListForChannel(channel);
261+
HTTPS.replaceChannel(lst, channel);
244262
} else if (topic == "http-on-examine-response") {
245263
this.log(DBUG, "Got http-on-examine-response ");
246264
HTTPS.handleSecureCookies(channel);
@@ -297,8 +315,8 @@ HTTPSEverywhere.prototype = {
297315
return;
298316
}
299317

300-
HTTPS.replaceChannel(newChannel);
301-
318+
var lst = this.getApplicableListForChannel(channel);
319+
HTTPS.replaceChannel(lst,newChannel);
302320
},
303321

304322
asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) {

0 commit comments

Comments
 (0)