diff --git a/src/http.js b/src/http.js index e5688cb757..fc96026037 100644 --- a/src/http.js +++ b/src/http.js @@ -1,7 +1,3 @@ -/* This is a wrapper around the LowLevelServer interface. It provides - * connection handling, overflow checking, and some data buffering. - */ - node.http.STATUS_CODES = { 100 : 'Continue' , 101 : 'Switching Protocols' , 200 : 'OK' @@ -47,6 +43,9 @@ var close_expression = /close/i; var chunk_expression = /chunk/i; var content_length_expression = /Content-Length/i; +/* This is a wrapper around the LowLevelServer interface. It provides + * connection handling, overflow checking, and some data buffering. + */ node.http.Server = function (RequestHandler, options) { if (!(this instanceof node.http.Server)) throw Error("Constructor called as a function"); @@ -63,6 +62,8 @@ node.http.Server = function (RequestHandler, options) { * are returned in the same order the requests come. */ + this.connection = connection; + var output = []; function toRaw(string) { @@ -142,12 +143,10 @@ node.http.Server = function (RequestHandler, options) { sent_connection_header = true; if (close_expression.exec(value)) connection_close = true; - } else if (transfer_encoding_expression.exec(field)) { sent_transfer_encoding_header = true; if (chunk_expression.exec(value)) chunked_encoding = true; - } else if (content_length_expression.exec(field)) { sent_content_length_header = true; } @@ -259,7 +258,107 @@ node.http.Server = function (RequestHandler, options) { return msg.onBodyComplete(chunk); }; }; + + // is this really needed? + connection.onEOF = function () { + connection.close(); + }; } this.__proto__.__proto__ = new node.http.LowLevelServer(ConnectionHandler, options); }; + +node.http.Client = function (port, host) { + var port = port; + var host = host; + + var pending_messages = []; + function Message (method, uri, header_lines) { + pending_messages.push(this); + + this.method = method; + this.path = path; + this.headers = headers; + + var chunked_encoding = false; + var connection_close = false; + + var sent_connection_header = false; + var sent_transfer_encoding_header = false; + var sent_content_length_header = false; + + var header = method + " " + uri + " HTTP/1.1\r\n"; + + for (var i = 0; i < header_lines.length; i++) { + var field = header_lines[i][0]; + var value = header_lines[i][1]; + + header += field + ": " + value + "\r\n"; + + if (connection_expression.exec(field)) { + sent_connection_header = true; + if (close_expression.exec(value)) + connection_close = true; + } else if (transfer_encoding_expression.exec(field)) { + sent_transfer_encoding_header = true; + if (chunk_expression.exec(value)) + chunked_encoding = true; + } else if (content_length_expression.exec(field)) { + sent_content_length_header = true; + } + } + + if (sent_connection_header == false) { + header += "Connection: keep-alive\r\n"; + } + + if (sent_content_length_header == false && sent_transfer_encoding_header == false) { + header += "Transfer-Encoding: chunked\r\n"; + chunked_encoding = true; + } + header += "\r\n"; + + var output = [header]; + + this.sendBody = function (chunk) { + }; + + this.finish = function () { + }; + } + + function spawn_client ( ) { + var c = new node.http.LowLevelClient(); + + c.onConnect = function () { + }; + + // On response + c.onMessage = function () { + }; + } + + this.get = function (path, headers) { + var m = new Message("GET", path, headers); + m.finish(); + return m; + }; + + this.head = function (path, headers) { + var m = new Message("HEAD", path, headers); + m.finish(); + return m; + }; + + this.post = function (path, headers) { + return new Message("POST", path, headers); + }; + + this.del = function (path, headers) { + return new Message("DELETE", path, headers); + }; + + this.put = function (path, headers) { + return new Message("PUT", path, headers); + }; +}; diff --git a/src/net.cc b/src/net.cc index c8e3626224..1d8d094c84 100644 --- a/src/net.cc +++ b/src/net.cc @@ -265,7 +265,7 @@ Connection::v8ForceClose (const Arguments& args) if (!connection) return Handle(); connection->ForceClose(); - //connection->Detach(); + connection->Detach(); return Undefined(); } diff --git a/src/node.cc b/src/node.cc index 7218547a10..c7306da3ea 100644 --- a/src/node.cc +++ b/src/node.cc @@ -252,8 +252,8 @@ main (int argc, char *argv[]) ev_async_init(&eio_watcher, node_eio_cb); eio_init(eio_want_poll, NULL); - V8::Initialize(); V8::SetFlagsFromCommandLine(&argc, argv, true); + V8::Initialize(); if(argc < 2) { fprintf(stderr, "No script was specified.\n"); @@ -317,7 +317,13 @@ main (int argc, char *argv[]) ev_loop(EV_DEFAULT_UC_ 0); context.Dispose(); - V8::Dispose(); + // The following line when uncommented causes an error. + // To reproduce do this: + // > node --prof test-http_simple.js + // + // > curl http://localhost:8000/quit/ + // + //V8::Dispose(); return exit_code; diff --git a/test-http_simple.js b/test-http_simple.js new file mode 100644 index 0000000000..0e283e73e7 --- /dev/null +++ b/test-http_simple.js @@ -0,0 +1,35 @@ +new node.http.Server(function (msg) { + var commands = msg.path.split("/"); + var body = ""; + var command = commands[1]; + var arg = commands[2]; + var status = 200; + + //p(msg.headers); + + if (command == "bytes") { + var n = parseInt(arg, 10) + if (n <= 0) + throw "bytes called with n <= 0" + for (var i = 0; i < n; i++) { + body += "C" + } + + } else if (command == "quit") { + msg.connection.server.close(); + } else { + status = 404; + body = "not found\n"; + } + + var content_length = body.length.toString(); + + msg.sendHeader( status + , [ ["Content-Type", "text/plain"] + , ["Content-Length", content_length] + ] + ); + msg.sendBody(body); + + msg.finish(); +}).listen(8000);