summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2010-03-19 19:22:04 -0700
committerRyan Dahl <ry@tinyclouds.org>2010-03-19 19:52:09 -0700
commitb80f6e9ed16f32920e81f9acf749d7bf9faf1320 (patch)
treea30a97c8c182468a1d7cabfd0369283fc4463a51
parent4278f35e892935787afb1db18ca8811fba0d18f7 (diff)
downloadnode-new-b80f6e9ed16f32920e81f9acf749d7bf9faf1320.tar.gz
http2 now default
-rw-r--r--benchmark/http_simple.js2
-rw-r--r--lib/http.js397
-rw-r--r--lib/http_old.js (renamed from lib/http2.js)397
-rw-r--r--src/node.cc2
-rw-r--r--test/simple/test-event-emitter-modify-in-emit.js2
-rw-r--r--test/simple/test-file-read-stream.js2
-rw-r--r--test/simple/test-file-write-stream.js2
-rw-r--r--test/simple/test-http-1.0.js2
-rw-r--r--test/simple/test-http-cat.js2
-rw-r--r--test/simple/test-http-chunked.js2
-rw-r--r--test/simple/test-http-client-race.js2
-rw-r--r--test/simple/test-http-client-upload.js2
-rw-r--r--test/simple/test-http-eof-on-connect.js2
-rw-r--r--test/simple/test-http-malformed-request.js2
-rw-r--r--test/simple/test-http-proxy.js2
-rw-r--r--test/simple/test-http-server.js2
-rw-r--r--test/simple/test-http-wget.js2
-rw-r--r--test/simple/test-http.js2
-rw-r--r--test/simple/test-remote-module-loading.js2
19 files changed, 414 insertions, 414 deletions
diff --git a/benchmark/http_simple.js b/benchmark/http_simple.js
index 6d21c38eb5..4051577992 100644
--- a/benchmark/http_simple.js
+++ b/benchmark/http_simple.js
@@ -1,7 +1,7 @@
path = require("path");
var puts = require("sys").puts;
-http = require("http2");
+http = require("http");
fixed = ""
for (var i = 0; i < 20*1024; i++) {
diff --git a/lib/http.js b/lib/http.js
index 832df6b2cb..a8d09d3ea8 100644
--- a/lib/http.js
+++ b/lib/http.js
@@ -1,11 +1,110 @@
var sys = require('sys');
+var net = require('net');
var events = require('events');
-// FIXME: The TCP binding isn't actually used here, but it needs to be
-// loaded before the http binding.
-process.binding('tcp');
+var HTTPParser = process.binding('http_parser').HTTPParser;
+
+var parserFreeList = [];
+
+function newParser (type) {
+ var parser;
+ if (parserFreeList.length) {
+ parser = parserFreeList.shift();
+ parser.reinitialize(type);
+ } else {
+ parser = new HTTPParser(type);
+
+ parser.onMessageBegin = function () {
+ parser.incoming = new IncomingMessage(parser.socket);
+ parser.field = null;
+ parser.value = null;
+ };
+
+ // Only servers will get URL events.
+ parser.onURL = function (b, start, len) {
+ var slice = b.asciiSlice(start, start+len);
+ if (parser.incoming.url) {
+ parser.incoming.url += slice;
+ } else {
+ // Almost always will branch here.
+ parser.incoming.url = slice;
+ }
+ };
+
+ parser.onHeaderField = function (b, start, len) {
+ var slice = b.asciiSlice(start, start+len).toLowerCase();
+ if (parser.value) {
+ parser.incoming._addHeaderLine(parser.field, parser.value);
+ parser.field = null;
+ parser.value = null;
+ }
+ if (parser.field) {
+ parser.field += slice;
+ } else {
+ parser.field = slice;
+ }
+ };
+
+ parser.onHeaderValue = function (b, start, len) {
+ var slice = b.asciiSlice(start, start+len);
+ if (parser.value) {
+ parser.value += slice;
+ } else {
+ parser.value = slice;
+ }
+ };
+
+ parser.onHeadersComplete = function (info) {
+ if (parser.field && parser.value) {
+ parser.incoming._addHeaderLine(parser.field, parser.value);
+ }
+
+ parser.incoming.httpVersionMajor = info.versionMajor;
+ parser.incoming.httpVersionMinor = info.versionMinor;
+
+ if (info.method) {
+ // server only
+ parser.incoming.method = info.method;
+ } else {
+ // client only
+ parser.incoming.statusCode = info.statusCode;
+ }
+
+ parser.onIncoming(parser.incoming, info.shouldKeepAlive);
+ };
+
+ parser.onBody = function (b, start, len) {
+ // TODO body encoding?
+ var enc = parser.incoming._encoding;
+ if (!enc) {
+ parser.incoming.emit('data', b.slice(start, start+len));
+ } else {
+ var string;
+ switch (enc) {
+ case 'utf8':
+ string = b.utf8Slice(start, start+len);
+ break;
+ case 'ascii':
+ string = b.asciiSlice(start, start+len);
+ break;
+ default:
+ throw new Error('Unsupported encoding ' + self._encoding + '. Use Buffer');
+ }
+ parser.incoming.emit('data', string);
+ }
+ };
+
+ parser.onMessageComplete = function () {
+ parser.incoming.emit("end");
+ };
+ }
+ return parser;
+}
+
+function freeParser (parser) {
+ if (parserFreeList.length < 1000) parserFreeList.push(parser);
+}
-var http = process.binding('http');
var CRLF = "\r\n";
var STATUS_CODES = exports.STATUS_CODES = {
@@ -56,10 +155,10 @@ var content_length_expression = /Content-Length/i;
/* Abstract base class for ServerRequest and ClientResponse. */
-function IncomingMessage (connection) {
+function IncomingMessage (socket) {
events.EventEmitter.call(this);
- this.connection = connection;
+ this.socket = socket;
this.httpVersion = null;
this.headers = {};
@@ -70,7 +169,7 @@ function IncomingMessage (connection) {
// response (client) only
this.statusCode = null;
- this.client = this.connection;
+ this.client = this.socket;
}
sys.inherits(IncomingMessage, events.EventEmitter);
exports.IncomingMessage = IncomingMessage;
@@ -80,16 +179,21 @@ IncomingMessage.prototype._parseQueryString = function () {
};
IncomingMessage.prototype.setBodyEncoding = function (enc) {
- // TODO: Find a cleaner way of doing this.
- this.connection.setEncoding(enc);
+ // TODO deprecation message?
+ this.setEncoding(enc);
+};
+
+IncomingMessage.prototype.setEncoding = function (enc) {
+ // TODO check values, error out on bad, and deprecation message?
+ this._encoding = enc.toLowerCase();
};
IncomingMessage.prototype.pause = function () {
- this.connection.pause();
+ this.socket.pause();
};
IncomingMessage.prototype.resume = function () {
- this.connection.resume();
+ this.socket.resume();
};
IncomingMessage.prototype._addHeaderLine = function (field, value) {
@@ -102,10 +206,10 @@ IncomingMessage.prototype._addHeaderLine = function (field, value) {
}
};
-function OutgoingMessage (connection) {
- events.EventEmitter.call(this, connection);
+function OutgoingMessage (socket) {
+ events.EventEmitter.call(this, socket);
- this.connection = connection;
+ this.socket = socket;
this.output = [];
this.outputEncodings = [];
@@ -126,7 +230,7 @@ exports.OutgoingMessage = OutgoingMessage;
OutgoingMessage.prototype._send = function (data, encoding) {
var length = this.output.length;
- if (length === 0) {
+ if (length === 0 || typeof data != 'string') {
this.output.push(data);
encoding = encoding || "ascii";
this.outputEncodings.push(encoding);
@@ -138,11 +242,7 @@ OutgoingMessage.prototype._send = function (data, encoding) {
if ((lastEncoding === encoding) ||
(!encoding && data.constructor === lastData.constructor)) {
- if (lastData.constructor === String) {
- this.output[length-1] = lastData + data;
- } else {
- this.output[length-1] = lastData.concat(data);
- }
+ this.output[length-1] = lastData + data;
return;
}
@@ -228,7 +328,11 @@ OutgoingMessage.prototype.write = function (chunk, encoding) {
encoding = encoding || "ascii";
if (this.chunked_encoding) {
- this._send(process._byteLength(chunk, encoding).toString(16));
+ if (typeof chunk == 'string') {
+ this._send(process._byteLength(chunk, encoding).toString(16));
+ } else {
+ this._send(chunk.length.toString(16));
+ }
this._send(CRLF);
this._send(chunk, encoding);
this._send(CRLF);
@@ -259,7 +363,7 @@ OutgoingMessage.prototype.close = function () {
function ServerResponse (req) {
- OutgoingMessage.call(this, req.connection);
+ OutgoingMessage.call(this, req.socket);
if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {
this.use_chunked_encoding_by_default = false;
@@ -297,8 +401,8 @@ ServerResponse.prototype.writeHead = function (statusCode) {
ServerResponse.prototype.sendHeader = ServerResponse.prototype.writeHead;
ServerResponse.prototype.writeHeader = ServerResponse.prototype.writeHead;
-function ClientRequest (connection, method, url, headers) {
- OutgoingMessage.call(this, connection);
+function ClientRequest (socket, method, url, headers) {
+ OutgoingMessage.call(this, socket);
this.should_keep_alive = false;
if (method === "GET" || method === "HEAD") {
@@ -330,85 +434,19 @@ ClientRequest.prototype.close = function () {
};
-function createIncomingMessageStream (connection, incoming_listener) {
- var incoming, field, value;
-
- connection.addListener("messageBegin", function () {
- incoming = new IncomingMessage(connection);
- field = null;
- value = null;
- });
-
- // Only servers will get URL events.
- connection.addListener("url", function (data) {
- incoming.url += data;
- });
-
- connection.addListener("headerField", function (data) {
- if (value) {
- incoming._addHeaderLine(field, value);
- field = null;
- value = null;
- }
- if (field) {
- field += data;
- } else {
- field = data;
- }
- });
-
- connection.addListener("headerValue", function (data) {
- if (value) {
- value += data;
- } else {
- value = data;
- }
- });
-
- connection.addListener("headerComplete", function (info) {
- if (field && value) {
- incoming._addHeaderLine(field, value);
- }
-
- incoming.httpVersion = info.httpVersion;
- incoming.httpVersionMajor = info.versionMajor;
- incoming.httpVersionMinor = info.versionMinor;
-
- if (info.method) {
- // server only
- incoming.method = info.method;
- } else {
- // client only
- incoming.statusCode = info.statusCode;
- }
-
- incoming_listener(incoming, info.should_keep_alive);
- });
-
- connection.addListener("body", function (chunk) {
- incoming.emit('data', chunk);
- });
-
- connection.addListener("messageComplete", function () {
- incoming.emit('end');
- });
-}
-
-/* Returns true if the message queue is finished and the connection
+/* Returns true if the message queue is finished and the socket
* should be closed. */
-function flushMessageQueue (connection, queue) {
+function flushMessageQueue (socket, queue) {
while (queue[0]) {
var message = queue[0];
while (message.output.length > 0) {
- if (connection.readyState !== "open" && connection.readyState !== "writeOnly") {
- return true;
- }
+ if (!socket.writable) return true;
var data = message.output.shift();
var encoding = message.outputEncodings.shift();
- connection.write(data, encoding);
+ socket.write(data, encoding);
}
if (!message.finished) break;
@@ -422,152 +460,173 @@ function flushMessageQueue (connection, queue) {
}
-exports.createServer = function (requestListener, options) {
- var server = new http.Server();
- //server.setOptions(options);
- server.addListener("request", requestListener);
- server.addListener("connection", connectionListener);
- return server;
+function Server (requestListener) {
+ net.Server.call(this);
+ this.addListener("request", requestListener);
+ this.addListener("connection", connectionListener);
+}
+sys.inherits(Server, net.Server);
+
+exports.Server = Server;
+
+exports.createServer = function (requestListener) {
+ return new Server(requestListener);
};
-function connectionListener (connection) {
- // An array of responses for each connection. In pipelined connections
+function connectionListener (socket) {
+ var self = this;
+ // An array of responses for each socket. In pipelined connections
// we need to keep track of the order they were sent.
var responses = [];
- connection.resetParser();
+ var parser = newParser('request');
+
+ socket.ondata = function (d, start, end) {
+ parser.execute(d, start, end - start);
+ };
+
+ socket.onend = function () {
+ parser.finish();
+ // unref the parser for easy gc
+ freeParser(parser);
- // is this really needed?
- connection.addListener("end", function () {
if (responses.length == 0) {
- connection.close();
+ socket.close();
} else {
responses[responses.length-1].closeOnFinish = true;
}
- });
-
+ };
- createIncomingMessageStream(connection, function (incoming, should_keep_alive) {
+ parser.socket = socket;
+ // The following callback is issued after the headers have been read on a
+ // new message. In this callback we setup the response object and pass it
+ // to the user.
+ parser.onIncoming = function (incoming, shouldKeepAlive) {
var req = incoming;
-
var res = new ServerResponse(req);
- res.should_keep_alive = should_keep_alive;
- res.addListener("flush", function () {
- if (flushMessageQueue(connection, responses)) {
- connection.close();
+
+ res.shouldKeepAlive = shouldKeepAlive;
+ res.addListener('flush', function () {
+ if (flushMessageQueue(socket, responses)) {
+ socket.close();
}
});
responses.push(res);
- connection.server.emit("request", req, res);
- });
+ self.emit('request', req, res);
+ };
}
-exports.createClient = function (port, host) {
- var client = new http.Client();
- var secure_credentials={ secure : false };
+function Client ( ) {
+ net.Stream.call(this);
+
+ var self = this;
var requests = [];
var currentRequest;
- client.tcpSetSecure = client.setSecure;
- client.setSecure = function(format_type, ca_certs, crl_list, private_key, certificate) {
- secure_credentials.secure = true;
- secure_credentials.format_type = format_type;
- secure_credentials.ca_certs = ca_certs;
- secure_credentials.crl_list = crl_list;
- secure_credentials.private_key = private_key;
- secure_credentials.certificate = certificate;
- }
+ var parser = newParser('response');
+ parser.socket = this;
- client._reconnect = function () {
- if (client.readyState != "opening") {
- //sys.debug("HTTP CLIENT: reconnecting readyState = " + client.readyState);
- client.connect(port, host);
- if (secure_credentials.secure) {
- client.tcpSetSecure(secure_credentials.format_type,
- secure_credentials.ca_certs,
- secure_credentials.crl_list,
- secure_credentials.private_key,
- secure_credentials.certificate);
- }
+ self._reconnect = function () {
+ if (self.readyState != "opening") {
+ sys.debug("HTTP CLIENT: reconnecting readyState = " + self.readyState);
+ self.connect(self.port, self.host);
}
};
- client._pushRequest = function (req) {
+ self._pushRequest = function (req) {
req.addListener("flush", function () {
- if (client.readyState == "closed") {
- //sys.debug("HTTP CLIENT request flush. reconnect. readyState = " + client.readyState);
- client._reconnect();
+ if (self.readyState == "closed") {
+ sys.debug("HTTP CLIENT request flush. reconnect. readyState = " + self.readyState);
+ self._reconnect();
return;
}
- //sys.debug("client flush readyState = " + client.readyState);
- if (req == currentRequest) flushMessageQueue(client, [req]);
+
+ sys.debug("self flush readyState = " + self.readyState);
+ if (req == currentRequest) flushMessageQueue(self, [req]);
});
requests.push(req);
};
- client.addListener("connect", function () {
- client.resetParser();
- currentRequest = requests.shift();
+ this.ondata = function (d, start, end) {
+ parser.execute(d, start, end - start);
+ };
+
+ self.addListener("connect", function () {
+ parser.reinitialize('response');
+ sys.puts('requests: ' + sys.inspect(requests));
+ currentRequest = requests.shift()
currentRequest.flush();
});
- client.addListener("end", function () {
- //sys.debug("client got end closing. readyState = " + client.readyState);
- client.close();
+ self.addListener("end", function () {
+ parser.finish();
+ freeParser(parser);
+
+ //sys.debug("self got end closing. readyState = " + self.readyState);
+ self.close();
});
- client.addListener("close", function (had_error) {
+ self.addListener("close", function (had_error) {
if (had_error) {
- client.emit("error");
+ self.emit("error");
return;
}
- //sys.debug("HTTP CLIENT onClose. readyState = " + client.readyState);
+ sys.debug("HTTP CLIENT onClose. readyState = " + self.readyState);
// If there are more requests to handle, reconnect.
if (requests.length > 0) {
- client._reconnect();
+ self._reconnect();
}
});
- createIncomingMessageStream(client, function (res) {
- //sys.debug("incoming response!");
+ parser.onIncoming = function (res) {
+ sys.debug("incoming response!");
res.addListener('end', function ( ) {
- //sys.debug("request complete disconnecting. readyState = " + client.readyState);
- client.close();
+ //sys.debug("request complete disconnecting. readyState = " + self.readyState);
+ self.close();
});
currentRequest.emit("response", res);
- });
-
- return client;
+ };
};
+sys.inherits(Client, net.Stream);
+
+exports.Client = Client;
+
+exports.createClient = function (port, host) {
+ var c = new Client;
+ c.port = port;
+ c.host = host;
+ return c;
+}
+
-http.Client.prototype.get = function () {
+Client.prototype.get = function () {
throw new Error("client.get(...) is now client.request('GET', ...)");
};
-http.Client.prototype.head = function () {
+Client.prototype.head = function () {
throw new Error("client.head(...) is now client.request('HEAD', ...)");
};
-http.Client.prototype.post = function () {
+Client.prototype.post = function () {
throw new Error("client.post(...) is now client.request('POST', ...)");
};
-http.Client.prototype.del = function () {
+Client.prototype.del = function () {
throw new Error("client.del(...) is now client.request('DELETE', ...)");
};
-http.Client.prototype.put = function () {
+Client.prototype.put = function () {
throw new Error("client.put(...) is now client.request('PUT', ...)");
};
-http.Client.prototype.request = function (method, url, headers) {
+Client.prototype.request = function (method, url, headers) {
if (typeof(url) != "string") { // assume method was omitted, shift arguments
headers = url;
url = method;
@@ -580,7 +639,7 @@ http.Client.prototype.request = function (method, url, headers) {
exports.cat = function (url, encoding_, headers_) {
- var encoding = 'utf8',
+ var encoding = 'utf8',
headers = {},
callback = null;
diff --git a/lib/http2.js b/lib/http_old.js
index a8d09d3ea8..832df6b2cb 100644
--- a/lib/http2.js
+++ b/lib/http_old.js
@@ -1,110 +1,11 @@
var sys = require('sys');
-var net = require('net');
var events = require('events');
-var HTTPParser = process.binding('http_parser').HTTPParser;
-
-var parserFreeList = [];
-
-function newParser (type) {
- var parser;
- if (parserFreeList.length) {
- parser = parserFreeList.shift();
- parser.reinitialize(type);
- } else {
- parser = new HTTPParser(type);
-
- parser.onMessageBegin = function () {
- parser.incoming = new IncomingMessage(parser.socket);
- parser.field = null;
- parser.value = null;
- };
-
- // Only servers will get URL events.
- parser.onURL = function (b, start, len) {
- var slice = b.asciiSlice(start, start+len);
- if (parser.incoming.url) {
- parser.incoming.url += slice;
- } else {
- // Almost always will branch here.
- parser.incoming.url = slice;
- }
- };
-
- parser.onHeaderField = function (b, start, len) {
- var slice = b.asciiSlice(start, start+len).toLowerCase();
- if (parser.value) {
- parser.incoming._addHeaderLine(parser.field, parser.value);
- parser.field = null;
- parser.value = null;
- }
- if (parser.field) {
- parser.field += slice;
- } else {
- parser.field = slice;
- }
- };
-
- parser.onHeaderValue = function (b, start, len) {
- var slice = b.asciiSlice(start, start+len);
- if (parser.value) {
- parser.value += slice;
- } else {
- parser.value = slice;
- }
- };
-
- parser.onHeadersComplete = function (info) {
- if (parser.field && parser.value) {
- parser.incoming._addHeaderLine(parser.field, parser.value);
- }
-
- parser.incoming.httpVersionMajor = info.versionMajor;
- parser.incoming.httpVersionMinor = info.versionMinor;
-
- if (info.method) {
- // server only
- parser.incoming.method = info.method;
- } else {
- // client only
- parser.incoming.statusCode = info.statusCode;
- }
-
- parser.onIncoming(parser.incoming, info.shouldKeepAlive);
- };
-
- parser.onBody = function (b, start, len) {
- // TODO body encoding?
- var enc = parser.incoming._encoding;
- if (!enc) {
- parser.incoming.emit('data', b.slice(start, start+len));
- } else {
- var string;
- switch (enc) {
- case 'utf8':
- string = b.utf8Slice(start, start+len);
- break;
- case 'ascii':
- string = b.asciiSlice(start, start+len);
- break;
- default:
- throw new Error('Unsupported encoding ' + self._encoding + '. Use Buffer');
- }
- parser.incoming.emit('data', string);
- }
- };
-
- parser.onMessageComplete = function () {
- parser.incoming.emit("end");
- };
- }
- return parser;
-}
-
-function freeParser (parser) {
- if (parserFreeList.length < 1000) parserFreeList.push(parser);
-}
+// FIXME: The TCP binding isn't actually used here, but it needs to be
+// loaded before the http binding.
+process.binding('tcp');
+var http = process.binding('http');
var CRLF = "\r\n";
var STATUS_CODES = exports.STATUS_CODES = {
@@ -155,10 +56,10 @@ var content_length_expression = /Content-Length/i;
/* Abstract base class for ServerRequest and ClientResponse. */
-function IncomingMessage (socket) {
+function IncomingMessage (connection) {
events.EventEmitter.call(this);
- this.socket = socket;
+ this.connection = connection;
this.httpVersion = null;
this.headers = {};
@@ -169,7 +70,7 @@ function IncomingMessage (socket) {
// response (client) only
this.statusCode = null;
- this.client = this.socket;
+ this.client = this.connection;
}
sys.inherits(IncomingMessage, events.EventEmitter);
exports.IncomingMessage = IncomingMessage;
@@ -179,21 +80,16 @@ IncomingMessage.prototype._parseQueryString = function () {
};
IncomingMessage.prototype.setBodyEncoding = function (enc) {
- // TODO deprecation message?
- this.setEncoding(enc);
-};
-
-IncomingMessage.prototype.setEncoding = function (enc) {
- // TODO check values, error out on bad, and deprecation message?
- this._encoding = enc.toLowerCase();
+ // TODO: Find a cleaner way of doing this.
+ this.connection.setEncoding(enc);
};
IncomingMessage.prototype.pause = function () {
- this.socket.pause();
+ this.connection.pause();
};
IncomingMessage.prototype.resume = function () {
- this.socket.resume();
+ this.connection.resume();
};
IncomingMessage.prototype._addHeaderLine = function (field, value) {
@@ -206,10 +102,10 @@ IncomingMessage.prototype._addHeaderLine = function (field, value) {
}
};
-function OutgoingMessage (socket) {
- events.EventEmitter.call(this, socket);
+function OutgoingMessage (connection) {
+ events.EventEmitter.call(this, connection);
- this.socket = socket;
+ this.connection = connection;
this.output = [];
this.outputEncodings = [];
@@ -230,7 +126,7 @@ exports.OutgoingMessage = OutgoingMessage;
OutgoingMessage.prototype._send = function (data, encoding) {
var length = this.output.length;
- if (length === 0 || typeof data != 'string') {
+ if (length === 0) {
this.output.push(data);
encoding = encoding || "ascii";
this.outputEncodings.push(encoding);
@@ -242,7 +138,11 @@ OutgoingMessage.prototype._send = function (data, encoding) {
if ((lastEncoding === encoding) ||
(!encoding && data.constructor === lastData.constructor)) {
- this.output[length-1] = lastData + data;
+ if (lastData.constructor === String) {
+ this.output[length-1] = lastData + data;
+ } else {
+ this.output[length-1] = lastData.concat(data);
+ }
return;
}
@@ -328,11 +228,7 @@ OutgoingMessage.prototype.write = function (chunk, encoding) {
encoding = encoding || "ascii";
if (this.chunked_encoding) {
- if (typeof chunk == 'string') {
- this._send(process._byteLength(chunk, encoding).toString(16));
- } else {
- this._send(chunk.length.toString(16));
- }
+ this._send(process._byteLength(chunk, encoding).toString(16));
this._send(CRLF);
this._send(chunk, encoding);
this._send(CRLF);
@@ -363,7 +259,7 @@ OutgoingMessage.prototype.close = function () {
function ServerResponse (req) {
- OutgoingMessage.call(this, req.socket);
+ OutgoingMessage.call(this, req.connection);
if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {
this.use_chunked_encoding_by_default = false;
@@ -401,8 +297,8 @@ ServerResponse.prototype.writeHead = function (statusCode) {
ServerResponse.prototype.sendHeader = ServerResponse.prototype.writeHead;
ServerResponse.prototype.writeHeader = ServerResponse.prototype.writeHead;
-function ClientRequest (socket, method, url, headers) {
- OutgoingMessage.call(this, socket);
+function ClientRequest (connection, method, url, headers) {
+ OutgoingMessage.call(this, connection);
this.should_keep_alive = false;
if (method === "GET" || method === "HEAD") {
@@ -434,19 +330,85 @@ ClientRequest.prototype.close = function () {
};
-/* Returns true if the message queue is finished and the socket
+function createIncomingMessageStream (connection, incoming_listener) {
+ var incoming, field, value;
+
+ connection.addListener("messageBegin", function () {
+ incoming = new IncomingMessage(connection);
+ field = null;
+ value = null;
+ });
+
+ // Only servers will get URL events.
+ connection.addListener("url", function (data) {
+ incoming.url += data;
+ });
+
+ connection.addListener("headerField", function (data) {
+ if (value) {
+ incoming._addHeaderLine(field, value);
+ field = null;
+ value = null;
+ }
+ if (field) {
+ field += data;
+ } else {
+ field = data;
+ }
+ });
+
+ connection.addListener("headerValue", function (data) {
+ if (value) {
+ value += data;
+ } else {
+ value = data;
+ }
+ });
+
+ connection.addListener("headerComplete", function (info) {
+ if (field && value) {
+ incoming._addHeaderLine(field, value);
+ }
+
+ incoming.httpVersion = info.httpVersion;
+ incoming.httpVersionMajor = info.versionMajor;
+ incoming.httpVersionMinor = info.versionMinor;
+
+ if (info.method) {
+ // server only
+ incoming.method = info.method;
+ } else {
+ // client only
+ incoming.statusCode = info.statusCode;
+ }
+
+ incoming_listener(incoming, info.should_keep_alive);
+ });
+
+ connection.addListener("body", function (chunk) {
+ incoming.emit('data', chunk);
+ });
+
+ connection.addListener("messageComplete", function () {
+ incoming.emit('end');
+ });
+}
+
+/* Returns true if the message queue is finished and the connection
* should be closed. */
-function flushMessageQueue (socket, queue) {
+function flushMessageQueue (connection, queue) {
while (queue[0]) {
var message = queue[0];
while (message.output.length > 0) {
- if (!socket.writable) return true;
+ if (connection.readyState !== "open" && connection.readyState !== "writeOnly") {
+ return true;
+ }
var data = message.output.shift();
var encoding = message.outputEncodings.shift();
- socket.write(data, encoding);
+ connection.write(data, encoding);
}
if (!message.finished) break;
@@ -460,173 +422,152 @@ function flushMessageQueue (socket, queue) {
}
-function Server (requestListener) {
- net.Server.call(this);
- this.addListener("request", requestListener);
- this.addListener("connection", connectionListener);
-}
-sys.inherits(Server, net.Server);
-
-exports.Server = Server;
-
-exports.createServer = function (requestListener) {
- return new Server(requestListener);
+exports.createServer = function (requestListener, options) {
+ var server = new http.Server();
+ //server.setOptions(options);
+ server.addListener("request", requestListener);
+ server.addListener("connection", connectionListener);
+ return server;
};
-function connectionListener (socket) {
- var self = this;
- // An array of responses for each socket. In pipelined connections
+function connectionListener (connection) {
+ // An array of responses for each connection. In pipelined connections
// we need to keep track of the order they were sent.
var responses = [];
- var parser = newParser('request');
-
- socket.ondata = function (d, start, end) {
- parser.execute(d, start, end - start);
- };
-
- socket.onend = function () {
- parser.finish();
- // unref the parser for easy gc
- freeParser(parser);
+ connection.resetParser();
+ // is this really needed?
+ connection.addListener("end", function () {
if (responses.length == 0) {
- socket.close();
+ connection.close();
} else {
responses[responses.length-1].closeOnFinish = true;
}
- };
+ });
- parser.socket = socket;
- // The following callback is issued after the headers have been read on a
- // new message. In this callback we setup the response object and pass it
- // to the user.
- parser.onIncoming = function (incoming, shouldKeepAlive) {
+
+ createIncomingMessageStream(connection, function (incoming, should_keep_alive) {
var req = incoming;
- var res = new ServerResponse(req);
- res.shouldKeepAlive = shouldKeepAlive;
- res.addListener('flush', function () {
- if (flushMessageQueue(socket, responses)) {
- socket.close();
+ var res = new ServerResponse(req);
+ res.should_keep_alive = should_keep_alive;
+ res.addListener("flush", function () {
+ if (flushMessageQueue(connection, responses)) {
+ connection.close();
}
});
responses.push(res);
- self.emit('request', req, res);
- };
+ connection.server.emit("request", req, res);
+ });
}
-function Client ( ) {
- net.Stream.call(this);
-
- var self = this;
+exports.createClient = function (port, host) {
+ var client = new http.Client();
+ var secure_credentials={ secure : false };
var requests = [];
var currentRequest;
- var parser = newParser('response');
- parser.socket = this;
+ client.tcpSetSecure = client.setSecure;
+ client.setSecure = function(format_type, ca_certs, crl_list, private_key, certificate) {
+ secure_credentials.secure = true;
+ secure_credentials.format_type = format_type;
+ secure_credentials.ca_certs = ca_certs;
+ secure_credentials.crl_list = crl_list;
+ secure_credentials.private_key = private_key;
+ secure_credentials.certificate = certificate;
+ }
- self._reconnect = function () {
- if (self.readyState != "opening") {
- sys.debug("HTTP CLIENT: reconnecting readyState = " + self.readyState);
- self.connect(self.port, self.host);
+ client._reconnect = function () {
+ if (client.readyState != "opening") {
+ //sys.debug("HTTP CLIENT: reconnecting readyState = " + client.readyState);
+ client.connect(port, host);
+ if (secure_credentials.secure) {
+ client.tcpSetSecure(secure_credentials.format_type,
+ secure_credentials.ca_certs,
+ secure_credentials.crl_list,
+ secure_credentials.private_key,
+ secure_credentials.certificate);
+ }
}
};
- self._pushRequest = function (req) {
+ client._pushRequest = function (req) {
req.addListener("flush", function () {
- if (self.readyState == "closed") {
- sys.debug("HTTP CLIENT request flush. reconnect. readyState = " + self.readyState);
- self._reconnect();
+ if (client.readyState == "closed") {
+ //sys.debug("HTTP CLIENT request flush. reconnect. readyState = " + client.readyState);
+ client._reconnect();
return;
}
-
- sys.debug("self flush readyState = " + self.readyState);
- if (req == currentRequest) flushMessageQueue(self, [req]);
+ //sys.debug("client flush readyState = " + client.readyState);
+ if (req == currentRequest) flushMessageQueue(client, [req]);
});
requests.push(req);
};
- this.ondata = function (d, start, end) {
- parser.execute(d, start, end - start);
- };
-
- self.addListener("connect", function () {
- parser.reinitialize('response');
- sys.puts('requests: ' + sys.inspect(requests));
- currentRequest = requests.shift()
+ client.addListener("connect", function () {
+ client.resetParser();
+ currentRequest = requests.shift();
currentRequest.flush();
});
- self.addListener("end", function () {
- parser.finish();
- freeParser(parser);
-
- //sys.debug("self got end closing. readyState = " + self.readyState);
- self.close();
+ client.addListener("end", function () {
+ //sys.debug("client got end closing. readyState = " + client.readyState);
+ client.close();
});
- self.addListener("close", function (had_error) {
+ client.addListener("close", function (had_error) {
if (had_error) {
- self.emit("error");
+ client.emit("error");
return;
}
- sys.debug("HTTP CLIENT onClose. readyState = " + self.readyState);
+ //sys.debug("HTTP CLIENT onClose. readyState = " + client.readyState);
// If there are more requests to handle, reconnect.
if (requests.length > 0) {
- self._reconnect();
+ client._reconnect();
}
});
- parser.onIncoming = function (res) {
- sys.debug("incoming response!");
+ createIncomingMessageStream(client, function (res) {
+ //sys.debug("incoming response!");
res.addListener('end', function ( ) {
- //sys.debug("request complete disconnecting. readyState = " + self.readyState);
- self.close();
+ //sys.debug("request complete disconnecting. readyState = " + client.readyState);
+ client.close();
});
currentRequest.emit("response", res);
- };
-};
-sys.inherits(Client, net.Stream);
-
-exports.Client = Client;
-
-exports.createClient = function (port, host) {
- var c = new Client;
- c.port = port;
- c.host = host;
- return c;
-}
+ });
+ return client;
+};
-Client.prototype.get = function () {
+http.Client.prototype.get = function () {
throw new Error("client.get(...) is now client.request('GET', ...)");
};
-Client.prototype.head = function () {
+http.Client.prototype.head = function () {
throw new Error("client.head(...) is now client.request('HEAD', ...)");
};
-Client.prototype.post = function () {
+http.Client.prototype.post = function () {
throw new Error("client.post(...) is now client.request('POST', ...)");
};
-Client.prototype.del = function () {
+http.Client.prototype.del = function () {
throw new Error("client.del(...) is now client.request('DELETE', ...)");
};
-Client.prototype.put = function () {
+http.Client.prototype.put = function () {
throw new Error("client.put(...) is now client.request('PUT', ...)");
};
-Client.prototype.request = function (method, url, headers) {
+http.Client.prototype.request = function (method, url, headers) {
if (typeof(url) != "string") { // assume method was omitted, shift arguments
headers = url;
url = method;
@@ -639,7 +580,7 @@ Client.prototype.request = function (method, url, headers) {
exports.cat = function (url, encoding_, headers_) {
- var encoding = 'utf8',
+ var encoding = 'utf8',
headers = {},
callback = null;
diff --git a/src/node.cc b/src/node.cc
index 42b7ff77bf..3fb9f80436 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1190,7 +1190,7 @@ static Handle<Value> Binding(const Arguments& args) {
exports->Set(String::New("file"), String::New(native_file));
exports->Set(String::New("fs"), String::New(native_fs));
exports->Set(String::New("http"), String::New(native_http));
- exports->Set(String::New("http2"), String::New(native_http2));
+ exports->Set(String::New("http_old"), String::New(native_http_old));
exports->Set(String::New("ini"), String::New(native_ini));
exports->Set(String::New("mjsunit"), String::New(native_mjsunit));
exports->Set(String::New("multipart"), String::New(native_multipart));
diff --git a/test/simple/test-event-emitter-modify-in-emit.js b/test/simple/test-event-emitter-modify-in-emit.js
index 1dd94ba712..81bba7c89e 100644
--- a/test/simple/test-event-emitter-modify-in-emit.js
+++ b/test/simple/test-event-emitter-modify-in-emit.js
@@ -35,4 +35,4 @@ e.addListener("foo", callback1);
e.addListener("foo", callback2);
assert.equal(2, e.listeners("foo").length)
e.removeAllListeners("foo")
-assert.equal(0, e.listeners("foo").length) \ No newline at end of file
+assert.equal(0, e.listeners("foo").length)
diff --git a/test/simple/test-file-read-stream.js b/test/simple/test-file-read-stream.js
index df57387947..3ac308b9a2 100644
--- a/test/simple/test-file-read-stream.js
+++ b/test/simple/test-file-read-stream.js
@@ -60,4 +60,4 @@ process.addListener('exit', function() {
for (var k in callbacks) {
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
}
-}); \ No newline at end of file
+});
diff --git a/test/simple/test-file-write-stream.js b/test/simple/test-file-write-stream.js
index 579455c7d9..df045998cd 100644
--- a/test/simple/test-file-write-stream.js
+++ b/test/simple/test-file-write-stream.js
@@ -59,4 +59,4 @@ process.addListener('exit', function() {
for (var k in callbacks) {
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
}
-}); \ No newline at end of file
+});
diff --git a/test/simple/test-http-1.0.js b/test/simple/test-http-1.0.js
index 106313d281..105acdcd8b 100644
--- a/test/simple/test-http-1.0.js
+++ b/test/simple/test-http-1.0.js
@@ -1,6 +1,6 @@
require("../common");
net = require("net");
-http = require("http2");
+http = require("http");
var body = "hello world\n";
var server_response = "";
diff --git a/test/simple/test-http-cat.js b/test/simple/test-http-cat.js
index 32177ee92b..e81a5c502f 100644
--- a/test/simple/test-http-cat.js
+++ b/test/simple/test-http-cat.js
@@ -1,5 +1,5 @@
require("../common");
-http = require("http2");
+http = require("http");
var body = "exports.A = function() { return 'A';}";
var server = http.createServer(function (req, res) {
diff --git a/test/simple/test-http-chunked.js b/test/simple/test-http-chunked.js
index 4325d113da..a838235472 100644
--- a/test/simple/test-http-chunked.js
+++ b/test/simple/test-http-chunked.js
@@ -1,5 +1,5 @@
require("../common");
-var http = require("http2");
+var http = require("http");
var UTF8_STRING = "Il était tué";
diff --git a/test/simple/test-http-client-race.js b/test/simple/test-http-client-race.js
index a3824cfce1..9076924b37 100644
--- a/test/simple/test-http-client-race.js
+++ b/test/simple/test-http-client-race.js
@@ -1,5 +1,5 @@
require("../common");
-http = require("http2");
+http = require("http");
url = require("url");
var body1_s = "1111111111111111";
diff --git a/test/simple/test-http-client-upload.js b/test/simple/test-http-client-upload.js
index e1d746c35d..b4c0f61acb 100644
--- a/test/simple/test-http-client-upload.js
+++ b/test/simple/test-http-client-upload.js
@@ -1,5 +1,5 @@
require("../common");
-http = require("http2");
+http = require("http");
var sent_body = "";
var server_req_complete = false;
diff --git a/test/simple/test-http-eof-on-connect.js b/test/simple/test-http-eof-on-connect.js
index 7838c8d141..1f2f2e5121 100644
--- a/test/simple/test-http-eof-on-connect.js
+++ b/test/simple/test-http-eof-on-connect.js
@@ -1,6 +1,6 @@
require("../common");
net = require("net");
-http = require("http2");
+http = require("http");
// This is a regression test for http://github.com/ry/node/issues/#issue/44
// It is separate from test-http-malformed-request.js because it is only
diff --git a/test/simple/test-http-malformed-request.js b/test/simple/test-http-malformed-request.js
index 98d6da780c..47bcfca324 100644
--- a/test/simple/test-http-malformed-request.js
+++ b/test/simple/test-http-malformed-request.js
@@ -1,6 +1,6 @@
require("../common");
net = require("net");
-http = require("http2");
+http = require("http");
url = require("url");
// Make sure no exceptions are thrown when receiving malformed HTTP
diff --git a/test/simple/test-http-proxy.js b/test/simple/test-http-proxy.js
index 5d57ba5310..348851d6ba 100644
--- a/test/simple/test-http-proxy.js
+++ b/test/simple/test-http-proxy.js
@@ -1,5 +1,5 @@
require("../common");
-http = require("http2");
+http = require("http");
url = require("url");
var PROXY_PORT = PORT;
diff --git a/test/simple/test-http-server.js b/test/simple/test-http-server.js
index e42d55429e..c7deeb8baf 100644
--- a/test/simple/test-http-server.js
+++ b/test/simple/test-http-server.js
@@ -1,6 +1,6 @@
require("../common");
net = require("net");
-http = require("http2");
+http = require("http");
url = require("url");
qs = require("querystring");
diff --git a/test/simple/test-http-wget.js b/test/simple/test-http-wget.js
index 38a4189603..1d7f341263 100644
--- a/test/simple/test-http-wget.js
+++ b/test/simple/test-http-wget.js
@@ -1,6 +1,6 @@
require("../common");
net = require("net");
-http = require("http2");
+http = require("http");
// wget sends an HTTP/1.0 request with Connection: Keep-Alive
//
diff --git a/test/simple/test-http.js b/test/simple/test-http.js
index df0ebea406..c59927763a 100644
--- a/test/simple/test-http.js
+++ b/test/simple/test-http.js
@@ -1,5 +1,5 @@
require("../common");
-http = require("http2");
+http = require("http");
url = require("url");
var responses_sent = 0;
diff --git a/test/simple/test-remote-module-loading.js b/test/simple/test-remote-module-loading.js
index 8a7edbbe27..0a2af87e08 100644
--- a/test/simple/test-remote-module-loading.js
+++ b/test/simple/test-remote-module-loading.js
@@ -1,6 +1,6 @@
require("../common");
-var http = require('http2');
+var http = require('http');
var sys = require('sys');
var url = require("url");
var modulesLoaded = 0;