netwerk/test/unit/test_traceable_channel.js

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 // Test nsITraceableChannel interface.
michael@0 2 // Replace original listener with TracingListener that modifies body of HTTP
michael@0 3 // response. Make sure that body received by original channel's listener
michael@0 4 // is correctly modified.
michael@0 5
michael@0 6 Cu.import("resource://testing-common/httpd.js");
michael@0 7
michael@0 8 var httpserver = new HttpServer();
michael@0 9 httpserver.start(-1);
michael@0 10 const PORT = httpserver.identity.primaryPort;
michael@0 11
michael@0 12 var pipe = null;
michael@0 13 var streamSink = null;
michael@0 14
michael@0 15 var originalBody = "original http response body";
michael@0 16 var gotOnStartRequest = false;
michael@0 17
michael@0 18 function TracingListener() {}
michael@0 19
michael@0 20 TracingListener.prototype = {
michael@0 21 onStartRequest: function(request, context) {
michael@0 22 dump("*** tracing listener onStartRequest\n");
michael@0 23
michael@0 24 gotOnStartRequest = true;
michael@0 25
michael@0 26 request.QueryInterface(Components.interfaces.nsIHttpChannelInternal);
michael@0 27
michael@0 28 // local/remote addresses broken in e10s: disable for now
michael@0 29 /*
michael@0 30 do_check_eq(request.localAddress, "127.0.0.1");
michael@0 31 do_check_eq(request.localPort > 0, true);
michael@0 32 do_check_neq(request.localPort, PORT);
michael@0 33 do_check_eq(request.remoteAddress, "127.0.0.1");
michael@0 34 do_check_eq(request.remotePort, PORT);
michael@0 35 */
michael@0 36
michael@0 37 // Make sure listener can't be replaced after OnStartRequest was called.
michael@0 38 request.QueryInterface(Components.interfaces.nsITraceableChannel);
michael@0 39 try {
michael@0 40 var newListener = new TracingListener();
michael@0 41 newListener.listener = request.setNewListener(newListener);
michael@0 42 } catch(e) {
michael@0 43 dump("TracingListener.onStartRequest swallowing exception: " + e + "\n");
michael@0 44 return; // OK
michael@0 45 }
michael@0 46 do_throw("replaced channel's listener during onStartRequest.");
michael@0 47 },
michael@0 48
michael@0 49 onStopRequest: function(request, context, statusCode) {
michael@0 50 dump("*** tracing listener onStopRequest\n");
michael@0 51
michael@0 52 do_check_eq(gotOnStartRequest, true);
michael@0 53
michael@0 54 try {
michael@0 55 var sin = Components.classes["@mozilla.org/scriptableinputstream;1"].
michael@0 56 createInstance(Ci.nsIScriptableInputStream);
michael@0 57
michael@0 58 streamSink.close();
michael@0 59 var input = pipe.inputStream;
michael@0 60 sin.init(input);
michael@0 61 do_check_eq(sin.available(), originalBody.length);
michael@0 62
michael@0 63 var result = sin.read(originalBody.length);
michael@0 64 do_check_eq(result, originalBody);
michael@0 65
michael@0 66 input.close();
michael@0 67 } catch (e) {
michael@0 68 dump("TracingListener.onStopRequest swallowing exception: " + e + "\n");
michael@0 69 } finally {
michael@0 70 httpserver.stop(do_test_finished);
michael@0 71 }
michael@0 72 },
michael@0 73
michael@0 74 QueryInterface: function(iid) {
michael@0 75 if (iid.equals(Components.interfaces.nsIRequestObserver) ||
michael@0 76 iid.equals(Components.interfaces.nsISupports)
michael@0 77 )
michael@0 78 return this;
michael@0 79 throw Components.results.NS_NOINTERFACE;
michael@0 80 },
michael@0 81
michael@0 82 listener: null
michael@0 83 }
michael@0 84
michael@0 85
michael@0 86 function HttpResponseExaminer() {}
michael@0 87
michael@0 88 HttpResponseExaminer.prototype = {
michael@0 89 register: function() {
michael@0 90 Cc["@mozilla.org/observer-service;1"].
michael@0 91 getService(Components.interfaces.nsIObserverService).
michael@0 92 addObserver(this, "http-on-examine-response", true);
michael@0 93 dump("Did HttpResponseExaminer.register\n");
michael@0 94 },
michael@0 95
michael@0 96 // Replace channel's listener.
michael@0 97 observe: function(subject, topic, data) {
michael@0 98 dump("In HttpResponseExaminer.observe\n");
michael@0 99 try {
michael@0 100 subject.QueryInterface(Components.interfaces.nsITraceableChannel);
michael@0 101
michael@0 102 var tee = Cc["@mozilla.org/network/stream-listener-tee;1"].
michael@0 103 createInstance(Ci.nsIStreamListenerTee);
michael@0 104 var newListener = new TracingListener();
michael@0 105 pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
michael@0 106 pipe.init(false, false, 0, 0xffffffff, null);
michael@0 107 streamSink = pipe.outputStream;
michael@0 108
michael@0 109 var originalListener = subject.setNewListener(tee);
michael@0 110 tee.init(originalListener, streamSink, newListener);
michael@0 111 } catch(e) {
michael@0 112 do_throw("can't replace listener " + e);
michael@0 113 }
michael@0 114 dump("Did HttpResponseExaminer.observe\n");
michael@0 115 },
michael@0 116
michael@0 117 QueryInterface: function(iid) {
michael@0 118 if (iid.equals(Components.interfaces.nsIObserver) ||
michael@0 119 iid.equals(Components.interfaces.nsISupportsWeakReference) ||
michael@0 120 iid.equals(Components.interfaces.nsISupports))
michael@0 121 return this;
michael@0 122 throw Components.results.NS_NOINTERFACE;
michael@0 123 }
michael@0 124 }
michael@0 125
michael@0 126 function test_handler(metadata, response) {
michael@0 127 response.setHeader("Content-Type", "text/html", false);
michael@0 128 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 129 response.bodyOutputStream.write(originalBody, originalBody.length);
michael@0 130 }
michael@0 131
michael@0 132 function make_channel(url) {
michael@0 133 var ios = Cc["@mozilla.org/network/io-service;1"].
michael@0 134 getService(Ci.nsIIOService);
michael@0 135 return ios.newChannel(url, null, null).
michael@0 136 QueryInterface(Components.interfaces.nsIHttpChannel);
michael@0 137 }
michael@0 138
michael@0 139 // Check if received body is correctly modified.
michael@0 140 function channel_finished(request, input, ctx) {
michael@0 141 httpserver.stop(do_test_finished);
michael@0 142 }
michael@0 143
michael@0 144 function run_test() {
michael@0 145 var observer = new HttpResponseExaminer();
michael@0 146 observer.register();
michael@0 147
michael@0 148 httpserver.registerPathHandler("/testdir", test_handler);
michael@0 149
michael@0 150 var channel = make_channel("http://localhost:" + PORT + "/testdir");
michael@0 151 channel.asyncOpen(new ChannelListener(channel_finished), null);
michael@0 152 do_test_pending();
michael@0 153 }

mercurial