Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

upgraded for node v0.0.4

  • Loading branch information...
commit 5ac32d1841de9141eb294982d25d27caeb05c3a8 1 parent e83c54b
@billywhizz authored
View
4 .gitignore
@@ -0,0 +1,4 @@
+.svn*
+*.in
+*.out
+*.log
View
0  README.md 100755 → 100644
File mode changed
View
66 benchmark/createtestfiles.js 100644 → 100755
@@ -2,6 +2,7 @@ var sys = require("sys");
var fastcgi = require("../lib/fastcgi");
var fs = require("fs");
+var records = parseInt(process.ARGV[2]);
var writer = new fastcgi.writer();
var response = "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Length: 10\r\nContent-Type: text/plain\r\n\r\n0123456789";
var params = [
@@ -14,33 +15,51 @@ var params = [
];
var paramlen = fastcgi.getParamLength(params);
-var log = fs.createWriteStream("http.out", {'flags': 'w'
- , 'encoding': null
- , 'mode': 0777
-});
+var fd = fs.openSync("http.out", "w", 0655);
+var log = {
+ "write": function(buff) {
+ return fs.writeSync(fd, buff, 0, buff.length);
+ },
+ "end": function() {
+ return fs.closeSync(fd);
+ }
+};
-for(var i=0; i<10000; i++) {
- log.write(response);
+var bb = new Buffer(response);
+for(var i=0; i<records; i++) {
+ log.write(bb);
}
log.end();
var request = "GET /test.js HTTP/1.1\r\nHost: shuttle.owner.net:82\r\nAccept: */*\r\nConnection: Keep-Alive\r\nAccept-Encoding: none\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Supplied by blueyonder; .NET CLR 1.1.4322; .NET CLR 2.0.50215)\r\n\r\n";
-var log = fs.createWriteStream("http.in", {'flags': 'w'
- , 'encoding': null
- , 'mode': 0777
-});
-for(var i=0; i<10000; i++) {
- log.write(request);
+var fd = fs.openSync("http.in", "w", 0655);
+log = {
+ "write": function(buff) {
+ return fs.writeSync(fd, buff, 0, buff.length);
+ },
+ "end": function() {
+ return fs.closeSync(fd);
+ }
+};
+
+bb = new Buffer(request);
+for(var i=0; i<records; i++) {
+ log.write(bb);
}
log.end();
-log = fs.createWriteStream("fastcgi.out", {'flags': 'w'
- , 'encoding': null
- , 'mode': 0555
-});
+var fd = fs.openSync("fastcgi.out", "w", 0655);
+log = {
+ "write": function(buff) {
+ return fs.writeSync(fd, buff, 0, buff.length);
+ },
+ "end": function() {
+ return fs.closeSync(fd);
+ }
+};
-for(var i=0; i<10000; i++) {
+for(var i=0; i<records; i++) {
writer.writeHeader({
"version": fastcgi.constants.version,
"type": fastcgi.constants.record.FCGI_STDOUT,
@@ -73,12 +92,23 @@ for(var i=0; i<10000; i++) {
}
log.end();
+/*
log = fs.createWriteStream("fastcgi.in", {'flags': 'w'
, 'encoding': null
, 'mode': 0555
});
+*/
+var fd = fs.openSync("fastcgi.in", "w", 0655);
+log = {
+ "write": function(buff) {
+ return fs.writeSync(fd, buff, 0, buff.length);
+ },
+ "end": function() {
+ return fs.closeSync(fd);
+ }
+};
-for(var i=0; i<10000; i++) {
+for(var i=0; i<records; i++) {
writer.writeHeader({
"version": fastcgi.constants.version,
"type": fastcgi.constants.record.FCGI_BEGIN,
View
24 benchmark/speed-fcgi.js 100644 → 100755
@@ -1,4 +1,3 @@
-var sys = require("sys");
var fs = require("fs");
var fastcgi = require("../lib/fastcgi");
@@ -7,23 +6,25 @@ var buffers = [];
var bytes = 0;
var parser = new fastcgi.parser();
+
var log = fs.createReadStream(process.ARGV[2], {
"flags": "r",
- "encoding": "binary",
+ "encoding": null,
"mode": 0755,
"bufferSize": process.ARGV[3]
});
-log.addListener("data", function(buffer) {
- bytes += buffer.length;
- parser.execute(buffer);
+log.addListener("data", function(buff) {
+ bytes += buff.length;
+ parser.execute(buff);
});
log.addListener("end", function() {
- sys.puts("finished reading file");
+ console.log("finished reading file");
clearTimeout(tt);
var now = new Date().getTime();
- sys.puts("Rec:" + (rec-lastrec) + ", Time: " + (now-then) + ", Rec/Sec: " + ((rec-lastrec)/((now-then)/1000)) + ", MBit/Sec: " + parseInt((((bytes-lastbytes)/((now-then)/1000))*8)/(1024*1024)));
+ console.log("Rec:" + (rec-lastrec) + ", Time: " + (now-then) + ", Rec/Sec: " + ((rec-lastrec)/((now-then)/1000)) + ", MBit/Sec: " + parseInt((((bytes-lastbytes)/((now-then)/1000))*8)/(1024*1024)));
+ console.log("total: " + rec);
});
/*
@@ -35,13 +36,14 @@ parser.onHeader = function(header) {
};
*/
+
parser.onRecord = function(record) {
- //sys.puts(JSON.stringify(record, null, "\t"));
+ //console.log(JSON.stringify(record));
rec++;
};
parser.onError = function(err) {
- sys.puts("error: " + JSON.stringify(err, null, "\t"));
+ console.log("error: " + JSON.stringify(err, null, "\t"));
throw(err);
};
@@ -51,8 +53,8 @@ var lastbytes = 0;
var tt = setInterval(function() {
var now = new Date().getTime();
- sys.puts("Rec:" + (rec-lastrec) + ", Time: " + (now-then) + ", Rec/Sec: " + ((rec-lastrec)/((now-then)/1000)) + ", MBit/Sec: " + parseInt((((bytes-lastbytes)/((now-then)/1000))*8)/(1024*1024)));
+ console.log("Rec:" + (rec-lastrec) + ", Time: " + (now-then) + ", Rec/Sec: " + ((rec-lastrec)/((now-then)/1000)).toFixed(0) + ", MBit/Sec: " + parseInt((((bytes-lastbytes)/((now-then)/1000))*8)/(1024*1024)));
then = now;
lastrec = rec;
lastbytes = bytes;
-}, 1000)
+}, 1000)
View
2  benchmark/speed-http.js 100644 → 100755
@@ -9,7 +9,7 @@ var bytes = 0;
var parser = new HTTPParser(process.ARGV[4]);
var log = fs.createReadStream(process.ARGV[2], {
"flags": "r",
- "encoding": "binary",
+ "encoding": null,
"mode": 0755,
"bufferSize": process.ARGV[3]
});
View
29 examples/client.js 100644 → 100755
@@ -1,4 +1,3 @@
-var sys = require("sys");
var net = require("net");
var fastcgi = require("../lib/fastcgi");
@@ -11,8 +10,15 @@ var params = [
["HTTP_HOST", "shuttle.owner.net:82"]
];
+var bytesin = 0;
+var bytesout = 0;
var reqid = 0;
+function writeSocket(socket, buffer) {
+ bytesout += buffer.length;
+ socket.write(buffer);
+}
+
function sendRequest(connection) {
reqid++;
connection.writer.writeHeader({
@@ -26,7 +32,7 @@ function sendRequest(connection) {
"role": fastcgi.constants.role.FCGI_RESPONDER,
"flags": fastcgi.constants.keepalive.ON
});
- connection.write(connection.writer.tobuffer());
+ writeSocket(connection, connection.writer.tobuffer());
connection.writer.writeHeader({
"version": fastcgi.constants.version,
"type": fastcgi.constants.record.FCGI_PARAMS,
@@ -35,7 +41,7 @@ function sendRequest(connection) {
"paddingLength": 0
});
connection.writer.writeParams(params);
- connection.write(connection.writer.tobuffer());
+ writeSocket(connection, connection.writer.tobuffer());
connection.writer.writeHeader({
"version": fastcgi.constants.version,
"type": fastcgi.constants.record.FCGI_PARAMS,
@@ -43,7 +49,7 @@ function sendRequest(connection) {
"contentLength": 0,
"paddingLength": 0
});
- connection.write(connection.writer.tobuffer());
+ writeSocket(connection, connection.writer.tobuffer());
connection.writer.writeHeader({
"version": fastcgi.constants.version,
"type": fastcgi.constants.record.FCGI_STDIN,
@@ -52,7 +58,7 @@ function sendRequest(connection) {
"paddingLength": 0
});
connection.writer.writeBody("hello");
- connection.write(connection.writer.tobuffer());
+ writeSocket(connection, connection.writer.tobuffer());
connection.writer.writeHeader({
"version": fastcgi.constants.version,
"type": fastcgi.constants.record.FCGI_STDIN,
@@ -60,7 +66,7 @@ function sendRequest(connection) {
"contentLength": 0,
"paddingLength": 0
});
- connection.write(connection.writer.tobuffer());
+ writeSocket(connection, connection.writer.tobuffer());
}
var count = 0;
@@ -71,6 +77,7 @@ connection.setNoDelay(true);
connection.setTimeout(0);
connection.ondata = function (buffer, start, end) {
+ bytesin += (end-start);
connection.parser.execute(buffer.slice(start, end));
};
@@ -85,7 +92,7 @@ connection.addListener("connect", function() {
}
};
connection.parser.onError = function(err) {
- sys.puts(JSON.stringify(err, null, "\t"));
+ console.log(JSON.stringify(err, null, "\t"));
};
sendRequest(connection);
});
@@ -99,7 +106,7 @@ connection.addListener("close", function() {
});
connection.addListener("error", function(exception) {
- sys.puts(JSON.stringify(exception));
+ console.log(JSON.stringify(exception));
});
connection.connect("/tmp/nginx.sock");
@@ -108,9 +115,11 @@ var then = new Date().getTime();
var last = 0;
setInterval(function() {
var now = new Date().getTime();
- var elapsed = now - then;
+ var elapsed = (now - then)/1000;
var rps = count - last;
- sys.puts("Record: " + recordId + ", Count: " + count + ", RPS: " + rps/(elapsed/1000));
+ console.log("InRate: " + parseInt((((bytesin)/elapsed)*8)/(1024*1024)) + ", OutRate: " + parseInt((((bytesout)/elapsed)*8)/(1024*1024)) + ", Record: " + recordId + ", Count: " + count + ", RPS: " + rps/elapsed);
then = new Date().getTime();
last = count;
+ bytesin = 0;
+ bytesout = 0;
}, 1000);
View
267 examples/lighttpd.conf 100644 → 100755
@@ -1,54 +1,11 @@
-# lighttpd configuration file
-#
-# use it as a base for lighttpd 1.0.0 and above
-#
-# $Id: lighttpd.conf,v 1.7 2004/11/03 22:26:05 weigon Exp $
-
-############ Options you really have to take care of ####################
-
-## modules to load
-# at least mod_access and mod_accesslog should be loaded
-# all other module should only be loaded if really neccesary
-# - saves some time
-# - saves memory
server.modules = (
-# "mod_rewrite",
-# "mod_redirect",
-# "mod_alias",
- "mod_access",
-# "mod_trigger_b4_dl",
-# "mod_auth",
-# "mod_status",
-# "mod_setenv",
- "mod_fastcgi",
-# "mod_proxy",
-# "mod_simple_vhost",
-# "mod_evhost",
-# "mod_userdir",
-# "mod_cgi",
-# "mod_compress",
-# "mod_ssi",
-# "mod_usertrack",
-# "mod_expire",
-# "mod_secdownload",
-# "mod_rrdtool",
- "mod_accesslog" )
+ "mod_fastcgi"
+)
-## A static document-root. For virtual hosting take a look at the
-## mod_simple_vhost module.
server.document-root = "/var/www/lighttpd/"
-
-## where to send error-messages to
server.errorlog = "/var/log/lighttpd/error.log"
-
-# files to check for if .../ is requested
index-file.names = ( "index.php", "index.html",
"index.htm", "default.htm" )
-
-## set the event-handler (read the performance section in the manual)
-# server.event-handler = "freebsd-kqueue" # needed on OS X
-
-# mimetype mapping
mimetype.assign = (
".rpm" => "application/x-rpm",
".pdf" => "application/pdf",
@@ -107,230 +64,24 @@ mimetype.assign = (
"" => "application/octet-stream",
)
-# Use the "Content-Type" extended attribute to obtain mime type if possible
-#mimetype.use-xattr = "enable"
-
-
-## send a different Server: header
-## be nice and keep it at lighttpd
-# server.tag = "lighttpd"
-
-#### accesslog module
-accesslog.filename = "/var/log/lighttpd/access.log"
-
-## deny access the file-extensions
-#
-# ~ is for backupfiles from vi, emacs, joe, ...
-# .inc is often used for code includes which should in general not be part
-# of the document-root
url.access-deny = ( "~", ".inc" )
$HTTP["url"] =~ "\.pdf$" {
server.range-requests = "disable"
}
-##
-# which extensions should not be handle via static-file transfer
-#
-# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
-
-######### Options that are good to be but not neccesary to be changed #######
-
-## bind to port (default: 80)
-server.port = 81
-
-## bind to localhost (default: all interfaces)
-#server.bind = "127.0.0.1"
-
-## error-handler for status 404
-#server.error-handler-404 = "/error-handler.html"
-#server.error-handler-404 = "/error-handler.php"
-
-## to help the rc.scripts
+server.port = 80
server.pid-file = "/var/run/lighttpd.pid"
-
-
-###### virtual hosts
-##
-## If you want name-based virtual hosting add the next three settings and load
-## mod_simple_vhost
-##
-## document-root =
-## virtual-server-root + virtual-server-default-host + virtual-server-docroot
-## or
-## virtual-server-root + http-host + virtual-server-docroot
-##
-#simple-vhost.server-root = "/srv/www/vhosts/"
-#simple-vhost.default-host = "www.example.org"
-#simple-vhost.document-root = "/htdocs/"
-
-
-##
-## Format: <errorfile-prefix><status-code>.html
-## -> ..../status-404.html for 'File not found'
-#server.errorfile-prefix = "/usr/share/lighttpd/errors/status-"
-#server.errorfile-prefix = "/srv/www/errors/status-"
-
-## virtual directory listings
-#dir-listing.activate = "enable"
-## select encoding for directory listings
-#dir-listing.encoding = "utf-8"
-
-## enable debugging
-#debug.log-request-header = "enable"
-#debug.log-response-header = "enable"
-#debug.log-request-handling = "enable"
-#debug.log-file-not-found = "enable"
-
-### only root can use these options
-#
-# chroot() to directory (default: no chroot() )
-#server.chroot = "/"
-
-## change uid to <uid> (default: don't care)
server.username = "lighttpd"
-
-## change uid to <uid> (default: don't care)
server.groupname = "lighttpd"
-#### compress module
-#compress.cache-dir = "/var/cache/lighttpd/compress/"
-#compress.filetype = ("text/plain", "text/html")
-
-#### proxy module
-## read proxy.txt for more info
-#proxy.server = ( ".php" =>
-# ( "localhost" =>
-# (
-# "host" => "192.168.0.101",
-# "port" => 80
-# )
-# )
-# )
-
-#### fastcgi module
-## read fastcgi.txt for more info
-## for PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini
-#fastcgi.server = ( ".php" =>
-# ( "localhost" =>
-# (
-# "socket" => "/var/run/lighttpd/php-fastcgi.socket",
-# "bin-path" => "/usr/bin/php-cgi"
-# )
-# )
-# )
-fastcgi.server = ( ".js" =>
- ( "localhost" =>
- (
- "socket" => "/tmp/nginx.sock",
- "check-local" => "disable"
- )
- )
- )
-
-
-#### CGI module
-#cgi.assign = ( ".pl" => "/usr/bin/perl",
-# ".cgi" => "/usr/bin/perl" )
-#
-
-#### SSL engine
-#ssl.engine = "enable"
-#ssl.pemfile = "/etc/ssl/private/lighttpd.pem"
-
-#### status module
-#status.status-url = "/server-status"
-#status.config-url = "/server-config"
-
-#### auth module
-## read authentication.txt for more info
-#auth.backend = "plain"
-#auth.backend.plain.userfile = "lighttpd.user"
-#auth.backend.plain.groupfile = "lighttpd.group"
-
-#auth.backend.ldap.hostname = "localhost"
-#auth.backend.ldap.base-dn = "dc=my-domain,dc=com"
-#auth.backend.ldap.filter = "(uid=$)"
-
-#auth.require = ( "/server-status" =>
-# (
-# "method" => "digest",
-# "realm" => "download archiv",
-# "require" => "user=jan"
-# ),
-# "/server-config" =>
-# (
-# "method" => "digest",
-# "realm" => "download archiv",
-# "require" => "valid-user"
-# )
-# )
-
-#### url handling modules (rewrite, redirect, access)
-#url.rewrite = ( "^/$" => "/server-status" )
-#url.redirect = ( "^/wishlist/(.+)" => "http://www.123.org/$1" )
-#### both rewrite/redirect support back reference to regex conditional using %n
-#$HTTP["host"] =~ "^www\.(.*)" {
-# url.redirect = ( "^/(.*)" => "http://%1/$1" )
-#}
-
-#
-# define a pattern for the host url finding
-# %% => % sign
-# %0 => domain name + tld
-# %1 => tld
-# %2 => domain name without tld
-# %3 => subdomain 1 name
-# %4 => subdomain 2 name
-#
-#evhost.path-pattern = "/srv/www/vhosts/%3/htdocs/"
-
-#### expire module
-#expire.url = ( "/buggy/" => "access 2 hours", "/asdhas/" => "access plus 1 seconds 2 minutes")
-
-#### ssi
-#ssi.extension = ( ".shtml" )
-
-#### rrdtool
-#rrdtool.binary = "/usr/bin/rrdtool"
-#rrdtool.db-name = "/var/lib/lighttpd/lighttpd.rrd"
-
-#### setenv
-#setenv.add-request-header = ( "TRAV_ENV" => "mysql://user@host/db" )
-#setenv.add-response-header = ( "X-Secret-Message" => "42" )
-
-## for mod_trigger_b4_dl
-# trigger-before-download.gdbm-filename = "/var/lib/lighttpd/trigger.db"
-# trigger-before-download.memcache-hosts = ( "127.0.0.1:11211" )
-# trigger-before-download.trigger-url = "^/trigger/"
-# trigger-before-download.download-url = "^/download/"
-# trigger-before-download.deny-url = "http://127.0.0.1/index.html"
-# trigger-before-download.trigger-timeout = 10
-
-#### variable usage:
-## variable name without "." is auto prefixed by "var." and becomes "var.bar"
-#bar = 1
-#var.mystring = "foo"
-
-## integer add
-#bar += 1
-## string concat, with integer cast as string, result: "www.foo1.com"
-#server.name = "www." + mystring + var.bar + ".com"
-## array merge
-#index-file.names = (foo + ".php") + index-file.names
-#index-file.names += (foo + ".php")
-
-#### include
-#include /etc/lighttpd/lighttpd-inc.conf
-## same as above if you run: "lighttpd -f /etc/lighttpd/lighttpd.conf"
-#include "lighttpd-inc.conf"
-
-#### include_shell
-#include_shell "echo var.a=1"
-## the above is same as:
-#var.a=1
+fastcgi.server = ( ".php" =>
+ (( "socket" => "/tmp/php-fastcgi.socket",
+ "bin-path" => "/media/storage/AJohnston/Code/oexp/platform/lib/node-fastcgi/examples/responder.js",
+ "check-local" => "disable"
+ ))
+)
-## include configuration snippets, usually provided by packages
include_shell "find /etc/lighttpd/conf.d -maxdepth 1 -name '*.conf' -exec cat {} \;"
View
60 examples/php-server.js 100644 → 100755
@@ -1,4 +1,3 @@
-var sys = require("sys");
var net = require("net");
var fastcgi = require("../lib/fastcgi");
@@ -18,14 +17,29 @@ You can then run this example to fire requests at the php server
You will need to change the SCRIPT_FILENAME param below to the full path of a script that is available to the php application
*/
var params = [
- ["SCRIPT_FILENAME", "/source/test.php"],
- ["HTTP_USER_AGENT", "tester"],
+ ["SCRIPT_FILENAME", "/source/phpinfo.php"],
+ ["QUERY_STRING", ""],
+ ["REQUEST_METHOD", "GET"],
+ ["CONTENT_TYPE", ""],
+ ["CONTENT_LENGTH", ""],
+ ["SCRIPT_NAME", "/test.php"],
+ ["REQUEST_URI", "/test.php"],
+ ["DOCUMENT_URI", "/test.php"],
+ ["DOCUMENT_ROOT", "/source"],
+ ["SERVER_PROTOCOL", "HTTP/1.1"],
+ ["GATEWAY_INTERFACE", "CGI/1.1"],
+ ["SERVER_SOFTWARE", "nginx/0.7.67"],
+ ["REMOTE_ADDR", "10.11.12.8"],
+ ["REMOTE_PORT", "4335"],
+ ["SERVER_ADDR", "10.11.12.8"],
+ ["SERVER_PORT", "82"],
+ ["SERVER_NAME", "_"],
+ ["REDIRECT_STATUS", "200"],
+ ["HTTP_USER_AGENT", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Supplied by blueyonder; .NET CLR 1.1.4322; .NET CLR 2.0.50215)"],
["HTTP_ACCEPT_ENCODING", "none"],
["HTTP_CONNECTION", "Keep-Alive"],
["HTTP_ACCEPT", "*/*"],
- ["DOCUMENT_ROOT", "/source/"],
- ["HTTP_HOST", "shuttle.owner.net:82"],
- ["PHP_FCGI_MAX_REQUESTS", "1000000"]
+ ["HTTP_HOST", "shuttle.owner.net:82"]
];
var reqid = 0;
@@ -42,7 +56,7 @@ function sendRequest(connection) {
});
connection.writer.writeBegin({
"role": fastcgi.constants.role.FCGI_RESPONDER,
- "flags": fastcgi.constants.keepalive.ON
+ "flags": fastcgi.constants.keepalive.OFF
});
connection.write(connection.writer.tobuffer());
connection.writer.writeHeader({
@@ -85,7 +99,7 @@ function client() {
connection.setTimeout(0);
connection.ondata = function (buffer, start, end) {
- //sys.puts(JSON.stringify(buffer.slice(start, end), null, "\t"));
+ //console.log(JSON.stringify(buffer.slice(start, end), null, "\t"));
connection.parser.execute(buffer.slice(start, end));
};
@@ -93,15 +107,19 @@ function client() {
connection.writer = new fastcgi.writer();
connection.parser = new fastcgi.parser();
connection.parser.onRecord = function(record) {
- //sys.puts(JSON.stringify(record, null, "\t"));
+ //console.log(JSON.stringify(record, null, "\t"));
count++;
recordId = record.header.recordId;
- if(record.header.type == fastcgi.constants.record.FCGI_END) {
+ };
+
+ connection.parser.onHeader = function(header) {
+ if(header.type == fastcgi.constants.record.FCGI_STDOUT) {
sendRequest(connection);
}
};
+
connection.parser.onError = function(err) {
- sys.puts(JSON.stringify(err, null, "\t"));
+ console.log(JSON.stringify(err, null, "\t"));
};
sendRequest(connection);
});
@@ -111,33 +129,35 @@ function client() {
});
connection.addListener("end", function() {
+ //console.log("end");
+ connection.destroy();
});
connection.addListener("close", function() {
- connection.end();
setTimeout(function() {
- connection.connect("/tmp/php.sock);
- }, 1000);
+ //console.log("reconnect");
+ //connection.connect("/tmp/nginx.sock");
+ connection.connect(6000, "icms.owner.net");
+ }, 0);
});
connection.addListener("error", function(exception) {
- sys.puts(JSON.stringify(exception));
+ console.log(JSON.stringify(exception));
connection.end();
});
- connection.connect("/tmp/php.sock");
-}
-for(var i=0; i< 1; i++) {
- client();
+ connection.connect(6000, "icms.owner.net");
}
+client();
+
var then = new Date().getTime();
var last = 0;
setInterval(function() {
var now = new Date().getTime();
var elapsed = now - then;
var rps = count - last;
- sys.puts("Record: " + recordId + ", Count: " + count + ", RPS: " + rps/(elapsed/1000));
+ console.log("Record: " + recordId + ", Count: " + count + ", RPS: " + rps/(elapsed/1000));
then = new Date().getTime();
last = count;
}, 1000);
View
76 examples/phpserve
@@ -0,0 +1,76 @@
+#!/bin/sh
+#
+# php-cgi - php-fastcgi swaping via spawn-fcgi
+#
+# chkconfig: - 85 15
+# description: Run php-cgi as app server
+# processname: php-cgi
+# config: /etc/sysconfig/phpfastcgi (defaults RH style)
+# pidfile: /var/run/php_cgi.pid
+# Note: See how to use this script :
+# http://www.cyberciti.biz/faq/rhel-fedora-install-configure-nginx-php5/
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+# Check that networking is up.
+[ "$NETWORKING" = "no" ] && exit 0
+
+spawnfcgi="/usr/bin/spawn-fcgi"
+php_cgi="/usr/bin/php-cgi"
+prog=$(basename $php_cgi)
+server_ip=0.0.0.0
+server_port=6000
+server_user=nginx
+server_group=nginx
+server_childs=4
+pidfile="/var/run/php_cgi.pid"
+
+# do not edit, put changes in /etc/sysconfig/phpfastcgi
+[ -f /etc/sysconfig/phpfastcgi ] && . /etc/sysconfig/phpfastcgi
+
+start() {
+ [ -x $php_cgi ] || exit 1
+ [ -x $spawnfcgi ] || exit 2
+ echo -n $"Starting $prog: "
+ export PHP_FCGI_MAX_REQUESTS=1000000
+ daemon $spawnfcgi -a ${server_ip} -p ${server_port} -u ${server_user} -g ${server_group} -P ${pidfile} -C ${server_childs} -f ${php_cgi}
+ retval=$?
+ echo
+ return $retval
+}
+
+stop() {
+ echo -n $"Stopping $prog: "
+ killproc -p ${pidfile} $prog -QUIT
+ retval=$?
+ echo
+ [ -f ${pidfile} ] && /bin/rm -f ${pidfile}
+ return $retval
+}
+
+restart(){
+ stop
+ sleep 2
+ start
+}
+
+rh_status(){
+ status -p ${pidfile} $prog
+}
+
+case "$1" in
+ start)
+ start;;
+ stop)
+ stop;;
+ restart)
+ restart;;
+ status)
+ rh_status;;
+ *)
+ echo $"Usage: $0 {start|stop|restart|status}"
+ exit 3
+esac
View
10 examples/responder.js
@@ -2,7 +2,7 @@
var util = require('util');
var fs = require("fs");
-var IOWatcher = process.IOWatcher;
+var IOWatcher = process.binding('io_watcher').IOWatcher;
var net = require("net");
var fastcgi = require("../lib/fastcgi");
@@ -16,24 +16,24 @@ process.on('uncaughtException', function (err) {
log.write('Caught exception: ' + JSON.stringify(err, null, "\t") + "\n");
});
-var output = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: 10\r\nContent-Type: text/plain\r\n\r\n0123456789";
+var output = "HTTP/1.1 200 OK\r\nContent-Length: 10\r\nContent-Type: text/plain\r\n\r\n0123456789";
watcher = new IOWatcher();
watcher.callback = function() {
var peerInfo = process.binding('net').accept(0);
clientfd = peerInfo.fd;
- log.write("accept: " + JSON.stringify(peerInfo, null, "\t") + "\n");
+ //log.write("accept: " + JSON.stringify(peerInfo, null, "\t") + "\n");
var s = new net.Stream(clientfd);
var parser = new fastcgi.parser();
var writer = new fastcgi.writer();
parser.onError = function(exception) {
- sys.puts(JSON.stringify(exception, null, "\t"));
+ log.write(JSON.stringify(exception, null, "\t"));
};
parser.onRecord = function(record) {
recordId = record.header.recordId;
- log.write("record: [\n" + JSON.stringify(record, null, "\t") + "]\n");
+ //log.write("record: [\n" + JSON.stringify(record, null, "\t") + "]\n");
switch(record.header.type) {
case fastcgi.constants.record.FCGI_BEGIN:
s.keepalive = (record.body.flags == 1);
View
26 examples/server.js 100644 → 100755
@@ -1,4 +1,3 @@
-var sys = require("sys");
var net = require("net");
var fastcgi = require("../lib/fastcgi");
@@ -9,10 +8,19 @@ var count = 0;
var connections = 0;
var gconnections = 0;
+var bytesin = 0;
+var bytesout = 0;
+
+function writeSocket(socket, buffer) {
+ bytesout += buffer.length;
+ socket.write(buffer);
+}
+
var fcgid = net.createServer(function (socket) {
socket.setTimeout(0);
socket.setNoDelay(true);
socket.ondata = function (buffer, start, end) {
+ bytesin += (end-start);
socket.parser.execute(buffer.slice(start, end));
};
socket.addListener("connect", function() {
@@ -25,7 +33,7 @@ var fcgid = net.createServer(function (socket) {
connections--;
});
socket.parser.onError = function(exception) {
- sys.puts(JSON.stringify(exception, null, "\t"));
+ console.log(JSON.stringify(exception, null, "\t"));
};
socket.parser.onRecord = function(record) {
recordId = record.header.recordId;
@@ -46,7 +54,7 @@ var fcgid = net.createServer(function (socket) {
"paddingLength": 0
});
socket.writer.writeBody(output);
- socket.write(socket.writer.tobuffer());
+ writeSocket(socket, socket.writer.tobuffer());
socket.writer.writeHeader({
"version": fastcgi.constants.version,
"type": fastcgi.constants.record.FCGI_STDOUT,
@@ -54,7 +62,7 @@ var fcgid = net.createServer(function (socket) {
"contentLength": 0,
"paddingLength": 0
});
- socket.write(socket.writer.tobuffer());
+ writeSocket(socket, socket.writer.tobuffer());
socket.writer.writeHeader({
"version": fastcgi.constants.version,
"type": fastcgi.constants.record.FCGI_END,
@@ -66,7 +74,7 @@ var fcgid = net.createServer(function (socket) {
"status": 0,
"protocolStatus": 200
});
- socket.write(socket.writer.tobuffer());
+ writeSocket(socket, socket.writer.tobuffer());
if(!socket.keepalive) {
socket.end();
}
@@ -78,15 +86,17 @@ var fcgid = net.createServer(function (socket) {
});
fcgid.listen("/tmp/nginx.sock");
-require("fs").chmodSync("/tmp/nginx.sock", 777);
var then = new Date().getTime();
var last = 0;
+
setInterval(function() {
var now = new Date().getTime();
- var elapsed = now - then;
+ var elapsed = (now - then)/1000;
var rps = count - last;
- sys.puts("Record: " + recordId + ", Count: " + count + ", RPS: " + rps/(elapsed/1000) + ", A/Conn: " + connections + ", T/Conn: " + gconnections);
+ console.log("InRate: " + parseInt((((bytesin)/elapsed)*8)/(1024*1024)) + ", OutRate: " + parseInt((((bytesout)/elapsed)*8)/(1024*1024)) + ", Record: " + recordId + ", Count: " + count + ", RPS: " + rps/elapsed + ", A/Conn: " + connections + ", T/Conn: " + gconnections);
then = new Date().getTime();
last = count;
+ bytesin = 0;
+ bytesout = 0;
}, 1000);
View
1  install-linux.sh
@@ -0,0 +1 @@
+cp lib/*.js /usr/local/lib/node/
View
79 lib/binary.js
@@ -0,0 +1,79 @@
+function Binary() {
+}
+
+Binary.prototype.pack = function(fields, buff, offset) {
+ var e = fields.length + 1;
+ var i = offset;
+ var next = 0;
+ while(--e) {
+ var field = fields[next++];
+ switch(Object.keys(field)[0]) {
+ case "int":
+ buff[i++] = field.int & 0xff;
+ break;
+ case "int16":
+ buff[i++] = (field.int16 >> 8) & 0xff;
+ buff[i++] = field.int16 & 0xff;
+ break;
+ case "int32":
+ buff[i++] = (field.int32 >> 24) & 0xff;
+ buff[i++] = (field.int32 >> 16) & 0xff;
+ buff[i++] = (field.int32 >> 8) & 0xff;
+ buff[i++] = field.int32 & 0xff;
+ break;
+ case "string":
+ case "ascii":
+ buff.asciiWrite(field.string, i);
+ i += field.string.length;
+ break;
+ case "utf8":
+ break;
+ }
+ }
+ //return 136;
+ return (i - offset);
+}
+
+Binary.prototype.unpack = function(pattern, offset, buff) {
+ var len = pattern.length;
+ var i = offset;
+ var pi = 0;
+ var res = [];
+ while(pi < len) {
+ switch(pattern[pi]) {
+ case "N":
+ res.push((buff[i++] << 24) + (buff[i++] << 16) + (buff[i++] << 8) + buff[i++]);
+ pi++;
+ break;
+ case "n":
+ res.push((buff[i++] << 8) + buff[i++]);
+ pi++;
+ break;
+ case "o":
+ res.push(buff[i++]);
+ pi++;
+ break;
+ case "s":
+ case "a":
+ var slen = 1;
+ var tmp = 0;
+ while(true) {
+ tmp = pattern[pi + slen];
+ if(!(tmp >= "0" && tmp <= "9")) {
+ break;
+ }
+ slen++;
+ }
+ var strlen = parseInt(pattern.substring(pi + 1, pi + slen));
+ res.push(buff.asciiSlice(i, i+strlen));
+ i += strlen;
+ pi += slen;
+ break;
+ case "u":
+ break;
+ }
+ }
+ return res;
+}
+
+exports.Binary = Binary;
View
80 lib/buffer_extras.js
@@ -1,80 +0,0 @@
-var Buffer = module.exports = require('buffer').Buffer;
-var proto = Buffer.prototype;
-
-// Writes a 32 bit integer at offset
-proto.int32Write = function int32Write(number, offset) {
- offset = offset || 0;
- this[offset] = (number & 0xff000000) >> 24;
- this[offset + 1] = (number & 0xff0000) >> 16;
- this[offset + 2] = (number & 0xff00) >> 8;
- this[offset + 3] = (number & 0xff);
-};
-
-// Writes a 16 bit integer at offset
-proto.int16Write = function int16Write(number, offset) {
- offset = offset || 0;
- this[offset] = (number & 0xff00) >> 8;
- this[offset + 1] = (number & 0xff);
-}
-
-// Writes a 16 bit integer at offset
-proto.intWrite = function intWrite(number, offset) {
- offset = offset || 0;
- this[offset] = (number & 0xff);
-}
-
-Buffer.fromString = function fromString(string) {
- var b = new Buffer(Buffer.byteLength(string));
- b.write(string, 'utf8');
- return b;
-}
-
-Buffer.makeWriter = function makeWriter() {
- var data = [];
- var writer;
- var push = {
- int32: function pushInt32(number) {
- var b = new Buffer(4);
- b.int32Write(number);
- data.push(b);
- return writer;
- },
- int16: function pushInt16(number) {
- var b = new Buffer(2);
- b.int16Write(number);
- data.push(b);
- return writer;
- },
- int: function pushInt(number) {
- var b = new Buffer(1);
- b.intWrite(number);
- data.push(b);
- return writer;
- },
- string: function pushString(string) {
- data.push(Buffer.fromString(string));
- return writer;
- }
- };
- writer = {
- data: data,
- push: push,
-
- // Convert an array of buffers into a single buffer using memcopy
- toBuffer: function toBuffer() {
- var total = 0;
- var i, l = data.length;
- for (i = 0; i < l; i++) {
- total += data[i].length;
- }
- var b = new Buffer(total);
- var offset = 0;
- for (i = 0; i < l; i++) {
- data[i].copy(b, offset);
- offset += data[i].length;
- }
- return b;
- }
- };
- return writer;
-}
View
342 lib/fastcgi-binary.js
@@ -1,342 +0,0 @@
-var sys = require("sys");
-var binary = require("./binary");
-
-//TODO: make the write handle a stream and write directly to it without creating buffers
-
-var _bin = new binary.Binary();
-
-var constants = {
- "version": 1,
- "record": {
- "FCGI_BEGIN": 1,
- "FCGI_ABORT": 2,
- "FCGI_END": 3,
- "FCGI_PARAMS": 4,
- "FCGI_STDIN": 5,
- "FCGI_STDOUT": 6,
- "FCGI_STDERR": 7,
- "FCGI_DATA": 8,
- "FCGI_GET_VALUES": 9,
- "FCGI_GET_VALUES_RESULT": 10,
- "FCGI_UNKNOWN_TYPE": 11
- },
- "keepalive": {
- "OFF": 0,
- "ON": 1
- },
- "parser": {
- "state": {
- "HEADER": 0,
- "BODY": 1,
- "PADDING": 2
- }
- },
- "general": {
- "FCGI_HEADER_LEN": 8,
- "FCGI_MAX_BODY": 8192
- },
- "errors": {
- "BUFFER_OVERFLOW": {
- "err": 1,
- "description": "buffer overflow"
- },
- "MAX_BODY_EXCEEDED": {
- "err": 2,
- "description": "a body greater than maximum body size was read/written"
- }
- },
- "flags": {
- "FCGI_KEEP_CONN": 1
- },
- "role": {
- "FCGI_RESPONDER": 1,
- "FCGI_AUTHORIZER": 2,
- "FCGI_FILTER": 3
- },
- "protocol": {
- "status": {
- "FCGI_REQUEST_COMPLETE": 0,
- "FCGI_CANT_MPX_CONN": 1,
- "FCGI_OVERLOADED": 2,
- "FCGI_UNKNOWN_ROLE": 3
- }
- },
- "values": {
- "FCGI_MAX_CONNS": "FCGI_MAX_CONNS",
- "FCGI_MAX_REQS": "FCGI_MAX_REQS",
- "FCGI_MPXS_CONNS": "FCGI_MPXS_CONNS"
- }
-}
-
-/*
-//TODO:
-- Add a resetonerror property to allow parser to stop processing immediately if an error is encountered
-- Add a reset method to clear the current parser
-- Pool of parsers?
-- make buffering more efficent - maybe parse down into the body types and raise event for each param etc.
-*/
-function Parser() {
- var _parser = this;
- var loc = 0;
- var record = {
- "header": {
- "version": 0,
- "type": 0,
- "recordId": 0,
- "contentLength": 0,
- "paddingLength": 0
- },
- "body": {}
- };
- var _header = new Buffer(constants.general.FCGI_HEADER_LEN);
- var _body = new Buffer(constants.general.FCGI_MAX_BODY);
- _parser.state = constants.parser.state.HEADER;
-
- _parser.onRecord = _parser.onError = _parser.onHeader = _parser.onParam = null;
-
- var tmp = null;
-
- function parseBody() {
- switch(record.header.type) {
- case constants.record.FCGI_BEGIN:
- tmp = _bin.unpack("no", 0, _body);
- record.body = {
- "role": tmp[0],
- "flags": tmp[1]
- }
- break;
- case constants.record.FCGI_ABORT:
- break;
- case constants.record.FCGI_END:
- tmp = _bin.unpack("No", 0, _body);
- record.body = {
- "status": tmp[0],
- "protocolStatus": tmp[1]
- }
- break;
- case constants.record.FCGI_PARAMS:
- case constants.record.FCGI_GET_VALUES:
- case constants.record.FCGI_GET_VALUES_RESULT:
- if(record.header.contentLength > 0) {
- var ploc = 0, name = "", value = "", vsize = 0, hsize = 0;
- record.body.params = {};
- while(ploc < record.header.contentLength) {
- hsize = _body[ploc];
- if(hsize >> 7 == 1) {
- hsize = _bin.unpack("N", 0, _body)[0] & 0x7fffffff;
- ploc += 4;
- }
- else {
- ploc++;
- }
- vsize = _body[ploc];
- if(vsize >> 7 == 1) {
- vsize = _bin.unpack("N", 0, _body)[0] & 0x7fffffff;
- ploc += 4;
- }
- else {
- ploc++;
- }
- if((ploc + hsize + vsize) <= _body.length) {
- name = _body.toString('utf8', ploc, ploc += hsize);
- value = _body.toString('utf8', ploc, ploc += vsize);
- if(_parser.onParam) _parser.onParam(name, value);
- record.body.params[name] = value;
- }
- else {
- //sys.puts(ploc + ":" + hsize + ":" + vsize + ":" + _body.length);
- if(_parser.onError) _parser.onError(new Error(JSON.stringify(constants.errors.BUFFER_OVERRUN)));
- ploc = record.header.contentLength;
- }
- }
- }
- break;
- case constants.record.FCGI_STDIN:
- case constants.record.FCGI_STDOUT:
- case constants.record.FCGI_STDERR:
- case constants.record.FCGI_DATA:
- if(record.header.contentLength > 0) {
- //TODO: am thinking i should return a buffer here, or maybe we should just emit chunks of the body as it comes in from the parser below
- record.body = _body.toString('utf8', 0, record.header.contentLength);
- }
- break;
- case constants.record.FCGI_UNKNOWN_TYPE:
- default:
- record.body = {
- "type": _body[0]
- }
- break;
- }
- }
-
- _parser.execute = function(buffer) {
- for (var i = 0; i < buffer.length; i++) {
- switch(_parser.state) {
- case constants.parser.state.HEADER:
- if(loc == constants.general.FCGI_HEADER_LEN - 1) {
- _header[loc] = buffer[i];
- var tmp = _bin.unpack("oonno", 0, _header);
- record.header.version = tmp[0];
- record.header.type = tmp[1];
- record.header.recordId = tmp[2];
- record.header.contentLength = tmp[3];
- record.header.paddingLength = tmp[4];
- record.body = {};
- // finished parsing header. inform the caller
- if(record.header.contentLength > 0) {
- if(_parser.onHeader) _parser.onHeader(record.header);
- _parser.state = constants.parser.state.BODY;
- }
- else {
- // the record has no body so skip the header event
- if(_parser.onRecord) _parser.onRecord(record);
- }
- loc=0;
- }
- else {
- _header[loc++] = buffer[i];
- }
- break;
- case constants.parser.state.BODY:
- if(loc == record.header.contentLength - 1) {
- _body[loc] = buffer[i];
- parseBody();
- // finished parsing record. inform the caller
- if(_parser.onRecord) _parser.onRecord(record);
- loc = 0;
- if(record.header.paddingLength > 0) {
- _parser.state = constants.parser.state.PADDING;
- }
- else {
- _parser.state = constants.parser.state.HEADER;
- }
- }
- else {
- _body[loc++] = buffer[i];
- }
- break;
- case constants.parser.state.PADDING:
- if(loc++ == record.header.paddingLength - 1) {
- _parser.state = constants.parser.state.HEADER;
- loc = 0;
- }
- break;
- }
- }
- }
-}
-
-function Writer() {
- var _writer = this;
- var _pos = 0;
- //TODO: add buffer overrun checks - won't be get errors thrown from pack method?? if so, add try/catch blocks
-
- _writer.buffer = null;
-
- _writer.tobuffer = function() {
- return _writer.buffer;
- }
-
- _writer.writeHeader = function(header) {
- _pos = 0;
- _writer.buffer = new Buffer(header.contentLength + header.paddingLength + constants.general.FCGI_HEADER_LEN);
- _bin.pack([
- {"int": header.version},
- {"int": header.type},
- {"int16": header.recordId},
- {"int16": header.contentLength},
- {"int": header.paddingLength},
- {"int": 0}
- ], _writer.buffer, _pos);
- _pos += constants.general.FCGI_HEADER_LEN;
- }
-
- _writer.writeParams = function(params) {
- var pbuff = [];
- var size = 0;
- params.forEach(function(param) {
- if(param[0].length > 127) {
- pbuff.push({"int32": param[0].length | 0x80000000});
- size += 4;
- }
- else {
- pbuff.push({"int": param[0].length});
- size++;
- }
- if(param[1].length > 127) {
- pbuff.push({"int32": param[1].length | 0x80000000});
- size += 4;
- }
- else {
- pbuff.push({"int": param[1].length});
- size++;
- }
- pbuff.push({"string": param[0]});
- pbuff.push({"string": param[1]});
- size += (param[0].length + param[1].length);
- });
- _bin.pack(pbuff, _writer.buffer, _pos);
- _pos += size;
- }
-
- //TODO: will we have unicode issues with lengths??
- _writer.writeBody = function(body) {
- _writer.buffer.write(body, _pos);
- _pos += body.length;
- }
-
- _writer.writeBegin = function(begin) {
- _bin.pack([
- {"int16": begin.role},
- {"int": begin.flags},
- {"int32": 0},
- {"int": 0}
- ], _writer.buffer, _pos);
- _pos += 8;
- }
-
- _writer.writeEnd = function(end) {
- _bin.pack([
- {"int32": end.status},
- {"int": end.protocolStatus},
- {"int": 0},
- {"int": 0},
- {"int": 0}
- ], _writer.buffer, _pos);
- _pos += 8;
- }
-
-}
-
-exports.parser = Parser;
-exports.writer = Writer;
-exports.constants = constants;
-
-// used to determine length of params body. pass in array of param pairs as follows:
-/*
-var len = fastcgi.getParamLength([
- ["HTTP_USER_AGENT", maxbuff],
- ["HTTP_ACCEPT_ENCODING", "none"],
- ["HTTP_CONNECTION", "Keep-Alive"]
-]);
-*/
-exports.getParamLength = function(params) {
- var size = 0;
- params.forEach(function(param) {
- size += (param[0].length + param[1].length);
- if(param[0].length > 127) {
- size += 4;
- }
- else {
- size++;
- }
- if(param[1].length > 127) {
- size += 4;
- }
- else {
- size++;
- }
- });
- return size;
-}
-
View
102 lib/fastcgi.js
@@ -1,5 +1,26 @@
-var sys = require("sys");
-var Buffer = require('./buffer_extras');
+var binary = require("binary");
+
+/*
+
+TODO:
+* make the write handle a stream and write directly to it without creating buffers
+* we assume everything is ascii
+* allow chunked parsing of body (not really necessary as fastcgi protocol allows breaking up of body into separate messages
+* allow writer to write to an existing buffer at offset passed in. should be a lot quicker than allocating and slicing...
+* don't do pre-allocated buffers in parser. just pass back start and end of current buffer to the callee. should be a lot faster
+* Add a resetonerror property to allow parser to stop processing immediately if an error is encountered
+* Add a reset method to clear the current parser
+* Pool of parsers?
+* make buffering more efficent - maybe parse down into the body types and raise event for each param etc.
+* think about overhead per connection
+* allow a http stream to be parsed on the fly and wrapped in cgi (in and out). maybe inherit from node.js stream and implement pipe (like HTTPS)
+* test for buffer overruns
+* unit tests
+* improve binary parser
+
+*/
+
+var _bin = new binary.Binary();
var constants = {
"version": 1,
@@ -64,13 +85,6 @@ var constants = {
}
}
-/*
-//TODO:
-- Add a resetonerror property to allow parser to stop processing immediately if an error is encountered
-- Add a reset method to clear the current parser
-- Pool of parsers?
-- make buffering more efficent - maybe parse down into the body types and raise event for each param etc.
-*/
function Parser() {
var _parser = this;
var loc = 0;
@@ -95,7 +109,7 @@ function Parser() {
function parseBody() {
switch(record.header.type) {
case constants.record.FCGI_BEGIN:
- tmp = _body.unpack("no", 0);
+ tmp = _bin.unpack("no", 0, _body);
record.body = {
"role": tmp[0],
"flags": tmp[1]
@@ -104,7 +118,7 @@ function Parser() {
case constants.record.FCGI_ABORT:
break;
case constants.record.FCGI_END:
- tmp = _body.unpack("No", 0);
+ tmp = _bin.unpack("No", 0, _body);
record.body = {
"status": tmp[0],
"protocolStatus": tmp[1]
@@ -119,7 +133,7 @@ function Parser() {
while(ploc < record.header.contentLength) {
hsize = _body[ploc];
if(hsize >> 7 == 1) {
- hsize = _body.unpack("N", ploc)[0] & 0x7fffffff;
+ hsize = _bin.unpack("N", 0, _body)[0] & 0x7fffffff;
ploc += 4;
}
else {
@@ -127,7 +141,7 @@ function Parser() {
}
vsize = _body[ploc];
if(vsize >> 7 == 1) {
- vsize = _body.unpack("N", ploc)[0] & 0x7fffffff;
+ vsize = _bin.unpack("N", 0, _body)[0] & 0x7fffffff;
ploc += 4;
}
else {
@@ -140,7 +154,6 @@ function Parser() {
record.body.params[name] = value;
}
else {
- //sys.puts(ploc + ":" + hsize + ":" + vsize + ":" + _body.length);
if(_parser.onError) _parser.onError(new Error(JSON.stringify(constants.errors.BUFFER_OVERRUN)));
ploc = record.header.contentLength;
}
@@ -171,7 +184,7 @@ function Parser() {
case constants.parser.state.HEADER:
if(loc == constants.general.FCGI_HEADER_LEN - 1) {
_header[loc] = buffer[i];
- var tmp = _header.unpack("oonno", 0);
+ var tmp = _bin.unpack("oonno", 0, _header);
record.header.version = tmp[0];
record.header.type = tmp[1];
record.header.recordId = tmp[2];
@@ -227,67 +240,78 @@ function Writer() {
var _pos = 0;
//TODO: add buffer overrun checks - won't be get errors thrown from pack method?? if so, add try/catch blocks
+ _writer.buffer = null;
+
_writer.tobuffer = function() {
- return _writer.w.toBuffer();
+ return _writer.buffer;
}
_writer.writeHeader = function(header) {
_pos = 0;
- _writer.w = Buffer.makeWriter(); //new Buffer(header.contentLength + header.paddingLength + constants.general.FCGI_HEADER_LEN);
- _writer.w.push.int(header.version);
- _writer.w.push.int(header.type);
- _writer.w.push.int16(header.recordId);
- _writer.w.push.int16(header.contentLength);
- _writer.w.push.int(header.paddingLength);
- _writer.w.push.int(0);
+ _writer.buffer = new Buffer(header.contentLength + header.paddingLength + constants.general.FCGI_HEADER_LEN);
+ _bin.pack([
+ {"int": header.version},
+ {"int": header.type},
+ {"int16": header.recordId},
+ {"int16": header.contentLength},
+ {"int": header.paddingLength},
+ {"int": 0}
+ ], _writer.buffer, _pos);
_pos += constants.general.FCGI_HEADER_LEN;
}
_writer.writeParams = function(params) {
+ var pbuff = [];
var size = 0;
params.forEach(function(param) {
if(param[0].length > 127) {
- _writer.w.push.int32(param[0].length | 0x80000000);
+ pbuff.push({"int32": param[0].length | 0x80000000});
size += 4;
}
else {
- _writer.w.push.int(param[0].length);
+ pbuff.push({"int": param[0].length});
size++;
}
if(param[1].length > 127) {
- _writer.w.push.int32(param[1].length | 0x80000000);
+ pbuff.push({"int32": param[1].length | 0x80000000});
size += 4;
}
else {
- _writer.w.push.int(param[1].length);
+ pbuff.push({"int": param[1].length});
size++;
}
- _writer.w.push.string(param[0]);
- _writer.w.push.string(param[1]);
+ pbuff.push({"string": param[0]});
+ pbuff.push({"string": param[1]});
size += (param[0].length + param[1].length);
});
+ _bin.pack(pbuff, _writer.buffer, _pos);
_pos += size;
}
+
//TODO: will we have unicode issues with lengths??
_writer.writeBody = function(body) {
- _writer.w.push.string(body);
+ _writer.buffer.write(body, _pos);
_pos += body.length;
}
_writer.writeBegin = function(begin) {
- _writer.w.push.int16(begin.role);
- _writer.w.push.int(begin.flags);
- _writer.w.push.int32(0);
- _writer.w.push.int(0);
+ _bin.pack([
+ {"int16": begin.role},
+ {"int": begin.flags},
+ {"int32": 0},
+ {"int": 0}
+ ], _writer.buffer, _pos);
_pos += 8;
}
_writer.writeEnd = function(end) {
- _writer.w.push.int32(end.status);
- _writer.w.push.int(end.protocolStatus);
- _writer.w.push.int(0);
- _writer.w.push.int(0);
- _writer.w.push.int(0);
+ _bin.pack([
+ {"int32": end.status},
+ {"int": end.protocolStatus},
+ {"int": 0},
+ {"int": 0},
+ {"int": 0}
+ ], _writer.buffer, _pos);
_pos += 8;
}
View
5 runbench.sh
@@ -0,0 +1,5 @@
+node benchmark/createtestfiles.js 1000000
+node benchmark/speed-http.js http.out 16384 response
+node benchmark/speed-fcgi.js fastcgi.out 16384
+node benchmark/speed-fcgi.js fastcgi.in 16384
+node benchmark/speed-http.js http.in 16384 request
View
1  spawn.sh
@@ -0,0 +1 @@
+spawn-fcgi -s /tmp/nginx.sock -F 4 -U nginx -G nginx -- examples/responder.js
View
0  tests/test.js 100644 → 100755
File mode changed
Please sign in to comment.
Something went wrong with that request. Please try again.