netwerk/test/unit/test_event_sink.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/test/unit/test_event_sink.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,174 @@
     1.4 +// This file tests channel event sinks (bug 315598 et al)
     1.5 +
     1.6 +Cu.import("resource://testing-common/httpd.js");
     1.7 +
     1.8 +XPCOMUtils.defineLazyGetter(this, "URL", function() {
     1.9 +  return "http://localhost:" + httpserv.identity.primaryPort;
    1.10 +});
    1.11 +
    1.12 +const sinkCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
    1.13 +const sinkContract = "@mozilla.org/network/unittest/channeleventsink;1";
    1.14 +
    1.15 +const categoryName = "net-channel-event-sinks";
    1.16 +
    1.17 +/**
    1.18 + * This object is both a factory and an nsIChannelEventSink implementation (so, it
    1.19 + * is de-facto a service). It's also an interface requestor that gives out
    1.20 + * itself when asked for nsIChannelEventSink.
    1.21 + */
    1.22 +var eventsink = {
    1.23 +  QueryInterface: function eventsink_qi(iid) {
    1.24 +    if (iid.equals(Components.interfaces.nsISupports) ||
    1.25 +        iid.equals(Components.interfaces.nsIFactory) ||
    1.26 +        iid.equals(Components.interfaces.nsIChannelEventSink))
    1.27 +      return this;
    1.28 +    throw Components.results.NS_ERROR_NO_INTERFACE;
    1.29 +  },
    1.30 +  createInstance: function eventsink_ci(outer, iid) {
    1.31 +    if (outer)
    1.32 +      throw Components.results.NS_ERROR_NO_AGGREGATION;
    1.33 +    return this.QueryInterface(iid);
    1.34 +  },
    1.35 +  lockFactory: function eventsink_lockf(lock) {
    1.36 +    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
    1.37 +  },
    1.38 +
    1.39 +  asyncOnChannelRedirect: function eventsink_onredir(oldChan, newChan, flags, callback) {
    1.40 +    // veto
    1.41 +    this.called = true;
    1.42 +    throw Components.results.NS_BINDING_ABORTED;
    1.43 +  },
    1.44 +
    1.45 +  getInterface: function eventsink_gi(iid) {
    1.46 +    if (iid.equals(Components.interfaces.nsIChannelEventSink))
    1.47 +      return this;
    1.48 +    throw Components.results.NS_ERROR_NO_INTERFACE;
    1.49 +  },
    1.50 +
    1.51 +  called: false
    1.52 +};
    1.53 +
    1.54 +var listener = {
    1.55 +  expectSinkCall: true,
    1.56 +
    1.57 +  onStartRequest: function test_onStartR(request, ctx) {
    1.58 +    try {
    1.59 +      // Commenting out this check pending resolution of bug 255119
    1.60 +      //if (Components.isSuccessCode(request.status))
    1.61 +      //  do_throw("Channel should have a failure code!");
    1.62 +
    1.63 +      // The current URI must be the original URI, as all redirects have been
    1.64 +      // cancelled
    1.65 +      if (!(request instanceof Components.interfaces.nsIChannel) ||
    1.66 +          !request.URI.equals(request.originalURI))
    1.67 +        do_throw("Wrong URI: Is <" + request.URI.spec + ">, should be <" +
    1.68 +                 request.originalURI.spec + ">");
    1.69 +
    1.70 +      if (request instanceof Components.interfaces.nsIHttpChannel) {
    1.71 +        // As we expect a blocked redirect, verify that we have a 3xx status
    1.72 +        do_check_eq(Math.floor(request.responseStatus / 100), 3);
    1.73 +        do_check_eq(request.requestSucceeded, false);
    1.74 +      }
    1.75 +
    1.76 +      do_check_eq(eventsink.called, this.expectSinkCall);
    1.77 +    } catch (e) {
    1.78 +      do_throw("Unexpected exception: " + e);
    1.79 +    }
    1.80 +
    1.81 +    throw Components.results.NS_ERROR_ABORT;
    1.82 +  },
    1.83 +
    1.84 +  onDataAvailable: function test_ODA() {
    1.85 +    do_throw("Should not get any data!");
    1.86 +  },
    1.87 +
    1.88 +  onStopRequest: function test_onStopR(request, ctx, status) {
    1.89 +    if (this._iteration <= 2) {
    1.90 +      run_test_continued();
    1.91 +    } else {
    1.92 +      do_test_pending();
    1.93 +      httpserv.stop(do_test_finished);
    1.94 +    }
    1.95 +    do_test_finished();
    1.96 +  },
    1.97 +
    1.98 +  _iteration: 1
    1.99 +};
   1.100 +
   1.101 +function makeChan(url) {
   1.102 +  var ios = Components.classes["@mozilla.org/network/io-service;1"]
   1.103 +                      .getService(Components.interfaces.nsIIOService);
   1.104 +  var chan = ios.newChannel(url, null, null)
   1.105 +                .QueryInterface(Components.interfaces.nsIHttpChannel);
   1.106 +
   1.107 +  return chan;
   1.108 +}
   1.109 +
   1.110 +var httpserv = null;
   1.111 +
   1.112 +function run_test() {
   1.113 +  httpserv = new HttpServer();
   1.114 +  httpserv.registerPathHandler("/redirect", redirect);
   1.115 +  httpserv.registerPathHandler("/redirectfile", redirectfile);
   1.116 +  httpserv.start(-1);
   1.117 +
   1.118 +  Components.manager.nsIComponentRegistrar.registerFactory(sinkCID,
   1.119 +    "Unit test Event sink", sinkContract, eventsink);
   1.120 +
   1.121 +  // Step 1: Set the callbacks on the listener itself
   1.122 +  var chan = makeChan(URL + "/redirect");
   1.123 +  chan.notificationCallbacks = eventsink;
   1.124 +
   1.125 +  chan.asyncOpen(listener, null);
   1.126 +
   1.127 +  do_test_pending();
   1.128 +}
   1.129 +
   1.130 +function run_test_continued() {
   1.131 +  eventsink.called = false;
   1.132 +
   1.133 +  var catMan = Components.classes["@mozilla.org/categorymanager;1"]
   1.134 +                         .getService(Components.interfaces.nsICategoryManager);
   1.135 +
   1.136 +  var chan;
   1.137 +  if (listener._iteration == 1) {
   1.138 +    // Step 2: Category entry
   1.139 +    catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
   1.140 +                                               sinkContract, false, true);
   1.141 +    chan = makeChan(URL + "/redirect")
   1.142 +  } else {
   1.143 +    // Step 3: Global contract id
   1.144 +    catMan.nsICategoryManager.deleteCategoryEntry(categoryName, "unit test",
   1.145 +                                                  false);
   1.146 +    listener.expectSinkCall = false;
   1.147 +    chan = makeChan(URL + "/redirectfile");
   1.148 +  }
   1.149 +
   1.150 +  listener._iteration++;
   1.151 +  chan.asyncOpen(listener, null);
   1.152 +
   1.153 +  do_test_pending();
   1.154 +}
   1.155 +
   1.156 +// PATHS
   1.157 +
   1.158 +// /redirect
   1.159 +function redirect(metadata, response) {
   1.160 +  response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
   1.161 +  response.setHeader("Location",
   1.162 +                     "http://localhost:" + metadata.port + "/",
   1.163 +                     false);
   1.164 +
   1.165 +  var body = "Moved\n";
   1.166 +  response.bodyOutputStream.write(body, body.length);
   1.167 +}
   1.168 +
   1.169 +// /redirectfile
   1.170 +function redirectfile(metadata, response) {
   1.171 +  response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
   1.172 +  response.setHeader("Content-Type", "text/plain", false);
   1.173 +  response.setHeader("Location", "file:///etc/", false);
   1.174 +
   1.175 +  var body = "Attempted to move to a file URI, but failed.\n";
   1.176 +  response.bodyOutputStream.write(body, body.length);
   1.177 +}

mercurial