From 916b9ca715b229b0703f0ed6c2fc065410fb189c Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 12 Jun 2009 17:37:43 +0200 Subject: [PATCH] Add Request objects on the HTTP server can be interrupted. --- src/http.cc | 17 +++++++---------- src/http.js | 34 +++++++++++++++++----------------- test/test-http-server.js | 2 +- website/api.html | 12 ++++++++++-- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/http.cc b/src/http.cc index b77a5dd15cd..5e0deff2fc5 100644 --- a/src/http.cc +++ b/src/http.cc @@ -80,9 +80,7 @@ void HTTPConnection::OnReceive (const void *buf, size_t len) { http_parser_execute(&parser_, static_cast(buf), len); - - if (http_parser_has_error(&parser_)) - ForceClose(); + if (http_parser_has_error(&parser_)) ForceClose(); } int @@ -187,16 +185,15 @@ HTTPConnection::on_headers_complete (http_parser *parser) ); message_handler->Set(HTTP_VERSION_SYMBOL, String::New(version)); - // SHOULD KEEP ALIVE - message_handler->Set( SHOULD_KEEP_ALIVE_SYMBOL - , http_parser_should_keep_alive(&connection->parser_) ? True() : False() - ); - + message_handler->Set(SHOULD_KEEP_ALIVE_SYMBOL, + http_parser_should_keep_alive(&connection->parser_) ? True() : False()); - Local on_headers_complete_v = message_handler->Get(ON_HEADERS_COMPLETE_SYMBOL); + Local on_headers_complete_v = + message_handler->Get(ON_HEADERS_COMPLETE_SYMBOL); if (on_headers_complete_v->IsFunction() == false) return 0; - Handle on_headers_complete = Handle::Cast(on_headers_complete_v); + Handle on_headers_complete = + Handle::Cast(on_headers_complete_v); TryCatch try_catch; Local ret = on_headers_complete->Call(message_handler, 0, NULL); diff --git a/src/http.js b/src/http.js index d099c480e77..6d5b2eda2f6 100644 --- a/src/http.js +++ b/src/http.js @@ -239,22 +239,24 @@ node.http.Server = function (RequestHandler, options) { var responses = []; connection.onMessage = function ( ) { + var interrupted = false; // filled in ... var req = { method : null // at onHeadersComplete , uri : "" // at onURI - , httpVersion : null // at onHeadersComplete + , httpVersion : null // at onHeadersComplete , headers : [] // at onHeaderField, onHeaderValue , onBody : null // by user , onBodyComplete : null // by user + , interrupt : function ( ) { interrupted = true; } , setBodyEncoding : function (enc) { connection.setEncoding(enc); } - } + }; var res = new node.http.ServerResponse(connection, responses); this.onURI = function (data) { req.uri += data; - return true + return !interrupted; }; var last_was_value = false; @@ -266,7 +268,7 @@ node.http.Server = function (RequestHandler, options) { else headers.push([data]); last_was_value = false; - return true; + return !interrupted; }; this.onHeaderValue = function (data) { @@ -276,31 +278,29 @@ node.http.Server = function (RequestHandler, options) { else last_pair[1] += data; last_was_value = true; - return true; + return !interrupted; }; this.onHeadersComplete = function () { req.httpVersion = this.httpVersion; - req.method = this.method; - req.uri = node.http.parseUri(req.uri); // TODO parse the URI lazily - + req.method = this.method; + // TODO parse the URI lazily? + req.uri = node.http.parseUri(req.uri); res.should_keep_alive = this.should_keep_alive; - return RequestHandler.apply(server, [req, res]); + RequestHandler.apply(server, [req, res]); + + return !interrupted; }; this.onBody = function (chunk) { - if (req.onBody) - return req.onBody(chunk); - else - return true; + if (req.onBody) req.onBody(chunk); + return !interrupted; }; this.onMessageComplete = function () { - if (req.onBodyComplete) - return req.onBodyComplete(); - else - return true; + if (req.onBodyComplete) req.onBodyComplete(); + return !interrupted; }; }; diff --git a/test/test-http-server.js b/test/test-http-server.js index 0cf09c697e0..69322d8ac40 100644 --- a/test/test-http-server.js +++ b/test/test-http-server.js @@ -43,7 +43,7 @@ function onLoad() { c.onReceive = function (chunk) { server_response += chunk; - if ( requests_sent == 1) { + if (requests_sent == 1) { c.send("POST /quit HTTP/1.1\r\n\r\n"); c.close(); assertEquals(c.readyState, "readOnly"); diff --git a/website/api.html b/website/api.html index 3290ae9d9b1..fbbdb43fa8f 100644 --- a/website/api.html +++ b/website/api.html @@ -622,7 +622,7 @@

node.http.ServerRequest

"1.1", "1.0" -
req.onBody
+
req.onBody = function (chunk) { };
Callback. Should be set by the user to be informed of when a piece of the message body is received. Example: @@ -640,7 +640,7 @@

node.http.ServerRequest

-
req.onBodyComplete
+
req.onBodyComplete = function () { };
Callback. Made exactly once for each message. No arguments. After onBodyComplete is executed @@ -652,6 +652,14 @@

node.http.ServerRequest

Set the encoding for the request body. Either "utf8" or "raw". Defaults to raw.
+ +
req.interrupt()
+
+ Interrupt the request. You will not receive anymore callbacks. + This is useful if, for example someone is streaming up a file but it + is too large and neesd to be stopped. The connection to the client + will be closed immediately. +

node.http.ServerResponse