|
1 Cu.import("resource://testing-common/httpd.js"); |
|
2 var httpserver = new HttpServer(); |
|
3 |
|
4 var ios; |
|
5 |
|
6 // Test the handling of a cache revalidation with mismatching last-modified |
|
7 // headers. If we get such a revalidation the cache entry should be purged. |
|
8 // see bug 717350 |
|
9 |
|
10 // In this test the wrong data is from 11-16-1994 with a value of 'A', |
|
11 // and the right data is from 11-15-1994 with a value of 'B'. |
|
12 |
|
13 // the same URL is requested 3 times. the first time the wrong data comes |
|
14 // back, the second time that wrong data is revalidated with a 304 but |
|
15 // a L-M header of the right data (this triggers a cache purge), and |
|
16 // the third time the right data is returned. |
|
17 |
|
18 var listener_3 = { |
|
19 // this listener is used to process the the request made after |
|
20 // the cache invalidation. it expects to see the 'right data' |
|
21 |
|
22 QueryInterface: function(iid) { |
|
23 if (iid.equals(Components.interfaces.nsIStreamListener) || |
|
24 iid.equals(Components.interfaces.nsIRequestObserver) || |
|
25 iid.equals(Components.interfaces.nsISupports)) |
|
26 return this; |
|
27 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
28 }, |
|
29 |
|
30 onStartRequest: function test_onStartR(request, ctx) {}, |
|
31 |
|
32 onDataAvailable: function test_ODA(request, cx, inputStream, |
|
33 offset, count) { |
|
34 var data = new BinaryInputStream(inputStream).readByteArray(count); |
|
35 |
|
36 do_check_eq(data[0], "B".charCodeAt(0)); |
|
37 }, |
|
38 |
|
39 onStopRequest: function test_onStopR(request, ctx, status) { |
|
40 httpserver.stop(do_test_finished); |
|
41 } |
|
42 }; |
|
43 |
|
44 XPCOMUtils.defineLazyGetter(this, "listener_2", function() { |
|
45 return { |
|
46 // this listener is used to process the revalidation of the |
|
47 // corrupted cache entry. its revalidation prompts it to be cleaned |
|
48 |
|
49 QueryInterface: function(iid) { |
|
50 if (iid.equals(Components.interfaces.nsIStreamListener) || |
|
51 iid.equals(Components.interfaces.nsIRequestObserver) || |
|
52 iid.equals(Components.interfaces.nsISupports)) |
|
53 return this; |
|
54 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
55 }, |
|
56 |
|
57 onStartRequest: function test_onStartR(request, ctx) {}, |
|
58 |
|
59 onDataAvailable: function test_ODA(request, cx, inputStream, |
|
60 offset, count) { |
|
61 var data = new BinaryInputStream(inputStream).readByteArray(count); |
|
62 |
|
63 // This is 'A' from a cache revalidation, but that reval will clean the cache |
|
64 // because of mismatched last-modified response headers |
|
65 |
|
66 do_check_eq(data[0], "A".charCodeAt(0)); |
|
67 }, |
|
68 |
|
69 onStopRequest: function test_onStopR(request, ctx, status) { |
|
70 var channel = request.QueryInterface(Ci.nsIHttpChannel); |
|
71 |
|
72 var chan = ios.newChannel("http://localhost:" + |
|
73 httpserver.identity.primaryPort + |
|
74 "/test1", "", null); |
|
75 chan.asyncOpen(listener_3, null); |
|
76 } |
|
77 }; |
|
78 }); |
|
79 |
|
80 XPCOMUtils.defineLazyGetter(this, "listener_1", function() { |
|
81 return { |
|
82 // this listener processes the initial request from a empty cache. |
|
83 // the server responds with the wrong data ('A') |
|
84 |
|
85 QueryInterface: function(iid) { |
|
86 if (iid.equals(Components.interfaces.nsIStreamListener) || |
|
87 iid.equals(Components.interfaces.nsIRequestObserver) || |
|
88 iid.equals(Components.interfaces.nsISupports)) |
|
89 return this; |
|
90 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
91 }, |
|
92 |
|
93 onStartRequest: function test_onStartR(request, ctx) {}, |
|
94 |
|
95 onDataAvailable: function test_ODA(request, cx, inputStream, |
|
96 offset, count) { |
|
97 var data = new BinaryInputStream(inputStream).readByteArray(count); |
|
98 do_check_eq(data[0], "A".charCodeAt(0)); |
|
99 }, |
|
100 |
|
101 onStopRequest: function test_onStopR(request, ctx, status) { |
|
102 var channel = request.QueryInterface(Ci.nsIHttpChannel); |
|
103 |
|
104 var chan = ios.newChannel("http://localhost:" + |
|
105 httpserver.identity.primaryPort + |
|
106 "/test1", "", null); |
|
107 chan.asyncOpen(listener_2, null); |
|
108 } |
|
109 }; |
|
110 }); |
|
111 |
|
112 function run_test() { |
|
113 do_get_profile(); |
|
114 ios = Cc["@mozilla.org/network/io-service;1"] |
|
115 .getService(Ci.nsIIOService); |
|
116 |
|
117 evict_cache_entries(); |
|
118 |
|
119 httpserver.registerPathHandler("/test1", handler); |
|
120 httpserver.start(-1); |
|
121 |
|
122 var port = httpserver.identity.primaryPort; |
|
123 |
|
124 var chan = ios.newChannel("http://localhost:" + port + "/test1", "", null); |
|
125 chan.asyncOpen(listener_1, null); |
|
126 |
|
127 do_test_pending(); |
|
128 } |
|
129 |
|
130 var iter=0; |
|
131 function handler(metadata, response) { |
|
132 iter++; |
|
133 if (metadata.hasHeader("If-Modified-Since")) { |
|
134 response.setStatusLine(metadata.httpVersion, 304, "Not Modified"); |
|
135 response.setHeader("Last-Modified", "Tue, 15 Nov 1994 12:45:26 GMT", false); |
|
136 } |
|
137 else { |
|
138 response.setStatusLine(metadata.httpVersion, 200, "OK"); |
|
139 response.setHeader("Cache-Control", "max-age=0", false) |
|
140 if (iter == 1) { |
|
141 // simulated wrong response |
|
142 response.setHeader("Last-Modified", "Wed, 16 Nov 1994 00:00:00 GMT", false); |
|
143 response.bodyOutputStream.write("A", 1); |
|
144 } |
|
145 if (iter == 3) { |
|
146 // 'correct' response |
|
147 response.setHeader("Last-Modified", "Tue, 15 Nov 1994 12:45:26 GMT", false); |
|
148 response.bodyOutputStream.write("B", 1); |
|
149 } |
|
150 } |
|
151 } |