test_trackingProtection_annotateChannels.js (12078B)
1 "use strict"; 2 3 const { UrlClassifierTestUtils } = ChromeUtils.importESModule( 4 "resource://testing-common/UrlClassifierTestUtils.sys.mjs" 5 ); 6 const { HttpServer } = ChromeUtils.importESModule( 7 "resource://testing-common/httpd.sys.mjs" 8 ); 9 10 // This test supports both e10s and non-e10s mode. In non-e10s mode, this test 11 // drives itself by creating a profile directory, setting up the URL classifier 12 // test tables and adjusting the prefs which are necessary to do the testing. 13 // In e10s mode however, some of these operations such as creating a profile 14 // directory, setting up the URL classifier test tables and setting prefs 15 // aren't supported in the content process, so we split the test into two 16 // parts, the part testing the normal priority case by setting both prefs to 17 // false (test_trackingProtection_annotateChannels_wrap1.js), and the part 18 // testing the lowest priority case by setting both prefs to true 19 // (test_trackingProtection_annotateChannels_wrap2.js). These wrapper scripts 20 // are also in charge of creating the profile directory and setting up the URL 21 // classifier test tables. 22 // 23 // Below where we need to take different actions based on the process type we're 24 // in, we use runtime.processType to take the correct actions. 25 26 const runtime = Services.appinfo; 27 if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) { 28 do_get_profile(); 29 } 30 31 const defaultTopWindowURI = NetUtil.newURI("http://www.example.com/"); 32 33 function listener(tracking, priority, throttleable, nextTest) { 34 this._tracking = tracking; 35 this._priority = priority; 36 this._throttleable = throttleable; 37 this._nextTest = nextTest; 38 } 39 listener.prototype = { 40 onStartRequest(request) { 41 Assert.equal( 42 request 43 .QueryInterface(Ci.nsIClassifiedChannel) 44 .isThirdPartyTrackingResource(), 45 this._tracking, 46 "tracking flag" 47 ); 48 Assert.equal( 49 request.QueryInterface(Ci.nsISupportsPriority).priority, 50 this._priority, 51 "channel priority" 52 ); 53 if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT && this._tracking) { 54 Assert.equal( 55 !!( 56 request.QueryInterface(Ci.nsIClassOfService).classFlags & 57 Ci.nsIClassOfService.Throttleable 58 ), 59 this._throttleable, 60 "throttleable flag" 61 ); 62 } 63 request.cancel(Cr.NS_ERROR_ABORT); 64 this._nextTest(); 65 }, 66 onDataAvailable: () => {}, 67 onStopRequest: () => {}, 68 }; 69 70 var httpServer; 71 var normalOrigin, trackingOrigin; 72 var testPriorityMap; 73 var currentTest; 74 // When this test is running in e10s mode, the parent process is in charge of 75 // setting the prefs for us, so here we merely read our prefs, and if they have 76 // been set we skip the normal priority test and only test the lowest priority 77 // case, and if it they have not been set we skip the lowest priority test and 78 // only test the normal priority case. 79 // In non-e10s mode, both of these will remain false and we adjust the prefs 80 // ourselves and test both of the cases in one go. 81 var skipNormalPriority = false, 82 skipLowestPriority = false; 83 84 function setup_test() { 85 httpServer = new HttpServer(); 86 httpServer.start(-1); 87 httpServer.identity.setPrimary( 88 "http", 89 "tracking.example.org", 90 httpServer.identity.primaryPort 91 ); 92 httpServer.identity.add( 93 "http", 94 "example.org", 95 httpServer.identity.primaryPort 96 ); 97 normalOrigin = "http://localhost:" + httpServer.identity.primaryPort; 98 trackingOrigin = 99 "http://tracking.example.org:" + httpServer.identity.primaryPort; 100 101 if (runtime.processType == runtime.PROCESS_TYPE_CONTENT) { 102 if ( 103 Services.prefs.getBoolPref( 104 "privacy.trackingprotection.annotate_channels" 105 ) && 106 Services.prefs.getBoolPref( 107 "privacy.trackingprotection.lower_network_priority" 108 ) 109 ) { 110 skipNormalPriority = true; 111 } else { 112 skipLowestPriority = true; 113 } 114 } 115 116 runTests(); 117 } 118 119 function doPriorityTest() { 120 if (!testPriorityMap.length) { 121 runTests(); 122 return; 123 } 124 125 currentTest = testPriorityMap.shift(); 126 127 // Let's be explicit about what we're testing! 128 Assert.ok( 129 "loadingPrincipal" in currentTest, 130 "check for incomplete test case" 131 ); 132 Assert.ok("topWindowURI" in currentTest, "check for incomplete test case"); 133 134 var channel = makeChannel( 135 currentTest.path, 136 currentTest.loadingPrincipal, 137 currentTest.topWindowURI 138 ); 139 channel.asyncOpen( 140 new listener( 141 currentTest.expectedTracking, 142 currentTest.expectedPriority, 143 currentTest.expectedThrottleable, 144 doPriorityTest 145 ) 146 ); 147 } 148 149 function makeChannel(path, loadingPrincipal, topWindowURI) { 150 var chan; 151 152 if (loadingPrincipal) { 153 chan = NetUtil.newChannel({ 154 uri: path, 155 loadingPrincipal, 156 securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, 157 contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER, 158 }); 159 } else { 160 chan = NetUtil.newChannel({ 161 uri: path, 162 loadUsingSystemPrincipal: true, 163 }); 164 } 165 chan.QueryInterface(Ci.nsIHttpChannel); 166 chan.requestMethod = "GET"; 167 if (topWindowURI) { 168 chan 169 .QueryInterface(Ci.nsIHttpChannelInternal) 170 .setTopWindowURIIfUnknown(topWindowURI); 171 } 172 return chan; 173 } 174 175 var tests = [ 176 // Create the HTTP server. 177 setup_test, 178 179 // Add the test table into tracking protection table. 180 function addTestTrackers() { 181 if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) { 182 UrlClassifierTestUtils.addTestTrackers().then(() => { 183 runTests(); 184 }); 185 } else { 186 runTests(); 187 } 188 }, 189 190 // Annotations OFF, normal loading principal, topWinURI of example.com 191 // => trackers should not be de-prioritized 192 function setupAnnotationsOff() { 193 if (skipNormalPriority) { 194 runTests(); 195 return; 196 } 197 if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) { 198 Services.prefs.setBoolPref( 199 "privacy.trackingprotection.annotate_channels", 200 false 201 ); 202 Services.prefs.setBoolPref( 203 "privacy.trackingprotection.lower_network_priority", 204 false 205 ); 206 } 207 var principal = 208 Services.scriptSecurityManager.createContentPrincipalFromOrigin( 209 normalOrigin 210 ); 211 testPriorityMap = [ 212 { 213 path: normalOrigin + "/innocent.css", 214 loadingPrincipal: principal, 215 topWindowURI: defaultTopWindowURI, 216 expectedTracking: false, 217 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 218 expectedThrottleable: false, // ignored since tracking==false 219 }, 220 { 221 path: normalOrigin + "/innocent.js", 222 loadingPrincipal: principal, 223 topWindowURI: defaultTopWindowURI, 224 expectedTracking: false, 225 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 226 expectedThrottleable: false, // ignored since tracking==false 227 }, 228 { 229 path: trackingOrigin + "/evil.css", 230 loadingPrincipal: principal, 231 topWindowURI: defaultTopWindowURI, 232 expectedTracking: false, 233 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 234 expectedThrottleable: false, // ignored since tracking==false 235 }, 236 { 237 path: trackingOrigin + "/evil.js", 238 loadingPrincipal: principal, 239 topWindowURI: defaultTopWindowURI, 240 expectedTracking: false, 241 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 242 expectedThrottleable: false, // ignored since tracking==false 243 }, 244 ]; 245 // We add the doPriorityTest test here so that it only gets injected in the 246 // test list if we're not skipping over this test. 247 tests.unshift(doPriorityTest); 248 runTests(); 249 }, 250 251 // Annotations ON, normal loading principal, topWinURI of example.com 252 // => trackers should be de-prioritized 253 function setupAnnotationsOn() { 254 if (skipLowestPriority) { 255 runTests(); 256 return; 257 } 258 if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) { 259 Services.prefs.setBoolPref( 260 "privacy.trackingprotection.annotate_channels", 261 true 262 ); 263 Services.prefs.setBoolPref( 264 "privacy.trackingprotection.lower_network_priority", 265 true 266 ); 267 } 268 var principal = 269 Services.scriptSecurityManager.createContentPrincipalFromOrigin( 270 normalOrigin 271 ); 272 testPriorityMap = [ 273 { 274 path: normalOrigin + "/innocent.css", 275 loadingPrincipal: principal, 276 topWindowURI: defaultTopWindowURI, 277 expectedTracking: false, 278 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 279 expectedThrottleable: false, // ignored since tracking==false 280 }, 281 { 282 path: normalOrigin + "/innocent.js", 283 loadingPrincipal: principal, 284 topWindowURI: defaultTopWindowURI, 285 expectedTracking: false, 286 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 287 expectedThrottleable: false, // ignored since tracking==false 288 }, 289 { 290 path: trackingOrigin + "/evil.css", 291 loadingPrincipal: principal, 292 topWindowURI: defaultTopWindowURI, 293 expectedTracking: true, 294 expectedPriority: Ci.nsISupportsPriority.PRIORITY_LOWEST, 295 expectedThrottleable: true, 296 }, 297 { 298 path: trackingOrigin + "/evil.js", 299 loadingPrincipal: principal, 300 topWindowURI: defaultTopWindowURI, 301 expectedTracking: true, 302 expectedPriority: Ci.nsISupportsPriority.PRIORITY_LOWEST, 303 expectedThrottleable: true, 304 }, 305 ]; 306 // We add the doPriorityTest test here so that it only gets injected in the 307 // test list if we're not skipping over this test. 308 tests.unshift(doPriorityTest); 309 runTests(); 310 }, 311 312 // Annotations ON, system loading principal, topWinURI of example.com 313 // => trackers should not be de-prioritized 314 function setupAnnotationsOnSystemPrincipal() { 315 if (skipLowestPriority) { 316 runTests(); 317 return; 318 } 319 if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) { 320 Services.prefs.setBoolPref( 321 "privacy.trackingprotection.annotate_channels", 322 true 323 ); 324 Services.prefs.setBoolPref( 325 "privacy.trackingprotection.lower_network_priority", 326 true 327 ); 328 } 329 testPriorityMap = [ 330 { 331 path: normalOrigin + "/innocent.css", 332 loadingPrincipal: null, // system principal 333 topWindowURI: defaultTopWindowURI, 334 expectedTracking: false, 335 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 336 expectedThrottleable: false, // ignored since tracking==false 337 }, 338 { 339 path: normalOrigin + "/innocent.js", 340 loadingPrincipal: null, // system principal 341 topWindowURI: defaultTopWindowURI, 342 expectedTracking: false, 343 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 344 expectedThrottleable: false, // ignored since tracking==false 345 }, 346 { 347 path: trackingOrigin + "/evil.css", 348 loadingPrincipal: null, // system principal 349 topWindowURI: defaultTopWindowURI, 350 expectedTracking: false, 351 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 352 expectedThrottleable: false, 353 }, 354 { 355 path: trackingOrigin + "/evil.js", 356 loadingPrincipal: null, // system principal 357 topWindowURI: defaultTopWindowURI, 358 expectedTracking: false, 359 expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL, 360 expectedThrottleable: true, 361 }, 362 ]; 363 // We add the doPriorityTest test here so that it only gets injected in the 364 // test list if we're not skipping over this test. 365 tests.unshift(doPriorityTest); 366 runTests(); 367 }, 368 369 function cleanUp() { 370 httpServer.stop(do_test_finished); 371 if (runtime.processType == runtime.PROCESS_TYPE_DEFAULT) { 372 UrlClassifierTestUtils.cleanupTestTrackers(); 373 } 374 runTests(); 375 }, 376 ]; 377 378 function runTests() { 379 if (!tests.length) { 380 do_test_finished(); 381 return; 382 } 383 384 var test = tests.shift(); 385 test(); 386 } 387 388 function run_test() { 389 runTests(); 390 do_test_pending(); 391 }