mirror of
https://github.com/d0zingcat/cors-anywhere.git
synced 2026-05-13 23:16:51 +00:00
Add redirectSameOrigin
Some clients try to use CORS Anywhere, even for same-origin requests... Add a new setting "redirectSameOrigin" to not waste server resources on proxying such requests. Fixes #42
This commit is contained in:
@@ -97,6 +97,9 @@ proxy requests. The following options are supported:
|
||||
* array of strings `originWhitelist` - If set, requests whose origin is not listed are blocked.
|
||||
If this list is empty, all origins are allowed.
|
||||
Example: `['https://good.example.com', 'http://good.example.com']`
|
||||
* boolean `redirectSameOrigin` - If true, requests to URLs from the same origin will not be proxied but redirected.
|
||||
The primary purpose for this option is to save server resources by delegating the request to the client
|
||||
(since same-origin requests should always succeed, even without proxying).
|
||||
* array of strings `requireHeader` - If set, the request must include this header or the API will refuse to proxy.
|
||||
Recommended if you want to prevent users from using the proxy for normal browsing.
|
||||
Example: `['Origin', 'X-Requested-With']`.
|
||||
|
||||
@@ -213,6 +213,7 @@ function getHandler(options, proxy) {
|
||||
maxRedirects: 5, // Maximum number of redirects to be followed.
|
||||
originBlacklist: [], // Requests from these origins will be blocked.
|
||||
originWhitelist: [], // If non-empty, requests not from an origin in this list will be blocked.
|
||||
redirectSameOrigin: false, // Redirect the client to the requested URL for same-origin requests.
|
||||
requireHeader: null, // Require a header to be set?
|
||||
removeHeaders: [], // Strip these request headers.
|
||||
setHeaders: {}, // Set these request headers.
|
||||
@@ -302,6 +303,17 @@ function getHandler(options, proxy) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (corsAnywhere.redirectSameOrigin && origin && location.href[origin.length] === '/' &&
|
||||
location.href.lastIndexOf(origin, 0) === 0) {
|
||||
// Send a permanent redirect to offload the server. Badly coded clients should not waste our resources.
|
||||
cors_headers.vary = 'origin';
|
||||
cors_headers['cache-control'] = 'private';
|
||||
cors_headers.location = location.href;
|
||||
res.writeHead(301, 'Please use a direct request', cors_headers);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
var isRequestedOverHttps = req.connection.encrypted || /^\s*https/.test(req.headers['x-forwarded-proto']);
|
||||
var proxyBaseUrl = (isRequestedOverHttps ? 'https://' : 'http://') + req.headers.host;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ cors_proxy.createServer({
|
||||
'x-heroku-dynos-in-use',
|
||||
'x-request-start',
|
||||
],
|
||||
redirectSameOrigin: true,
|
||||
httpProxyOptions: {
|
||||
// Do not add X-Forwarded-For, etc. headers, because Heroku already adds it.
|
||||
xfwd: false,
|
||||
|
||||
@@ -102,6 +102,24 @@ nock('https://example.com')
|
||||
.reply(200, 'Response from https://example.com')
|
||||
;
|
||||
|
||||
nock('http://example.com.com')
|
||||
.persist()
|
||||
.get('/')
|
||||
.reply(200, 'Response from example.com.com')
|
||||
;
|
||||
|
||||
nock('http://example.com:1234')
|
||||
.persist()
|
||||
.get('/')
|
||||
.reply(200, 'Response from example.com:1234')
|
||||
;
|
||||
|
||||
nock('http://prefix.example.com')
|
||||
.persist()
|
||||
.get('/')
|
||||
.reply(200, 'Response from prefix.example.com')
|
||||
;
|
||||
|
||||
echoheaders('http://example.com');
|
||||
echoheaders('http://example.com:1337');
|
||||
echoheaders('https://example.com');
|
||||
|
||||
75
test/test.js
75
test/test.js
@@ -505,6 +505,81 @@ describe('originWhitelist', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('redirectSameOrigin', function() {
|
||||
before(function() {
|
||||
cors_anywhere = createServer({
|
||||
redirectSameOrigin: true,
|
||||
});
|
||||
cors_anywhere_port = cors_anywhere.listen(0).address().port;
|
||||
});
|
||||
after(stopServer);
|
||||
|
||||
it('GET /example.com with Origin: http://example.com', function(done) {
|
||||
request(cors_anywhere)
|
||||
.get('/example.com/')
|
||||
.set('Origin', 'http://example.com')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect('Cache-Control', 'private')
|
||||
.expect('Vary', 'origin')
|
||||
.expect('Location', 'http://example.com/')
|
||||
.expect(301, done);
|
||||
});
|
||||
|
||||
it('GET /example.com with Origin: https://example.com', function(done) {
|
||||
// Not same-origin because of different schemes.
|
||||
request(cors_anywhere)
|
||||
.get('/example.com/')
|
||||
.set('Origin', 'https://example.com')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect(200, 'Response from example.com', done);
|
||||
});
|
||||
|
||||
it('GET /example.com with Origin: http://example.com:1234', function(done) {
|
||||
// Not same-origin because of different ports.
|
||||
request(cors_anywhere)
|
||||
.get('/example.com/')
|
||||
.set('Origin', 'http://example.com:1234')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect(200, 'Response from example.com', done);
|
||||
});
|
||||
|
||||
it('GET /example.com:1234 with Origin: http://example.com', function(done) {
|
||||
// Not same-origin because of different ports.
|
||||
request(cors_anywhere)
|
||||
.get('/example.com:1234/')
|
||||
.set('Origin', 'http://example.com')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect(200, 'Response from example.com:1234', done);
|
||||
});
|
||||
|
||||
it('GET /example.com with Origin: http://example.com.test', function(done) {
|
||||
// Not same-origin because of different host names.
|
||||
request(cors_anywhere)
|
||||
.get('/example.com/')
|
||||
.set('Origin', 'http://example.com.test')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect(200, 'Response from example.com', done);
|
||||
});
|
||||
|
||||
it('GET /example.com.com with Origin: http://example.com', function(done) {
|
||||
// Not same-origin because of different host names.
|
||||
request(cors_anywhere)
|
||||
.get('/example.com.com/')
|
||||
.set('Origin', 'http://example.com')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect(200, 'Response from example.com.com', done);
|
||||
});
|
||||
|
||||
it('GET /prefix.example.com with Origin: http://example.com', function(done) {
|
||||
// Not same-origin because of different host names.
|
||||
request(cors_anywhere)
|
||||
.get('/prefix.example.com/')
|
||||
.set('Origin', 'http://example.com')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect(200, 'Response from prefix.example.com', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('requireHeader', function() {
|
||||
before(function() {
|
||||
cors_anywhere = createServer({
|
||||
|
||||
Reference in New Issue
Block a user