forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			307 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			307 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const ANNOTATION_TABLE_NAME = "mochitest1-track-simple";
 | 
						|
const ANNOTATION_TABLE_PREF = "urlclassifier.trackingAnnotationTable";
 | 
						|
const ANNOTATION_ENTITYLIST_TABLE_NAME = "mochitest1-trackwhite-simple";
 | 
						|
const ANNOTATION_ENTITYLIST_TABLE_PREF =
 | 
						|
  "urlclassifier.trackingAnnotationWhitelistTable";
 | 
						|
 | 
						|
const TRACKING_TABLE_NAME = "mochitest2-track-simple";
 | 
						|
const TRACKING_TABLE_PREF = "urlclassifier.trackingTable";
 | 
						|
const ENTITYLIST_TABLE_NAME = "mochitest2-trackwhite-simple";
 | 
						|
const ENTITYLIST_TABLE_PREF = "urlclassifier.trackingWhitelistTable";
 | 
						|
 | 
						|
const SOCIAL_ANNOTATION_TABLE_NAME = "mochitest3-track-simple";
 | 
						|
const SOCIAL_ANNOTATION_TABLE_PREF =
 | 
						|
  "urlclassifier.features.socialtracking.annotate.blacklistTables";
 | 
						|
const SOCIAL_TRACKING_TABLE_NAME = "mochitest4-track-simple";
 | 
						|
const SOCIAL_TRACKING_TABLE_PREF =
 | 
						|
  "urlclassifier.features.socialtracking.blacklistTables";
 | 
						|
const EMAIL_TRACKING_TABLE_NAME = "mochitest5-track-simple";
 | 
						|
const EMAIL_TRACKING_TABLE_PREF =
 | 
						|
  "urlclassifier.features.emailtracking.blocklistTables";
 | 
						|
 | 
						|
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 | 
						|
 | 
						|
