mirror of
https://github.com/nodejs/node.git
synced 2024-11-29 15:06:33 +01:00
Fix a bug in HTTP server when receiving half-closes.
This commit is contained in:
parent
a5d5056327
commit
6a172d7119
30
src/http.js
30
src/http.js
@ -105,6 +105,7 @@ function toRaw(string) {
|
||||
node.http.ServerResponse = function (connection, responses) {
|
||||
responses.push(this);
|
||||
this.connection = connection;
|
||||
this.closeOnFinish = false;
|
||||
var output = [];
|
||||
|
||||
// The send method appends data onto the output array. The deal is,
|
||||
@ -151,14 +152,7 @@ node.http.ServerResponse = function (connection, responses) {
|
||||
output.push(data);
|
||||
};
|
||||
|
||||
this.flush = function () {
|
||||
if (responses.length > 0 && responses[0] === this)
|
||||
while (output.length > 0)
|
||||
connection.send(output.shift());
|
||||
};
|
||||
|
||||
var chunked_encoding = false;
|
||||
var connection_close = false;
|
||||
|
||||
this.sendHeader = function (status_code, headers) {
|
||||
var sent_connection_header = false;
|
||||
@ -225,6 +219,14 @@ node.http.ServerResponse = function (connection, responses) {
|
||||
this.flush();
|
||||
};
|
||||
|
||||
this.flush = function () {
|
||||
if (responses.length > 0 && responses[0] === this)
|
||||
while (output.length > 0) {
|
||||
var out = output.shift();
|
||||
connection.send(out);
|
||||
}
|
||||
};
|
||||
|
||||
this.finished = false;
|
||||
this.finish = function () {
|
||||
if (chunked_encoding)
|
||||
@ -235,12 +237,10 @@ node.http.ServerResponse = function (connection, responses) {
|
||||
while (responses.length > 0 && responses[0].finished) {
|
||||
var res = responses[0];
|
||||
res.flush();
|
||||
if (res.closeOnFinish)
|
||||
connection.fullClose();
|
||||
responses.shift();
|
||||
}
|
||||
|
||||
if (responses.length == 0 && connection_close) {
|
||||
connection.fullClose();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@ -322,7 +322,11 @@ node.http.Server = function (RequestHandler, options) {
|
||||
|
||||
// is this really needed?
|
||||
connection.onEOF = function () {
|
||||
connection.close();
|
||||
puts("HTTP SERVER got eof");
|
||||
if (responses.length == 0)
|
||||
connection.close();
|
||||
else
|
||||
responses[responses.length-1].closeOnFinish = true;
|
||||
};
|
||||
}
|
||||
|
||||
@ -355,7 +359,7 @@ node.http.Client = function (port, host) {
|
||||
if (connection_expression.exec(field)) {
|
||||
sent_connection_header = true;
|
||||
if (close_expression.exec(value))
|
||||
connection_close = true;
|
||||
this.closeOnFinish = true;
|
||||
} else if (transfer_encoding_expression.exec(field)) {
|
||||
sent_transfer_encoding_header = true;
|
||||
if (chunk_expression.exec(value))
|
||||
|
@ -440,7 +440,7 @@ void name () \
|
||||
TryCatch try_catch; \
|
||||
callback->Call(handle_, 0, NULL); \
|
||||
if (try_catch.HasCaught()) \
|
||||
fatal_exception(try_catch); \
|
||||
node::fatal_exception(try_catch); \
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_CALLBACK(Connection::OnConnect, ON_CONNECT_SYMBOL)
|
||||
|
@ -7,24 +7,26 @@ function onLoad() {
|
||||
var request_number = 0;
|
||||
|
||||
new node.http.Server(function (req, res) {
|
||||
var server = this;
|
||||
res.id = request_number;
|
||||
req.id = request_number++;
|
||||
|
||||
|
||||
if (req.id == 0) {
|
||||
puts("get req");
|
||||
//puts("get req");
|
||||
assertEquals("GET", req.method);
|
||||
assertEquals("/hello", req.uri.path);
|
||||
}
|
||||
|
||||
if (req.id == 1) {
|
||||
puts("post req");
|
||||
//puts("post req");
|
||||
assertEquals("POST", req.method);
|
||||
assertEquals("/quit", req.uri.path);
|
||||
server.close();
|
||||
puts("server closed");
|
||||
this.close();
|
||||
//puts("server closed");
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
//puts("send response");
|
||||
res.sendHeader(200, [["Content-Type", "text/plain"]]);
|
||||
res.sendBody(req.uri.path);
|
||||
res.finish();
|
||||
@ -35,13 +37,14 @@ function onLoad() {
|
||||
var c = new node.tcp.Connection();
|
||||
var req_sent = 0;
|
||||
c.onConnect = function () {
|
||||
puts("send get");
|
||||
//puts("send get");
|
||||
c.send( "GET /hello HTTP/1.1\r\n\r\n" );
|
||||
req_sent += 1;
|
||||
};
|
||||
var total = "";
|
||||
|
||||
c.onReceive = function (chunk) {
|
||||
//puts("client recv");
|
||||
total += chunk.encodeUtf8();
|
||||
puts("total: " + JSON.stringify(total));
|
||||
|
||||
@ -49,12 +52,20 @@ function onLoad() {
|
||||
puts("send post");
|
||||
c.send("POST /quit HTTP/1.1\r\n\r\n");
|
||||
c.close();
|
||||
puts("client half close");
|
||||
assertEquals(c.readyState, "readOnly");
|
||||
req_sent += 1;
|
||||
}
|
||||
};
|
||||
|
||||
c.onEOF = function () {
|
||||
puts("client got eof");
|
||||
};
|
||||
|
||||
c.onDisconnect = function () {
|
||||
puts("client disocnnected");
|
||||
puts("client disconnected");
|
||||
|
||||
assertEquals(c.readyState, "closed");
|
||||
|
||||
var hello = new RegExp("/hello");
|
||||
assertTrue(hello.exec(total) != null);
|
||||
|
@ -48,23 +48,34 @@ function onLoad() {
|
||||
client.send("PING");
|
||||
};
|
||||
|
||||
var sent_final_ping = false;
|
||||
|
||||
client.onReceive = function (data) {
|
||||
assertEquals("open", client.readyState);
|
||||
//puts("client recved data: " + JSON.stringify(data));
|
||||
stdout.print(".");
|
||||
assertEquals("PONG", data);
|
||||
count += 1;
|
||||
|
||||
if (sent_final_ping) {
|
||||
assertEquals("readOnly", client.readyState);
|
||||
return;
|
||||
} else {
|
||||
assertEquals("open", client.readyState);
|
||||
}
|
||||
|
||||
if (count < N) {
|
||||
client.send("PING");
|
||||
} else {
|
||||
puts("sending FIN");
|
||||
puts("sending final ping");
|
||||
sent_final_ping = true;
|
||||
client.send("PING");
|
||||
client.close();
|
||||
}
|
||||
};
|
||||
|
||||
client.onEOF = function () {
|
||||
puts("pinger: onEOF");
|
||||
assertEquals(N, count);
|
||||
assertEquals(N+1, count);
|
||||
};
|
||||
|
||||
client.connect(port);
|
||||
|
@ -2,15 +2,32 @@ var c = new node.http.Client(8000, "localhost")
|
||||
|
||||
var req = c.get("/hello/world", [["Accept", "*/*"]]);
|
||||
req.finish(function (res) {
|
||||
puts("got response: " + res.status_code.toString());
|
||||
puts("response 1: " + res.status_code.toString());
|
||||
|
||||
res.onBody = function (chunk) {
|
||||
puts("got response body <" + chunk.encodeUtf8() + ">");
|
||||
puts("response 1 body <" + chunk.encodeUtf8() + ">");
|
||||
return true;
|
||||
};
|
||||
|
||||
res.onBodyComplete = function () {
|
||||
puts("response complete!");
|
||||
puts("response 1 complete!");
|
||||
return true;
|
||||
};
|
||||
});
|
||||
|
||||
/*
|
||||
var req = c.get("/something/else", []);
|
||||
req.finish(function (res) {
|
||||
puts("response 2: " + res.status_code.toString());
|
||||
|
||||
res.onBody = function (chunk) {
|
||||
puts("response 2 body <" + chunk.encodeUtf8() + ">");
|
||||
return true;
|
||||
};
|
||||
|
||||
res.onBodyComplete = function () {
|
||||
puts("response 2 complete!");
|
||||
return true;
|
||||
};
|
||||
});
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user