From c8098855f7996600aa22566c744a2187206f0d19 Mon Sep 17 00:00:00 2001 From: Nicolas Leclerc Date: Tue, 1 Jul 2014 01:14:03 +0200 Subject: [PATCH 1/2] Added option to ignore rewrite for existing file urls. --- README.md | 1 + gateway-rewrite.js | 169 +++++++++++++++++++++++---------------------- 2 files changed, 88 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index ad163ae..e0b79ef 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ var gateway_rw = require('gateway-rewrite'); var rwGateway = function (dir){ return gateway_rw(require('path').resolve(dir), { + // ignoreExistingFiles: true // Uncomment this line to allow fallthrough to following middleware when requesting a file that actually exists. rules: [ { rule: '^(/api/.+)', diff --git a/gateway-rewrite.js b/gateway-rewrite.js index d96014d..3d12f72 100644 --- a/gateway-rewrite.js +++ b/gateway-rewrite.js @@ -47,106 +47,111 @@ module.exports = function gateway_rewrite(docroot, options) { req.pause() - for (var j = 0; j < options.rules.length && !matches; j++) { - var rule = options.rules[j].rule; - var re = new RegExp(rule); - - if (url.pathname.match(re)) { - matches ++; - var handler = options.rules[j].cgi - var file = options.rules[j].to - var uri = url.pathname - var path = normalize(join(docroot, file)) - - // populate the environment - var host = (req.headers.host || '').split(':') - var env = { - SERVER_ROOT: docroot, - DOCUMENT_ROOT: docroot, - SERVER_NAME: host[0], - SERVER_PORT: host[1] || 80, - HTTPS: req.connection.encrypted ? 'On' : 'Off', - REDIRECT_STATUS: 200, - - SCRIPT_NAME: file, - REQUEST_URI: uri, - SCRIPT_FILENAME: path, - PATH_TRANSLATED: path, - REQUEST_METHOD: req.method, - QUERY_STRING: url.query || '', - GATEWAY_INTERFACE: 'CGI/1.1', - SERVER_PROTOCOL: 'HTTP/1.1', - PATH: process.env.PATH, - __proto__: options.env || {}, - - REMOTE_ADDR: '127.0.0.1' // Fake - } + var ignoreExistingFiles = options.ignoreExistingFiles + var requestedPath = join(docroot, url.pathname) + + if (!ignoreExistingFiles || !fs.lstatSync(requestedPath).isFile()) { + for (var j = 0; j < options.rules.length && !matches; j++) { + var rule = options.rules[j].rule; + var re = new RegExp(rule); + + if (url.pathname.match(re)) { + matches ++; + var handler = options.rules[j].cgi + var file = options.rules[j].to + var uri = url.pathname + var path = normalize(join(docroot, file)) + + // populate the environment + var host = (req.headers.host || '').split(':') + var env = { + SERVER_ROOT: docroot, + DOCUMENT_ROOT: docroot, + SERVER_NAME: host[0], + SERVER_PORT: host[1] || 80, + HTTPS: req.connection.encrypted ? 'On' : 'Off', + REDIRECT_STATUS: 200, + + SCRIPT_NAME: file, + REQUEST_URI: uri, + SCRIPT_FILENAME: path, + PATH_TRANSLATED: path, + REQUEST_METHOD: req.method, + QUERY_STRING: url.query || '', + GATEWAY_INTERFACE: 'CGI/1.1', + SERVER_PROTOCOL: 'HTTP/1.1', + PATH: process.env.PATH, + __proto__: options.env || {}, + + REMOTE_ADDR: '127.0.0.1' // Fake + } - // expose request headers - for (var header in req.headers) { - var name = 'HTTP_' + header.toUpperCase().replace(/-/g, '_') - env[name] = req.headers[header] - } + // expose request headers + for (var header in req.headers) { + var name = 'HTTP_' + header.toUpperCase().replace(/-/g, '_') + env[name] = req.headers[header] + } - if ('content-length' in req.headers) { - env.CONTENT_LENGTH = req.headers['content-length'] - } + if ('content-length' in req.headers) { + env.CONTENT_LENGTH = req.headers['content-length'] + } - if ('content-type' in req.headers) { - env.CONTENT_TYPE = req.headers['content-type'] - } + if ('content-type' in req.headers) { + env.CONTENT_TYPE = req.headers['content-type'] + } - var child = spawn(handler, [], { - 'env': env - }).on('exit', function (code) { - exit = code - done() - }) + var child = spawn(handler, [], { + 'env': env + }).on('exit', function (code) { + exit = code + done() + }) - var line = [] + var line = [] - child.stdout.on('end', done).on('data', function (buf) { + child.stdout.on('end', done).on('data', function (buf) { - if (body) { - return res.write(buf) - } + if (body) { + return res.write(buf) + } - for (var i = 0; i < buf.length; i++) { + for (var i = 0; i < buf.length; i++) { - var c = buf[i] + var c = buf[i] - if (c == 0xA) { - if (!line.length) { - body = true - res.writeHead(statusCode || 200, reason) - res.write(buf.slice(i + 1)) - return - } + if (c == 0xA) { + if (!line.length) { + body = true + res.writeHead(statusCode || 200, reason) + res.write(buf.slice(i + 1)) + return + } - var s = line.join('') - line = [] - if (!statusCode) { - var m = statusExp.exec(s) - if (m) { - statusCode = m[1] - reason = m[2] - continue; + var s = line.join('') + line = [] + if (!statusCode) { + var m = statusExp.exec(s) + if (m) { + statusCode = m[1] + reason = m[2] + continue; + } } - } - var idx = s.indexOf(':') - if ( !body ) { + var idx = s.indexOf(':') + if ( !body ) { + } + res.setHeader(s.slice(0, idx), s.slice(idx + 1).trim()) + } else if (c != 0xD) { + line.push(String.fromCharCode(c)) } - res.setHeader(s.slice(0, idx), s.slice(idx + 1).trim()) - } else if (c != 0xD) { - line.push(String.fromCharCode(c)) } - } - }) + }) - req.pipe(child.stdin) + req.pipe(child.stdin) + } } } From 4ae435dcc0ed1076a1a6d9a9b2985bc52ff7e81f Mon Sep 17 00:00:00 2001 From: Nicolas Leclerc Date: Tue, 1 Jul 2014 02:56:20 +0200 Subject: [PATCH 2/2] Fixed error when requesting file path that doesn't exist. --- gateway-rewrite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway-rewrite.js b/gateway-rewrite.js index 3d12f72..b10efad 100644 --- a/gateway-rewrite.js +++ b/gateway-rewrite.js @@ -50,7 +50,7 @@ module.exports = function gateway_rewrite(docroot, options) { var ignoreExistingFiles = options.ignoreExistingFiles var requestedPath = join(docroot, url.pathname) - if (!ignoreExistingFiles || !fs.lstatSync(requestedPath).isFile()) { + if (!ignoreExistingFiles || !fs.existsSync(requestedPath) || !fs.lstatSync(requestedPath).isFile()) { for (var j = 0; j < options.rules.length && !matches; j++) { var rule = options.rules[j].rule; var re = new RegExp(rule);