diff --git a/lib/cors-anywhere.js b/lib/cors-anywhere.js index fd2859f..7026469 100644 --- a/lib/cors-anywhere.js +++ b/lib/cors-anywhere.js @@ -64,7 +64,7 @@ function withCORS(headers, request) { var exposedHeaders = headers['access-control-expose-headers'] || ''; if (!/,\s*location\s*,/i.test(','+exposedHeaders+',')) exposedHeaders += ',location'; - if (!/,\s*x-request-url\s*,/i.test(','+exposedHeaders+',')) exposedHeaders += ',x-request-url'; + if (!/,\s*x-request-url\s*,/i.test(','+exposedHeaders+',')) exposedHeaders += ',x-request-url,x-final-url'; if (exposedHeaders.charAt(0) === ',') exposedHeaders = exposedHeaders.substr(1); headers['access-control-expose-headers'] = exposedHeaders; @@ -121,6 +121,10 @@ function onProxyResponse(req, res, response) { var requestState = req.corsAnywhereRequestState; var statusCode = response.statusCode; + + if (!requestState.redirectCount_) { + res.setHeader('x-request-url', requestState.location.full_url); + } // Handle redirects if (statusCode === 301 || statusCode === 302 || statusCode === 303 || statusCode === 307 || statusCode === 308) { var locationHeader = response.headers['location']; @@ -129,7 +133,7 @@ function onProxyResponse(req, res, response) { if (statusCode === 301 || statusCode === 302 || statusCode === 303) { // Exclude 307 & 308, because they are rare, and require preserving the method + request body - requestState.redirectCount_ = requestState.requestState_ + 1 || 1; + requestState.redirectCount_ = requestState.redirectCount_ + 1 || 1; if (requestState.redirectCount_ <= requestState.maxRedirects) { // Handle redirects within the server, because some clients (e.g. Android Stock Browser) // cancel redirects. @@ -139,8 +143,7 @@ function onProxyResponse(req, res, response) { req.method = 'GET'; requestState.location = parseURL(locationHeader); proxyRequest(req, res, proxy); - // TODO: Is it possible to trigger reverseProxy.end() (from node-http-proxy) without - // manually emiting the "event" event on req? + // Trigger reverseProxy.end() to initiate the proxy req.emit('end'); response.end(); @@ -158,7 +161,7 @@ function onProxyResponse(req, res, response) { delete response.headers['set-cookie']; delete response.headers['set-cookie2']; - response.headers['x-request-url'] = requestState.location.full_url; + response.headers['x-final-url'] = requestState.location.full_url; } diff --git a/lib/help.txt b/lib/help.txt index 5fac4c9..3d0d654 100644 --- a/lib/help.txt +++ b/lib/help.txt @@ -11,11 +11,13 @@ If the protocol is omitted, it defaults to http (https if port 443 is specified) Cookies are disabled and stripped from requests. Redirects are automatically followed. For debugging purposes, each followed redirect results -in the addition of a X-CORS-Redirect-n header, where n starts at 1. This header is not +in the addition of a X-CORS-Redirect-n header, where n starts at 1. These headers are not accessible by the XMLHttpRequest API. +After 5 redirects, redirects are not followed any more. The redirect response is sent back +to the browser, which can choose to follow the redirect (handled automatically by the browser). -The final request URL is available in the X-Request-URL response header. Non-existence of -this header implies that the requested URL was not recognized. +The requested URL is available in the X-Request-URL response header. +The final URL, after following all redirects, is available in the X-Final-URL response header. To prevent the use of the proxy for casual browsing, the API requires either the Origin