Skip to content
This repository has been archived by the owner on Jun 25, 2022. It is now read-only.

Commit

Permalink
Merge pull request #93 from technoboy10/v2
Browse files Browse the repository at this point in the history
Update master to v2.1.0
  • Loading branch information
technoboy10 authored Mar 29, 2017
2 parents bfa7974 + ea26043 commit 913d5ef
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 89 deletions.
65 changes: 62 additions & 3 deletions modules/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let serverHeadersBlacklist = new Set([
'connection',
]);

var sizeLimit = 2e6; //TODO: change this to something different depending on tier. It's fine for now.
/*
get handler handles standard GET reqs as well as streams
*/
Expand All @@ -31,7 +32,7 @@ function get (req, res, next) {
return res.end('Phrase in URL is disallowed.');
}

// require CORS header
// require Origin header
if (!requireHeader.some(header => req.headers[header])) {
res.statusCode = 403;
return res.end('Origin: header is required');
Expand All @@ -55,10 +56,14 @@ function get (req, res, next) {
headers['X-Fowarded-For'] = (forwardedFor ? forwardedFor + ',' : '') + req.connection.remoteAddress;

var data = 0; // This variable contains the size of the data (for limiting file size)
var limit = 2e6; //TODO: change this to something different depending on tier. It's fine for now.
request
.get(url, {headers}) // GET the document that the user specified
.on('response', function (page) {
// Check content length - if it's larger than the size limit, end the request with a 413 error.
if (Number(page.headers['content-length']) > sizeLimit) {
res.statusCode = 413;
res.end('ERROR 413: Maximum allowed size is ' + sizeLimit + ' bytes.');
}
res.statusCode = page.statusCode;

// if the page already supports cors, redirect to the URL directly
Expand All @@ -77,7 +82,7 @@ function get (req, res, next) {
})
.on('data', function (chunk) {
data += chunk.length;
if (data > limit){
if (data > sizeLimit){
res.abort(); // kills response and request cleanly
}
})
Expand All @@ -98,6 +103,60 @@ function post (req, res, next) {

function put (req, res, next) {
res.header('Access-Control-Allow-Origin', '*'); // Actually do the CORS thing! :)

var url = req.params[0];
var data = 0;

// require Origin header
if (!requireHeader.some(header => req.headers[header])) {
res.statusCode = 403;
return res.end('Origin: header is required');
}

// TODO redirect same origin
/* from cors-anywhere: 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). */

// forward client headers to server

var headers = {};
for (var header in req.headers) {
if (!clientHeadersBlacklist.has(header.toLowerCase())) {
headers[header] = req.headers[header];
}
}

var forwardedFor = req.headers['X-Fowarded-For'];
headers['X-Fowarded-For'] = (forwardedFor ? forwardedFor + ',' : '') + req.connection.remoteAddress;
req.pipe(
request
.put(url, {headers})
.on('data', function (chunk) {
data += chunk.length;
if (data > sizeLimit){
res.abort(); // kills response and request cleanly
}
})
.on('response', function (page) {
res.statusCode = page.statusCode;

// if the page already supports cors, redirect to the URL directly
if (page.headers['access-control-allow-origin'] === '*') { // TODO is this best?
res.redirect(url, next);
}

// include only desired headers
for (var header in page.headers) {
if (!serverHeadersBlacklist.has(header)) {
res.header(header, page.headers[header]);
}
}
// must flush here -- otherwise pipe() will include the headers anyway!
res.flushHeaders();
}));
next();
}

Expand Down
9 changes: 9 additions & 0 deletions modules/server.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const restify = require('restify');
const toobusy = require('toobusy-js');
var proxy = require('./proxy');

const server = restify.createServer({
Expand All @@ -7,6 +8,14 @@ const server = restify.createServer({

server.use(restify.queryParser({ mapParams: false }));

server.use(function (req, res, next) {
if (toobusy()) {
res.send(503, 'Server is overloaded! Please try again later.');
} else {
next();
}
});

const freeTier = restify.throttle({
rate: 3,
burst: 10,
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"dependencies": {
"request": "2.81.0",
"restify": "4.3.0",
"restify-router": "0.2.1"
"restify-router": "0.2.1",
"toobusy-js": "^0.5.1"
}
}
5 changes: 4 additions & 1 deletion tests/integration/limits.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ describe('Large file request', function () {
.expect(function (res) {
res.body.length < 2e6;
})
.expect(200, done);
.expect(function (res) {
res.statusCode == 200 || res.statusCode == 413;
})
.end(done);
});
});
Loading

0 comments on commit 913d5ef

Please sign in to comment.