test_bug468594.js (4442B)
1 // 2 // This script emulates the test called "Freshness" 3 // by Mark Nottingham, located at 4 // 5 // http://mnot.net/javascript/xmlhttprequest/cache.html 6 // 7 // The issue with Mr. Nottinghams page is that the server 8 // always seems to send an Expires-header in the response, 9 // breaking the finer details of the test. This script has 10 // full control of response-headers, however, and can perform 11 // the intended testing plus some extra stuff. 12 // 13 // Please see RFC 2616 section 13.2.1 6th paragraph for the 14 // definition of "explicit expiration time" being used here. 15 16 "use strict"; 17 18 const { HttpServer } = ChromeUtils.importESModule( 19 "resource://testing-common/httpd.sys.mjs" 20 ); 21 22 var httpserver = new HttpServer(); 23 var index = 0; 24 var tests = [ 25 { url: "/freshness", server: "0", expected: "0" }, 26 { url: "/freshness", server: "1", expected: "0" }, // cached 27 28 // RFC 2616 section 13.9 2nd paragraph says not to heuristically cache 29 // querystring, but we allow it to maintain web compat 30 { url: "/freshness?a", server: "2", expected: "2" }, 31 { url: "/freshness?a", server: "3", expected: "2" }, 32 33 // explicit expiration dates in the future should be cached 34 { 35 url: "/freshness?b", 36 server: "4", 37 expected: "4", 38 responseheader: "Expires: " + getDateString(1), 39 }, 40 { url: "/freshness?b", server: "5", expected: "4" }, // cached due to Expires 41 42 { 43 url: "/freshness?c", 44 server: "6", 45 expected: "6", 46 responseheader: "Cache-Control: max-age=3600", 47 }, 48 { url: "/freshness?c", server: "7", expected: "6" }, // cached due to max-age 49 50 // explicit expiration dates in the past should NOT be cached 51 { 52 url: "/freshness?d", 53 server: "8", 54 expected: "8", 55 responseheader: "Expires: " + getDateString(-1), 56 }, 57 { url: "/freshness?d", server: "9", expected: "9" }, 58 59 { 60 url: "/freshness?e", 61 server: "10", 62 expected: "10", 63 responseheader: "Cache-Control: max-age=0", 64 }, 65 { url: "/freshness?e", server: "11", expected: "11" }, 66 67 { url: "/freshness", server: "99", expected: "0" }, // cached 68 ]; 69 70 function logit(i, data) { 71 dump( 72 tests[i].url + 73 "\t requested [" + 74 tests[i].server + 75 "]" + 76 " got [" + 77 data + 78 "] expected [" + 79 tests[i].expected + 80 "]" 81 ); 82 if (tests[i].responseheader) { 83 dump("\t[" + tests[i].responseheader + "]"); 84 } 85 dump("\n"); 86 } 87 88 function setupChannel(suffix, value) { 89 var chan = NetUtil.newChannel({ 90 uri: "http://localhost:" + httpserver.identity.primaryPort + suffix, 91 loadUsingSystemPrincipal: true, 92 }); 93 var httpChan = chan.QueryInterface(Ci.nsIHttpChannel); 94 httpChan.requestMethod = "GET"; 95 httpChan.setRequestHeader("x-request", value, false); 96 return httpChan; 97 } 98 99 function triggerNextTest() { 100 var channel = setupChannel(tests[index].url, tests[index].server); 101 channel.asyncOpen(new ChannelListener(checkValueAndTrigger, null)); 102 } 103 104 function checkValueAndTrigger(request, data) { 105 logit(index, data); 106 Assert.equal(tests[index].expected, data); 107 108 if (index < tests.length - 1) { 109 index++; 110 triggerNextTest(); 111 } else { 112 httpserver.stop(do_test_finished); 113 } 114 } 115 116 function run_test() { 117 httpserver.registerPathHandler("/freshness", handler); 118 httpserver.start(-1); 119 120 // clear cache 121 evict_cache_entries(); 122 triggerNextTest(); 123 124 do_test_pending(); 125 } 126 127 function handler(metadata, response) { 128 var body = metadata.getHeader("x-request"); 129 response.setHeader("Content-Type", "text/plain", false); 130 response.setHeader("Date", getDateString(0), false); 131 132 var header = tests[index].responseheader; 133 if (header == null) { 134 response.setHeader("Last-Modified", getDateString(-1), false); 135 } else { 136 var splitHdr = header.split(": "); 137 response.setHeader(splitHdr[0], splitHdr[1], false); 138 } 139 140 response.setStatusLine(metadata.httpVersion, 200, "OK"); 141 response.bodyOutputStream.write(body, body.length); 142 } 143 144 function getDateString(yearDelta) { 145 var months = [ 146 "Jan", 147 "Feb", 148 "Mar", 149 "Apr", 150 "May", 151 "Jun", 152 "Jul", 153 "Aug", 154 "Sep", 155 "Oct", 156 "Nov", 157 "Dec", 158 ]; 159 var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 160 161 var d = new Date(); 162 return ( 163 days[d.getUTCDay()] + 164 ", " + 165 d.getUTCDate() + 166 " " + 167 months[d.getUTCMonth()] + 168 " " + 169 (d.getUTCFullYear() + yearDelta) + 170 " " + 171 d.getUTCHours() + 172 ":" + 173 d.getUTCMinutes() + 174 ":" + 175 d.getUTCSeconds() + 176 " UTC" 177 ); 178 }