From e30e4415eedfb7f97db5de0490b64f01e0f1d5fe Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 18 Jun 2009 14:34:49 +0200 Subject: [PATCH 1/6] Fixes for ipv6 --- test-http_simple.js => http_simple.js | 0 src/net.cc | 20 +++--- test/test-tcp-pingpong.js | 92 +++++++++++++++------------ test_client.js | 41 ------------ 4 files changed, 63 insertions(+), 90 deletions(-) rename test-http_simple.js => http_simple.js (100%) delete mode 100644 test_client.js diff --git a/test-http_simple.js b/http_simple.js similarity index 100% rename from test-http_simple.js rename to http_simple.js diff --git a/src/net.cc b/src/net.cc index 8148937c18..3b262b6283 100644 --- a/src/net.cc +++ b/src/net.cc @@ -42,14 +42,14 @@ using namespace node; #define CLOSED_SYMBOL String::NewSymbol("closed") static const struct addrinfo server_tcp_hints = -/* ai_flags */ { AI_PASSIVE | AI_ADDRCONFIG +/* ai_flags */ { AI_PASSIVE /* ai_family */ , AF_UNSPEC /* ai_socktype */ , SOCK_STREAM , 0 }; static const struct addrinfo client_tcp_hints = -/* ai_flags */ { AI_ADDRCONFIG +/* ai_flags */ { 0 /* ai_family */ , AF_UNSPEC /* ai_socktype */ , SOCK_STREAM , 0 @@ -591,21 +591,21 @@ static void SetRemoteAddress (Local connection_handle, struct sockaddr *addr) { HandleScope scope; - char ip4[INET_ADDRSTRLEN], ip6[INET6_ADDRSTRLEN]; + char ip[INET6_ADDRSTRLEN]; Local remote_address; + if (addr->sa_family == AF_INET) { struct sockaddr_in *sa = reinterpret_cast(addr); - inet_ntop(AF_INET, &(sa->sin_addr), ip4, INET_ADDRSTRLEN); - remote_address = String::New(ip4); + inet_ntop(AF_INET, &(sa->sin_addr), ip, INET6_ADDRSTRLEN); + remote_address = String::New(ip); } else if (addr->sa_family == AF_INET6) { struct sockaddr_in6 *sa6 = reinterpret_cast(addr); - inet_ntop(AF_INET6, &(sa6->sin6_addr), ip6, INET6_ADDRSTRLEN); - remote_address = String::New(ip6); + inet_ntop(AF_INET6, &(sa6->sin6_addr), ip, INET6_ADDRSTRLEN); + remote_address = String::New(ip); + + } else assert(0 && "received a bad sa_family"); - } else { - assert(0 && "received a bad sa_family"); - } connection_handle->Set(REMOTE_ADDRESS_SYMBOL, remote_address); } diff --git a/test/test-tcp-pingpong.js b/test/test-tcp-pingpong.js index aa7570d086..9e03fbda73 100644 --- a/test/test-tcp-pingpong.js +++ b/test/test-tcp-pingpong.js @@ -1,40 +1,44 @@ include("mjsunit.js"); -var port = 12123; -var N = 1000; -var count = 0; -var sent_final_ping = false; - -function Ponger (socket) { - socket.setEncoding("utf8"); - socket.timeout = 0; - - assertEquals("127.0.0.1", socket.remoteAddress); - - socket.onReceive = function (data) { - assertEquals("open", socket.readyState); - assertTrue(count <= N); - if (/PING/.exec(data)) { - socket.send("PONG"); - } - }; - - socket.onEOF = function () { - assertEquals("writeOnly", socket.readyState); - socket.close(); - }; - - socket.onDisconnect = function (had_error) { - assertFalse(had_error); - assertEquals("closed", socket.readyState); - socket.server.close(); - }; -} - -function onLoad () { - var server = new node.tcp.Server(Ponger); - server.listen(port); +var tests_run = 0; + +function pingPongTest (port, host, on_complete) { + var N = 1000; + var count = 0; + var sent_final_ping = false; + + var server = new node.tcp.Server(function (socket) { + assertTrue(socket.remoteAddress !== null); + assertTrue(socket.remoteAddress !== undefined); + if (host === "127.0.0.1") + assertEquals(socket.remoteAddress, "127.0.0.1"); + else if (host == null) + assertEquals(socket.remoteAddress, "127.0.0.1"); + + socket.setEncoding("utf8"); + socket.timeout = 0; + + socket.onReceive = function (data) { + assertEquals("open", socket.readyState); + assertTrue(count <= N); + if (/PING/.exec(data)) { + socket.send("PONG"); + } + }; + + socket.onEOF = function () { + assertEquals("writeOnly", socket.readyState); + socket.close(); + }; + + socket.onDisconnect = function (had_error) { + assertFalse(had_error); + assertEquals("closed", socket.readyState); + socket.server.close(); + }; + }); + server.listen(port, host); var client = new node.tcp.Connection(); assertEquals("closed", client.readyState); @@ -65,15 +69,25 @@ function onLoad () { client.close(); } }; - - client.onEOF = function () { + + client.onDisconnect = function () { + assertEquals(N+1, count); + assertTrue(sent_final_ping); + if (on_complete) on_complete(); + tests_run += 1; }; assertEquals("closed", client.readyState); - client.connect(port, "localhost"); + client.connect(port, host); +} + +function onLoad () { + /* All are run at once, so run on different ports */ + pingPongTest(20989, "localhost"); + pingPongTest(20988, null); + pingPongTest(20997, "::1"); } function onExit () { - assertEquals(N+1, count); - assertTrue(sent_final_ping); + assertEquals(3, tests_run); } diff --git a/test_client.js b/test_client.js deleted file mode 100644 index 02ba11956c..0000000000 --- a/test_client.js +++ /dev/null @@ -1,41 +0,0 @@ -var c = new node.http.Client(8000, "127.0.0.1"); - -c.onError = function () { - puts("http client connection error."); -}; - -var req = c.get("/bytes/123", [["Accept", "*/*"]]); -req.finish(function (res) { - puts("response 1: " + res.statusCode.toString()); - - res.onBody = function (chunk) { - chunk = chunk.encodeUtf8(); - puts("response 1 body <" + JSON.stringify(chunk) + ">"); - return true; - }; - - res.onBodyComplete = function () { - puts("response 1 complete!"); - return true; - }; -}); - -setTimeout(function () { - var req2 = c.get("/something/else"); - //node.debug("start req2"); - req2.finish(function (res) { - puts("response 2: " + res.statusCode.toString()); - - res.onBody = function (chunk) { - chunk = chunk.encodeUtf8(); - puts("response 2 body <" + JSON.stringify(chunk) + ">"); - return true; - }; - - res.onBodyComplete = function () { - puts("response 2 complete!"); - return true; - }; - }); -}, 2000); - From 61fcbb1cd6947a21d92c109991451bfb4a3f5e20 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 18 Jun 2009 14:36:30 +0200 Subject: [PATCH 2/6] Add benchmark dir with ruby script --- http_simple.js => benchmark/http_simple.js | 0 benchmark/http_simple.rb | 95 ++++++++++++++++++++++ 2 files changed, 95 insertions(+) rename http_simple.js => benchmark/http_simple.js (100%) create mode 100644 benchmark/http_simple.rb diff --git a/http_simple.js b/benchmark/http_simple.js similarity index 100% rename from http_simple.js rename to benchmark/http_simple.js diff --git a/benchmark/http_simple.rb b/benchmark/http_simple.rb new file mode 100644 index 0000000000..ee33f57f1d --- /dev/null +++ b/benchmark/http_simple.rb @@ -0,0 +1,95 @@ +DIR = File.dirname(__FILE__) + +def fib(n) + return 1 if n <= 1 + fib(n-1) + fib(n-2) +end + +def wait(seconds) + n = (seconds / 0.01).to_i + n.times do + sleep(0.01) + #File.read(DIR + '/yahoo.html') + end +end + +class SimpleApp + @@responses = {} + + def initialize + @count = 0 + end + + def deferred?(env) + false + end + + def call(env) + path = env['PATH_INFO'] || env['REQUEST_URI'] + commands = path.split('/') + + @count += 1 + if commands.include?('periodical_activity') and @count % 10 != 1 + return [200, {'Content-Type'=>'text/plain'}, "quick response!\r\n"] + end + + if commands.include?('fibonacci') + n = commands.last.to_i + raise "fibonacci called with n <= 0" if n <= 0 + body = (1..n).to_a.map { |i| fib(i).to_s }.join(' ') + status = 200 + + elsif commands.include?('wait') + n = commands.last.to_f + raise "wait called with n <= 0" if n <= 0 + wait(n) + body = "waited about #{n} seconds" + status = 200 + + elsif commands.include?('bytes') + n = commands.last.to_i + raise "bytes called with n <= 0" if n <= 0 + body = @@responses[n] || "C"*n + status = 200 + + elsif commands.include?('fixed') + n = 20 * 1024; + body = @@responses[n] || "C"*n + status = 200 + + elsif commands.include?('test_post_length') + input_body = "" + while chunk = env['rack.input'].read(512) + input_body << chunk + end + if env['CONTENT_LENGTH'].to_i == input_body.length + body = "Content-Length matches input length" + status = 200 + else + body = "Content-Length doesn't matches input length! + content_length = #{env['CONTENT_LENGTH'].to_i} + input_body.length = #{input_body.length}" + status = 500 + end + else + status = 404 + body = "Undefined url" + end + + body += "\r\n" + headers = {'Content-Type' => 'text/plain', 'Content-Length' => body.length.to_s } + [status, headers, [body]] + end +end + + +if $0 == __FILE__ + #require DIR + '/../lib/ebb' + require 'rubygems' + require 'rack' + require 'thin' + require 'ebb' +# Rack::Handler::Mongrel.run(SimpleApp.new, :Port => 8000) + Thin::Server.start("0.0.0.0", 8000, SimpleApp.new) +# Ebb::start_server(SimpleApp.new, :port => 8000) +end From 89d891f91215da941f4bf16585aeb6ba95be663e Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 18 Jun 2009 14:50:10 +0200 Subject: [PATCH 3/6] Small clean up in test-http-client-race --- test/test-http-client-race.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/test-http-client-race.js b/test/test-http-client-race.js index 7761d4960d..d387c7b600 100644 --- a/test/test-http-client-race.js +++ b/test/test-http-client-race.js @@ -1,14 +1,18 @@ include("mjsunit.js"); PORT = 8888; +var body1_s = "1111111111111111"; +var body2_s = "22222"; + var server = new node.http.Server(function (req, res) { - res.sendHeader(200, [["content-type", "text/plain"]]); - if (req.uri.path == "/1") - res.sendBody("hello world 1\n"); - else - res.sendBody("hello world 2\n"); + var body = req.uri.path === "/1" ? body1_s : body2_s; + res.sendHeader(200, [ + ["Content-Type", "text/plain"], + ["Content-Length", body.length] + ]); + res.sendBody(body); res.finish(); -}) +}); server.listen(PORT); var client = new node.http.Client(PORT); @@ -33,6 +37,6 @@ client.get("/1").finish(function (res1) { }); function onExit () { - assertEquals("hello world 1\n", body1); - assertEquals("hello world 2\n", body2); + assertEquals(body1_s, body1); + assertEquals(body2_s, body2); } From 2b557c467f8411bbcf16bfe05e715821ecfe76ca Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 18 Jun 2009 14:58:17 +0200 Subject: [PATCH 4/6] Namespace trimming: remove node.constants --- src/file.js | 24 ++++++++++++------------ src/node.cc | 4 +--- website/api.html | 6 +++--- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/file.js b/src/file.js index a087be4ad9..b4b99fefde 100644 --- a/src/file.js +++ b/src/file.js @@ -12,7 +12,7 @@ node.fs.cat = function (path, encoding, callback) { callback(-1); }; - var content = (encoding == node.constants.UTF8 ? "" : []); + var content = (encoding == node.UTF8 ? "" : []); var pos = 0; var chunkSize = 16*1024; @@ -41,9 +41,9 @@ node.fs.File = function (options) { options = options || {}; if (options.encoding === "utf8") { - self.encoding = node.constants.UTF8; + self.encoding = node.UTF8; } else { - self.encoding = node.constants.RAW; + self.encoding = node.RAW; } //node.debug("encoding: opts=" + options.encoding + " self=" + self.encoding); @@ -104,22 +104,22 @@ node.fs.File = function (options) { var flags; switch (mode) { case "r": - flags = node.constants.O_RDONLY; + flags = node.O_RDONLY; break; case "r+": - flags = node.constants.O_RDWR; + flags = node.O_RDWR; break; case "w": - flags = node.constants.O_CREAT | node.constants.O_TRUNC | node.constants.O_WRONLY; + flags = node.O_CREAT | node.O_TRUNC | node.O_WRONLY; break; case "w+": - flags = node.constants.O_CREAT | node.constants.O_TRUNC | node.constants.O_RDWR; + flags = node.O_CREAT | node.O_TRUNC | node.O_RDWR; break; case "a": - flags = node.constants.O_APPEND | node.constants.O_CREAT | node.constants.O_WRONLY; + flags = node.O_APPEND | node.O_CREAT | node.O_WRONLY; break; case "a+": - flags = node.constants.O_APPEND | node.constants.O_CREAT | node.constants.O_RDWR; + flags = node.O_APPEND | node.O_CREAT | node.O_RDWR; break; default: throw "Unknown mode"; @@ -173,9 +173,9 @@ node.fs.File = function (options) { }; }; -stdout = new node.fs.File({ fd: node.constants.STDOUT_FILENO }); -stderr = new node.fs.File({ fd: node.constants.STDERR_FILENO }); -stdin = new node.fs.File({ fd: node.constants.STDIN_FILENO }); +stdout = new node.fs.File({ fd: node.STDOUT_FILENO }); +stderr = new node.fs.File({ fd: node.STDERR_FILENO }); +stdin = new node.fs.File({ fd: node.STDIN_FILENO }); puts = stdout.puts; print = stdout.print; diff --git a/src/node.cc b/src/node.cc index 31005d91b1..07384838b7 100644 --- a/src/node.cc +++ b/src/node.cc @@ -303,9 +303,7 @@ Load (int argc, char *argv[]) Timer::Initialize(node_obj); - Local constants = Object::New(); - node_obj->Set(String::NewSymbol("constants"), constants); - DefineConstants(constants); + DefineConstants(node_obj); Local fs = Object::New(); node_obj->Set(String::NewSymbol("fs"), fs); diff --git a/website/api.html b/website/api.html index 4ec4061e05..59bb15a4ac 100644 --- a/website/api.html +++ b/website/api.html @@ -206,7 +206,7 @@ node.fs.rename("/tmp/hello", "/tmp/world", function (status) { open(2)

