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 b77a5dd15c..5e0deff2fc 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 d099c480e7..6d5b2eda2f 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 0cf09c697e..69322d8ac4 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 3290ae9d9b..fbbdb43fa8 100644
--- a/website/api.html
+++ b/website/api.html
@@ -622,7 +622,7 @@ server.listen(7000, "localhost");
"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 @@ req.onBody = function (chunk) {
- req.onBodyComplete
+ req.onBodyComplete = function () { };
Callback. Made exactly once for each message. No arguments.
After onBodyComplete
is executed
@@ -652,6 +652,14 @@ req.onBody = function (chunk) {
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