diff --git a/lib/_http_common.js b/lib/_http_common.js index 4cf30eeebd..0d55651da1 100644 --- a/lib/_http_common.js +++ b/lib/_http_common.js @@ -27,7 +27,6 @@ var IncomingMessage = incoming.IncomingMessage; var readStart = incoming.readStart; var readStop = incoming.readStop; - var debug = require('util').debuglog('http'); exports.debug = debug; @@ -35,6 +34,11 @@ exports.CRLF = '\r\n'; exports.chunkExpression = /chunk/i; exports.continueExpression = /100-continue/i; +var kOnHeaders = HTTPParser.kOnHeaders | 0; +var kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0; +var kOnBody = HTTPParser.kOnBody | 0; +var kOnMessageComplete = HTTPParser.kOnMessageComplete | 0; + // Only called in the slow case where slow means // that the request headers were either fragmented // across multiple TCP packets or too large to be @@ -180,10 +184,10 @@ var parsers = new FreeList('parsers', 1000, function() { // across multiple TCP packets or too large to be // processed in a single run. This method is also // called to process trailing HTTP headers. - parser.onHeaders = parserOnHeaders; - parser.onHeadersComplete = parserOnHeadersComplete; - parser.onBody = parserOnBody; - parser.onMessageComplete = parserOnMessageComplete; + parser[kOnHeaders] = parserOnHeaders; + parser[kOnHeadersComplete] = parserOnHeadersComplete; + parser[kOnBody] = parserOnBody; + parser[kOnMessageComplete] = parserOnMessageComplete; return parser; }); diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 72fda5e251..80485ec05f 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -60,10 +60,10 @@ using v8::Object; using v8::String; using v8::Value; -static Cached on_headers_sym; -static Cached on_headers_complete_sym; -static Cached on_body_sym; -static Cached on_message_complete_sym; +const uint32_t kOnHeaders = 0; +const uint32_t kOnHeadersComplete = 1; +const uint32_t kOnBody = 2; +const uint32_t kOnMessageComplete = 3; static Cached method_sym; static Cached status_code_sym; @@ -255,7 +255,7 @@ class Parser : public ObjectWrap { HTTP_CB(on_headers_complete) { Local obj = handle(node_isolate); - Local cb = obj->Get(on_headers_complete_sym); + Local cb = obj->Get(kOnHeadersComplete); if (!cb->IsFunction()) return 0; @@ -315,7 +315,7 @@ class Parser : public ObjectWrap { HandleScope scope(node_isolate); Local obj = handle(node_isolate); - Local cb = obj->Get(on_body_sym); + Local cb = obj->Get(kOnBody); if (!cb->IsFunction()) return 0; @@ -344,7 +344,7 @@ class Parser : public ObjectWrap { Flush(); // Flush trailing HTTP headers. Local obj = handle(node_isolate); - Local cb = obj->Get(on_message_complete_sym); + Local cb = obj->Get(kOnMessageComplete); if (!cb->IsFunction()) return 0; @@ -506,7 +506,7 @@ class Parser : public ObjectWrap { HandleScope scope(node_isolate); Local obj = handle(node_isolate); - Local cb = obj->Get(on_headers_sym); + Local cb = obj->Get(kOnHeaders); if (!cb->IsFunction()) return; @@ -558,6 +558,14 @@ void InitHttpParser(Handle target) { Integer::New(HTTP_REQUEST, node_isolate)); t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "RESPONSE"), Integer::New(HTTP_RESPONSE, node_isolate)); + t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnHeaders"), + Integer::NewFromUnsigned(kOnHeaders, node_isolate)); + t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnHeadersComplete"), + Integer::NewFromUnsigned(kOnHeadersComplete, node_isolate)); + t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnBody"), + Integer::NewFromUnsigned(kOnBody, node_isolate)); + t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnMessageComplete"), + Integer::NewFromUnsigned(kOnMessageComplete, node_isolate)); NODE_SET_PROTOTYPE_METHOD(t, "execute", Parser::Execute); NODE_SET_PROTOTYPE_METHOD(t, "finish", Parser::Finish); @@ -566,15 +574,6 @@ void InitHttpParser(Handle target) { target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "HTTPParser"), t->GetFunction()); - on_headers_sym = - FIXED_ONE_BYTE_STRING(node_isolate, "onHeaders"); - on_headers_complete_sym = - FIXED_ONE_BYTE_STRING(node_isolate, "onHeadersComplete"); - on_body_sym = - FIXED_ONE_BYTE_STRING(node_isolate, "onBody"); - on_message_complete_sym = - FIXED_ONE_BYTE_STRING(node_isolate, "onMessageComplete"); - #define X(num, name, string) \ name ## _sym = OneByteString(node_isolate, #string); HTTP_METHOD_MAP(X) diff --git a/test/simple/test-http-parser-bad-ref.js b/test/simple/test-http-parser-bad-ref.js index 4a9c70515b..0e2a77bb3a 100644 --- a/test/simple/test-http-parser-bad-ref.js +++ b/test/simple/test-http-parser-bad-ref.js @@ -7,6 +7,11 @@ var common = require('../common'); var assert = require('assert'); var HTTPParser = process.binding('http_parser').HTTPParser; +var kOnHeaders = HTTPParser.kOnHeaders | 0; +var kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0; +var kOnBody = HTTPParser.kOnBody | 0; +var kOnMessageComplete = HTTPParser.kOnMessageComplete | 0; + var headersComplete = 0; var messagesComplete = 0; @@ -23,19 +28,19 @@ function demoBug(part1, part2) { parser.headers = []; parser.url = ''; - parser.onHeaders = function(headers, url) { + parser[kOnHeaders] = function(headers, url) { parser.headers = parser.headers.concat(headers); parser.url += url; }; - parser.onHeadersComplete = function(info) { + parser[kOnHeadersComplete] = function(info) { headersComplete++; console.log('url', info.url); }; - parser.onBody = function(b, start, len) { }; + parser[kOnBody] = function(b, start, len) { }; - parser.onMessageComplete = function() { + parser[kOnMessageComplete] = function() { messagesComplete++; }; diff --git a/test/simple/test-http-parser.js b/test/simple/test-http-parser.js index e8c8095131..e0f1fbf090 100644 --- a/test/simple/test-http-parser.js +++ b/test/simple/test-http-parser.js @@ -28,6 +28,11 @@ var CRLF = '\r\n'; var REQUEST = HTTPParser.REQUEST; var RESPONSE = HTTPParser.RESPONSE; +var kOnHeaders = HTTPParser.kOnHeaders | 0; +var kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0; +var kOnBody = HTTPParser.kOnBody | 0; +var kOnMessageComplete = HTTPParser.kOnMessageComplete | 0; + // The purpose of this test is not to check HTTP compliance but to test the // binding. Tests for pathological http messages should be submitted // upstream to https://github.com/joyent/http-parser for inclusion into @@ -40,19 +45,19 @@ function newParser(type) { parser.headers = []; parser.url = ''; - parser.onHeaders = function(headers, url) { + parser[kOnHeaders] = function(headers, url) { parser.headers = parser.headers.concat(headers); parser.url += url; }; - parser.onHeadersComplete = function(info) { + parser[kOnHeadersComplete] = function(info) { }; - parser.onBody = function(b, start, len) { + parser[kOnBody] = function(b, start, len) { assert.ok(false, 'Function should not be called.'); }; - parser.onMessageComplete = function() { + parser[kOnMessageComplete] = function() { }; return parser; @@ -92,7 +97,7 @@ function expectBody(expected) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'GET'); assert.equal(info.url || parser.url, '/hello'); assert.equal(info.versionMajor, 1); @@ -106,7 +111,7 @@ function expectBody(expected) { // thrown from parser.execute() // - parser.onHeadersComplete = function(info) { + parser[kOnHeadersComplete] = function(info) { throw new Error('hello world'); }; @@ -131,14 +136,14 @@ function expectBody(expected) { var parser = newParser(RESPONSE); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, undefined); assert.equal(info.versionMajor, 1); assert.equal(info.versionMinor, 1); assert.equal(info.statusCode, 200); }); - parser.onBody = mustCall(function(buf, start, len) { + parser[kOnBody] = mustCall(function(buf, start, len) { var body = '' + buf.slice(start, start + len); assert.equal(body, 'pong'); }); @@ -157,7 +162,7 @@ function expectBody(expected) { var parser = newParser(RESPONSE); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, undefined); assert.equal(info.versionMajor, 1); assert.equal(info.versionMinor, 0); @@ -194,16 +199,16 @@ function expectBody(expected) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'POST'); assert.equal(info.url || parser.url, '/it'); assert.equal(info.versionMajor, 1); assert.equal(info.versionMinor, 1); // expect to see trailing headers now - parser.onHeaders = mustCall(onHeaders); + parser[kOnHeaders] = mustCall(onHeaders); }); - parser.onBody = mustCall(function(buf, start, len) { + parser[kOnBody] = mustCall(function(buf, start, len) { var body = '' + buf.slice(start, start + len); assert.equal(body, 'ping'); seen_body = true; @@ -226,7 +231,7 @@ function expectBody(expected) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'GET'); assert.equal(info.versionMajor, 1); assert.equal(info.versionMinor, 0); @@ -255,7 +260,7 @@ function expectBody(expected) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'GET'); assert.equal(info.url || parser.url, '/foo/bar/baz?quux=42#1337'); assert.equal(info.versionMajor, 1); @@ -287,14 +292,14 @@ function expectBody(expected) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'POST'); assert.equal(info.url || parser.url, '/it'); assert.equal(info.versionMajor, 1); assert.equal(info.versionMinor, 1); }); - parser.onBody = mustCall(function(buf, start, len) { + parser[kOnBody] = mustCall(function(buf, start, len) { var body = '' + buf.slice(start, start + len); assert.equal(body, 'foo=42&bar=1337'); }); @@ -322,7 +327,7 @@ function expectBody(expected) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'POST'); assert.equal(info.url || parser.url, '/it'); assert.equal(info.versionMajor, 1); @@ -337,7 +342,7 @@ function expectBody(expected) { assert.equal(body, body_parts[body_part++]); } - parser.onBody = mustCall(onBody, body_parts.length); + parser[kOnBody] = mustCall(onBody, body_parts.length); parser.execute(request, 0, request.length); })(); @@ -358,7 +363,7 @@ function expectBody(expected) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'POST'); assert.equal(info.url || parser.url, '/it'); assert.equal(info.versionMajor, 1); @@ -375,7 +380,7 @@ function expectBody(expected) { assert.equal(body, body_parts[body_part++]); } - parser.onBody = mustCall(onBody, body_parts.length); + parser[kOnBody] = mustCall(onBody, body_parts.length); parser.execute(request, 0, request.length); request = Buffer( @@ -415,7 +420,7 @@ function expectBody(expected) { function test(a, b) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'POST'); assert.equal(info.url || parser.url, '/helpme'); assert.equal(info.versionMajor, 1); @@ -424,7 +429,7 @@ function expectBody(expected) { var expected_body = '123123456123456789123456789ABC123456789ABCDEF'; - parser.onBody = function(buf, start, len) { + parser[kOnBody] = function(buf, start, len) { var chunk = '' + buf.slice(start, start + len); assert.equal(expected_body.indexOf(chunk), 0); expected_body = expected_body.slice(chunk.length); @@ -471,7 +476,7 @@ function expectBody(expected) { var parser = newParser(REQUEST); - parser.onHeadersComplete = mustCall(function(info) { + parser[kOnHeadersComplete] = mustCall(function(info) { assert.equal(info.method, 'POST'); assert.equal(info.url || parser.url, '/it'); assert.equal(info.versionMajor, 1); @@ -483,7 +488,7 @@ function expectBody(expected) { var expected_body = '123123456123456789123456789ABC123456789ABCDEF'; - parser.onBody = function(buf, start, len) { + parser[kOnBody] = function(buf, start, len) { var chunk = '' + buf.slice(start, start + len); assert.equal(expected_body.indexOf(chunk), 0); expected_body = expected_body.slice(chunk.length); @@ -538,12 +543,12 @@ function expectBody(expected) { }; var parser = newParser(REQUEST); - parser.onHeadersComplete = onHeadersComplete1; - parser.onBody = expectBody('ping'); + parser[kOnHeadersComplete] = onHeadersComplete1; + parser[kOnBody] = expectBody('ping'); parser.execute(req1, 0, req1.length); parser.reinitialize(REQUEST); - parser.onBody = expectBody('pong'); - parser.onHeadersComplete = onHeadersComplete2; + parser[kOnBody] = expectBody('pong'); + parser[kOnHeadersComplete] = onHeadersComplete2; parser.execute(req2, 0, req2.length); })();