1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/unit/test_mismatch_last-modified.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,151 @@ 1.4 +Cu.import("resource://testing-common/httpd.js"); 1.5 +var httpserver = new HttpServer(); 1.6 + 1.7 +var ios; 1.8 + 1.9 +// Test the handling of a cache revalidation with mismatching last-modified 1.10 +// headers. If we get such a revalidation the cache entry should be purged. 1.11 +// see bug 717350 1.12 + 1.13 +// In this test the wrong data is from 11-16-1994 with a value of 'A', 1.14 +// and the right data is from 11-15-1994 with a value of 'B'. 1.15 + 1.16 +// the same URL is requested 3 times. the first time the wrong data comes 1.17 +// back, the second time that wrong data is revalidated with a 304 but 1.18 +// a L-M header of the right data (this triggers a cache purge), and 1.19 +// the third time the right data is returned. 1.20 + 1.21 +var listener_3 = { 1.22 + // this listener is used to process the the request made after 1.23 + // the cache invalidation. it expects to see the 'right data' 1.24 + 1.25 + QueryInterface: function(iid) { 1.26 + if (iid.equals(Components.interfaces.nsIStreamListener) || 1.27 + iid.equals(Components.interfaces.nsIRequestObserver) || 1.28 + iid.equals(Components.interfaces.nsISupports)) 1.29 + return this; 1.30 + throw Components.results.NS_ERROR_NO_INTERFACE; 1.31 + }, 1.32 + 1.33 + onStartRequest: function test_onStartR(request, ctx) {}, 1.34 + 1.35 + onDataAvailable: function test_ODA(request, cx, inputStream, 1.36 + offset, count) { 1.37 + var data = new BinaryInputStream(inputStream).readByteArray(count); 1.38 + 1.39 + do_check_eq(data[0], "B".charCodeAt(0)); 1.40 + }, 1.41 + 1.42 + onStopRequest: function test_onStopR(request, ctx, status) { 1.43 + httpserver.stop(do_test_finished); 1.44 + } 1.45 +}; 1.46 + 1.47 +XPCOMUtils.defineLazyGetter(this, "listener_2", function() { 1.48 + return { 1.49 + // this listener is used to process the revalidation of the 1.50 + // corrupted cache entry. its revalidation prompts it to be cleaned 1.51 + 1.52 + QueryInterface: function(iid) { 1.53 + if (iid.equals(Components.interfaces.nsIStreamListener) || 1.54 + iid.equals(Components.interfaces.nsIRequestObserver) || 1.55 + iid.equals(Components.interfaces.nsISupports)) 1.56 + return this; 1.57 + throw Components.results.NS_ERROR_NO_INTERFACE; 1.58 + }, 1.59 + 1.60 + onStartRequest: function test_onStartR(request, ctx) {}, 1.61 + 1.62 + onDataAvailable: function test_ODA(request, cx, inputStream, 1.63 + offset, count) { 1.64 + var data = new BinaryInputStream(inputStream).readByteArray(count); 1.65 + 1.66 + // This is 'A' from a cache revalidation, but that reval will clean the cache 1.67 + // because of mismatched last-modified response headers 1.68 + 1.69 + do_check_eq(data[0], "A".charCodeAt(0)); 1.70 + }, 1.71 + 1.72 + onStopRequest: function test_onStopR(request, ctx, status) { 1.73 + var channel = request.QueryInterface(Ci.nsIHttpChannel); 1.74 + 1.75 + var chan = ios.newChannel("http://localhost:" + 1.76 + httpserver.identity.primaryPort + 1.77 + "/test1", "", null); 1.78 + chan.asyncOpen(listener_3, null); 1.79 + } 1.80 +}; 1.81 +}); 1.82 + 1.83 +XPCOMUtils.defineLazyGetter(this, "listener_1", function() { 1.84 + return { 1.85 + // this listener processes the initial request from a empty cache. 1.86 + // the server responds with the wrong data ('A') 1.87 + 1.88 + QueryInterface: function(iid) { 1.89 + if (iid.equals(Components.interfaces.nsIStreamListener) || 1.90 + iid.equals(Components.interfaces.nsIRequestObserver) || 1.91 + iid.equals(Components.interfaces.nsISupports)) 1.92 + return this; 1.93 + throw Components.results.NS_ERROR_NO_INTERFACE; 1.94 + }, 1.95 + 1.96 + onStartRequest: function test_onStartR(request, ctx) {}, 1.97 + 1.98 + onDataAvailable: function test_ODA(request, cx, inputStream, 1.99 + offset, count) { 1.100 + var data = new BinaryInputStream(inputStream).readByteArray(count); 1.101 + do_check_eq(data[0], "A".charCodeAt(0)); 1.102 + }, 1.103 + 1.104 + onStopRequest: function test_onStopR(request, ctx, status) { 1.105 + var channel = request.QueryInterface(Ci.nsIHttpChannel); 1.106 + 1.107 + var chan = ios.newChannel("http://localhost:" + 1.108 + httpserver.identity.primaryPort + 1.109 + "/test1", "", null); 1.110 + chan.asyncOpen(listener_2, null); 1.111 + } 1.112 +}; 1.113 +}); 1.114 + 1.115 +function run_test() { 1.116 + do_get_profile(); 1.117 + ios = Cc["@mozilla.org/network/io-service;1"] 1.118 + .getService(Ci.nsIIOService); 1.119 + 1.120 + evict_cache_entries(); 1.121 + 1.122 + httpserver.registerPathHandler("/test1", handler); 1.123 + httpserver.start(-1); 1.124 + 1.125 + var port = httpserver.identity.primaryPort; 1.126 + 1.127 + var chan = ios.newChannel("http://localhost:" + port + "/test1", "", null); 1.128 + chan.asyncOpen(listener_1, null); 1.129 + 1.130 + do_test_pending(); 1.131 +} 1.132 + 1.133 +var iter=0; 1.134 +function handler(metadata, response) { 1.135 + iter++; 1.136 + if (metadata.hasHeader("If-Modified-Since")) { 1.137 + response.setStatusLine(metadata.httpVersion, 304, "Not Modified"); 1.138 + response.setHeader("Last-Modified", "Tue, 15 Nov 1994 12:45:26 GMT", false); 1.139 + } 1.140 + else { 1.141 + response.setStatusLine(metadata.httpVersion, 200, "OK"); 1.142 + response.setHeader("Cache-Control", "max-age=0", false) 1.143 + if (iter == 1) { 1.144 + // simulated wrong response 1.145 + response.setHeader("Last-Modified", "Wed, 16 Nov 1994 00:00:00 GMT", false); 1.146 + response.bodyOutputStream.write("A", 1); 1.147 + } 1.148 + if (iter == 3) { 1.149 + // 'correct' response 1.150 + response.setHeader("Last-Modified", "Tue, 15 Nov 1994 12:45:26 GMT", false); 1.151 + response.bodyOutputStream.write("B", 1); 1.152 + } 1.153 + } 1.154 +}