diff --git a/LICENSE b/LICENSE index a4e0c1f..02a9690 100644 --- a/LICENSE +++ b/LICENSE @@ -4,12 +4,12 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED diff --git a/README.md b/README.md index b5e86c3..3bbc1b8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Inline PHP Server Running on Node.js ==================================== Be worried, be very worried. The name **NodePHP** takes its name from the fact that we are effectively -turning a nice Node.js server into a FastCGI interface that interacts with PHP-FPM. +turning a nice Node.js server into a FastCGI interface that interacts with PHP-FPM. This is omega-alpha-super-beta-proof-of-concept but it already runs a few simple scripts. Mostly done for my talks on **Node.js for PHP Developers** this turns out to be quite an interesting project that @@ -21,9 +21,9 @@ sure they have PHP-FPM running somewhere on their system. If it is, they will be web-directory (that the FPM user has access to) and simply type `node php` and from there they will see a nice little output that looks like this: - bash$~ PHP Server is now running on port 9001 - Incoming Request: GET /test.php - --> Request Response Status Code: "200" + bash$~ PHP Server is now running on port 9001 + Incoming Request: GET /test.php + --> Request Response Status Code: "200" This is going to be running in the browser allowing you to develop and test your applications faster. Hopefully you will end up **forking** the project and helping out because I do not have enough time to do all I would want to @@ -39,38 +39,38 @@ Installing ---------- Well this is a bit tricky, there are a few things you will need in order to get this thang running: - - You need a running PHP-FPM server. - - You need to have Node.js installed with NPM - - Install **node-fastcgi-parser** ( https://github.com/billywhizz/node-fastcgi-parser ) - - Then you `git clone git://github.com/davidcoallier/node-php.git`, then you `git submodule init`, then you `git submodule update`, and `npm install` + - You need a running PHP-FPM server. + - You need to have Node.js installed with NPM + - Install **node-fastcgi-parser** ( https://github.com/billywhizz/node-fastcgi-parser ) + - Then you `git clone git://github.com/davidcoallier/node-php.git`, then you `git submodule init`, then you `git submodule update`, and `npm install` For this beta version, we assume that you are running FPM off `localhost` on port `9000`. If you are running through a **socket** you may want to make your own script that looks like this: - var php = require('nodephp'); - php.nodephp({ - fcgi: { - port: '/tmp/php-fpm.sock', - host: null, - }, - server: { - port: 9998 - } - }); + var php = require('nodephp'); + php.nodephp({ + fcgi: { + port: '/tmp/php-fpm.sock', + host: null, + }, + server: { + port: 9998 + } + }); Please note that the sock connection has not been tested yet. All that has been tested is connecting to a different FastCGI port and starting the server on a different port like such: - var php = require('nodephp'); - php.nodephp({ - fcgi: { - port: 9001, - host: 'localhost', - }, - server: { - port: 9111 - } - }); + var php = require('nodephp'); + php.nodephp({ + fcgi: { + port: 9001, + host: 'localhost', + }, + server: { + port: 9111 + } + }); Serving Static Files @@ -78,34 +78,34 @@ Serving Static Files You will realise rapidly enough that only running this is quite useless as it does not serve static files and such. This is why the **node-php** code has the abiliyt to define **blocks** — albeit simple blocks. They are defined in the second argument of the nodephp call: - var php = require('nodephp'); - php.nodephp({ - fcgi: { - port: 9001, - host: 'localhost', - }, - server: { - port: 9111 - } - }, { - "\.(js|css|png|jpg|jpeg|gif|txt|less)$": php.NODEPHP_TYPE_STATIC, - "\.php$": php.NODEPHP_TYPE_FCGI, - "index": "index.php" - }); + var php = require('nodephp'); + php.nodephp({ + fcgi: { + port: 9001, + host: 'localhost', + }, + server: { + port: 9111 + } + }, { + "\.(js|css|png|jpg|jpeg|gif|txt|less)$": php.NODEPHP_TYPE_STATIC, + "\.php$": php.NODEPHP_TYPE_FCGI, + "index": "index.php" + }); Where the following are: - NODEPHP_TYPE_STATIC: Static files that do not need to go through the fastcgi handler (`fastcgi_pass`) - NODEPHP_TYPE_FCGI: Files you do send through the FCGI handler. - + NODEPHP_TYPE_STATIC: Static files that do not need to go through the fastcgi handler (`fastcgi_pass`) + NODEPHP_TYPE_FCGI: Files you do send through the FCGI handler. + If you want more simple using the default `localhost:9000` for the FCGI handler: - var php = require('nodephp'); - php.nodephp({}, { - "\.(js|css|png|jpg|jpeg|gif|txt|less)$": php.NODEPHP_TYPE_STATIC, - "\.php$": php.NODEPHP_TYPE_FCGI, - "index": "index.php" - }); + var php = require('nodephp'); + php.nodephp({}, { + "\.(js|css|png|jpg|jpeg|gif|txt|less)$": php.NODEPHP_TYPE_STATIC, + "\.php$": php.NODEPHP_TYPE_FCGI, + "index": "index.php" + }); Hopefully this helps. @@ -113,10 +113,10 @@ Hopefully this helps. Issues & Todos ------------------ There are a few very important issues right now: - - - There is no POST handling. I'm not that far in the FCGI specs yet — need to find how to send data (post data) - - There is no **base** url. If you include ../../../../poop it will try to load it and most likely will fail. - - If you try to load a file that the PHP-FPM worker does not have access to, it will fail silently and you will swear. A lot. By silently I mean, it will give you a 404 even though the files do exist. + + - There is no POST handling. I'm not that far in the FCGI specs yet — need to find how to send data (post data) + - There is no **base** url. If you include ../../../../poop it will try to load it and most likely will fail. + - If you try to load a file that the PHP-FPM worker does not have access to, it will fail silently and you will swear. A lot. By silently I mean, it will give you a 404 even though the files do exist. Disclaimer diff --git a/lib/cli-wrapper.js b/lib/cli-wrapper.js index a7a9dfb..4799784 100644 --- a/lib/cli-wrapper.js +++ b/lib/cli-wrapper.js @@ -1,14 +1,14 @@ #!/usr/bin/env node var path = require("path"), - args = process.argv.slice(1) + args = process.argv.slice(1) var arg, base; do arg = args.shift(); - while ( arg !== __filename && - (base = path.basename(arg)) !== "node-php" && - base !== "php" && - base !== "php.js" + while ( arg !== __filename && + (base = path.basename(arg)) !== "node-php" && + base !== "php" && + base !== "php.js" ) require("./php").run(args) diff --git a/lib/nodephp.js b/lib/nodephp.js index 9402461..4f00c8d 100644 --- a/lib/nodephp.js +++ b/lib/nodephp.js @@ -1,55 +1,55 @@ -var url = require('url'); -var fs = require('fs'); -var path = require("path"); -var http = require("http"); -var net = require("net"); -var sys = require("sys"); +var url = require('url'); +var fs = require('fs'); +var path = require("path"); +var http = require("http"); +var net = require("net"); +var sys = require("sys"); var fastcgi = require("fastcgi"); var NODEPHP_STATIC = 'static'; -var NODEPHP_FCGI = 'fcgi'; +var NODEPHP_FCGI = 'fcgi'; var params; var FCGI_RESPONDER = fastcgi.constants.role.FCGI_RESPONDER; -var FCGI_BEGIN = fastcgi.constants.record.FCGI_BEGIN; -var FCGI_STDIN = fastcgi.constants.record.FCGI_STDIN; -var FCGI_STDOUT = fastcgi.constants.record.FCGI_STDOUT; -var FCGI_PARAMS = fastcgi.constants.record.FCGI_PARAMS; -var FCGI_END = fastcgi.constants.record.FCGI_END; +var FCGI_BEGIN = fastcgi.constants.record.FCGI_BEGIN; +var FCGI_STDIN = fastcgi.constants.record.FCGI_STDIN; +var FCGI_STDOUT = fastcgi.constants.record.FCGI_STDOUT; +var FCGI_PARAMS = fastcgi.constants.record.FCGI_PARAMS; +var FCGI_END = fastcgi.constants.record.FCGI_END; /** * Make headers for FPM * * Some headers have to be modified to fit the FPM * handler and some others don't. For instance, the Content-Type - * header, when received, has to be made upper-case and the + * header, when received, has to be made upper-case and the * hyphen has to be made into an underscore. However, the Accept * header has to be made uppercase, hyphens turned into underscores * and the string "HTTP_" has to be appended to the header. * - * @param array headers An array of existing user headers from Node.js - * @param array params An array of pre-built headers set in serveFpm + * @param array headers An array of existing user headers from Node.js + * @param array params An array of pre-built headers set in serveFpm * - * @return array An array of complete headers. + * @return array An array of complete headers. */ function makeHeaders(headers, params) { - if (headers.length <= 0) { - return params; - } - - for (prop in headers) { - head = headers[prop]; - prop = prop.replace(/-/, '_').toUpperCase(); - if (prop.indexOf('CONTENT_TYPE') < 0) { - // Quick hack for PHP, might be more or less headers. - prop = 'HTTP_' + prop; - } - - params[params.length] = [prop, head] - } - - return params; + if (headers.length <= 0) { + return params; + } + + for (prop in headers) { + head = headers[prop]; + prop = prop.replace(/-/, '_').toUpperCase(); + if (prop.indexOf('CONTENT_TYPE') < 0) { + // Quick hack for PHP, might be more or less headers. + prop = 'HTTP_' + prop; + } + + params[params.length] = [prop, head] + } + + return params; }; /** @@ -61,119 +61,119 @@ function makeHeaders(headers, params) { * We pass the request, the response, some params and some options * that we then use to serve the response to our client. * - * @param object Request The HTTP Request object. + * @param object Request The HTTP Request object. * @param object Response The HTTP Response object to use. - * @param array Params A list of parameters to pass to FCGI - * @param array options A list of options like the port of the fpm server. + * @param array Params A list of parameters to pass to FCGI + * @param array options A list of options like the port of the fpm server. * * @return void */ function server(request, response, params, options) { - var connection = new net.Stream(); - connection.setNoDelay(true); - - var writer = null; - var parser = null; - - var header = { - "version": fastcgi.constants.version, - "type": FCGI_BEGIN, - "recordId": 0, - "contentLength": 0, - "paddingLength": 0 - }; - var begin = { - "role": FCGI_RESPONDER, - "flags": 0 - }; - - function sendRequest (connection) { - header.type = FCGI_BEGIN; - header.contentLength = 8; - writer.writeHeader(header); - writer.writeBegin(begin); - connection.write(writer.tobuffer()); - - header.type = FCGI_PARAMS; - header.contentLength = fastcgi.getParamLength(params); - writer.writeHeader(header); - writer.writeParams(params); - connection.write(writer.tobuffer()); - - header.type = FCGI_STDOUT; - writer.writeHeader(header); - connection.write(writer.tobuffer()); - - connection.end(); - }; - - connection.ondata = function (buffer, start, end) { - parser.execute(buffer, start, end); - }; - - connection.addListener("connect", function() { - writer = new fastcgi.writer(); - parser = new fastcgi.parser(); - - body=""; - - parser.onRecord = function(record) { - if (record.header.type == FCGI_STDOUT) { - body = record.body; - - parts = body.split("\r\n\r\n"); - - headers = parts[0]; - headerParts = headers.split("\r\n"); - - body = parts[1]; - - var responseStatus = 200; - - headers = []; - try { - for(i in headerParts) { - header = headerParts[i].split(': '); - if (header[0].indexOf('Status') >= 0) { - responseStatus = header[1].substr(0, 3); - continue; - } - - headers.push([header[0], header[1]]); - } - } catch (err) { - //console.log(err); - } - - headers.push(['X-Server' , 'Node.js-' + process.version]); - response.writeHead(responseStatus, headers); - response.end(body); - - console.log(' --> Request Response Status Code: "' + responseStatus + '"'); - } - }; - - parser.onHeader = function(header) { - body = ''; - }; - - parser.onError = function(err) { - //console.log(err); - }; - - sendRequest(connection); - }); - - connection.addListener("close", function() { - connection.end(); - }); - - connection.addListener("error", function(err) { - sys.puts(sys.inspect(err.stack)); - connection.end(); - }); - - connection.connect(options.fcgi.port, options.fcgi.host); + var connection = new net.Stream(); + connection.setNoDelay(true); + + var writer = null; + var parser = null; + + var header = { + "version": fastcgi.constants.version, + "type": FCGI_BEGIN, + "recordId": 0, + "contentLength": 0, + "paddingLength": 0 + }; + var begin = { + "role": FCGI_RESPONDER, + "flags": 0 + }; + + function sendRequest (connection) { + header.type = FCGI_BEGIN; + header.contentLength = 8; + writer.writeHeader(header); + writer.writeBegin(begin); + connection.write(writer.tobuffer()); + + header.type = FCGI_PARAMS; + header.contentLength = fastcgi.getParamLength(params); + writer.writeHeader(header); + writer.writeParams(params); + connection.write(writer.tobuffer()); + + header.type = FCGI_STDOUT; + writer.writeHeader(header); + connection.write(writer.tobuffer()); + + connection.end(); + }; + + connection.ondata = function (buffer, start, end) { + parser.execute(buffer, start, end); + }; + + connection.addListener("connect", function() { + writer = new fastcgi.writer(); + parser = new fastcgi.parser(); + + body=""; + + parser.onRecord = function(record) { + if (record.header.type == FCGI_STDOUT) { + body = record.body; + + parts = body.split("\r\n\r\n"); + + headers = parts[0]; + headerParts = headers.split("\r\n"); + + body = parts[1]; + + var responseStatus = 200; + + headers = []; + try { + for(i in headerParts) { + header = headerParts[i].split(': '); + if (header[0].indexOf('Status') >= 0) { + responseStatus = header[1].substr(0, 3); + continue; + } + + headers.push([header[0], header[1]]); + } + } catch (err) { + //console.log(err); + } + + headers.push(['X-Server' , 'Node.js-' + process.version]); + response.writeHead(responseStatus, headers); + response.end(body); + + console.log(' --> Request Response Status Code: "' + responseStatus + '"'); + } + }; + + parser.onHeader = function(header) { + body = ''; + }; + + parser.onError = function(err) { + //console.log(err); + }; + + sendRequest(connection); + }); + + connection.addListener("close", function() { + connection.end(); + }); + + connection.addListener("error", function(err) { + sys.puts(sys.inspect(err.stack)); + connection.end(); + }); + + connection.connect(options.fcgi.port, options.fcgi.host); } /** @@ -181,200 +181,200 @@ function server(request, response, params, options) { * * This function is used to serve static files back to the users. A static * file is determined by looking at the map of static files we have in the - * function and the file is then read, served with it's associated + * function and the file is then read, served with it's associated * content-type and then the response object is used to say: "We're done." Next. * - * @param string file The request file to parse. - * @param string path The path to the file to parse. - * @param object response The HTTP Response object. - * @param object request The HTTP Request object. + * @param string file The request file to parse. + * @param string path The path to the file to parse. + * @param object response The HTTP Response object. + * @param object request The HTTP Request object. * - * @return void + * @return void */ function serveStatic(file, path, response, request) { - // List taken from djangode - // @link https://github.com/simonw/djangode/blob/master/djangode.js - var types = { - ".3gp" : "video/3gpp", - ".a" : "application/octet-stream", - ".ai" : "application/postscript", - ".aif" : "audio/x-aiff", - ".aiff" : "audio/x-aiff", - ".asc" : "application/pgp-signature", - ".asf" : "video/x-ms-asf", - ".asm" : "text/x-asm", - ".asx" : "video/x-ms-asf", - ".atom" : "application/atom+xml", - ".au" : "audio/basic", - ".avi" : "video/x-msvideo", - ".bat" : "application/x-msdownload", - ".bin" : "application/octet-stream", - ".bmp" : "image/bmp", - ".bz2" : "application/x-bzip2", - ".c" : "text/x-c", - ".cab" : "application/vnd.ms-cab-compressed", - ".cc" : "text/x-c", - ".chm" : "application/vnd.ms-htmlhelp", - ".class" : "application/octet-stream", - ".com" : "application/x-msdownload", - ".conf" : "text/plain", - ".cpp" : "text/x-c", - ".crt" : "application/x-x509-ca-cert", - ".css" : "text/css", - ".csv" : "text/csv", - ".cxx" : "text/x-c", - ".deb" : "application/x-debian-package", - ".der" : "application/x-x509-ca-cert", - ".diff" : "text/x-diff", - ".djv" : "image/vnd.djvu", - ".djvu" : "image/vnd.djvu", - ".dll" : "application/x-msdownload", - ".dmg" : "application/octet-stream", - ".doc" : "application/msword", - ".dot" : "application/msword", - ".dtd" : "application/xml-dtd", - ".dvi" : "application/x-dvi", - ".ear" : "application/java-archive", - ".eml" : "message/rfc822", - ".eps" : "application/postscript", - ".exe" : "application/x-msdownload", - ".f" : "text/x-fortran", - ".f77" : "text/x-fortran", - ".f90" : "text/x-fortran", - ".flv" : "video/x-flv", - ".for" : "text/x-fortran", - ".gem" : "application/octet-stream", - ".gemspec": "text/x-script.ruby", - ".gif" : "image/gif", - ".gz" : "application/x-gzip", - ".h" : "text/x-c", - ".hh" : "text/x-c", - ".htm" : "text/html", - ".html" : "text/html", - ".ico" : "image/vnd.microsoft.icon", - ".ics" : "text/calendar", - ".ifb" : "text/calendar", - ".iso" : "application/octet-stream", - ".jar" : "application/java-archive", - ".java" : "text/x-java-source", - ".jnlp" : "application/x-java-jnlp-file", - ".jpeg" : "image/jpeg", - ".jpg" : "image/jpeg", - ".js" : "application/javascript", - ".json" : "application/json", - ".log" : "text/plain", - ".m3u" : "audio/x-mpegurl", - ".m4v" : "video/mp4", - ".man" : "text/troff", - ".mathml" : "application/mathml+xml", - ".mbox" : "application/mbox", - ".mdoc" : "text/troff", - ".me" : "text/troff", - ".mid" : "audio/midi", - ".midi" : "audio/midi", - ".mime" : "message/rfc822", - ".mml" : "application/mathml+xml", - ".mng" : "video/x-mng", - ".mov" : "video/quicktime", - ".mp3" : "audio/mpeg", - ".mp4" : "video/mp4", - ".mp4v" : "video/mp4", - ".mpeg" : "video/mpeg", - ".mpg" : "video/mpeg", - ".ms" : "text/troff", - ".msi" : "application/x-msdownload", - ".odp" : "application/vnd.oasis.opendocument.presentation", - ".ods" : "application/vnd.oasis.opendocument.spreadsheet", - ".odt" : "application/vnd.oasis.opendocument.text", - ".ogg" : "application/ogg", - ".p" : "text/x-pascal", - ".pas" : "text/x-pascal", - ".pbm" : "image/x-portable-bitmap", - ".pdf" : "application/pdf", - ".pem" : "application/x-x509-ca-cert", - ".pgm" : "image/x-portable-graymap", - ".pgp" : "application/pgp-encrypted", - ".pkg" : "application/octet-stream", - ".pl" : "text/x-script.perl", - ".pm" : "text/x-script.perl-module", - ".png" : "image/png", - ".pnm" : "image/x-portable-anymap", - ".ppm" : "image/x-portable-pixmap", - ".pps" : "application/vnd.ms-powerpoint", - ".ppt" : "application/vnd.ms-powerpoint", - ".ps" : "application/postscript", - ".psd" : "image/vnd.adobe.photoshop", - ".py" : "text/x-script.python", - ".qt" : "video/quicktime", - ".ra" : "audio/x-pn-realaudio", - ".rake" : "text/x-script.ruby", - ".ram" : "audio/x-pn-realaudio", - ".rar" : "application/x-rar-compressed", - ".rb" : "text/x-script.ruby", - ".rdf" : "application/rdf+xml", - ".roff" : "text/troff", - ".rpm" : "application/x-redhat-package-manager", - ".rss" : "application/rss+xml", - ".rtf" : "application/rtf", - ".ru" : "text/x-script.ruby", - ".s" : "text/x-asm", - ".sgm" : "text/sgml", - ".sgml" : "text/sgml", - ".sh" : "application/x-sh", - ".sig" : "application/pgp-signature", - ".snd" : "audio/basic", - ".so" : "application/octet-stream", - ".svg" : "image/svg+xml", - ".svgz" : "image/svg+xml", - ".swf" : "application/x-shockwave-flash", - ".t" : "text/troff", - ".tar" : "application/x-tar", - ".tbz" : "application/x-bzip-compressed-tar", - ".tcl" : "application/x-tcl", - ".tex" : "application/x-tex", - ".texi" : "application/x-texinfo", - ".texinfo" : "application/x-texinfo", - ".text" : "text/plain", - ".tif" : "image/tiff", - ".tiff" : "image/tiff", - ".torrent" : "application/x-bittorrent", - ".tr" : "text/troff", - ".txt" : "text/plain", - ".vcf" : "text/x-vcard", - ".vcs" : "text/x-vcalendar", - ".vrml" : "model/vrml", - ".war" : "application/java-archive", - ".wav" : "audio/x-wav", - ".weba" : "audio/webm", - ".webm" : "video/webm", - ".wma" : "audio/x-ms-wma", - ".wmv" : "video/x-ms-wmv", - ".wmx" : "video/x-ms-wmx", - ".wrl" : "model/vrml", - ".wsdl" : "application/wsdl+xml", - ".xbm" : "image/x-xbitmap", - ".xhtml" : "application/xhtml+xml", - ".xls" : "application/vnd.ms-excel", - ".xml" : "application/xml", - ".xpm" : "image/x-xpixmap", - ".xsl" : "application/xml", - ".xslt" : "application/xslt+xml", - ".yaml" : "text/yaml", - ".yml" : "text/yaml", - ".zip" : "application/zip" - }; - - console.log('Incoming Request: ' + request.method + ' ' + request.url); - try { - response.writeHead(200, {'Content-Type': types[file.substr(file.lastIndexOf('.'), file.length)]}); - response.write(fs.readFileSync(path + file, 'utf8')); - response.end(); - } catch (Exception) { - response.writeHead(400, {'Content-Type': types[file.substr(file.lastIndexOf('.'), file.length)]}); - response.write('
* {
- * fcgi: {port: 9000, host: localhost},
- * server: {port: 9001}
+ * fcgi: {port: 9000, host: localhost},
+ * server: {port: 9001}
* }
*
*
* The block parameter is used to define the rules of which types to serve.
*
* {
- * "\.(js|css)$": 'static',
+ * "\.(js|css)$": 'static',
* }
*
*/
function createServer(opts, block) {
- // Let's mix those options.
- var options = Object.create({
- fcgi: {
- port: 9000,
- host: 'localhost', // This can be a socket.
- },
- server: {
- port: 9001,
- }
- });
- options.extend(opts);
-
- http.createServer(function(request, response) {
- /**
- * Here's a list of things to change:
- *
- * - Retrieve teh correct script invoked by parsing the request.url
- * and analysing the filename passed.
- *
- * - Rewrite rules?
- * - Location blocks?
- * - Get the headers and insert them correctly in Params.
- */
-
- // We simulate that the index page is is index.php if the requested
- // script was "/".
- var script_file = request.url == '/' ? '/index.php' : url.parse(request.url).pathname;
- var script_name = script_file.substr(1, script_file.length);
-
- // We only pass `pwd` as the second argument an we can run a server
- // with the directory index of the current directory. Handy.
- var __script_dir__ = process.cwd();
-
- // For now.
- var pathname = url.parse(request.url).pathname;
- var extension = pathname.substr(pathname.lastIndexOf('.'), pathname.length);
-
- for (rule in block) {
- if (rule == 'index') { continue; }
- if (pathname.match(rule)) {
- if (block[rule] == NODEPHP_STATIC) {
- return serveStatic(pathname, __script_dir__, response, request);
- } else if (block[rule] == NODEPHP_FCGI) {
- return serveFpm(script_file, __script_dir__, request, response, params, options);
- }
- }
- }
-
- // If we get here, it means we didn't find a PHP file and we didn't find a static file. Might
- // be time for a rewrite and our rewrites are simple: /index?...
- var default_index = block['index'] || '/index.php';
- serveFpm(default_index, __script_dir__, request, response, params, options);
-
- }).listen(options.server.port);
-
- console.log("PHP Server is now running on http://" + options.server.host + ":" + options.server.port);
+ // Let's mix those options.
+ var options = Object.create({
+ fcgi: {
+ port: 9000,
+ host: 'localhost', // This can be a socket.
+ },
+ server: {
+ port: 9001,
+ }
+ });
+ options.extend(opts);
+
+ http.createServer(function(request, response) {
+ /**
+ * Here's a list of things to change:
+ *
+ * - Retrieve teh correct script invoked by parsing the request.url
+ * and analysing the filename passed.
+ *
+ * - Rewrite rules?
+ * - Location blocks?
+ * - Get the headers and insert them correctly in Params.
+ */
+
+ // We simulate that the index page is is index.php if the requested
+ // script was "/".
+ var script_file = request.url == '/' ? '/index.php' : url.parse(request.url).pathname;
+ var script_name = script_file.substr(1, script_file.length);
+
+ // We only pass `pwd` as the second argument an we can run a server
+ // with the directory index of the current directory. Handy.
+ var __script_dir__ = process.cwd();
+
+ // For now.
+ var pathname = url.parse(request.url).pathname;
+ var extension = pathname.substr(pathname.lastIndexOf('.'), pathname.length);
+
+ for (rule in block) {
+ if (rule == 'index') { continue; }
+ if (pathname.match(rule)) {
+ if (block[rule] == NODEPHP_STATIC) {
+ return serveStatic(pathname, __script_dir__, response, request);
+ } else if (block[rule] == NODEPHP_FCGI) {
+ return serveFpm(script_file, __script_dir__, request, response, params, options);
+ }
+ }
+ }
+
+ // If we get here, it means we didn't find a PHP file and we didn't find a static file. Might
+ // be time for a rewrite and our rewrites are simple: /index?...
+ var default_index = block['index'] || '/index.php';
+ serveFpm(default_index, __script_dir__, request, response, params, options);
+
+ }).listen(options.server.port);
+
+ console.log("PHP Server is now running on http://" + options.server.host + ":" + options.server.port);
};
/**
* Even though some people hate this (With good reasons)
* I find it works very well for what I need and I don't
- * have time to implement somethign more clever.
+ * have time to implement somethign more clever.
*
* Enjoy and if you want comments and ideas about this, see
* my link: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
*/
Object.defineProperty(Object.prototype, "extend", {
- enumerable: false,
- value: function(from) {
- var props = Object.getOwnPropertyNames(from);
- var dest = this;
- props.forEach(function(name) {
- if (name in dest) {
- var destination = Object.getOwnPropertyDescriptor(from, name);
- Object.defineProperty(dest, name, destination);
- }
- });
- return this;
- }
+ enumerable: false,
+ value: function(from) {
+ var props = Object.getOwnPropertyNames(from);
+ var dest = this;
+ props.forEach(function(name) {
+ if (name in dest) {
+ var destination = Object.getOwnPropertyDescriptor(from, name);
+ Object.defineProperty(dest, name, destination);
+ }
+ });
+ return this;
+ }
});
exports.nodephp = createServer;
exports.NODEPHP_TYPE_STATIC = NODEPHP_STATIC;
-exports.NODEPHP_TYPE_FCGI = NODEPHP_FCGI;
+exports.NODEPHP_TYPE_FCGI = NODEPHP_FCGI;
diff --git a/package.json b/package.json
index 7dab556..524b91f 100644
--- a/package.json
+++ b/package.json
@@ -1,24 +1,24 @@
-{
- "name" : "nodephp",
- "version" : "0.1.1",
- "description" : "A node.js web-server that interacts with PHP-FPM through FastCGI",
- "keywords": ["php", "webserver", "rad", "fastcgi", "php-fpm"],
- "homepage": "http://github.com/davidcoallier/node-php",
- "tag": "pre-alpha",
- "repository": {
- "type": "git",
- "url": "git://github.com/davidcoallier/node-php.git"
- },
- "author" : "David Coallier