Don't use parseUri for HTTP server
The big parseUri RE was showing up often in profiles - this is simpler and yields better performance by taking advantage of the C http parser.
This commit is contained in:
parent
7b8842b619
commit
e2b7902469
21
doc/api.txt
21
doc/api.txt
@ -665,7 +665,7 @@ The request method as a string. Read only. Example:
|
||||
|
||||
+request.uri+ ::
|
||||
Request URI Object. This contains only the parameters that are
|
||||
present in the actual HTTP request. That is, if the request is
|
||||
present in the actual HTTP request. If the request is
|
||||
+
|
||||
----------------------------------------
|
||||
GET /status?name=ryan HTTP/1.1\r\n
|
||||
@ -676,23 +676,12 @@ Accept: text/plain\r\n
|
||||
Then +request.uri+ will be
|
||||
+
|
||||
----------------------------------------
|
||||
{ path: "/status",
|
||||
file: "status",
|
||||
directory: "/",
|
||||
params: { "name" : "ryan" }
|
||||
{ full: "/status?name=ryan",
|
||||
path: "/status",
|
||||
queryString: "name=ryan",
|
||||
fragment: ""
|
||||
}
|
||||
----------------------------------------
|
||||
+
|
||||
In particular, note that +request.uri.protocol+ is
|
||||
+undefined+. This is because there was no URI protocol given
|
||||
in the actual HTTP Request.
|
||||
+
|
||||
Here is what's available: +request.uri.anchor+, +request.uri.query+,
|
||||
+request.uri.file+, +request.uri.directory+, +request.uri.path+,
|
||||
+request.uri.relative+, +request.uri.port+, +request.uri.host+,
|
||||
+request.uri.password+, +request.uri.user+, +request.uri.authority+,
|
||||
+request.uri.protocol+, +request.uri.params+, +request.uri.toString()+,
|
||||
+request.uri.source+
|
||||
|
||||
|
||||
+request.headers+ ::
|
||||
|
23
lib/http.js
23
lib/http.js
@ -125,7 +125,13 @@ function IncomingMessage (connection) {
|
||||
this.headers = {};
|
||||
|
||||
// request (server) only
|
||||
this.uri = "";
|
||||
this.uri = {
|
||||
full: "",
|
||||
queryString: "",
|
||||
fragment: "",
|
||||
path: ""
|
||||
};
|
||||
|
||||
this.method = null;
|
||||
|
||||
// response (client) only
|
||||
@ -338,7 +344,19 @@ function createIncomingMessageStream (connection, incoming_listener) {
|
||||
|
||||
// Only servers will get URI events.
|
||||
connection.addListener("uri", function (data) {
|
||||
incoming.uri += data;
|
||||
incoming.uri.full += data;
|
||||
});
|
||||
|
||||
connection.addListener("path", function (data) {
|
||||
incoming.uri.path += data;
|
||||
});
|
||||
|
||||
connection.addListener("fragment", function (data) {
|
||||
incoming.uri.fragment += data;
|
||||
});
|
||||
|
||||
connection.addListener("queryString", function (data) {
|
||||
incoming.uri.queryString += data;
|
||||
});
|
||||
|
||||
connection.addListener("headerField", function (data) {
|
||||
@ -372,7 +390,6 @@ function createIncomingMessageStream (connection, incoming_listener) {
|
||||
if (info.method) {
|
||||
// server only
|
||||
incoming.method = info.method;
|
||||
incoming.uri = exports.parseUri(incoming.uri); // TODO parse the URI lazily?
|
||||
} else {
|
||||
// client only
|
||||
incoming.statusCode = info.statusCode;
|
||||
|
33
src/http.cc
33
src/http.cc
@ -95,6 +95,39 @@ HTTPConnection::on_uri (http_parser *parser, const char *buf, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
HTTPConnection::on_query_string (http_parser *parser, const char *buf, size_t len)
|
||||
{
|
||||
HandleScope scope;
|
||||
HTTPConnection *connection = static_cast<HTTPConnection*>(parser->data);
|
||||
assert(connection->attached_);
|
||||
Local<Value> argv[1] = { String::New(buf, len) };
|
||||
connection->Emit("queryString", 1, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
HTTPConnection::on_path (http_parser *parser, const char *buf, size_t len)
|
||||
{
|
||||
HandleScope scope;
|
||||
HTTPConnection *connection = static_cast<HTTPConnection*>(parser->data);
|
||||
assert(connection->attached_);
|
||||
Local<Value> argv[1] = { String::New(buf, len) };
|
||||
connection->Emit("path", 1, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
HTTPConnection::on_fragment (http_parser *parser, const char *buf, size_t len)
|
||||
{
|
||||
HandleScope scope;
|
||||
HTTPConnection *connection = static_cast<HTTPConnection*>(parser->data);
|
||||
assert(connection->attached_);
|
||||
Local<Value> argv[1] = { String::New(buf, len) };
|
||||
connection->Emit("fragment", 1, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
HTTPConnection::on_header_field (http_parser *parser, const char *buf, size_t len)
|
||||
{
|
||||
|
@ -24,6 +24,9 @@ protected:
|
||||
http_parser_init (&parser_, type);
|
||||
parser_.on_message_begin = on_message_begin;
|
||||
parser_.on_uri = on_uri;
|
||||
parser_.on_path = on_path;
|
||||
parser_.on_fragment = on_fragment;
|
||||
parser_.on_query_string = on_query_string;
|
||||
parser_.on_header_field = on_header_field;
|
||||
parser_.on_header_value = on_header_value;
|
||||
parser_.on_headers_complete = on_headers_complete;
|
||||
@ -36,6 +39,9 @@ protected:
|
||||
|
||||
static int on_message_begin (http_parser *parser);
|
||||
static int on_uri (http_parser *parser, const char *at, size_t length);
|
||||
static int on_query_string (http_parser *parser, const char *at, size_t length);
|
||||
static int on_path (http_parser *parser, const char *at, size_t length);
|
||||
static int on_fragment (http_parser *parser, const char *at, size_t length);
|
||||
static int on_header_field (http_parser *parser, const char *buf, size_t len);
|
||||
static int on_header_value (http_parser *parser, const char *buf, size_t len);
|
||||
static int on_headers_complete (http_parser *parser);
|
||||
|
Loading…
x
Reference in New Issue
Block a user