Browse Source

Add Request objects on the HTTP server can be interrupted.

v0.7.4-release v0.0.4
Ryan 16 years ago
parent
commit
916b9ca715
  1. 17
      src/http.cc
  2. 34
      src/http.js
  3. 2
      test/test-http-server.js
  4. 12
      website/api.html

17
src/http.cc

@ -80,9 +80,7 @@ void
HTTPConnection::OnReceive (const void *buf, size_t len) HTTPConnection::OnReceive (const void *buf, size_t len)
{ {
http_parser_execute(&parser_, static_cast<const char*>(buf), len); http_parser_execute(&parser_, static_cast<const char*>(buf), len);
if (http_parser_has_error(&parser_)) ForceClose();
if (http_parser_has_error(&parser_))
ForceClose();
} }
int int
@ -187,16 +185,15 @@ HTTPConnection::on_headers_complete (http_parser *parser)
); );
message_handler->Set(HTTP_VERSION_SYMBOL, String::New(version)); message_handler->Set(HTTP_VERSION_SYMBOL, String::New(version));
// SHOULD KEEP ALIVE message_handler->Set(SHOULD_KEEP_ALIVE_SYMBOL,
message_handler->Set( SHOULD_KEEP_ALIVE_SYMBOL http_parser_should_keep_alive(&connection->parser_) ? True() : False());
, http_parser_should_keep_alive(&connection->parser_) ? True() : False()
);
Local<Value> on_headers_complete_v = message_handler->Get(ON_HEADERS_COMPLETE_SYMBOL); Local<Value> on_headers_complete_v =
message_handler->Get(ON_HEADERS_COMPLETE_SYMBOL);
if (on_headers_complete_v->IsFunction() == false) return 0; if (on_headers_complete_v->IsFunction() == false) return 0;
Handle<Function> on_headers_complete = Handle<Function>::Cast(on_headers_complete_v); Handle<Function> on_headers_complete =
Handle<Function>::Cast(on_headers_complete_v);
TryCatch try_catch; TryCatch try_catch;
Local<Value> ret = on_headers_complete->Call(message_handler, 0, NULL); Local<Value> ret = on_headers_complete->Call(message_handler, 0, NULL);

34
src/http.js

@ -239,22 +239,24 @@ node.http.Server = function (RequestHandler, options) {
var responses = []; var responses = [];
connection.onMessage = function ( ) { connection.onMessage = function ( ) {
var interrupted = false;
// filled in ... // filled in ...
var req = { method : null // at onHeadersComplete var req = { method : null // at onHeadersComplete
, uri : "" // at onURI , uri : "" // at onURI
, httpVersion : null // at onHeadersComplete , httpVersion : null // at onHeadersComplete
, headers : [] // at onHeaderField, onHeaderValue , headers : [] // at onHeaderField, onHeaderValue
, onBody : null // by user , onBody : null // by user
, onBodyComplete : null // by user , onBodyComplete : null // by user
, interrupt : function ( ) { interrupted = true; }
, setBodyEncoding : function (enc) { , setBodyEncoding : function (enc) {
connection.setEncoding(enc); connection.setEncoding(enc);
} }
} };
var res = new node.http.ServerResponse(connection, responses); var res = new node.http.ServerResponse(connection, responses);
this.onURI = function (data) { this.onURI = function (data) {
req.uri += data; req.uri += data;
return true return !interrupted;
}; };
var last_was_value = false; var last_was_value = false;
@ -266,7 +268,7 @@ node.http.Server = function (RequestHandler, options) {
else else
headers.push([data]); headers.push([data]);
last_was_value = false; last_was_value = false;
return true; return !interrupted;
}; };
this.onHeaderValue = function (data) { this.onHeaderValue = function (data) {
@ -276,31 +278,29 @@ node.http.Server = function (RequestHandler, options) {
else else
last_pair[1] += data; last_pair[1] += data;
last_was_value = true; last_was_value = true;
return true; return !interrupted;
}; };
this.onHeadersComplete = function () { this.onHeadersComplete = function () {
req.httpVersion = this.httpVersion; req.httpVersion = this.httpVersion;
req.method = this.method; req.method = this.method;
req.uri = node.http.parseUri(req.uri); // TODO parse the URI lazily // TODO parse the URI lazily?
req.uri = node.http.parseUri(req.uri);
res.should_keep_alive = this.should_keep_alive; 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) { this.onBody = function (chunk) {
if (req.onBody) if (req.onBody) req.onBody(chunk);
return req.onBody(chunk); return !interrupted;
else
return true;
}; };
this.onMessageComplete = function () { this.onMessageComplete = function () {
if (req.onBodyComplete) if (req.onBodyComplete) req.onBodyComplete();
return req.onBodyComplete(); return !interrupted;
else
return true;
}; };
}; };

2
test/test-http-server.js

@ -43,7 +43,7 @@ function onLoad() {
c.onReceive = function (chunk) { c.onReceive = function (chunk) {
server_response += chunk; server_response += chunk;
if ( requests_sent == 1) { if (requests_sent == 1) {
c.send("POST /quit HTTP/1.1\r\n\r\n"); c.send("POST /quit HTTP/1.1\r\n\r\n");
c.close(); c.close();
assertEquals(c.readyState, "readOnly"); assertEquals(c.readyState, "readOnly");

12
website/api.html

@ -622,7 +622,7 @@ server.listen(7000, "localhost");</pre>
<code>"1.1"</code>, <code>"1.0"</code> <code>"1.1"</code>, <code>"1.0"</code>
</dd> </dd>
<dt><code>req.onBody</code></dt> <dt><code>req.onBody = function (chunk) { }; </code></dt>
<dd> <dd>
Callback. Should be set by the user to be informed of when a Callback. Should be set by the user to be informed of when a
piece of the message body is received. Example: piece of the message body is received. Example:
@ -640,7 +640,7 @@ req.onBody = function (chunk) {
</p> </p>
</dd> </dd>
<dt><code>req.onBodyComplete</code></dt> <dt><code>req.onBodyComplete = function () { };</code></dt>
<dd> <dd>
Callback. Made exactly once for each message. No arguments. Callback. Made exactly once for each message. No arguments.
After <code>onBodyComplete</code> is executed After <code>onBodyComplete</code> is executed
@ -652,6 +652,14 @@ req.onBody = function (chunk) {
Set the encoding for the request body. Either <code>"utf8"</code> Set the encoding for the request body. Either <code>"utf8"</code>
or <code>"raw"</code>. Defaults to raw. or <code>"raw"</code>. Defaults to raw.
</dd> </dd>
<dt><code>req.interrupt()</code></dt>
<dd>
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.
</dd>
</dl> </dl>
<h3 id="http_server_response"><code>node.http.ServerResponse</code></h3> <h3 id="http_server_response"><code>node.http.ServerResponse</code></h3>

Loading…
Cancel
Save