added static cors-anywhere
This commit is contained in:
12
cors-anywhere/test/cert.pem
Normal file
12
cors-anywhere/test/cert.pem
Normal file
@@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBsTCCARoCCQDp0DuED0RAJzANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJj
|
||||
b3JzLWFueXdoZXJlIHRlc3QwHhcNMTUwNTA2MDcyOTM1WhcNMTUwNjA1MDcyOTM1
|
||||
WjAdMRswGQYDVQQDDBJjb3JzLWFueXdoZXJlIHRlc3QwgZ8wDQYJKoZIhvcNAQEB
|
||||
BQADgY0AMIGJAoGBALzTF5ClJKvkB6h9h7kLORV+mMV3ySDs+oGZn0NgXM+yb9Zh
|
||||
69r5e95zZJl/V432LFdy0hkEcVteUkC2REWG8D4COGfiwWsXyZdaP1qqLpDpPAMm
|
||||
v6xFHjW6rVuxzfr4GUjE0Zh9Fg2R2SbtCOcHS/LZoDVOqOvn6+urP6XFY4aFAgMB
|
||||
AAEwDQYJKoZIhvcNAQELBQADgYEAYXMhS8ouff/c8lSUUs/CLh010cj5RPk/ivS7
|
||||
aN2PArzQ6pZvhpgJKf7XAQksBtLYYZMzIpG6W8zhPSbqzly7lELAdE+sxcbbfu8A
|
||||
FMjNVFQ2Fm1c8ImX8qpE3nhVrPAiwfPjGBqKHTl730gvbh1XH9TC4O4dZcbEomX3
|
||||
5MsxQfc=
|
||||
-----END CERTIFICATE-----
|
||||
64
cors-anywhere/test/child.js
Normal file
64
cors-anywhere/test/child.js
Normal file
@@ -0,0 +1,64 @@
|
||||
// When this module is loaded, CORS Anywhere is started.
|
||||
// Then, a request is generated to warm up the server (just in case).
|
||||
// Then the base URL of CORS Anywhere is sent to the parent process.
|
||||
// ...
|
||||
// When the parent process is done, it sends an empty message to this child
|
||||
// process, which in turn records the change in used heap space.
|
||||
// The difference in heap space is finally sent back to the parent process.
|
||||
// ...
|
||||
// The parent process should then kill this child.
|
||||
|
||||
process.on('uncaughtException', function(e) {
|
||||
console.error('Uncaught exception in child process: ' + e);
|
||||
console.error(e.stack);
|
||||
process.exit(-1);
|
||||
});
|
||||
|
||||
// Invoke memoryUsage() without using its result to make sure that any internal
|
||||
// datastructures that supports memoryUsage() is initialized and won't pollute
|
||||
// the memory usage measurement later on.
|
||||
process.memoryUsage();
|
||||
|
||||
var heapUsedStart = 0;
|
||||
function getMemoryUsage(callback) {
|
||||
// Note: Requires --expose-gc
|
||||
// 6 is the minimum amount of gc() calls before calling gc() again does not
|
||||
// reduce memory any more.
|
||||
for (var i = 0; i < 6; ++i) {
|
||||
global.gc();
|
||||
}
|
||||
callback(process.memoryUsage().heapUsed);
|
||||
}
|
||||
|
||||
var server;
|
||||
if (process.argv.indexOf('use-http-instead-of-cors-anywhere') >= 0) {
|
||||
server = require('http').createServer(function(req, res) { res.end(); });
|
||||
} else {
|
||||
server = require('../').createServer();
|
||||
}
|
||||
|
||||
server.listen(0, function() {
|
||||
// Perform 1 request to warm up.
|
||||
require('http').get({
|
||||
hostname: '127.0.0.1',
|
||||
port: server.address().port,
|
||||
path: '/http://invalid:99999',
|
||||
agent: false,
|
||||
}, function() {
|
||||
notifyParent();
|
||||
});
|
||||
|
||||
function notifyParent() {
|
||||
getMemoryUsage(function(usage) {
|
||||
heapUsedStart = usage;
|
||||
process.send('http://127.0.0.1:' + server.address().port + '/');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
process.once('message', function() {
|
||||
getMemoryUsage(function(heapUsedEnd) {
|
||||
var delta = heapUsedEnd - heapUsedStart;
|
||||
process.send(delta);
|
||||
});
|
||||
});
|
||||
7
cors-anywhere/test/customHelp.html
Normal file
7
cors-anywhere/test/customHelp.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Custom HTML help!!</h2>
|
||||
</body>
|
||||
</html>
|
||||
1
cors-anywhere/test/customHelp.txt
Normal file
1
cors-anywhere/test/customHelp.txt
Normal file
@@ -0,0 +1 @@
|
||||
Server is OK!!
|
||||
1
cors-anywhere/test/dummy.txt
Normal file
1
cors-anywhere/test/dummy.txt
Normal file
@@ -0,0 +1 @@
|
||||
dummy content
|
||||
15
cors-anywhere/test/key.pem
Normal file
15
cors-anywhere/test/key.pem
Normal file
@@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQC80xeQpSSr5AeofYe5CzkVfpjFd8kg7PqBmZ9DYFzPsm/WYeva
|
||||
+Xvec2SZf1eN9ixXctIZBHFbXlJAtkRFhvA+Ajhn4sFrF8mXWj9aqi6Q6TwDJr+s
|
||||
RR41uq1bsc36+BlIxNGYfRYNkdkm7QjnB0vy2aA1Tqjr5+vrqz+lxWOGhQIDAQAB
|
||||
AoGBAISy8OelN01Zlowxk/VWTsqtSl3UHdP21uHHfWaTTQZlxzTpYiBknkmp3LQH
|
||||
CxfoPidCuSX9ulBUzAdQUFBwUVp8wyPIRjpNyRiD58dLNxG0G+OACqnLxNWqIf6F
|
||||
vS3UqrRGIA5u+GSz+0g3DAeVA5JmsAyHQGkJsh3pcuD8/7wNAkEA7MScGfySy9td
|
||||
dDBekVU5/GaVg4DA4ELtDNfa99ARB89XP0ps/XrOPEL9yxTjWIHH+qxuhpfG6zGN
|
||||
ouxZlvBT9wJBAMwpig4A4JE8M8pBDwMY4213gud8B1grQTbhz5bv51aTaIEQFcxw
|
||||
sGfEmAfVToI+kVTrdFggy42YCSMSvwuF4mMCQQDZHkqPwf/TlSwT2i8+UstD28aL
|
||||
uswkWvsKZf9UdKbJZKd7UIK1x6HLvRsC2frJNOnvw6PvJMuy7dQWbWqScXxtAkBv
|
||||
/5msdO68vbnriiUiHdUliBpXwsKEq7Xq1ZV7x7+wzszVgG106ZzcUAzWvz2CVbCE
|
||||
VWZNsi/4TR82DmKff6LhAkBA/xceWaZjxh5dkWkIrMFWd2GFhGlpfwYw7oELwRL8
|
||||
RYXzc1Mr2fDdZDgwgjg67JQqIhOQ3E4RGKPgZ+E7Pk3/
|
||||
-----END RSA PRIVATE KEY-----
|
||||
152
cors-anywhere/test/setup.js
Normal file
152
cors-anywhere/test/setup.js
Normal file
@@ -0,0 +1,152 @@
|
||||
var nock = require('nock');
|
||||
if (parseInt(process.versions.node, 10) >= 8) {
|
||||
// See DEP0066 at https://nodejs.org/api/deprecations.html.
|
||||
// _headers and _headerNames have been removed from Node v8, which causes
|
||||
// nock <= 9.0.13 to fail. The snippet below monkey-patches the library, see
|
||||
// https://github.com/node-nock/nock/pull/929/commits/f6369d0edd2a172024124f
|
||||
// for the equivalent logic without proxies.
|
||||
Object.defineProperty(require('http').ClientRequest.prototype, '_headers', {
|
||||
get: function() {
|
||||
var request = this;
|
||||
// eslint-disable-next-line no-undef
|
||||
return new Proxy(request.getHeaders(), {
|
||||
set: function(target, property, value) {
|
||||
request.setHeader(property, value);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
},
|
||||
set: function() {
|
||||
// Ignore.
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
nock.enableNetConnect('127.0.0.1');
|
||||
|
||||
function echoheaders(origin) {
|
||||
nock(origin)
|
||||
.persist()
|
||||
.get('/echoheaders')
|
||||
.reply(function() {
|
||||
var headers = this.req.headers;
|
||||
var excluded_headers = [
|
||||
'accept-encoding',
|
||||
'user-agent',
|
||||
'connection',
|
||||
// Remove this header since its value is platform-specific.
|
||||
'x-forwarded-for',
|
||||
'test-include-xfwd',
|
||||
];
|
||||
if (!('test-include-xfwd' in headers)) {
|
||||
excluded_headers.push('x-forwarded-port');
|
||||
excluded_headers.push('x-forwarded-proto');
|
||||
}
|
||||
var response = {};
|
||||
Object.keys(headers).forEach(function(name) {
|
||||
if (excluded_headers.indexOf(name) === -1) {
|
||||
response[name] = headers[name];
|
||||
}
|
||||
});
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
nock('http://example.com')
|
||||
.persist()
|
||||
.get('/')
|
||||
.reply(200, 'Response from example.com')
|
||||
|
||||
.post('/echopost')
|
||||
.reply(200, function(uri, requestBody) {
|
||||
return requestBody;
|
||||
})
|
||||
|
||||
.get('/setcookie')
|
||||
.reply(200, '', {
|
||||
'Set-Cookie': 'x',
|
||||
'Set-Cookie2': 'y',
|
||||
'Set-Cookie3': 'z', // This is not a special cookie setting header.
|
||||
})
|
||||
|
||||
.get('/redirecttarget')
|
||||
.reply(200, 'redirect target', {
|
||||
'Some-header': 'value',
|
||||
})
|
||||
|
||||
.head('/redirect')
|
||||
.reply(302, '', {
|
||||
Location: '/redirecttarget',
|
||||
})
|
||||
|
||||
.get('/redirect')
|
||||
.reply(302, 'redirecting...', {
|
||||
'header at redirect': 'should not be here',
|
||||
Location: '/redirecttarget',
|
||||
})
|
||||
|
||||
.get('/redirectposttarget')
|
||||
.reply(200, 'post target')
|
||||
|
||||
.post('/redirectposttarget')
|
||||
.reply(200, 'post target (POST)')
|
||||
|
||||
.post('/redirectpost')
|
||||
.reply(302, 'redirecting...', {
|
||||
Location: '/redirectposttarget',
|
||||
})
|
||||
|
||||
.post('/redirect307')
|
||||
.reply(307, 'redirecting...', {
|
||||
Location: '/redirectposttarget',
|
||||
})
|
||||
|
||||
.get('/redirect2redirect')
|
||||
.reply(302, 'redirecting to redirect...', {
|
||||
Location: '/redirect',
|
||||
})
|
||||
|
||||
.get('/redirectloop')
|
||||
.reply(302, 'redirecting ad infinitum...', {
|
||||
Location: '/redirectloop',
|
||||
})
|
||||
|
||||
.get('/redirectwithoutlocation')
|
||||
.reply(302, 'maybe found')
|
||||
|
||||
.get('/proxyerror')
|
||||
.replyWithError('throw node')
|
||||
;
|
||||
|
||||
nock('https://example.com')
|
||||
.persist()
|
||||
.get('/')
|
||||
.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');
|
||||
echoheaders('https://example.com:1337');
|
||||
|
||||
nock('http://robots.txt')
|
||||
.get('/')
|
||||
.reply(200, 'this is http://robots.txt');
|
||||
133
cors-anywhere/test/test-examples.js
Normal file
133
cors-anywhere/test/test-examples.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* CORS Anywhere is designed for use as a standalone server. Sometimes you want
|
||||
* to have extra functionality on top of the default CORS server. If it may be
|
||||
* useful to others, please open a feature request on the issue tracker at
|
||||
* https://github.com/Rob--W/cors-anywhere/issues.
|
||||
*
|
||||
* If it is only useful to your application, look below for some examples.
|
||||
* These examples are provided as-is without guarantees. Use at your own risk.
|
||||
*/
|
||||
|
||||
/* eslint-env mocha */
|
||||
require('./setup');
|
||||
|
||||
var createServer = require('../').createServer;
|
||||
var assert = require('assert');
|
||||
var request = require('supertest');
|
||||
|
||||
var http = require('http');
|
||||
|
||||
describe('Examples', function() {
|
||||
// Note: In the examples below we don't listen on any port after calling
|
||||
// createServer() because it is not needed to start listening on a port if the
|
||||
// CORS Anywhere is only used internally.
|
||||
|
||||
// And normally you have to listen on some port, like this:
|
||||
//
|
||||
// http_server.listen(port_number);
|
||||
//
|
||||
// But in these test, the call to request() automatically handles that part so
|
||||
// the examples don't have an explicit .listen() call.
|
||||
|
||||
it('Rewrite proxy URL', function(done) {
|
||||
var cors_anywhere = createServer();
|
||||
|
||||
var http_server = http.createServer(function(req, res) {
|
||||
// For testing, check whether req.url is the same as what we input below.
|
||||
assert.strictEqual(req.url, '/dummy-for-testing');
|
||||
|
||||
// Basic example: Always proxy example.com.
|
||||
req.url = '/http://example.com';
|
||||
|
||||
cors_anywhere.emit('request', req, res);
|
||||
});
|
||||
|
||||
request(http_server)
|
||||
.get('/dummy-for-testing')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect('x-request-url', 'http://example.com/')
|
||||
.expect(200, 'Response from example.com', done);
|
||||
});
|
||||
|
||||
it('Transform response to uppercase (streaming)', function(done) {
|
||||
var cors_anywhere = createServer();
|
||||
|
||||
var http_server = http.createServer(function(req, res) {
|
||||
var originalWrite = res.write;
|
||||
|
||||
res.write = function(data, encoding, callback) {
|
||||
if (Buffer.isBuffer(data)) {
|
||||
data = data.toString();
|
||||
}
|
||||
|
||||
assert.strictEqual(typeof data, 'string');
|
||||
|
||||
// This example shows how to transform the response to upper case.
|
||||
data = data.toUpperCase();
|
||||
|
||||
originalWrite.call(this, data, encoding, callback);
|
||||
};
|
||||
|
||||
cors_anywhere.emit('request', req, res);
|
||||
});
|
||||
|
||||
request(http_server)
|
||||
.get('/example.com')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect('x-request-url', 'http://example.com/')
|
||||
.expect(200, 'RESPONSE FROM EXAMPLE.COM', done);
|
||||
});
|
||||
|
||||
it('Transform response to uppercase (buffered)', function(done) {
|
||||
var cors_anywhere = createServer();
|
||||
|
||||
var http_server = http.createServer(function(req, res) {
|
||||
var originalWrite = res.write;
|
||||
var originalEnd = res.end;
|
||||
|
||||
var buffers = [];
|
||||
|
||||
res.write = function(data, encoding, callback) {
|
||||
assert.ok(Buffer.isBuffer(data) || typeof data === 'string');
|
||||
|
||||
buffers.push(data);
|
||||
if (callback) {
|
||||
process.nextTick(callback, null);
|
||||
}
|
||||
};
|
||||
res.end = function(data, encoding, callback) {
|
||||
if (data) {
|
||||
this.write(data, encoding);
|
||||
}
|
||||
|
||||
// After calling .end(), .write shouldn't be called any more. So let's
|
||||
// restore it so that the default error handling for writing to closed
|
||||
// streams would occur.
|
||||
this.write = originalWrite;
|
||||
|
||||
// Combine all chunks. Note that we're assuming that all chunks are
|
||||
// utf8 strings or buffers whose content is utf8-encoded. If this
|
||||
// assumption is not true, then you have to update the .write method
|
||||
// above.
|
||||
data = buffers.join('');
|
||||
|
||||
// This example shows how to transform the response to upper case.
|
||||
data = data.toUpperCase();
|
||||
|
||||
// .end should be called once, so let's restore it so that any default
|
||||
// error handling occurs if it occurs again.
|
||||
this.end = originalEnd;
|
||||
this.end(data, 'utf8', callback);
|
||||
};
|
||||
|
||||
cors_anywhere.emit('request', req, res);
|
||||
});
|
||||
|
||||
request(http_server)
|
||||
.get('/example.com')
|
||||
.expect('Access-Control-Allow-Origin', '*')
|
||||
.expect('x-request-url', 'http://example.com/')
|
||||
.expect(200, 'RESPONSE FROM EXAMPLE.COM', done);
|
||||
});
|
||||
});
|
||||
|
||||
111
cors-anywhere/test/test-memory.js
Normal file
111
cors-anywhere/test/test-memory.js
Normal file
@@ -0,0 +1,111 @@
|
||||
/* eslint-env mocha */
|
||||
// Run this specific test using:
|
||||
// npm test -- -f memory
|
||||
var http = require('http');
|
||||
var path = require('path');
|
||||
var url = require('url');
|
||||
var fork = require('child_process').fork;
|
||||
|
||||
describe('memory usage', function() {
|
||||
var cors_api_url;
|
||||
|
||||
var server;
|
||||
var cors_anywhere_child;
|
||||
before(function(done) {
|
||||
server = http.createServer(function(req, res) {
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
}).listen(0, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
server.close(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(function(done) {
|
||||
var cors_module_path = path.join(__dirname, 'child');
|
||||
var args = [];
|
||||
// Uncomment this if you want to compare the performance of CORS Anywhere
|
||||
// with the standard no-op http module.
|
||||
// args.push('use-http-instead-of-cors-anywhere');
|
||||
cors_anywhere_child = fork(cors_module_path, args, {
|
||||
execArgv: ['--expose-gc'],
|
||||
});
|
||||
cors_anywhere_child.once('message', function(cors_url) {
|
||||
cors_api_url = cors_url;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
cors_anywhere_child.kill();
|
||||
});
|
||||
|
||||
/**
|
||||
* Perform N CORS Anywhere proxy requests to a simple test server.
|
||||
*
|
||||
* @param {number} n - number of repetitions.
|
||||
* @param {number} requestSize - Approximate size of request in kilobytes.
|
||||
* @param {number} memMax - Expected maximum memory usage in kilobytes.
|
||||
* @param {function} done - Upon success, called without arguments.
|
||||
* Upon failure, called with the error as parameter.
|
||||
*/
|
||||
function performNRequests(n, requestSize, memMax, done) {
|
||||
var remaining = n;
|
||||
var request = url.parse(
|
||||
cors_api_url + 'http://127.0.0.1:' + server.address().port);
|
||||
request.agent = false; // Force Connection: Close
|
||||
request.headers = {
|
||||
'Long-header': new Array(requestSize * 1e3).join('x'),
|
||||
};
|
||||
(function requestAgain() {
|
||||
if (remaining-- === 0) {
|
||||
cors_anywhere_child.once('message', function(memory_usage_delta) {
|
||||
console.log('Memory usage delta: ' + memory_usage_delta +
|
||||
' (' + n + ' requests of ' + requestSize + ' kb each)');
|
||||
if (memory_usage_delta > memMax * 1e3) {
|
||||
// Note: Even if this error is reached, always profile (e.g. using
|
||||
// node-inspector) whether it is a true leak, and not e.g. noise
|
||||
// caused by the implementation of V8/Node.js.
|
||||
// Uncomment args.push('use-http-instead-of-cors-anywhere') at the
|
||||
// fork() call to get a sense of what's normal.
|
||||
throw new Error('Possible memory leak: ' + memory_usage_delta +
|
||||
' bytes was not released, which exceeds the ' + memMax +
|
||||
' kb limit by ' +
|
||||
Math.round(memory_usage_delta / memMax / 10 - 100) + '%.');
|
||||
}
|
||||
done();
|
||||
});
|
||||
cors_anywhere_child.send(null);
|
||||
return;
|
||||
}
|
||||
http.request(request, function() {
|
||||
requestAgain();
|
||||
}).on('error', function(error) {
|
||||
done(error);
|
||||
}).end();
|
||||
})();
|
||||
}
|
||||
|
||||
it('100 GET requests 50k', function(done) {
|
||||
// This test is just for comparison with the following tests.
|
||||
performNRequests(100, 50, 1200, done);
|
||||
});
|
||||
|
||||
// 100x 1k and 100x 50k for comparison.
|
||||
// Both should use about the same amount of memory if there is no leak.
|
||||
it('1000 GET requests 1k', function(done) {
|
||||
// Every request should complete within 10ms.
|
||||
this.timeout(1000 * 10);
|
||||
performNRequests(1000, 1, 2000, done);
|
||||
});
|
||||
it('1000 GET requests 50k', function(done) {
|
||||
// Every request should complete within 10ms.
|
||||
this.timeout(1000 * 10);
|
||||
performNRequests(1000, 50, 2000, done);
|
||||
});
|
||||
});
|
||||
231
cors-anywhere/test/test-ratelimit.js
Normal file
231
cors-anywhere/test/test-ratelimit.js
Normal file
@@ -0,0 +1,231 @@
|
||||
/* eslint-env mocha */
|
||||
|
||||
var createRateLimitChecker = require('../lib/rate-limit');
|
||||
|
||||
var lolex = require('lolex');
|
||||
var assert = require('assert');
|
||||
|
||||
function assertNotLimited(rateLimitReturnValue) {
|
||||
if (rateLimitReturnValue) {
|
||||
assert.fail('Expected no limit, but got ' + rateLimitReturnValue);
|
||||
}
|
||||
}
|
||||
|
||||
function assertLimited(rateLimitReturnValue, limit, period) {
|
||||
var msg;
|
||||
if (period === 1) {
|
||||
msg = 'The number of requests is limited to ' + limit + ' per minute. ';
|
||||
} else {
|
||||
msg = 'The number of requests is limited to ' + limit + ' per ' + period + ' minutes. ';
|
||||
}
|
||||
msg += 'Please self-host CORS Anywhere if you need more quota. ' +
|
||||
'See https://github.com/Rob--W/cors-anywhere#demo-server';
|
||||
assert.equal(rateLimitReturnValue, msg);
|
||||
}
|
||||
|
||||
describe('Rate limit', function() {
|
||||
var clock;
|
||||
beforeEach(function() {
|
||||
clock = lolex.install();
|
||||
});
|
||||
afterEach(function() {
|
||||
clock.uninstall();
|
||||
});
|
||||
it('is unlimited by default', function() {
|
||||
var checkRateLimit = createRateLimitChecker();
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertNotLimited(checkRateLimit('https://example.com'));
|
||||
assertNotLimited(checkRateLimit('https://example.com:1234'));
|
||||
|
||||
checkRateLimit = createRateLimitChecker('');
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
|
||||
checkRateLimit = createRateLimitChecker(' ');
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
});
|
||||
|
||||
it('zero per minute / 5 minutes', function() {
|
||||
var checkRateLimit = createRateLimitChecker('0 1');
|
||||
assertLimited(checkRateLimit('http://example.com'), 0, 1);
|
||||
assertLimited(checkRateLimit('https://example.com'), 0, 1);
|
||||
|
||||
checkRateLimit = createRateLimitChecker('0 5');
|
||||
assertLimited(checkRateLimit('http://example.com'), 0, 5);
|
||||
assertLimited(checkRateLimit('https://example.com'), 0, 5);
|
||||
});
|
||||
|
||||
it('one per minute', function() {
|
||||
var checkRateLimit = createRateLimitChecker('1 1');
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertLimited(checkRateLimit('http://example.com'), 1, 1);
|
||||
assertNotLimited(checkRateLimit('http://example.com:1234'));
|
||||
assertLimited(checkRateLimit('http://example.com:1234'), 1, 1);
|
||||
|
||||
clock.tick(59000);
|
||||
assertLimited(checkRateLimit('http://example.com'), 1, 1);
|
||||
|
||||
clock.tick(1000);
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertLimited(checkRateLimit('http://example.com'), 1, 1);
|
||||
assertNotLimited(checkRateLimit('http://example.com:1234'));
|
||||
assertLimited(checkRateLimit('http://example.com:1234'), 1, 1);
|
||||
});
|
||||
|
||||
it('different domains, one per minute', function() {
|
||||
var checkRateLimit = createRateLimitChecker('1 1');
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertNotLimited(checkRateLimit('http://example.net'));
|
||||
assertNotLimited(checkRateLimit('http://wexample.net'));
|
||||
assertNotLimited(checkRateLimit('http://xample.net'));
|
||||
assertNotLimited(checkRateLimit('http://www.example.net'));
|
||||
assertLimited(checkRateLimit('http://example.com'), 1, 1);
|
||||
assertLimited(checkRateLimit('http://example.net'), 1, 1);
|
||||
assertLimited(checkRateLimit('http://wexample.net'), 1, 1);
|
||||
assertLimited(checkRateLimit('http://xample.net'), 1, 1);
|
||||
assertLimited(checkRateLimit('http://www.example.net'), 1, 1);
|
||||
|
||||
clock.tick(60000); // 1 minute
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertNotLimited(checkRateLimit('http://example.net'));
|
||||
assertNotLimited(checkRateLimit('http://wexample.net'));
|
||||
assertNotLimited(checkRateLimit('http://xample.net'));
|
||||
assertNotLimited(checkRateLimit('http://www.example.net'));
|
||||
});
|
||||
|
||||
it('unlimited domains, string', function() {
|
||||
var checkRateLimit = createRateLimitChecker('1 2 example.com');
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
|
||||
assertNotLimited(checkRateLimit('http://wexample.com'));
|
||||
assertNotLimited(checkRateLimit('http://xample.com'));
|
||||
assertNotLimited(checkRateLimit('http://www.example.com'));
|
||||
assertLimited(checkRateLimit('http://wexample.com'), 1, 2);
|
||||
assertLimited(checkRateLimit('http://xample.com'), 1, 2);
|
||||
assertLimited(checkRateLimit('http://www.example.com'), 1, 2);
|
||||
});
|
||||
|
||||
it('unlimited domains, RegExp', function() {
|
||||
var checkRateLimit = createRateLimitChecker('1 2 /example\\.com/');
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
|
||||
assertNotLimited(checkRateLimit('http://wexample.com'));
|
||||
assertNotLimited(checkRateLimit('http://xample.com'));
|
||||
assertNotLimited(checkRateLimit('http://www.example.com'));
|
||||
assertLimited(checkRateLimit('http://wexample.com'), 1, 2);
|
||||
assertLimited(checkRateLimit('http://xample.com'), 1, 2);
|
||||
assertLimited(checkRateLimit('http://www.example.com'), 1, 2);
|
||||
});
|
||||
|
||||
it('multiple domains, string', function() {
|
||||
var checkRateLimit = createRateLimitChecker('1 2 a b cc ');
|
||||
assertNotLimited(checkRateLimit('http://a'));
|
||||
assertNotLimited(checkRateLimit('http://a'));
|
||||
assertNotLimited(checkRateLimit('http://b'));
|
||||
assertNotLimited(checkRateLimit('http://b'));
|
||||
assertNotLimited(checkRateLimit('http://cc'));
|
||||
assertNotLimited(checkRateLimit('http://cc'));
|
||||
assertNotLimited(checkRateLimit('http://c'));
|
||||
assertLimited(checkRateLimit('http://c'), 1, 2);
|
||||
});
|
||||
|
||||
it('multiple domains, RegExp', function() {
|
||||
var checkRateLimit = createRateLimitChecker('1 2 /a/ /b/ /cc/ ');
|
||||
assertNotLimited(checkRateLimit('http://a'));
|
||||
assertNotLimited(checkRateLimit('http://a'));
|
||||
assertNotLimited(checkRateLimit('http://b'));
|
||||
assertNotLimited(checkRateLimit('http://b'));
|
||||
assertNotLimited(checkRateLimit('http://cc'));
|
||||
assertNotLimited(checkRateLimit('http://cc'));
|
||||
assertNotLimited(checkRateLimit('http://ccc'));
|
||||
assertLimited(checkRateLimit('http://ccc'), 1, 2);
|
||||
});
|
||||
|
||||
it('multiple domains, string and RegExp', function() {
|
||||
var checkRateLimit = createRateLimitChecker('1 2 a /b/');
|
||||
assertNotLimited(checkRateLimit('http://a'));
|
||||
assertNotLimited(checkRateLimit('http://a'));
|
||||
assertNotLimited(checkRateLimit('http://b'));
|
||||
assertNotLimited(checkRateLimit('http://b'));
|
||||
assertNotLimited(checkRateLimit('http://ab'));
|
||||
assertLimited(checkRateLimit('http://ab'), 1, 2);
|
||||
});
|
||||
|
||||
it('multiple domains, RegExp and string', function() {
|
||||
var checkRateLimit = createRateLimitChecker('1 2 /a/ b');
|
||||
assertNotLimited(checkRateLimit('http://a'));
|
||||
assertNotLimited(checkRateLimit('http://a'));
|
||||
assertNotLimited(checkRateLimit('http://b'));
|
||||
assertNotLimited(checkRateLimit('http://b'));
|
||||
assertNotLimited(checkRateLimit('http://ab'));
|
||||
assertLimited(checkRateLimit('http://ab'), 1, 2);
|
||||
});
|
||||
|
||||
it('wildcard subdomains', function() {
|
||||
var checkRateLimit = createRateLimitChecker('0 1 /(.*\\.)?example\\.com/');
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertNotLimited(checkRateLimit('http://www.example.com'));
|
||||
assertLimited(checkRateLimit('http://xexample.com'), 0, 1);
|
||||
assertLimited(checkRateLimit('http://example.com.br'), 0, 1);
|
||||
});
|
||||
|
||||
it('wildcard ports', function() {
|
||||
var checkRateLimit = createRateLimitChecker('0 1 /example\\.com(:\\d{1,5})?/');
|
||||
assertNotLimited(checkRateLimit('http://example.com'));
|
||||
assertNotLimited(checkRateLimit('http://example.com:1234'));
|
||||
});
|
||||
|
||||
it('empty host', function() {
|
||||
var checkRateLimit = createRateLimitChecker('0 1');
|
||||
assertLimited(checkRateLimit(''), 0, 1);
|
||||
// Empty host actually means empty origin. But let's also test for 'http://'.
|
||||
assertLimited(checkRateLimit('http://'), 0, 1);
|
||||
|
||||
checkRateLimit = createRateLimitChecker('0 1 ');
|
||||
assertLimited(checkRateLimit(''), 0, 1);
|
||||
assertLimited(checkRateLimit('http://'), 0, 1);
|
||||
|
||||
checkRateLimit = createRateLimitChecker('0 1 //');
|
||||
assertNotLimited(checkRateLimit(''));
|
||||
assertNotLimited(checkRateLimit('http://'));
|
||||
});
|
||||
|
||||
it('null origin', function() {
|
||||
var checkRateLimit = createRateLimitChecker('0 1');
|
||||
assertLimited(checkRateLimit('null'), 0, 1);
|
||||
assertLimited(checkRateLimit('http://null'), 0, 1);
|
||||
|
||||
checkRateLimit = createRateLimitChecker('0 1 null');
|
||||
assertNotLimited(checkRateLimit('null'));
|
||||
assertNotLimited(checkRateLimit('http://null'));
|
||||
|
||||
checkRateLimit = createRateLimitChecker('0 1 /null/');
|
||||
assertNotLimited(checkRateLimit('null'));
|
||||
assertNotLimited(checkRateLimit('http://null'));
|
||||
});
|
||||
|
||||
it('case-insensitive', function() {
|
||||
var checkRateLimit = createRateLimitChecker('0 1 NULL');
|
||||
assertNotLimited(checkRateLimit('null'));
|
||||
assertNotLimited(checkRateLimit('http://null'));
|
||||
|
||||
checkRateLimit = createRateLimitChecker('0 1 /NULL/');
|
||||
assertNotLimited(checkRateLimit('null'));
|
||||
assertNotLimited(checkRateLimit('http://null'));
|
||||
});
|
||||
|
||||
it('bad input', function() {
|
||||
assert.throws(function() {
|
||||
createRateLimitChecker('0 1 /');
|
||||
}, /Invalid CORSANYWHERE_RATELIMIT\. Regex at index 0 must start and end with a slash \("\/"\)\./);
|
||||
|
||||
assert.throws(function() {
|
||||
createRateLimitChecker('0 1 a /');
|
||||
}, /Invalid CORSANYWHERE_RATELIMIT\. Regex at index 1 must start and end with a slash \("\/"\)\./);
|
||||
|
||||
assert.throws(function() {
|
||||
createRateLimitChecker('0 1 /(/');
|
||||
}, /Invalid regular expression/);
|
||||
});
|
||||
});
|
||||
1080
cors-anywhere/test/test.js
Normal file
1080
cors-anywhere/test/test.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user