Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Expose HTTP header boundary #2745

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/node_http_parser.cc
Expand Up @@ -83,6 +83,7 @@ static Persistent<String> unsubscribe_sym;
static Persistent<String> unknown_method_sym; static Persistent<String> unknown_method_sym;


static Persistent<String> method_sym; static Persistent<String> method_sym;
static Persistent<String> boundary_sym;
static Persistent<String> status_code_sym; static Persistent<String> status_code_sym;
static Persistent<String> http_version_sym; static Persistent<String> http_version_sym;
static Persistent<String> version_major_sym; static Persistent<String> version_major_sym;
Expand Down Expand Up @@ -315,6 +316,9 @@ class Parser : public ObjectWrap {
message_info->Set(status_code_sym, Integer::New(parser_.status_code)); message_info->Set(status_code_sym, Integer::New(parser_.status_code));
} }


// BOUNDARY
message_info->Set(boundary_sym, Integer::New(parser_.boundary));

// VERSION // VERSION
message_info->Set(version_major_sym, Integer::New(parser_.http_major)); message_info->Set(version_major_sym, Integer::New(parser_.http_major));
message_info->Set(version_minor_sym, Integer::New(parser_.http_minor)); message_info->Set(version_minor_sym, Integer::New(parser_.http_minor));
Expand Down Expand Up @@ -636,6 +640,7 @@ void InitHttpParser(Handle<Object> target) {
unknown_method_sym = NODE_PSYMBOL("UNKNOWN_METHOD"); unknown_method_sym = NODE_PSYMBOL("UNKNOWN_METHOD");


method_sym = NODE_PSYMBOL("method"); method_sym = NODE_PSYMBOL("method");
boundary_sym = NODE_PSYMBOL("boundary");
status_code_sym = NODE_PSYMBOL("statusCode"); status_code_sym = NODE_PSYMBOL("statusCode");
http_version_sym = NODE_PSYMBOL("httpVersion"); http_version_sym = NODE_PSYMBOL("httpVersion");
version_major_sym = NODE_PSYMBOL("versionMajor"); version_major_sym = NODE_PSYMBOL("versionMajor");
Expand Down
62 changes: 48 additions & 14 deletions test/simple/test-http-parser.js
Expand Up @@ -96,6 +96,7 @@ function expectBody(expected) {
parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'GET'); assert.equal(info.method, 'GET');
assert.equal(info.url || parser.url, '/hello'); assert.equal(info.url || parser.url, '/hello');
assert.equal(info.boundary, request.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
}); });
Expand Down Expand Up @@ -135,6 +136,7 @@ function expectBody(expected) {


parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, undefined); assert.equal(info.method, undefined);
assert.equal(info.boundary, request.length - 4); // - 'pong'.length
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
assert.equal(info.statusCode, 200); assert.equal(info.statusCode, 200);
Expand Down Expand Up @@ -162,6 +164,7 @@ function expectBody(expected) {


parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, undefined); assert.equal(info.method, undefined);
assert.equal(info.boundary, request.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 0); assert.equal(info.versionMinor, 0);
assert.equal(info.statusCode, 200); assert.equal(info.statusCode, 200);
Expand All @@ -176,10 +179,13 @@ function expectBody(expected) {
// Trailing headers. // Trailing headers.
// //
(function() { (function() {
var request = Buffer( var headers =
'POST /it HTTP/1.1' + CRLF + 'POST /it HTTP/1.1' + CRLF +
'Transfer-Encoding: chunked' + CRLF + 'Transfer-Encoding: chunked' + CRLF +
CRLF + CRLF;

var request = Buffer(
headers +
'4' + CRLF + '4' + CRLF +
'ping' + CRLF + 'ping' + CRLF +
'0' + CRLF + '0' + CRLF +
Expand All @@ -201,6 +207,7 @@ function expectBody(expected) {
parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'POST'); assert.equal(info.method, 'POST');
assert.equal(info.url || parser.url, '/it'); assert.equal(info.url || parser.url, '/it');
assert.equal(info.boundary, headers.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
// expect to see trailing headers now // expect to see trailing headers now
Expand Down Expand Up @@ -233,6 +240,7 @@ function expectBody(expected) {


parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'GET'); assert.equal(info.method, 'GET');
assert.equal(info.boundary, request.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 0); assert.equal(info.versionMinor, 0);
assert.deepEqual(info.headers || parser.headers, assert.deepEqual(info.headers || parser.headers,
Expand Down Expand Up @@ -264,6 +272,7 @@ function expectBody(expected) {
parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'GET'); assert.equal(info.method, 'GET');
assert.equal(info.url || parser.url, '/foo/bar/baz?quux=42#1337'); assert.equal(info.url || parser.url, '/foo/bar/baz?quux=42#1337');
assert.equal(info.boundary, request.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 0); assert.equal(info.versionMinor, 0);


Expand Down Expand Up @@ -297,6 +306,7 @@ function expectBody(expected) {
parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'POST'); assert.equal(info.method, 'POST');
assert.equal(info.url || parser.url, '/it'); assert.equal(info.url || parser.url, '/it');
assert.equal(info.boundary, request.length - 15); // - 'foo=42&bar=1337'.length
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
}); });
Expand All @@ -314,11 +324,14 @@ function expectBody(expected) {
// Test chunked request body // Test chunked request body
// //
(function() { (function() {
var request = Buffer( var headers =
'POST /it HTTP/1.1' + CRLF + 'POST /it HTTP/1.1' + CRLF +
'Content-Type: text/plain' + CRLF + 'Content-Type: text/plain' + CRLF +
'Transfer-Encoding: chunked' + CRLF + 'Transfer-Encoding: chunked' + CRLF +
CRLF + CRLF;

var request = Buffer(
headers +
'3' + CRLF + '3' + CRLF +
'123' + CRLF + '123' + CRLF +
'6' + CRLF + '6' + CRLF +
Expand All @@ -333,6 +346,7 @@ function expectBody(expected) {
parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'POST'); assert.equal(info.method, 'POST');
assert.equal(info.url || parser.url, '/it'); assert.equal(info.url || parser.url, '/it');
assert.equal(info.boundary, headers.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
}); });
Expand All @@ -353,11 +367,14 @@ function expectBody(expected) {
// Test chunked request body spread over multiple buffers (packets) // Test chunked request body spread over multiple buffers (packets)
// //
(function() { (function() {
var request = Buffer( var headers =
'POST /it HTTP/1.1' + CRLF + 'POST /it HTTP/1.1' + CRLF +
'Content-Type: text/plain' + CRLF + 'Content-Type: text/plain' + CRLF +
'Transfer-Encoding: chunked' + CRLF + 'Transfer-Encoding: chunked' + CRLF +
CRLF + CRLF;

var request = Buffer(
headers +
'3' + CRLF + '3' + CRLF +
'123' + CRLF + '123' + CRLF +
'6' + CRLF + '6' + CRLF +
Expand All @@ -369,6 +386,7 @@ function expectBody(expected) {
parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'POST'); assert.equal(info.method, 'POST');
assert.equal(info.url || parser.url, '/it'); assert.equal(info.url || parser.url, '/it');
assert.equal(info.boundary, headers.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
}); });
Expand Down Expand Up @@ -403,11 +421,14 @@ function expectBody(expected) {
// Stress test. // Stress test.
// //
(function() { (function() {
var request = Buffer( var headers =
'POST /helpme HTTP/1.1' + CRLF + 'POST /helpme HTTP/1.1' + CRLF +
'Content-Type: text/plain' + CRLF + 'Content-Type: text/plain' + CRLF +
'Transfer-Encoding: chunked' + CRLF + 'Transfer-Encoding: chunked' + CRLF +
CRLF + CRLF;

var request = Buffer(
headers +
'3' + CRLF + '3' + CRLF +
'123' + CRLF + '123' + CRLF +
'6' + CRLF + '6' + CRLF +
Expand All @@ -427,6 +448,7 @@ function expectBody(expected) {
parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'POST'); assert.equal(info.method, 'POST');
assert.equal(info.url || parser.url, '/helpme'); assert.equal(info.url || parser.url, '/helpme');
assert.equal(info.boundary, headers.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
}); });
Expand Down Expand Up @@ -459,11 +481,14 @@ function expectBody(expected) {
// Byte by byte test. // Byte by byte test.
// //
(function() { (function() {
var request = Buffer( var headers =
'POST /it HTTP/1.1' + CRLF + 'POST /it HTTP/1.1' + CRLF +
'Content-Type: text/plain' + CRLF + 'Content-Type: text/plain' + CRLF +
'Transfer-Encoding: chunked' + CRLF + 'Transfer-Encoding: chunked' + CRLF +
CRLF + CRLF;

var request = Buffer(
headers +
'3' + CRLF + '3' + CRLF +
'123' + CRLF + '123' + CRLF +
'6' + CRLF + '6' + CRLF +
Expand All @@ -482,6 +507,7 @@ function expectBody(expected) {
parser.onHeadersComplete = mustCall(function(info) { parser.onHeadersComplete = mustCall(function(info) {
assert.equal(info.method, 'POST'); assert.equal(info.method, 'POST');
assert.equal(info.url || parser.url, '/it'); assert.equal(info.url || parser.url, '/it');
assert.equal(info.boundary, headers.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
assert.deepEqual(info.headers || parser.headers, assert.deepEqual(info.headers || parser.headers,
Expand Down Expand Up @@ -509,27 +535,34 @@ function expectBody(expected) {
// Test parser reinit sequence. // Test parser reinit sequence.
// //
(function() { (function() {
var req1 = Buffer( var headers1 =
'PUT /this HTTP/1.1' + CRLF + 'PUT /this HTTP/1.1' + CRLF +
'Content-Type: text/plain' + CRLF + 'Content-Type: text/plain' + CRLF +
'Transfer-Encoding: chunked' + CRLF + 'Transfer-Encoding: chunked' + CRLF +
CRLF + CRLF;

var req1 = Buffer(
headers1 +
'4' + CRLF + '4' + CRLF +
'ping' + CRLF + 'ping' + CRLF +
'0' + CRLF '0' + CRLF
); );


var req2 = Buffer( var headers2 =
'POST /that HTTP/1.0' + CRLF + 'POST /that HTTP/1.0' + CRLF +
'Content-Type: text/plain' + CRLF + 'Content-Type: text/plain' + CRLF +
'Content-Length: 4' + CRLF + 'Content-Length: 4' + CRLF +
CRLF + CRLF;

var req2 = Buffer(
headers2 +
'pong' 'pong'
); );


function onHeadersComplete1(info) { function onHeadersComplete1(info) {
assert.equal(info.method, 'PUT'); assert.equal(info.method, 'PUT');
assert.equal(info.url, '/this'); assert.equal(info.url, '/this');
assert.equal(info.boundary, headers1.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 1); assert.equal(info.versionMinor, 1);
assert.deepEqual(info.headers, assert.deepEqual(info.headers,
Expand All @@ -540,6 +573,7 @@ function expectBody(expected) {
function onHeadersComplete2(info) { function onHeadersComplete2(info) {
assert.equal(info.method, 'POST'); assert.equal(info.method, 'POST');
assert.equal(info.url, '/that'); assert.equal(info.url, '/that');
assert.equal(info.boundary, headers2.length);
assert.equal(info.versionMajor, 1); assert.equal(info.versionMajor, 1);
assert.equal(info.versionMinor, 0); assert.equal(info.versionMinor, 0);
assert.deepEqual(info.headers, assert.deepEqual(info.headers,
Expand Down