file_CrossSiteXHR_server.sjs (6256B)
1 const CC = Components.Constructor; 2 const BinaryInputStream = CC( 3 "@mozilla.org/binaryinputstream;1", 4 "nsIBinaryInputStream", 5 "setInputStream" 6 ); 7 Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); 8 9 // eslint-disable-next-line complexity 10 function handleRequest(request, response) { 11 var query = {}; 12 request.queryString.split("&").forEach(function (val) { 13 var [name, value] = val.split("="); 14 query[name] = unescape(value); 15 }); 16 17 var isPreflight = request.method == "OPTIONS"; 18 19 var bodyStream = new BinaryInputStream(request.bodyInputStream); 20 var bodyBytes = []; 21 while ((bodyAvail = bodyStream.available()) > 0) { 22 Array.prototype.push.apply(bodyBytes, bodyStream.readByteArray(bodyAvail)); 23 } 24 25 var body = decodeURIComponent( 26 escape(String.fromCharCode.apply(null, bodyBytes)) 27 ); 28 29 if (query.hop) { 30 query.hop = parseInt(query.hop, 10); 31 hops = JSON.parse(query.hops); 32 var curHop = hops[query.hop - 1]; 33 query.allowOrigin = curHop.allowOrigin; 34 query.allowHeaders = curHop.allowHeaders; 35 query.allowMethods = curHop.allowMethods; 36 query.allowCred = curHop.allowCred; 37 query.noAllowPreflight = curHop.noAllowPreflight; 38 if (curHop.setCookie) { 39 query.setCookie = unescape(curHop.setCookie); 40 } 41 if (curHop.cookie) { 42 query.cookie = unescape(curHop.cookie); 43 } 44 query.noCookie = curHop.noCookie; 45 } 46 47 // Check that request was correct 48 49 if (!isPreflight && query.body && body != query.body) { 50 sendHttp500( 51 response, 52 "Wrong body. Expected " + query.body + " got " + body 53 ); 54 return; 55 } 56 57 if (!isPreflight && "headers" in query) { 58 headers = JSON.parse(query.headers); 59 for (headerName in headers) { 60 // Content-Type is changed if there was a body 61 if ( 62 !(headerName == "Content-Type" && body) && 63 (!request.hasHeader(headerName) || 64 request.getHeader(headerName) != headers[headerName]) 65 ) { 66 var actual = request.hasHeader(headerName) 67 ? request.getHeader(headerName) 68 : "<missing header>"; 69 sendHttp500( 70 response, 71 "Header " + 72 headerName + 73 " had wrong value. Expected " + 74 headers[headerName] + 75 " got " + 76 actual 77 ); 78 return; 79 } 80 } 81 } 82 83 if ( 84 isPreflight && 85 "requestHeaders" in query && 86 request.getHeader("Access-Control-Request-Headers") != query.requestHeaders 87 ) { 88 sendHttp500( 89 response, 90 "Access-Control-Request-Headers had wrong value. Expected " + 91 query.requestHeaders + 92 " got " + 93 request.getHeader("Access-Control-Request-Headers") 94 ); 95 return; 96 } 97 98 if ( 99 isPreflight && 100 "requestMethod" in query && 101 request.getHeader("Access-Control-Request-Method") != query.requestMethod 102 ) { 103 sendHttp500( 104 response, 105 "Access-Control-Request-Method had wrong value. Expected " + 106 query.requestMethod + 107 " got " + 108 request.getHeader("Access-Control-Request-Method") 109 ); 110 return; 111 } 112 113 if ("origin" in query && request.getHeader("Origin") != query.origin) { 114 sendHttp500( 115 response, 116 "Origin had wrong value. Expected " + 117 query.origin + 118 " got " + 119 request.getHeader("Origin") 120 ); 121 return; 122 } 123 124 if ("cookie" in query) { 125 cookies = {}; 126 request 127 .getHeader("Cookie") 128 .split(/ *; */) 129 .forEach(function (val) { 130 var [name, value] = val.split("="); 131 cookies[name] = unescape(value); 132 }); 133 134 query.cookie.split(",").forEach(function (val) { 135 var [name, value] = val.split("="); 136 if (cookies[name] != value) { 137 sendHttp500( 138 response, 139 "Cookie " + 140 name + 141 " had wrong value. Expected " + 142 value + 143 " got " + 144 cookies[name] 145 ); 146 } 147 }); 148 } 149 150 if (query.noCookie && request.hasHeader("Cookie")) { 151 sendHttp500( 152 response, 153 "Got cookies when didn't expect to: " + request.getHeader("Cookie") 154 ); 155 return; 156 } 157 158 // Send response 159 160 if (!isPreflight && query.status) { 161 response.setStatusLine(null, query.status, query.statusMessage); 162 } 163 if (isPreflight && query.preflightStatus) { 164 response.setStatusLine(null, query.preflightStatus, "preflight status"); 165 } 166 167 if (query.allowOrigin && (!isPreflight || !query.noAllowPreflight)) { 168 response.setHeader("Access-Control-Allow-Origin", query.allowOrigin); 169 } 170 171 if (query.allowCred) { 172 response.setHeader("Access-Control-Allow-Credentials", "true"); 173 } 174 175 if (query.setCookie) { 176 response.setHeader("Set-Cookie", query.setCookie + "; path=/"); 177 } 178 179 if (isPreflight) { 180 if (query.allowHeaders) { 181 response.setHeader("Access-Control-Allow-Headers", query.allowHeaders); 182 } 183 184 if (query.allowMethods) { 185 response.setHeader("Access-Control-Allow-Methods", query.allowMethods); 186 } 187 } else { 188 if (query.responseHeaders) { 189 let responseHeaders = JSON.parse(query.responseHeaders); 190 for (let responseHeader in responseHeaders) { 191 response.setHeader(responseHeader, responseHeaders[responseHeader]); 192 } 193 } 194 195 if (query.exposeHeaders) { 196 response.setHeader("Access-Control-Expose-Headers", query.exposeHeaders); 197 } 198 } 199 200 if (!isPreflight && query.hop && query.hop < hops.length) { 201 newURL = 202 hops[query.hop].server + 203 "/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?" + 204 "hop=" + 205 (query.hop + 1) + 206 "&hops=" + 207 escape(query.hops); 208 if ("headers" in query) { 209 newURL += "&headers=" + escape(query.headers); 210 } 211 response.setStatusLine(null, 307, "redirect"); 212 response.setHeader("Location", newURL); 213 214 return; 215 } 216 217 // Send response body 218 if (!isPreflight && request.method != "HEAD") { 219 response.setHeader("Content-Type", "application/xml", false); 220 response.write("<res>hello pass</res>\n"); 221 } 222 if (isPreflight && "preflightBody" in query) { 223 response.setHeader("Content-Type", "text/plain", false); 224 response.write(query.preflightBody); 225 } 226 } 227 228 function sendHttp500(response, text) { 229 response.setStatusLine(null, 500, text); 230 }