Browse Source

Merge branch 'master' of git://github.com/ry/node

v0.7.4-release
Urban Hafner 16 years ago
parent
commit
fc63f840b0
  1. 0
      benchmark/http_simple.js
  2. 95
      benchmark/http_simple.rb
  3. 24
      src/file.js
  4. 43
      src/net.cc
  5. 4
      src/node.cc
  6. 20
      test/test-http-client-race.js
  7. 42
      test/test-tcp-pingpong.js
  8. 41
      test_client.js
  9. 6
      website/api.html
  10. 4
      website/index.html
  11. 2
      wscript

0
test-http_simple.js → benchmark/http_simple.js

95
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

24
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;

43
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
@ -243,7 +243,8 @@ Connection::Resolve (eio_req *req)
{
Connection *connection = static_cast<Connection*> (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<struct sockaddr_in*>(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<struct sockaddr_in6*>(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
@ -591,21 +574,21 @@ static void
SetRemoteAddress (Local<Object> connection_handle, struct sockaddr *addr)
{
HandleScope scope;
char ip4[INET_ADDRSTRLEN], ip6[INET6_ADDRSTRLEN];
char ip[INET6_ADDRSTRLEN];
Local<String> remote_address;
if (addr->sa_family == AF_INET) {
struct sockaddr_in *sa = reinterpret_cast<struct sockaddr_in*>(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<struct sockaddr_in6*>(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);
}

4
src/node.cc

@ -303,9 +303,7 @@ Load (int argc, char *argv[])
Timer::Initialize(node_obj);
Local<Object> constants = Object::New();
node_obj->Set(String::NewSymbol("constants"), constants);
DefineConstants(constants);
DefineConstants(node_obj);
Local<Object> fs = Object::New();
node_obj->Set(String::NewSymbol("fs"), fs);

20
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);
}

42
test/test-tcp-pingpong.js

@ -1,17 +1,24 @@
include("mjsunit.js");
var port = 12123;
var tests_run = 0;
function pingPongTest (port, host, on_complete) {
var N = 1000;
var count = 0;
var sent_final_ping = false;
function Ponger (socket) {
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;
assertEquals("127.0.0.1", socket.remoteAddress);
socket.onReceive = function (data) {
assertEquals("open", socket.readyState);
assertTrue(count <= N);
@ -30,11 +37,8 @@ function Ponger (socket) {
assertEquals("closed", socket.readyState);
socket.server.close();
};
}
function onLoad () {
var server = new node.tcp.Server(Ponger);
server.listen(port);
});
server.listen(port, host);
var client = new node.tcp.Connection();
assertEquals("closed", client.readyState);
@ -66,14 +70,24 @@ function onLoad () {
}
};
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);
}

41
test_client.js

@ -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);

6
website/api.html

@ -206,7 +206,7 @@ node.fs.rename("/tmp/hello", "/tmp/world", function (status) {
<a href="http://opengroup.org/onlinepubs/007908799/xsh/open.html">open(2)</a>
<p>
The constants like <code>O_CREAT</code> are defined at
<code>node.constants.O_CREAT</code>.
<code>node.O_CREAT</code>.
</p>
</dd>
@ -243,8 +243,8 @@ node.fs.rename("/tmp/hello", "/tmp/world", function (status) {
</p>
<p>
<code>encoding</code> is either <code>node.constants.UTF8</code>
or <code>node.constants.RAW</code>.
<code>encoding</code> is either <code>node.UTF8</code>
or <code>node.RAW</code>.
</p>
</dd>
</dl>

4
website/index.html

@ -154,6 +154,10 @@ Server running at http://127.0.0.1:8000/</pre>
<a href="http://github.com/ry/node/tree/master">git repo</a>
</p>
<ul>
<li>
2009.06.18
<a href="http://s3.amazonaws.com/four.livejournal/20090618/node-0.0.5.tar.gz">node-0.0.5.tar.gz</a>
</li>
<li>
2009.06.13
<a href="http://s3.amazonaws.com/four.livejournal/20090613/node-0.0.4.tar.gz">node-0.0.4.tar.gz</a>

2
wscript

@ -8,7 +8,7 @@ from logging import fatal
import js2c
VERSION='0.0.4'
VERSION='0.0.5'
APPNAME='node'
srcdir = '.'

Loading…
Cancel
Save