|
1 # This Source Code Form is subject to the terms of the Mozilla Public |
|
2 # License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
|
4 |
|
5 // XXX: This should all be moved into the dbservice class so it happens |
|
6 // in the background thread. |
|
7 |
|
8 /** |
|
9 * Abstract base class for a lookup table. |
|
10 * @construction |
|
11 */ |
|
12 function UrlClassifierTable() { |
|
13 this.debugZone = "urlclassifier-table"; |
|
14 this.name = ''; |
|
15 this.needsUpdate = false; |
|
16 this.enchashDecrypter_ = new PROT_EnchashDecrypter(); |
|
17 this.wrappedJSObject = this; |
|
18 } |
|
19 |
|
20 UrlClassifierTable.prototype.QueryInterface = function(iid) { |
|
21 if (iid.equals(Components.interfaces.nsISupports) || |
|
22 iid.equals(Components.interfaces.nsIUrlClassifierTable)) |
|
23 return this; |
|
24 |
|
25 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
26 } |
|
27 |
|
28 /** |
|
29 * Subclasses need to implement this method. |
|
30 */ |
|
31 UrlClassifierTable.prototype.exists = function(url, callback) { |
|
32 throw Components.results.NS_ERROR_NOT_IMPLEMENTED; |
|
33 } |
|
34 |
|
35 ///////////////////////////////////////////////////////////////////// |
|
36 // Url table implementation |
|
37 function UrlClassifierTableUrl() { |
|
38 UrlClassifierTable.call(this); |
|
39 } |
|
40 UrlClassifierTableUrl.inherits(UrlClassifierTable); |
|
41 |
|
42 /** |
|
43 * Look up a URL in a URL table |
|
44 */ |
|
45 UrlClassifierTableUrl.prototype.exists = function(url, callback) { |
|
46 // nsIUrlClassifierUtils.canonicalizeURL is the old way of canonicalizing a |
|
47 // URL. Unfortunately, it doesn't normalize numeric domains so alternate IP |
|
48 // formats (hex, octal, etc) won't trigger a match. |
|
49 // this.enchashDecrypter_.getCanonicalUrl does the right thing and |
|
50 // normalizes a URL to 4 decimal numbers, but the update server may still be |
|
51 // giving us encoded IP addresses. So to be safe, we check both cases. |
|
52 var urlUtils = Cc["@mozilla.org/url-classifier/utils;1"] |
|
53 .getService(Ci.nsIUrlClassifierUtils); |
|
54 var oldCanonicalized = urlUtils.canonicalizeURL(url); |
|
55 var canonicalized = this.enchashDecrypter_.getCanonicalUrl(url); |
|
56 G_Debug(this, "Looking up: " + url + " (" + oldCanonicalized + " and " + |
|
57 canonicalized + ")"); |
|
58 (new ExistsMultiQuerier([oldCanonicalized, canonicalized], |
|
59 this.name, |
|
60 callback)).run(); |
|
61 } |
|
62 |
|
63 ///////////////////////////////////////////////////////////////////// |
|
64 // Domain table implementation |
|
65 |
|
66 function UrlClassifierTableDomain() { |
|
67 UrlClassifierTable.call(this); |
|
68 this.debugZone = "urlclassifier-table-domain"; |
|
69 this.ioService_ = Cc["@mozilla.org/network/io-service;1"] |
|
70 .getService(Ci.nsIIOService); |
|
71 } |
|
72 UrlClassifierTableDomain.inherits(UrlClassifierTable); |
|
73 |
|
74 /** |
|
75 * Look up a URL in a domain table |
|
76 * We also try to lookup domain + first path component (e.g., |
|
77 * www.mozilla.org/products). |
|
78 * |
|
79 * @returns Boolean true if the url domain is in the table |
|
80 */ |
|
81 UrlClassifierTableDomain.prototype.exists = function(url, callback) { |
|
82 var canonicalized = this.enchashDecrypter_.getCanonicalUrl(url); |
|
83 var urlObj = this.ioService_.newURI(canonicalized, null, null); |
|
84 var host = ''; |
|
85 try { |
|
86 host = urlObj.host; |
|
87 } catch (e) { } |
|
88 var hostComponents = host.split("."); |
|
89 |
|
90 // Try to get the path of the URL. Pseudo urls (like wyciwyg:) throw |
|
91 // errors when trying to convert to an nsIURL so we wrap in a try/catch |
|
92 // block. |
|
93 var path = "" |
|
94 try { |
|
95 urlObj.QueryInterface(Ci.nsIURL); |
|
96 path = urlObj.filePath; |
|
97 } catch (e) { } |
|
98 |
|
99 var pathComponents = path.split("/"); |
|
100 |
|
101 // We don't have a good way map from hosts to domains, so we instead try |
|
102 // each possibility. Could probably optimize to start at the second dot? |
|
103 var possible = []; |
|
104 for (var i = 0; i < hostComponents.length - 1; i++) { |
|
105 host = hostComponents.slice(i).join("."); |
|
106 possible.push(host); |
|
107 |
|
108 // The path starts with a "/", so we are interested in the second path |
|
109 // component if it is available |
|
110 if (pathComponents.length >= 2 && pathComponents[1].length > 0) { |
|
111 host = host + "/" + pathComponents[1]; |
|
112 possible.push(host); |
|
113 } |
|
114 } |
|
115 |
|
116 // Run the possible domains against the db. |
|
117 (new ExistsMultiQuerier(possible, this.name, callback)).run(); |
|
118 } |
|
119 |
|
120 ///////////////////////////////////////////////////////////////////// |
|
121 // Enchash table implementation |
|
122 |
|
123 function UrlClassifierTableEnchash() { |
|
124 UrlClassifierTable.call(this); |
|
125 this.debugZone = "urlclassifier-table-enchash"; |
|
126 } |
|
127 UrlClassifierTableEnchash.inherits(UrlClassifierTable); |
|
128 |
|
129 /** |
|
130 * Look up a URL in an enchashDB. We try all sub domains (up to MAX_DOTS). |
|
131 */ |
|
132 UrlClassifierTableEnchash.prototype.exists = function(url, callback) { |
|
133 url = this.enchashDecrypter_.getCanonicalUrl(url); |
|
134 var host = this.enchashDecrypter_.getCanonicalHost(url, |
|
135 PROT_EnchashDecrypter.MAX_DOTS); |
|
136 |
|
137 var possible = []; |
|
138 for (var i = 0; i < PROT_EnchashDecrypter.MAX_DOTS + 1; i++) { |
|
139 possible.push(host); |
|
140 |
|
141 var index = host.indexOf("."); |
|
142 if (index == -1) |
|
143 break; |
|
144 host = host.substring(index + 1); |
|
145 } |
|
146 // Run the possible domains against the db. |
|
147 (new EnchashMultiQuerier(possible, this.name, callback, url)).run(); |
|
148 } |