netwerk/test/unit/test_traceable_channel.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/test/unit/test_traceable_channel.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,153 @@
     1.4 +// Test nsITraceableChannel interface.
     1.5 +// Replace original listener with TracingListener that modifies body of HTTP
     1.6 +// response. Make sure that body received by original channel's listener
     1.7 +// is correctly modified.
     1.8 +
     1.9 +Cu.import("resource://testing-common/httpd.js");
    1.10 +
    1.11 +var httpserver = new HttpServer();
    1.12 +httpserver.start(-1);
    1.13 +const PORT = httpserver.identity.primaryPort;
    1.14 +
    1.15 +var pipe = null;
    1.16 +var streamSink = null;
    1.17 +
    1.18 +var originalBody = "original http response body";
    1.19 +var gotOnStartRequest = false;
    1.20 +
    1.21 +function TracingListener() {}
    1.22 +
    1.23 +TracingListener.prototype = {
    1.24 +  onStartRequest: function(request, context) {
    1.25 +    dump("*** tracing listener onStartRequest\n");
    1.26 +
    1.27 +    gotOnStartRequest = true;
    1.28 +
    1.29 +    request.QueryInterface(Components.interfaces.nsIHttpChannelInternal);
    1.30 +
    1.31 +// local/remote addresses broken in e10s: disable for now
    1.32 +/*
    1.33 +    do_check_eq(request.localAddress, "127.0.0.1");
    1.34 +    do_check_eq(request.localPort > 0, true);
    1.35 +    do_check_neq(request.localPort, PORT);
    1.36 +    do_check_eq(request.remoteAddress, "127.0.0.1");
    1.37 +    do_check_eq(request.remotePort, PORT);
    1.38 +*/
    1.39 +
    1.40 +    // Make sure listener can't be replaced after OnStartRequest was called.
    1.41 +    request.QueryInterface(Components.interfaces.nsITraceableChannel);
    1.42 +    try {
    1.43 +      var newListener = new TracingListener();
    1.44 +      newListener.listener = request.setNewListener(newListener);
    1.45 +    } catch(e) {
    1.46 +      dump("TracingListener.onStartRequest swallowing exception: " + e + "\n");
    1.47 +      return; // OK
    1.48 +    }
    1.49 +    do_throw("replaced channel's listener during onStartRequest.");
    1.50 +  },
    1.51 +
    1.52 +  onStopRequest: function(request, context, statusCode) {
    1.53 +    dump("*** tracing listener onStopRequest\n");
    1.54 +    
    1.55 +    do_check_eq(gotOnStartRequest, true);
    1.56 +
    1.57 +    try {
    1.58 +      var sin = Components.classes["@mozilla.org/scriptableinputstream;1"].
    1.59 +          createInstance(Ci.nsIScriptableInputStream);
    1.60 +
    1.61 +      streamSink.close();
    1.62 +      var input = pipe.inputStream;
    1.63 +      sin.init(input);
    1.64 +      do_check_eq(sin.available(), originalBody.length);
    1.65 +    
    1.66 +      var result = sin.read(originalBody.length);
    1.67 +      do_check_eq(result, originalBody);
    1.68 +    
    1.69 +      input.close();
    1.70 +    } catch (e) {
    1.71 +      dump("TracingListener.onStopRequest swallowing exception: " + e + "\n");
    1.72 +    } finally {
    1.73 +      httpserver.stop(do_test_finished);
    1.74 +    }
    1.75 +  },
    1.76 +
    1.77 +  QueryInterface: function(iid) {
    1.78 +    if (iid.equals(Components.interfaces.nsIRequestObserver) ||
    1.79 +        iid.equals(Components.interfaces.nsISupports)
    1.80 +        )
    1.81 +      return this;
    1.82 +    throw Components.results.NS_NOINTERFACE;
    1.83 +  },
    1.84 +
    1.85 +  listener: null
    1.86 +}
    1.87 +
    1.88 +
    1.89 +function HttpResponseExaminer() {}
    1.90 +
    1.91 +HttpResponseExaminer.prototype = {
    1.92 +  register: function() {
    1.93 +    Cc["@mozilla.org/observer-service;1"].
    1.94 +      getService(Components.interfaces.nsIObserverService).
    1.95 +      addObserver(this, "http-on-examine-response", true);
    1.96 +    dump("Did HttpResponseExaminer.register\n");
    1.97 +  },
    1.98 +
    1.99 +  // Replace channel's listener.
   1.100 +  observe: function(subject, topic, data) {
   1.101 +    dump("In HttpResponseExaminer.observe\n");
   1.102 +    try {
   1.103 +      subject.QueryInterface(Components.interfaces.nsITraceableChannel);
   1.104 +      
   1.105 +      var tee = Cc["@mozilla.org/network/stream-listener-tee;1"].
   1.106 +          createInstance(Ci.nsIStreamListenerTee);
   1.107 +      var newListener = new TracingListener();
   1.108 +      pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
   1.109 +      pipe.init(false, false, 0, 0xffffffff, null);
   1.110 +      streamSink = pipe.outputStream;
   1.111 +      
   1.112 +      var originalListener = subject.setNewListener(tee);
   1.113 +      tee.init(originalListener, streamSink, newListener);
   1.114 +    } catch(e) {
   1.115 +      do_throw("can't replace listener " + e);
   1.116 +    }
   1.117 +    dump("Did HttpResponseExaminer.observe\n");
   1.118 +  },
   1.119 +
   1.120 +  QueryInterface: function(iid) {
   1.121 +    if (iid.equals(Components.interfaces.nsIObserver) ||
   1.122 +        iid.equals(Components.interfaces.nsISupportsWeakReference) ||
   1.123 +        iid.equals(Components.interfaces.nsISupports))
   1.124 +      return this;
   1.125 +    throw Components.results.NS_NOINTERFACE;
   1.126 +  }
   1.127 +}
   1.128 +
   1.129 +function test_handler(metadata, response) {
   1.130 +  response.setHeader("Content-Type", "text/html", false);
   1.131 +  response.setStatusLine(metadata.httpVersion, 200, "OK");
   1.132 +  response.bodyOutputStream.write(originalBody, originalBody.length);
   1.133 +}
   1.134 +
   1.135 +function make_channel(url) {
   1.136 +  var ios = Cc["@mozilla.org/network/io-service;1"].
   1.137 +    getService(Ci.nsIIOService);
   1.138 +  return ios.newChannel(url, null, null).
   1.139 +    QueryInterface(Components.interfaces.nsIHttpChannel);
   1.140 +}
   1.141 +
   1.142 +// Check if received body is correctly modified.
   1.143 +function channel_finished(request, input, ctx) {
   1.144 +  httpserver.stop(do_test_finished);
   1.145 +}
   1.146 +
   1.147 +function run_test() {
   1.148 +  var observer = new HttpResponseExaminer();
   1.149 +  observer.register();
   1.150 +
   1.151 +  httpserver.registerPathHandler("/testdir", test_handler);
   1.152 +
   1.153 +  var channel = make_channel("http://localhost:" + PORT + "/testdir");
   1.154 +  channel.asyncOpen(new ChannelListener(channel_finished), null);
   1.155 +  do_test_pending();
   1.156 +}

mercurial