test_loadinfo_redirectchain.html (11140B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Bug 1194052 - Append Principal to RedirectChain within LoadInfo before the channel is succesfully openend</title> 5 <!-- Including SimpleTest.js so we can use waitForExplicitFinish !--> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 8 </head> 9 <body> 10 <iframe style="width:100%;" id="testframe"></iframe> 11 12 <script class="testbody" type="text/javascript"> 13 14 /* 15 * We perform the following tests on the redirectchain of the loadinfo: 16 * (1) checkLoadInfoWithoutRedirects: 17 * checks the length of the redirectchain and tries to pop an element 18 * which should result in an exception and not a crash. 19 * (2) checkLoadInfoWithTwoRedirects: 20 * perform two redirects and confirm that both redirect chains 21 * contain the redirected URIs. 22 * (3) checkLoadInfoWithInternalRedirects: 23 * perform two redirects including CSPs upgrade-insecure-requests 24 * so that the redirectchain which includes internal redirects differs. 25 * (4) checkLoadInfoWithInternalRedirectsAndFallback 26 * perform two redirects including CSPs upgrade-insecure-requests 27 * including a 404 repsonse and hence a fallback. 28 * (5) checkHTTPURITruncation 29 * perform a redirect to a URI with an HTTP scheme to check that unwanted 30 * URI components are removed before being added to the redirectchain. 31 * (6) checkHTTPSURITruncation 32 * perform a redirect to a URI with an HTTPS scheme to check that unwanted 33 * URI components are removed before being added to the redirectchain. 34 */ 35 36 SimpleTest.waitForExplicitFinish(); 37 38 // ************** HELPERS *************** 39 40 function compareChains(aLoadInfo, aExpectedRedirectChain, aExpectedRedirectChainIncludingInternalRedirects) { 41 var redirectChain = aLoadInfo.redirectChain; 42 var redirectChainIncludingInternalRedirects = aLoadInfo.redirectChainIncludingInternalRedirects; 43 44 is(redirectChain.length, 45 aExpectedRedirectChain.length, 46 "confirming length of redirectChain is " + aExpectedRedirectChain.length); 47 48 is(redirectChainIncludingInternalRedirects.length, 49 aExpectedRedirectChainIncludingInternalRedirects.length, 50 "confirming length of redirectChainIncludingInternalRedirects is " + 51 aExpectedRedirectChainIncludingInternalRedirects.length); 52 } 53 54 function compareTruncatedChains(redirectChain, aExpectedRedirectChain) { 55 is(redirectChain.length, 56 aExpectedRedirectChain.length, 57 "confirming length of redirectChain is " + aExpectedRedirectChain.length); 58 59 for (var i = 0; i < redirectChain.length; i++) { 60 is(redirectChain[i], 61 aExpectedRedirectChain[i], 62 "redirect chain should match expected chain"); 63 } 64 } 65 66 67 // *************** TEST 1 *************** 68 69 function checkLoadInfoWithoutRedirects() { 70 var myXHR = new XMLHttpRequest(); 71 myXHR.open("GET", "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-0"); 72 73 myXHR.onload = function() { 74 var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo; 75 var redirectChain = loadinfo.redirectChain; 76 var redirectChainIncludingInternalRedirects = loadinfo.redirectChainIncludingInternalRedirects; 77 78 is(redirectChain.length, 0, "no redirect, length should be 0"); 79 is(redirectChainIncludingInternalRedirects.length, 0, "no redirect, length should be 0"); 80 is(myXHR.responseText, "checking redirectchain", "sanity check to make sure redirects succeeded"); 81 82 // try to pop an element from redirectChain 83 try { 84 loadinfo.popRedirectedPrincipal(false); 85 ok(false, "should not be possible to pop from redirectChain"); 86 } 87 catch(e) { 88 ok(true, "popping element from empty redirectChain should throw"); 89 } 90 91 // try to pop an element from redirectChainIncludingInternalRedirects 92 try { 93 loadinfo.popRedirectedPrincipal(true); 94 ok(false, "should not be possible to pop from redirectChainIncludingInternalRedirects"); 95 } 96 catch(e) { 97 ok(true, "popping element from empty redirectChainIncludingInternalRedirects should throw"); 98 } 99 // move on to the next test 100 checkLoadInfoWithTwoRedirects(); 101 } 102 myXHR.onerror = function() { 103 ok(false, "xhr problem within checkLoadInfoWithoutRedirect()"); 104 } 105 myXHR.send(); 106 } 107 108 // *************** TEST 2 *************** 109 110 function checkLoadInfoWithTwoRedirects() { 111 var myXHR = new XMLHttpRequest(); 112 myXHR.open("GET", "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-2"); 113 114 const EXPECTED_REDIRECT_CHAIN = [ 115 "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", 116 "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs" 117 ]; 118 119 const EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = EXPECTED_REDIRECT_CHAIN; 120 121 // Referrer header will not change when redirect 122 const EXPECTED_REFERRER = 123 "http://mochi.test:8888/tests/netwerk/test/mochitests/test_loadinfo_redirectchain.html"; 124 const isAndroid = !!navigator.userAgent.includes("Android"); 125 const EXPECTED_REMOTE_IP = isAndroid ? "10.0.2.2" : "127.0.0.1"; 126 127 myXHR.onload = function() { 128 is(myXHR.responseText, "checking redirectchain", "sanity check to make sure redirects succeeded"); 129 130 var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo; 131 132 compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS); 133 134 for (var i = 0; i < loadinfo.redirectChain.length; i++) { 135 is(loadinfo.redirectChain[i].referrerURI.spec, EXPECTED_REFERRER, "referrer should match"); 136 is(loadinfo.redirectChain[i].remoteAddress, EXPECTED_REMOTE_IP, "remote address should match"); 137 } 138 139 // move on to the next test 140 checkLoadInfoWithInternalRedirects(); 141 } 142 myXHR.onerror = function() { 143 ok(false, "xhr problem within checkLoadInfoWithTwoRedirects()"); 144 } 145 myXHR.send(); 146 } 147 148 // *************** TEST 3 *************** 149 150 function confirmCheckLoadInfoWithInternalRedirects(event) { 151 const EXPECTED_REDIRECT_CHAIN = [ 152 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2", 153 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1" 154 ]; 155 156 const EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = [ 157 "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2", 158 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2", 159 "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1", 160 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1", 161 "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-0", 162 ]; 163 164 var loadinfo = JSON.parse(event.data.loadinfo); 165 compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS); 166 167 // remove the postMessage listener and move on to the next test 168 window.removeEventListener("message", confirmCheckLoadInfoWithInternalRedirects); 169 checkLoadInfoWithInternalRedirectsAndFallback(); 170 } 171 172 function checkLoadInfoWithInternalRedirects() { 173 // load the XHR request into an iframe so we can apply a CSP to the iframe 174 // a postMessage returns the result back to the main page. 175 window.addEventListener("message", confirmCheckLoadInfoWithInternalRedirects); 176 document.getElementById("testframe").src = 177 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-https-2"; 178 } 179 180 // *************** TEST 4 *************** 181 182 function confirmCheckLoadInfoWithInternalRedirectsAndFallback(event) { 183 var EXPECTED_REDIRECT_CHAIN = [ 184 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2", 185 ]; 186 187 var EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = [ 188 "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2", 189 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2", 190 "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-1", 191 ]; 192 193 var loadinfo = JSON.parse(event.data.loadinfo); 194 compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS); 195 196 // remove the postMessage listener and finish test 197 window.removeEventListener("message", confirmCheckLoadInfoWithInternalRedirectsAndFallback); 198 checkHTTPURITruncation(); 199 } 200 201 function checkLoadInfoWithInternalRedirectsAndFallback() { 202 // load the XHR request into an iframe so we can apply a CSP to the iframe 203 // a postMessage returns the result back to the main page. 204 window.addEventListener("message", confirmCheckLoadInfoWithInternalRedirectsAndFallback); 205 document.getElementById("testframe").src = 206 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-err-2"; 207 } 208 209 // *************** TEST 5 *************** 210 211 function checkHTTPURITruncation() { 212 var myXHR = new XMLHttpRequest(); 213 myXHR.open("GET", "http://root:toor@mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-1#baz"); 214 215 const EXPECTED_REDIRECT_CHAIN = [ 216 "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-1 217 ]; 218 219 var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo; 220 221 myXHR.onload = function() { 222 var redirectChain = []; 223 224 for (var i = 0; i < loadinfo.redirectChain.length; i++) { 225 redirectChain[i] = loadinfo.redirectChain[i].principal.asciiSpec; 226 } 227 228 compareTruncatedChains(redirectChain, EXPECTED_REDIRECT_CHAIN); 229 230 // move on to the next test 231 checkHTTPSURITruncation(); 232 } 233 myXHR.onerror = function(e) { 234 ok(false, "xhr problem within checkHTTPURITruncation()" + e); 235 } 236 myXHR.send(); 237 } 238 239 // *************** TEST 6 *************** 240 241 function confirmCheckHTTPSURITruncation(event) { 242 const EXPECTED_REDIRECT_CHAIN = [ 243 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-https-2 244 "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-https-1 245 ]; 246 247 var loadinfo = JSON.parse(event.data.loadinfo); 248 compareTruncatedChains(loadinfo.redirectChain, EXPECTED_REDIRECT_CHAIN); 249 250 // remove the postMessage listener and move on to the next test 251 window.removeEventListener("message", confirmCheckHTTPSURITruncation); 252 SimpleTest.finish(); 253 } 254 255 function checkHTTPSURITruncation() { 256 // load the XHR request into an iframe so we can apply a CSP to the iframe 257 // a postMessage returns the result back to the main page. 258 window.addEventListener("message", confirmCheckHTTPSURITruncation); 259 document.getElementById("testframe").src = 260 "https://root:toor@example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-https-2#baz"; 261 } 262 263 // *************** START TESTS *************** 264 265 checkLoadInfoWithoutRedirects(); 266 267 </script> 268 </body> 269 </html>