The constants like O_CREAT are defined at - node.constants.O_CREAT. + node.O_CREAT.

@@ -243,8 +243,8 @@ node.fs.rename("/tmp/hello", "/tmp/world", function (status) {

- encoding is either node.constants.UTF8 - or node.constants.RAW. + encoding is either node.UTF8 + or node.RAW.

From 7ec90dbfd0aa8d36efc3f3e275b44281e1707286 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 18 Jun 2009 15:35:02 +0200 Subject: [PATCH 5/6] Clean up debug code in net.cc --- src/net.cc | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/net.cc b/src/net.cc index 3b262b6283..dc57992977 100644 --- a/src/net.cc +++ b/src/net.cc @@ -243,7 +243,8 @@ Connection::Resolve (eio_req *req) { Connection *connection = static_cast (req->data); struct addrinfo *address = NULL; - req->result = getaddrinfo(connection->host_, connection->port_, &client_tcp_hints, &address); + req->result = getaddrinfo(connection->host_, connection->port_, + &client_tcp_hints, &address); req->ptr2 = address; free(connection->host_); @@ -264,29 +265,11 @@ AddressDefaultToIPv4 (struct addrinfo *address_list) { struct addrinfo *address = NULL; -/* - char ip4[INET_ADDRSTRLEN], ip6[INET6_ADDRSTRLEN]; - for (address = address_list; address != NULL; address = address->ai_next) { - if (address->ai_family == AF_INET) { - struct sockaddr_in *sa = reinterpret_cast(address->ai_addr); - inet_ntop(AF_INET, &(sa->sin_addr), ip4, INET_ADDRSTRLEN); - printf("%s\n", ip4); - - } else if (address->ai_family == AF_INET6) { - struct sockaddr_in6 *sa6 = reinterpret_cast(address->ai_addr); - inet_ntop(AF_INET6, &(sa6->sin6_addr), ip6, INET6_ADDRSTRLEN); - printf("%s\n", ip6); - } - } -*/ - for (address = address_list; address != NULL; address = address->ai_next) { if (address->ai_addr->sa_family == AF_INET) break; } - if (address == NULL) address = address_list; - - return address; + return address == NULL ? address_list : address; } int From ec5f3dbae11ed121d24744861a8fce55636ecd66 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 18 Jun 2009 23:22:31 +0200 Subject: [PATCH 6/6] bump version --- website/index.html | 4 ++++ wscript | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index de0eaff468..d8e6faa6e8 100644 --- a/website/index.html +++ b/website/index.html @@ -154,6 +154,10 @@ Server running at http://127.0.0.1:8000/ git repo

    +
  • + 2009.06.18 + node-0.0.5.tar.gz +
  • 2009.06.13 node-0.0.4.tar.gz diff --git a/wscript b/wscript index 2b40f64395..8d49a88118 100644 --- a/wscript +++ b/wscript @@ -8,7 +8,7 @@ from logging import fatal import js2c -VERSION='0.0.4' +VERSION='0.0.5' APPNAME='node' srcdir = '.'