mirror of
https://github.com/d0zingcat/cors-anywhere.git
synced 2026-05-13 23:16:51 +00:00
Upgrade from http-proxy 0.10.x to 1.3.0
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
// © 2013 Rob W <gwnRob@gmail.com>
|
||||
// © 2013 - 2014 Rob Wu <rob@robwu.nl>
|
||||
// Released under the MIT license
|
||||
|
||||
'use strict';
|
||||
/* jshint node:true, eqnull:true, sub:true, quotmark:single, unused:true */
|
||||
|
||||
var http = require('http');
|
||||
var httpProxy = require('http-proxy');
|
||||
var net = require('net');
|
||||
var url = require('url');
|
||||
@@ -37,7 +38,7 @@ function showUsage(headers, response) {
|
||||
* @return {boolean} Whether the requested resource can be accessed.
|
||||
*/
|
||||
function isValidHostName(hostname) {
|
||||
return !(
|
||||
return !!(
|
||||
regexp_tld.test(hostname) ||
|
||||
net.isIPv4(hostname) ||
|
||||
net.isIPv6(hostname)
|
||||
@@ -85,24 +86,20 @@ function proxyRequest(req, res, proxy) {
|
||||
req.headers.host = location.host;
|
||||
|
||||
// Start proxying the request
|
||||
proxy.proxyRequest(req, res, {
|
||||
host: location.hostname,
|
||||
port: location.port,
|
||||
target: {
|
||||
https: location.isHttps
|
||||
}
|
||||
proxy.web(req, res, {
|
||||
target: location
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* "Allow observer to modify headers or abort response"
|
||||
* https://github.com/nodejitsu/node-http-proxy/blob/ebbba73e/lib/node-http-proxy/http-proxy.js#L321-L322
|
||||
* https://github.com/nodejitsu/node-http-proxy/blob/05f0b891/lib/http-proxy/passes/web-incoming.js#L147
|
||||
*
|
||||
* This method modifies the response headers of the proxied response.
|
||||
* If a redirect is detected, the response is not sent to the client,
|
||||
* and a new request is initiated.
|
||||
*
|
||||
* @param response {ClientRequest} The response of the proxied request
|
||||
* @param req {IncomingMessage} Incoming HTTP request, augmented with property corsAnywhereRequestState
|
||||
* @param req.corsAnywhereRequestState {object}
|
||||
* @param req.corsAnywhereRequestState.location {object} See parseURL
|
||||
@@ -110,11 +107,10 @@ function proxyRequest(req, res, proxy) {
|
||||
* @param req.corsAnywhereRequestState.maxRedirects {number} Maximum number of redirects
|
||||
* @param req.corsAnywhereRequestState.redirectCount_ {number} Internally used to count redirects
|
||||
* @param res {ServerResponse} Outgoing (proxied) HTTP request
|
||||
* @param response {ClientRequest} The
|
||||
*
|
||||
* @this {HttpProxy}
|
||||
*/
|
||||
function onProxyResponse(req, res, response) {
|
||||
function onProxyResponse(response, req, res) {
|
||||
/* jshint validthis:true */
|
||||
var proxy = this;
|
||||
var requestState = req.corsAnywhereRequestState;
|
||||
@@ -145,28 +141,25 @@ function onProxyResponse(req, res, response) {
|
||||
requestState.location = parseURL(locationHeader);
|
||||
|
||||
// ### Dispose the current proxied request
|
||||
// Verified assumption: When proxy.proxyRequest is called for the first time,
|
||||
// there are no event listeners on the "req" object.
|
||||
|
||||
// First remove the "end" event, to avoid the req.end() call by node-http-proxy/http-proxy
|
||||
// https://github.com/nodejitsu/node-http-proxy/blob/ebbba73e/lib/node-http-proxy/http-proxy.js#L310-319
|
||||
response.removeAllListeners('end');
|
||||
// Trigger disposal of the reverseProxy
|
||||
// https://github.com/nodejitsu/node-http-proxy/blob/ebbba73e/lib/node-http-proxy/http-proxy.js#L375-L378
|
||||
req.emit('aborted');
|
||||
// Remove all listeners (=events reset to initial state)
|
||||
req.removeAllListeners();
|
||||
|
||||
// Initiate a new proxy request.
|
||||
proxyRequest(req, res, proxy);
|
||||
// Trigger reverseProxy.end() to initiate the proxy
|
||||
// The event listener is added at the end of HttpProxy.prototype.proxyRequest, synchronously.
|
||||
// https://github.com/nodejitsu/node-http-proxy/blob/ebbba73e/lib/node-http-proxy/http-proxy.js#L407-L415
|
||||
req.emit('end');
|
||||
|
||||
// The proxyResponse event is wrapped in a try-catch, throwing an error
|
||||
// prevents the response from being passed to the client.
|
||||
throw new Error('Prevent current response from being passed through.');
|
||||
// Haha - hack! This should be fixed when (if?) node-http-proxy supports cancelation of requests..
|
||||
// Shadow all methods that mutate the |res| object.
|
||||
// See https://github.com/nodejitsu/node-http-proxy/blob/05f0b891/lib/http-proxy/passes/web-outgoing.js
|
||||
var setHeader = res.setHeader;
|
||||
var writeHead = res.writeHead;
|
||||
res.setHeader = res.writeHead = function noop() {};
|
||||
response.on = function noop2() {};
|
||||
response.pipe = function(res) {
|
||||
res.setHeader = setHeader;
|
||||
res.writeHead = writeHead;
|
||||
// Trigger proxyReq.abort() (this is not of any imporance, it's just used to stop wasting resources.)
|
||||
// https://github.com/nodejitsu/node-http-proxy/blob/05f0b891/lib/http-proxy/passes/web-incoming.js#L125-L128
|
||||
req.emit('aborted');
|
||||
// Remove all listeners (=reset events to initial state)
|
||||
req.removeAllListeners();
|
||||
// Initiate a new proxy request.
|
||||
proxyRequest(req, res, proxy);
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
response.headers['location'] = requestState.proxyBaseUrl + '/' + locationHeader;
|
||||
@@ -214,7 +207,7 @@ function parseURL(req_url) {
|
||||
}
|
||||
|
||||
// Request handler factory
|
||||
var getHandler = exports.getHandler = function(options) {
|
||||
var getHandler = exports.getHandler = function(options, proxy) {
|
||||
var corsAnywhere = {
|
||||
maxRedirects: 5, // Maximum number of redirects to be followed.
|
||||
requireHeader: null, // Require a header to be set?
|
||||
@@ -245,7 +238,7 @@ var getHandler = exports.getHandler = function(options) {
|
||||
});
|
||||
};
|
||||
|
||||
return function(req, res, proxy) {
|
||||
return function(req, res) {
|
||||
var cors_headers = withCORS({}, req);
|
||||
if (req.method == 'OPTIONS') {
|
||||
// Pre-flight request. Reply successfully:
|
||||
@@ -278,7 +271,7 @@ var getHandler = exports.getHandler = function(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isValidHostName(location.hostname)) {
|
||||
if (!isValidHostName(location.hostname)) {
|
||||
// Don't even try to proxy invalid hosts (such as /favicon.ico, /robots.txt)
|
||||
res.writeHead(404, 'Invalid host', cors_headers);
|
||||
res.end('Invalid host: ' + location.hostname);
|
||||
@@ -305,11 +298,6 @@ var getHandler = exports.getHandler = function(options) {
|
||||
proxyBaseUrl: proxyBaseUrl
|
||||
};
|
||||
|
||||
if (!proxy.hasCorsAnywhereResponseHandler) { // Runs once per HttpProxy instance
|
||||
proxy.on('proxyResponse', onProxyResponse);
|
||||
proxy.hasCorsAnywhereResponseHandler = true;
|
||||
}
|
||||
|
||||
proxyRequest(req, res, proxy);
|
||||
};
|
||||
};
|
||||
@@ -321,9 +309,7 @@ exports.createServer = function createServer(options) {
|
||||
|
||||
// Default options:
|
||||
var httpProxyOptions = {
|
||||
xforward: {
|
||||
enable: true // Append X-Forwarded-* headers
|
||||
}
|
||||
xfwd: true, // Append X-Forwarded-* headers
|
||||
};
|
||||
// Allow user to override defaults and add own options
|
||||
if (options.httpProxyOptions) {
|
||||
@@ -332,14 +318,21 @@ exports.createServer = function createServer(options) {
|
||||
});
|
||||
}
|
||||
|
||||
var handler = getHandler(options);
|
||||
var server = httpProxy.createServer(httpProxyOptions, handler);
|
||||
var proxy = httpProxy.createServer(httpProxyOptions);
|
||||
var server = http.createServer(getHandler(options, proxy));
|
||||
|
||||
// When the server fails, just show a 404 instead of Internal server error
|
||||
server.proxy.on('proxyError', function(err, req, res) {
|
||||
proxy.on('error', function(err, req, res) {
|
||||
if (res._headerSent) {
|
||||
// E.g. when the server replies with an invalid Content-Length value,
|
||||
// causing the response to end as expected while triggering the
|
||||
// "HPE_INVALID_CONSTANT" error.
|
||||
return;
|
||||
}
|
||||
res.writeHead(404, {'Access-Control-Allow-Origin': '*'});
|
||||
res.end('Not found because of proxy error: ' + err);
|
||||
});
|
||||
proxy.on('proxyRes', onProxyResponse);
|
||||
|
||||
return server;
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "0.1.9",
|
||||
"description": "CORS Anywhere is a reverse proxy which adds CORS headers to the proxied request. Request URL is taken from the path",
|
||||
"license": "MIT",
|
||||
"author": "Rob Wu <gwnRob@gmail.com>",
|
||||
"author": "Rob Wu <rob@robwu.nl>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Rob--W/cors-anywhere.git"
|
||||
@@ -21,7 +21,7 @@
|
||||
],
|
||||
"main": "./lib/cors-anywhere.js",
|
||||
"dependencies": {
|
||||
"http-proxy": "~0.10"
|
||||
"http-proxy": "1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webkit-devtools-agent": "~0.2.1"
|
||||
|
||||
@@ -15,10 +15,8 @@ cors_proxy.createServer({
|
||||
'x-request-start'
|
||||
],
|
||||
httpProxyOptions: {
|
||||
enable: {
|
||||
// Do not add X-Forwarded-For, etc. headers, because Heroku already adds it.
|
||||
xforward: false
|
||||
}
|
||||
// Do not add X-Forwarded-For, etc. headers, because Heroku already adds it.
|
||||
xfwd: false
|
||||
}
|
||||
}).listen(port, host, function() {
|
||||
console.log('Running CORS Anywhere on ' + host + ':' + port);
|
||||
|
||||
Reference in New Issue
Block a user