koa-plugins/plugins/php/phpfpm.js
2020-03-01 17:38:34 +01:00

176 lines
No EOL
3.6 KiB
JavaScript

/**
* phpfpm-framework, call php scripts (index.php for frameworks) by fastcgi
*
* @author Chunlong longbill longbill.cn@gmail.com
* @author Alexandre Kalendarev akalend@mail.ru
* @author Soldovskij Boris soldovskij@hotmail.com
*/
var fastcgiConnector = require('fastcgi-client');
module.exports = phpfpm;
/**
* phpfpm
* @param options
*
* default options will be { host:127.0.0.1, port:9000 }
*/
function phpfpm(options)
{
options = options || {};
!options.host && (options.host = '127.0.0.1');
!options.port && (options.port = 9000);
!options.documentRoot && (options.documentRoot = '');
this.options = options;
var self = this;
options.skipCheckServer = true;
this.client = fastcgiConnector(options);
this.ready = false;
this.client.on('ready', function()
{
self.ready = true;
self._clearQueue();
});
this.queue = [];
this.PARAMS =
{
QUERY_STRING: '',
REQUEST_METHOD: '',
CONTENT_TYPE: '',
CONTENT_LENGTH: '',
SCRIPT_FILENAME: '',
SCRIPT_NAME: '',
REQUEST_URI: '',
DOCUMENT_URI: '',
DOCUMENT_ROOT: '',
SERVER_PROTOCOL: 'HTTP/1.1',
GATEWAY_INTERFACE: 'CGI/1.1',
REMOTE_ADDR: '127.0.0.1',
REMOTE_PORT: 1234,
SERVER_ADDR: '127.0.0.1',
SERVER_PORT: 80,
SERVER_NAME: '127.0.0.1',
SERVER_SOFTWARE: 'node-phpfpm',
REDIRECT_STATUS: 200
};
}
/**
* clear the queued tasks after connected to phpfpm
*/
phpfpm.prototype._clearQueue = function()
{
var evt;
while(evt = this.queue.shift())
{
this.run(evt.info, evt.cb);
}
};
phpfpm.prototype.setParam = function(paramName, value)
{
this.PARAMS[paramName] = value;
}
/**
* send command to phpfpm to run a php script
*/
phpfpm.prototype.run = function(info, cb)
{
if (typeof info == 'string') info = { method: 'GET', uri: info };
if (info.url && !info.uri) info.uri = info.url;
if (!this.ready)
{
this.queue.push({info: info, cb:cb});
return;
}
if (info.body && !info.method) info.method = 'POST';
//support json data
if (info.json)
{
info.body = JSON.stringify(info.json);
!info.method && (info.method = 'POST');
info.contentType = 'application/json';
}
!info.method && (info.method = 'GET');
info.method = info.method.toUpperCase();
var uri_ini = info.uri;
var phpfile = info.uri;
// if (!phpfile.match(/^\//))
phpfile = this.options.documentRoot + phpfile;
this.setParam('QUERY_STRING', info.queryString.split('?').pop());
this.setParam('REQUEST_METHOD', info.method);
this.setParam('CONTENT_TYPE', info.contentType || '');
this.setParam('CONTENT_LENGTH', info.contentLength || '');
this.setParam('SCRIPT_FILENAME', phpfile);
this.setParam('SCRIPT_NAME', phpfile.split('/').pop());
this.setParam('REQUEST_URI', info.queryString);
this.setParam('DOCUMENT_URI', phpfile);
this.setParam('DOCUMENT_ROOT', this.options.documentRoot);
if (info.referer) {
this.PARAMS.HTTP_REFERER = info.referer;
}
if (info.remote_addr) {
this.PARAMS.REMOTE_ADDR = info.remote_addr;
}
if (info.hostname) {
this.PARAMS.SERVER_NAME = info.hostname;
}
if (info.debug) {
console.log(this.PARAMS);
}
var self = this;
self.client.request(this.PARAMS, function(err, request)
{
if (err)
{
cb(99, err.toString(), err.toString());
return;
}
var body = '',errors = '';
request.stdout.on('data', function(data)
{
body += data.toString('utf8');
});
request.stderr.on('data', function(data)
{
errors += data.toString('utf8');
});
request.stdout.on('end', function()
{
body = body.replace(/^[\s\S]*?\r\n\r\n/, '');
cb(false, body, errors);
});
if (info.method == 'POST')
{
request.stdin._write(info.body, 'utf8');
}
request.stdin.end();
});
};
module.exports = phpfpm;