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 +}