export var UrlClassifierTestUtils = {
 | 
						|
  addTestTrackers() {
 | 
						|
    // Add some URLs to the tracking databases
 | 
						|
    let annotationURL1 = "tracking.example.org/"; // only for annotations
 | 
						|
    let annotationURL2 = "itisatracker.org/";
 | 
						|
    let annotationURL3 = "trackertest.org/";
 | 
						|
    let annotationURL4 = "another-tracking.example.net/";
 | 
						|
    let annotationURL5 = "tlsresumptiontest.example.org/";
 | 
						|
    let annotationEntitylistedURL = "itisatrap.org/?resource=example.org";
 | 
						|
    let trackingURL1 = "tracking.example.com/"; // only for TP
 | 
						|
    let trackingURL2 = "itisatracker.org/";
 | 
						|
    let trackingURL3 = "trackertest.org/";
 | 
						|
    let entitylistedURL = "itisatrap.org/?resource=itisatracker.org";
 | 
						|
    let socialTrackingURL = "social-tracking.example.org/";
 | 
						|
    let emailTrackingURL = "email-tracking.example.org/";
 | 
						|
 | 
						|
    let annotationUpdate =
 | 
						|
      "n:1000\ni:" +
 | 
						|
      ANNOTATION_TABLE_NAME +
 | 
						|
      "\nad:5\n" +
 | 
						|
      "a:1:32:" +
 | 
						|
      annotationURL1.length +
 | 
						|
      "\n" +
 | 
						|
      annotationURL1 +
 | 
						|
      "\n" +
 | 
						|
      "a:2:32:" +
 | 
						|
      annotationURL2.length +
 | 
						|
      "\n" +
 | 
						|
      annotationURL2 +
 | 
						|
      "\n" +
 | 
						|
      "a:3:32:" +
 | 
						|
      annotationURL3.length +
 | 
						|
      "\n" +
 | 
						|
      annotationURL3 +
 | 
						|
      "\n" +
 | 
						|
      "a:4:32:" +
 | 
						|
      annotationURL4.length +
 | 
						|
      "\n" +
 | 
						|
      annotationURL4 +
 | 
						|
      "\n" +
 | 
						|
      "a:5:32:" +
 | 
						|
      annotationURL5.length +
 | 
						|
      "\n" +
 | 
						|
      annotationURL5 +
 | 
						|
      "\n";
 | 
						|
    let socialAnnotationUpdate =
 | 
						|
      "n:1000\ni:" +
 | 
						|
      SOCIAL_ANNOTATION_TABLE_NAME +
 | 
						|
      "\nad:1\n" +
 | 
						|
      "a:1:32:" +
 | 
						|
      socialTrackingURL.length +
 | 
						|
      "\n" +
 | 
						|
      socialTrackingURL +
 | 
						|
      "\n";
 | 
						|
    let annotationEntitylistUpdate =
 | 
						|
      "n:1000\ni:" +
 | 
						|
      ANNOTATION_ENTITYLIST_TABLE_NAME +
 | 
						|
      "\nad:1\n" +
 | 
						|
      "a:1:32:" +
 | 
						|
      annotationEntitylistedURL.length +
 | 
						|
      "\n" +
 | 
						|
      annotationEntitylistedURL +
 | 
						|
      "\n";
 | 
						|
    let trackingUpdate =
 | 
						|
      "n:1000\ni:" +
 | 
						|
      TRACKING_TABLE_NAME +
 | 
						|
      "\nad:3\n" +
 | 
						|
      "a:1:32:" +
 | 
						|
      trackingURL1.length +
 | 
						|
      "\n" +
 | 
						|
      trackingURL1 +
 | 
						|
      "\n" +
 | 
						|
      "a:2:32:" +
 | 
						|
      trackingURL2.length +
 | 
						|
      "\n" +
 | 
						|
      trackingURL2 +
 | 
						|
      "\n" +
 | 
						|
      "a:3:32:" +
 | 
						|
      trackingURL3.length +
 | 
						|
      "\n" +
 | 
						|
      trackingURL3 +
 | 
						|
      "\n";
 | 
						|
    let socialTrackingUpdate =
 | 
						|
      "n:1000\ni:" +
 | 
						|
      SOCIAL_TRACKING_TABLE_NAME +
 | 
						|
      "\nad:1\n" +
 | 
						|
      "a:1:32:" +
 | 
						|
      socialTrackingURL.length +
 | 
						|
      "\n" +
 | 
						|
      socialTrackingURL +
 | 
						|
      "\n";
 | 
						|
    let emailTrackingUpdate =
 | 
						|
      "n:1000\ni:" +
 | 
						|
      EMAIL_TRACKING_TABLE_NAME +
 | 
						|
      "\nad:1\n" +
 | 
						|
      "a:1:32:" +
 | 
						|
      emailTrackingURL.length +
 | 
						|
      "\n" +
 | 
						|
      emailTrackingURL +
 | 
						|
      "\n";
 | 
						|
    let entitylistUpdate =
 | 
						|
      "n:1000\ni:" +
 | 
						|
      ENTITYLIST_TABLE_NAME +
 | 
						|
      "\nad:1\n" +
 | 
						|
      "a:1:32:" +
 | 
						|
      entitylistedURL.length +
 | 
						|
      "\n" +
 | 
						|
      entitylistedURL +
 | 
						|
      "\n";
 | 
						|
 | 
						|
    var tables = [
 | 
						|
      {
 | 
						|
        pref: ANNOTATION_TABLE_PREF,
 | 
						|
        name: ANNOTATION_TABLE_NAME,
 | 
						|
        update: annotationUpdate,
 | 
						|
      },
 | 
						|
      {
 | 
						|
        pref: SOCIAL_ANNOTATION_TABLE_PREF,
 | 
						|
        name: SOCIAL_ANNOTATION_TABLE_NAME,
 | 
						|
        update: socialAnnotationUpdate,
 | 
						|
      },
 | 
						|
      {
 | 
						|
        pref: ANNOTATION_ENTITYLIST_TABLE_PREF,
 | 
						|
        name: ANNOTATION_ENTITYLIST_TABLE_NAME,
 | 
						|
        update: annotationEntitylistUpdate,
 | 
						|
      },
 | 
						|
      {
 | 
						|
        pref: TRACKING_TABLE_PREF,
 | 
						|
        name: TRACKING_TABLE_NAME,
 | 
						|
        update: trackingUpdate,
 | 
						|
      },
 | 
						|
      {
 | 
						|
        pref: SOCIAL_TRACKING_TABLE_PREF,
 | 
						|
        name: SOCIAL_TRACKING_TABLE_NAME,
 | 
						|
        update: socialTrackingUpdate,
 | 
						|
      },
 | 
						|
      {
 | 
						|
        pref: EMAIL_TRACKING_TABLE_PREF,
 | 
						|
        name: EMAIL_TRACKING_TABLE_NAME,
 | 
						|
        update: emailTrackingUpdate,
 | 
						|
      },
 | 
						|
      {
 | 
						|
        pref: ENTITYLIST_TABLE_PREF,
 | 
						|
        name: ENTITYLIST_TABLE_NAME,
 | 
						|
        update: entitylistUpdate,
 | 
						|
      },
 | 
						|
    ];
 | 
						|
 | 
						|
    let tableIndex = 0;
 | 
						|
    let doOneUpdate = () => {
 | 
						|
      if (tableIndex == tables.length) {
 | 
						|
        return Promise.resolve();
 | 
						|
      }
 | 
						|
      return this.useTestDatabase(tables[tableIndex]).then(
 | 
						|
        () => {
 | 
						|
          tableIndex++;
 | 
						|
          return doOneUpdate();
 | 
						|
        },
 | 
						|
        aErrMsg => {
 | 
						|
          dump("Rejected: " + aErrMsg + ". Retry later.\n");
 | 
						|
          return new Promise(resolve => {
 | 
						|
            timer.initWithCallback(resolve, 100, Ci.nsITimer.TYPE_ONE_SHOT);
 | 
						|
          }).then(doOneUpdate);
 | 
						|
        }
 | 
						|
      );
 | 
						|
    };
 | 
						|
 | 
						|
    return doOneUpdate();
 | 
						|
  },
 | 
						|
 | 
						|
  cleanupTestTrackers() {
 | 
						|
    Services.prefs.clearUserPref(ANNOTATION_TABLE_PREF);
 | 
						|
    Services.prefs.clearUserPref(SOCIAL_ANNOTATION_TABLE_PREF);
 | 
						|
    Services.prefs.clearUserPref(ANNOTATION_ENTITYLIST_TABLE_PREF);
 | 
						|
    Services.prefs.clearUserPref(TRACKING_TABLE_PREF);
 | 
						|
    Services.prefs.clearUserPref(SOCIAL_TRACKING_TABLE_PREF);
 | 
						|
    Services.prefs.clearUserPref(EMAIL_TRACKING_TABLE_PREF);
 | 
						|
    Services.prefs.clearUserPref(ENTITYLIST_TABLE_PREF);
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Add some entries to a test tracking protection database, and resets
 | 
						|
   * back to the default database after the test ends.
 | 
						|
   *
 | 
						|
   * @return {Promise}
 | 
						|
   */
 | 
						|
  useTestDatabase(table) {
 | 
						|
    Services.prefs.setCharPref(table.pref, table.name);
 | 
						|
 | 
						|
    return new Promise((resolve, reject) => {
 | 
						|
      let dbService = Cc["@mozilla.org/url-classifier/dbservice;1"].getService(
 | 
						|
        Ci.nsIUrlClassifierDBService
 | 
						|
      );
 | 
						|
      let listener = {
 | 
						|
        QueryInterface: iid => {
 | 
						|
          if (
 | 
						|
            iid.equals(Ci.nsISupports) ||
 | 
						|
            iid.equals(Ci.nsIUrlClassifierUpdateObserver)
 | 
						|
          ) {
 | 
						|
            return listener;
 | 
						|
          }
 | 
						|
 | 
						|
          throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
 | 
						|
        },
 | 
						|
        updateUrlRequested: url => {},
 | 
						|
        streamFinished: status => {},
 | 
						|
        updateError: errorCode => {
 | 
						|
          reject("Got updateError when updating " + table.name);
 | 
						|
        },
 | 
						|
        updateSuccess: requestedTimeout => {
 | 
						|
          resolve();
 | 
						|
        },
 | 
						|
      };
 | 
						|
 | 
						|
      try {
 | 
						|
        dbService.beginUpdate(listener, table.name, "");
 | 
						|
        dbService.beginStream("", "");
 | 
						|
        dbService.updateStream(table.update);
 | 
						|
        dbService.finishStream();
 | 
						|
        dbService.finishUpdate();
 | 
						|
      } catch (e) {
 | 
						|
        reject("Failed to update with dbService: " + table.name);
 | 
						|
      }
 | 
						|
    });
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Handle the next "urlclassifier-before-block-channel" event.
 | 
						|
   * @param {Object} options
 | 
						|
   * @param {String} [options.filterOrigin] - Only handle event for channels
 | 
						|
   * with matching origin.
 | 
						|
   * @param {function} [options.onBeforeBlockChannel] - Optional callback for
 | 
						|
   * the event. Called before acting on the channel.
 | 
						|
   * @param {("allow"|"replace")} [options.action] - Whether to allow or replace
 | 
						|
   * the channel.
 | 
						|
   * @returns {Promise} - Resolves once event has been handled.
 | 
						|
   */
 | 
						|
  handleBeforeBlockChannel({
 | 
						|
    filterOrigin = null,
 | 
						|
    onBeforeBlockChannel,
 | 
						|
    action,
 | 
						|
  }) {
 | 
						|
    if (action && action != "allow" && action != "replace") {
 | 
						|
      throw new Error("Invalid action " + action);
 | 
						|
    }
 | 
						|
    let channelClassifierService = Cc[
 | 
						|
      "@mozilla.org/url-classifier/channel-classifier-service;1"
 | 
						|
    ].getService(Ci.nsIChannelClassifierService);
 | 
						|
 | 
						|
    let resolver;
 | 
						|
    let promise = new Promise(resolve => {
 | 
						|
      resolver = resolve;
 | 
						|
    });
 | 
						|
 | 
						|
    let observer = {
 | 
						|
      observe(subject, topic) {
 | 
						|
        if (topic != "urlclassifier-before-block-channel") {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
        let channel = subject.QueryInterface(Ci.nsIUrlClassifierBlockedChannel);
 | 
						|
 | 
						|
        if (filterOrigin) {
 | 
						|
          let { url } = channel;
 | 
						|
          let { origin } = new URL(url);
 | 
						|
          if (filterOrigin != origin) {
 | 
						|
            return;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        if (onBeforeBlockChannel) {
 | 
						|
          onBeforeBlockChannel(channel);
 | 
						|
        }
 | 
						|
        if (action) {
 | 
						|
          channel[action]();
 | 
						|
        }
 | 
						|
 | 
						|
        channelClassifierService.removeListener(observer);
 | 
						|
        resolver();
 | 
						|
      },
 | 
						|
    };
 | 
						|
    channelClassifierService.addListener(observer);
 | 
						|
    return promise;
 | 
						|
  },
 | 
						|
};
 |