Last active
December 2, 2021 10:25
-
-
Save hoshi-takanori/ca54044b3daa3e369463 to your computer and use it in GitHub Desktop.
Invoke CGI from Express.js.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var express = require('express'); | |
var cgi = require('./cgi'); | |
app = express(); | |
var script = __dirname + '/hello.cgi'; | |
app.get('/', cgi(script, function (req, options) { | |
options.env.USERNAME = 'Mr. User'; | |
})); | |
app.use(function (err, req, res, next) { | |
res.send(500, 'Error: ' + err.message); | |
}); | |
app.listen(process.env.PORT || 3000); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs'); | |
var url = require('url'); | |
var path = require('path'); | |
var spawn = require('child_process').spawn; | |
var CGIParser = require('cgi/parser'); | |
module.exports = function (cgiPath, callback) { | |
return function (req, res, next) { | |
try { | |
var stat = fs.statSync(cgiPath); | |
if (! stat.isFile() || (stat.mode & parseInt('111', 8)) == 0) { | |
return next(new Error('cgi file\'s mode = ' + stat.mode)); | |
} | |
} catch (err) { | |
return next(err); | |
} | |
var parsedUrl = url.parse(req.url); | |
var env = { | |
REQUEST_METHOD: req.method, | |
QUERY_STRING: parsedUrl.query || '' | |
}; | |
if ('content-length' in req.headers) { | |
env.CONTENT_LENGTH = req.headers['content-length']; | |
} | |
var options = { cwd: path.dirname(cgiPath), env: env }; | |
if (callback) callback(req, options); | |
var proc = spawn(cgiPath, [], options); | |
req.pipe(proc.stdin); | |
var result = new CGIParser(proc.stdout); | |
result.on('headers', function (headers) { | |
headers.forEach(function (header) { | |
if (header.key === 'Status') return; | |
res.setHeader(header.key, header.value); | |
}); | |
res.statusCode = parseInt(headers.status, 10) || 200; | |
result.pipe(res); | |
}); | |
proc.on('exit', function (code, signal) { | |
if (code || signal) { | |
next(new Error('cgi proc died: code = ' + code + ', signal = ' + signal)); | |
} | |
}); | |
proc.stdout.on('end', function () { | |
if (result) result.cleanup(); | |
}); | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
echo Status: 200 | |
echo Content-Type: text/plain | |
echo | |
echo Hello, $USERNAME! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "express-cgi", | |
"version": "0.0.1", | |
"private": true, | |
"scripts": { | |
"start": "node app" | |
}, | |
"dependencies": { | |
"express": "*", | |
"cgi": "*" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment