Add extra documentation (in code).

Removed ? from path's regexp, because
"http://cors-anywhere/" + "/domain.com/file" =
"http://cors-anywhere//domain.com/file" SHOULD be an invalid request.

"//domain.com/file" can be resolved to "http://domain.com/file", but
"/domain.com/file" should resolved to http://host/domain.com/file,
but since the host is unknown, the API should just fail.
This commit is contained in:
Rob Wu
2013-08-28 12:10:08 +02:00
parent 198e927baa
commit c37e496dee

View File

@@ -30,8 +30,13 @@ function showUsage(headers, response) {
}
}
/**
* Check whether the specified hostname is valid.
*
* @param hostname {string} Host name (excluding port) of requested resource.
* @return {boolean} Whether the requested resource can be accessed.
*/
function hasNoContent(hostname) {
// Show 404 for non-requests. For instance when hostname is favicon.ico, robots.txt, ...
return !(
regexp_tld.test(hostname) ||
net.isIPv4(hostname) ||
@@ -39,8 +44,12 @@ function hasNoContent(hostname) {
);
}
// First argument: The response.headers object
// Second argument: The request object.
/**
* Adds CORS headers to the response headers.
*
* @param headers {object} Response headers
* @param request {ServerRequest}
*/
function withCORS(headers, request) {
var origin = request.headers.origin || 'null';
headers['access-control-allow-origin'] = origin === 'null' ? '*' : origin;
@@ -61,9 +70,23 @@ function withCORS(headers, request) {
return headers;
}
/**
* @param host {string} Host name (excluding port) of requested resource
*/
function isForbidden(host) {
return false; // TODO
}
/**
* Performs the actual proxy request.
*
* @param req {ServerRequest} Incoming http request
* @param res {ServerResponse} Outgoing (proxied) http request
* @param proxy {HttpProxy}
* @param full_url {string} Canonical URL of outgoing (proxied) http request.
* @param isRequestedOverHttps {boolean} Whether the incoming request originates from https
*/
function proxyRequest(req, res, proxy, full_url, isRequestedOverHttps, proxyOptions) {
if (isForbidden(proxyOptions.host)) {
res.writeHead(403, 'Refused to visit', withCORS({'Location': full_url}, req));
@@ -142,7 +165,7 @@ var getHandler = exports.getHandler = function(options) {
} else {
// Actual request. First, extract the desired URL from the request:
var full_url, host, hostname, port, path, match, isHttps;
match = req.url.match(/^\/?(?:(https?:)?\/\/)?(([^\/?]+?)(?::(\d{0,5})(?=[\/?]|$))?)([\/?][\S\s]*|$)/i);
match = req.url.match(/^\/(?:(https?:)?\/\/)?(([^\/?]+?)(?::(\d{0,5})(?=[\/?]|$))?)([\/?][\S\s]*|$)/i);
// ^^^^^^^ ^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^
// 1:protocol 3:hostname 4:port 5:path + query string
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -162,12 +185,12 @@ var getHandler = exports.getHandler = function(options) {
} else if (match[4] > 65535) {
// Port is higher than 65535
res.writeHead(400, 'Invalid port', cors_headers);
res.end();
res.end('Invalid port: ' + match[4]);
return;
} else if ( hasNoContent(match[3]) ) {
// Don't even try to proxy invalid hosts
// Don't even try to proxy invalid hosts (such as /favicon.ico, /robots.txt)
res.writeHead(404, 'Invalid host', cors_headers);
res.end();
res.end('Invalid host: ' + match[3]);
return;
} else if (!hasRequiredHeaders(req.headers)) {
res.writeHead(400, 'Header required', cors_headers);