mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
http: optimize on_headers_complete
Use an array instead of an object to pass a parsed header chunk from c++ to javascript. This offers a 5-10% speedup on the http_simple benchmark, as evidenced by running: ab -k -t 100 -c 100 http://127.0.0.1:8000/bytes/100 PR: https://github.com/iojs/io.js/pull/292 Reviewed-by: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
@@ -36,16 +36,14 @@ function parserOnHeaders(headers, url) {
|
||||
this._url += url;
|
||||
}
|
||||
|
||||
// info.headers and info.url are set only if .onHeaders()
|
||||
// has not been called for this request.
|
||||
//
|
||||
// info.url is not set for response parsers but that's not
|
||||
// applicable here since all our parsers are request parsers.
|
||||
function parserOnHeadersComplete(info) {
|
||||
debug('parserOnHeadersComplete', info);
|
||||
// `headers` and `url` are set only if .onHeaders() has not been called for
|
||||
// this request.
|
||||
// `url` is not set for response parsers but that's not applicable here since
|
||||
// all our parsers are request parsers.
|
||||
function parserOnHeadersComplete(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
var parser = this;
|
||||
var headers = info.headers;
|
||||
var url = info.url;
|
||||
|
||||
if (!headers) {
|
||||
headers = parser._headers;
|
||||
@@ -58,38 +56,37 @@ function parserOnHeadersComplete(info) {
|
||||
}
|
||||
|
||||
parser.incoming = new IncomingMessage(parser.socket);
|
||||
parser.incoming.httpVersionMajor = info.versionMajor;
|
||||
parser.incoming.httpVersionMinor = info.versionMinor;
|
||||
parser.incoming.httpVersion = info.versionMajor + '.' + info.versionMinor;
|
||||
parser.incoming.httpVersionMajor = versionMajor;
|
||||
parser.incoming.httpVersionMinor = versionMinor;
|
||||
parser.incoming.httpVersion = versionMajor + '.' + versionMinor;
|
||||
parser.incoming.url = url;
|
||||
|
||||
var n = headers.length;
|
||||
|
||||
// If parser.maxHeaderPairs <= 0 - assume that there're no limit
|
||||
if (parser.maxHeaderPairs > 0) {
|
||||
// If parser.maxHeaderPairs <= 0 assume that there's no limit.
|
||||
if (parser.maxHeaderPairs > 0)
|
||||
n = Math.min(n, parser.maxHeaderPairs);
|
||||
}
|
||||
|
||||
parser.incoming._addHeaderLines(headers, n);
|
||||
|
||||
if (isNumber(info.method)) {
|
||||
if (isNumber(method)) {
|
||||
// server only
|
||||
parser.incoming.method = HTTPParser.methods[info.method];
|
||||
parser.incoming.method = HTTPParser.methods[method];
|
||||
} else {
|
||||
// client only
|
||||
parser.incoming.statusCode = info.statusCode;
|
||||
parser.incoming.statusMessage = info.statusMessage;
|
||||
parser.incoming.statusCode = statusCode;
|
||||
parser.incoming.statusMessage = statusMessage;
|
||||
}
|
||||
|
||||
parser.incoming.upgrade = info.upgrade;
|
||||
parser.incoming.upgrade = upgrade;
|
||||
|
||||
var skipBody = false; // response to HEAD or CONNECT
|
||||
|
||||
if (!info.upgrade) {
|
||||
// For upgraded connections and CONNECT method request,
|
||||
// we'll emit this after parser.execute
|
||||
// so that we can capture the first part of the new protocol
|
||||
skipBody = parser.onIncoming(parser.incoming, info.shouldKeepAlive);
|
||||
if (!upgrade) {
|
||||
// For upgraded connections and CONNECT method request, we'll emit this
|
||||
// after parser.execute so that we can capture the first part of the new
|
||||
// protocol.
|
||||
skipBody = parser.onIncoming(parser.incoming, shouldKeepAlive);
|
||||
}
|
||||
|
||||
return skipBody;
|
||||
|
||||
@@ -92,7 +92,6 @@ namespace node {
|
||||
V(fsevent_string, "FSEvent") \
|
||||
V(gid_string, "gid") \
|
||||
V(handle_string, "handle") \
|
||||
V(headers_string, "headers") \
|
||||
V(heap_size_limit_string, "heap_size_limit") \
|
||||
V(heap_total_string, "heapTotal") \
|
||||
V(heap_used_string, "heapUsed") \
|
||||
@@ -114,7 +113,6 @@ namespace node {
|
||||
V(mark_sweep_compact_string, "mark-sweep-compact") \
|
||||
V(max_buffer_string, "maxBuffer") \
|
||||
V(message_string, "message") \
|
||||
V(method_string, "method") \
|
||||
V(minttl_string, "minttl") \
|
||||
V(mode_string, "mode") \
|
||||
V(model_string, "model") \
|
||||
@@ -176,7 +174,6 @@ namespace node {
|
||||
V(service_string, "service") \
|
||||
V(servername_string, "servername") \
|
||||
V(session_id_string, "sessionId") \
|
||||
V(should_keep_alive_string, "shouldKeepAlive") \
|
||||
V(signal_string, "signal") \
|
||||
V(size_string, "size") \
|
||||
V(smalloc_p_string, "_smalloc_p") \
|
||||
@@ -184,8 +181,6 @@ namespace node {
|
||||
V(sni_context_string, "sni_context") \
|
||||
V(speed_string, "speed") \
|
||||
V(stack_string, "stack") \
|
||||
V(status_code_string, "statusCode") \
|
||||
V(status_message_string, "statusMessage") \
|
||||
V(status_string, "status") \
|
||||
V(stdio_string, "stdio") \
|
||||
V(subject_string, "subject") \
|
||||
@@ -209,16 +204,12 @@ namespace node {
|
||||
V(type_string, "type") \
|
||||
V(uid_string, "uid") \
|
||||
V(unknown_string, "<unknown>") \
|
||||
V(upgrade_string, "upgrade") \
|
||||
V(url_string, "url") \
|
||||
V(used_heap_size_string, "used_heap_size") \
|
||||
V(user_string, "user") \
|
||||
V(uv_string, "uv") \
|
||||
V(valid_from_string, "valid_from") \
|
||||
V(valid_to_string, "valid_to") \
|
||||
V(verify_error_string, "verifyError") \
|
||||
V(version_major_string, "versionMajor") \
|
||||
V(version_minor_string, "versionMinor") \
|
||||
V(version_string, "version") \
|
||||
V(weight_string, "weight") \
|
||||
V(windows_verbatim_arguments_string, "windowsVerbatimArguments") \
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
namespace node {
|
||||
|
||||
using v8::Array;
|
||||
using v8::Boolean;
|
||||
using v8::Context;
|
||||
using v8::Exception;
|
||||
using v8::Function;
|
||||
@@ -46,6 +47,7 @@ using v8::Local;
|
||||
using v8::Object;
|
||||
using v8::String;
|
||||
using v8::Uint32;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
const uint32_t kOnHeaders = 0;
|
||||
@@ -218,55 +220,68 @@ class Parser : public BaseObject {
|
||||
|
||||
|
||||
HTTP_CB(on_headers_complete) {
|
||||
// Arguments for the on-headers-complete javascript callback. This
|
||||
// list needs to be kept in sync with the actual argument list for
|
||||
// `parserOnHeadersComplete` in lib/_http_common.js.
|
||||
enum on_headers_complete_arg_index {
|
||||
A_VERSION_MAJOR = 0,
|
||||
A_VERSION_MINOR,
|
||||
A_HEADERS,
|
||||
A_METHOD,
|
||||
A_URL,
|
||||
A_STATUS_CODE,
|
||||
A_STATUS_MESSAGE,
|
||||
A_UPGRADE,
|
||||
A_SHOULD_KEEP_ALIVE,
|
||||
A_MAX
|
||||
};
|
||||
|
||||
Local<Value> argv[A_MAX];
|
||||
Local<Object> obj = object();
|
||||
Local<Value> cb = obj->Get(kOnHeadersComplete);
|
||||
|
||||
if (!cb->IsFunction())
|
||||
return 0;
|
||||
|
||||
Local<Object> message_info = Object::New(env()->isolate());
|
||||
Local<Value> undefined = Undefined(env()->isolate());
|
||||
for (size_t i = 0; i < ARRAY_SIZE(argv); i++)
|
||||
argv[i] = undefined;
|
||||
|
||||
if (have_flushed_) {
|
||||
// Slow case, flush remaining headers.
|
||||
Flush();
|
||||
} else {
|
||||
// Fast case, pass headers and URL to JS land.
|
||||
message_info->Set(env()->headers_string(), CreateHeaders());
|
||||
argv[A_HEADERS] = CreateHeaders();
|
||||
if (parser_.type == HTTP_REQUEST)
|
||||
message_info->Set(env()->url_string(), url_.ToString(env()));
|
||||
argv[A_URL] = url_.ToString(env());
|
||||
}
|
||||
num_fields_ = num_values_ = 0;
|
||||
|
||||
num_fields_ = 0;
|
||||
num_values_ = 0;
|
||||
|
||||
// METHOD
|
||||
if (parser_.type == HTTP_REQUEST) {
|
||||
message_info->Set(env()->method_string(),
|
||||
Uint32::NewFromUnsigned(env()->isolate(),
|
||||
parser_.method));
|
||||
argv[A_METHOD] =
|
||||
Uint32::NewFromUnsigned(env()->isolate(), parser_.method);
|
||||
}
|
||||
|
||||
// STATUS
|
||||
if (parser_.type == HTTP_RESPONSE) {
|
||||
message_info->Set(env()->status_code_string(),
|
||||
Integer::New(env()->isolate(), parser_.status_code));
|
||||
message_info->Set(env()->status_message_string(),
|
||||
status_message_.ToString(env()));
|
||||
argv[A_STATUS_CODE] =
|
||||
Integer::New(env()->isolate(), parser_.status_code);
|
||||
argv[A_STATUS_MESSAGE] = status_message_.ToString(env());
|
||||
}
|
||||
|
||||
// VERSION
|
||||
message_info->Set(env()->version_major_string(),
|
||||
Integer::New(env()->isolate(), parser_.http_major));
|
||||
message_info->Set(env()->version_minor_string(),
|
||||
Integer::New(env()->isolate(), parser_.http_minor));
|
||||
argv[A_VERSION_MAJOR] = Integer::New(env()->isolate(), parser_.http_major);
|
||||
argv[A_VERSION_MINOR] = Integer::New(env()->isolate(), parser_.http_minor);
|
||||
|
||||
message_info->Set(env()->should_keep_alive_string(),
|
||||
http_should_keep_alive(&parser_) ?
|
||||
True(env()->isolate()) : False(env()->isolate()));
|
||||
argv[A_SHOULD_KEEP_ALIVE] =
|
||||
Boolean::New(env()->isolate(), http_should_keep_alive(&parser_));
|
||||
|
||||
message_info->Set(env()->upgrade_string(),
|
||||
parser_.upgrade ? True(env()->isolate())
|
||||
: False(env()->isolate()));
|
||||
argv[A_UPGRADE] = Boolean::New(env()->isolate(), parser_.upgrade);
|
||||
|
||||
Local<Value> argv[1] = { message_info };
|
||||
Local<Value> head_response =
|
||||
cb.As<Function>()->Call(obj, ARRAY_SIZE(argv), argv);
|
||||
|
||||
|
||||
@@ -76,15 +76,17 @@ function expectBody(expected) {
|
||||
'GET /hello HTTP/1.1' + CRLF +
|
||||
CRLF);
|
||||
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
assert.equal(method, methods.indexOf('GET'));
|
||||
assert.equal(url || parser.url, '/hello');
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('GET'));
|
||||
assert.equal(info.url || parser.url, '/hello');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 1);
|
||||
});
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser.execute(request, 0, request.length);
|
||||
|
||||
//
|
||||
@@ -115,21 +117,24 @@ function expectBody(expected) {
|
||||
CRLF +
|
||||
'pong');
|
||||
|
||||
var parser = newParser(RESPONSE);
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, undefined);
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
assert.equal(statusCode, 200);
|
||||
assert.equal(statusMessage, 'OK');
|
||||
};
|
||||
|
||||
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);
|
||||
assert.equal(info.statusMessage, "OK");
|
||||
});
|
||||
|
||||
parser[kOnBody] = mustCall(function(buf, start, len) {
|
||||
var onBody = function(buf, start, len) {
|
||||
var body = '' + buf.slice(start, start + len);
|
||||
assert.equal(body, 'pong');
|
||||
});
|
||||
};
|
||||
|
||||
var parser = newParser(RESPONSE);
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser[kOnBody] = mustCall(onBody);
|
||||
parser.execute(request, 0, request.length);
|
||||
})();
|
||||
|
||||
@@ -142,17 +147,19 @@ function expectBody(expected) {
|
||||
'HTTP/1.0 200 Connection established' + CRLF +
|
||||
CRLF);
|
||||
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 0);
|
||||
assert.equal(method, undefined);
|
||||
assert.equal(statusCode, 200);
|
||||
assert.equal(statusMessage, 'Connection established');
|
||||
assert.deepEqual(headers || parser.headers, []);
|
||||
};
|
||||
|
||||
var parser = newParser(RESPONSE);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, undefined);
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 0);
|
||||
assert.equal(info.statusCode, 200);
|
||||
assert.equal(info.statusMessage, "Connection established");
|
||||
assert.deepEqual(info.headers || parser.headers, []);
|
||||
});
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser.execute(request, 0, request.length);
|
||||
})();
|
||||
|
||||
@@ -174,29 +181,31 @@ function expectBody(expected) {
|
||||
|
||||
var seen_body = false;
|
||||
|
||||
function onHeaders(headers, url) {
|
||||
var onHeaders = function(headers, url) {
|
||||
assert.ok(seen_body); // trailers should come after the body
|
||||
assert.deepEqual(headers,
|
||||
['Vary', '*', 'Content-Type', 'text/plain']);
|
||||
}
|
||||
assert.deepEqual(headers, ['Vary', '*', 'Content-Type', 'text/plain']);
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('POST'));
|
||||
assert.equal(info.url || parser.url, '/it');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 1);
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('POST'));
|
||||
assert.equal(url || parser.url, '/it');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
// expect to see trailing headers now
|
||||
parser[kOnHeaders] = mustCall(onHeaders);
|
||||
});
|
||||
};
|
||||
|
||||
parser[kOnBody] = mustCall(function(buf, start, len) {
|
||||
var onBody = function(buf, start, len) {
|
||||
var body = '' + buf.slice(start, start + len);
|
||||
assert.equal(body, 'ping');
|
||||
seen_body = true;
|
||||
});
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser[kOnBody] = mustCall(onBody);
|
||||
parser.execute(request, 0, request.length);
|
||||
})();
|
||||
|
||||
@@ -212,18 +221,19 @@ function expectBody(expected) {
|
||||
'X-Filler2: 42' + CRLF +
|
||||
CRLF);
|
||||
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('GET'));
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 0);
|
||||
assert.deepEqual(
|
||||
headers || parser.headers,
|
||||
['X-Filler', '1337', 'X-Filler', '42', 'X-Filler2', '42']);
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('GET'));
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 0);
|
||||
assert.deepEqual(info.headers || parser.headers,
|
||||
['X-Filler', '1337',
|
||||
'X-Filler', '42',
|
||||
'X-Filler2', '42']);
|
||||
});
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser.execute(request, 0, request.length);
|
||||
})();
|
||||
|
||||
@@ -241,23 +251,25 @@ function expectBody(expected) {
|
||||
lots_of_headers +
|
||||
CRLF);
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('GET'));
|
||||
assert.equal(url || parser.url, '/foo/bar/baz?quux=42#1337');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 0);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('GET'));
|
||||
assert.equal(info.url || parser.url, '/foo/bar/baz?quux=42#1337');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 0);
|
||||
|
||||
var headers = info.headers || parser.headers;
|
||||
var headers = headers || parser.headers;
|
||||
|
||||
assert.equal(headers.length, 2 * 256); // 256 key/value pairs
|
||||
for (var i = 0; i < headers.length; i += 2) {
|
||||
assert.equal(headers[i], 'X-Filler');
|
||||
assert.equal(headers[i + 1], '42');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser.execute(request, 0, request.length);
|
||||
})();
|
||||
|
||||
@@ -273,20 +285,23 @@ function expectBody(expected) {
|
||||
CRLF +
|
||||
'foo=42&bar=1337');
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('POST'));
|
||||
assert.equal(url || parser.url, '/it');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
};
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('POST'));
|
||||
assert.equal(info.url || parser.url, '/it');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 1);
|
||||
});
|
||||
|
||||
parser[kOnBody] = mustCall(function(buf, start, len) {
|
||||
var onBody = function(buf, start, len) {
|
||||
var body = '' + buf.slice(start, start + len);
|
||||
assert.equal(body, 'foo=42&bar=1337');
|
||||
});
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser[kOnBody] = mustCall(onBody);
|
||||
parser.execute(request, 0, request.length);
|
||||
})();
|
||||
|
||||
@@ -308,23 +323,25 @@ function expectBody(expected) {
|
||||
'1234567890' + CRLF +
|
||||
'0' + CRLF);
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('POST'));
|
||||
assert.equal(info.url || parser.url, '/it');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 1);
|
||||
});
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('POST'));
|
||||
assert.equal(url || parser.url, '/it');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
};
|
||||
|
||||
var body_part = 0,
|
||||
body_parts = ['123', '123456', '1234567890'];
|
||||
|
||||
function onBody(buf, start, len) {
|
||||
var onBody = function(buf, start, len) {
|
||||
var body = '' + buf.slice(start, start + len);
|
||||
assert.equal(body, body_parts[body_part++]);
|
||||
}
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser[kOnBody] = mustCall(onBody, body_parts.length);
|
||||
parser.execute(request, 0, request.length);
|
||||
})();
|
||||
@@ -344,25 +361,26 @@ function expectBody(expected) {
|
||||
'6' + CRLF +
|
||||
'123456' + CRLF);
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('POST'));
|
||||
assert.equal(info.url || parser.url, '/it');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 1);
|
||||
});
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('POST'));
|
||||
assert.equal(url || parser.url, '/it');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
};
|
||||
|
||||
var body_part = 0,
|
||||
body_parts = [
|
||||
'123', '123456', '123456789',
|
||||
'123456789ABC', '123456789ABCDEF'];
|
||||
body_parts =
|
||||
['123', '123456', '123456789', '123456789ABC', '123456789ABCDEF'];
|
||||
|
||||
function onBody(buf, start, len) {
|
||||
var onBody = function(buf, start, len) {
|
||||
var body = '' + buf.slice(start, start + len);
|
||||
assert.equal(body, body_parts[body_part++]);
|
||||
}
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser[kOnBody] = mustCall(onBody, body_parts.length);
|
||||
parser.execute(request, 0, request.length);
|
||||
|
||||
@@ -401,23 +419,26 @@ function expectBody(expected) {
|
||||
'0' + CRLF);
|
||||
|
||||
function test(a, b) {
|
||||
var parser = newParser(REQUEST);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('POST'));
|
||||
assert.equal(info.url || parser.url, '/helpme');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 1);
|
||||
});
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers,
|
||||
method, url, statusCode, statusMessage,
|
||||
upgrade, shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('POST'));
|
||||
assert.equal(url || parser.url, '/helpme');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
};
|
||||
|
||||
var expected_body = '123123456123456789123456789ABC123456789ABCDEF';
|
||||
|
||||
parser[kOnBody] = function(buf, start, len) {
|
||||
var onBody = 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);
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser[kOnBody] = onBody;
|
||||
parser.execute(a, 0, a.length);
|
||||
parser.execute(b, 0, b.length);
|
||||
|
||||
@@ -457,26 +478,30 @@ function expectBody(expected) {
|
||||
'123456789ABCDEF' + CRLF +
|
||||
'0' + CRLF);
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
|
||||
parser[kOnHeadersComplete] = mustCall(function(info) {
|
||||
assert.equal(info.method, methods.indexOf('POST'));
|
||||
assert.equal(info.url || parser.url, '/it');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 1);
|
||||
assert.deepEqual(info.headers || parser.headers,
|
||||
['Content-Type', 'text/plain',
|
||||
'Transfer-Encoding', 'chunked']);
|
||||
});
|
||||
var onHeadersComplete = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('POST'));
|
||||
assert.equal(url || parser.url, '/it');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
assert.deepEqual(
|
||||
headers || parser.headers,
|
||||
['Content-Type', 'text/plain', 'Transfer-Encoding', 'chunked']);
|
||||
};
|
||||
|
||||
var expected_body = '123123456123456789123456789ABC123456789ABCDEF';
|
||||
|
||||
parser[kOnBody] = function(buf, start, len) {
|
||||
var onBody = 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);
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
parser[kOnHeadersComplete] = mustCall(onHeadersComplete);
|
||||
parser[kOnBody] = onBody;
|
||||
|
||||
for (var i = 0; i < request.length; ++i) {
|
||||
parser.execute(request, i, 1);
|
||||
}
|
||||
@@ -505,24 +530,27 @@ function expectBody(expected) {
|
||||
CRLF +
|
||||
'pong');
|
||||
|
||||
function onHeadersComplete1(info) {
|
||||
assert.equal(info.method, methods.indexOf('PUT'));
|
||||
assert.equal(info.url, '/this');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 1);
|
||||
assert.deepEqual(info.headers,
|
||||
['Content-Type', 'text/plain',
|
||||
'Transfer-Encoding', 'chunked']);
|
||||
var onHeadersComplete1 = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('PUT'));
|
||||
assert.equal(url, '/this');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 1);
|
||||
assert.deepEqual(
|
||||
headers,
|
||||
['Content-Type', 'text/plain', 'Transfer-Encoding', 'chunked']);
|
||||
};
|
||||
|
||||
function onHeadersComplete2(info) {
|
||||
assert.equal(info.method, methods.indexOf('POST'));
|
||||
assert.equal(info.url, '/that');
|
||||
assert.equal(info.versionMajor, 1);
|
||||
assert.equal(info.versionMinor, 0);
|
||||
assert.deepEqual(info.headers,
|
||||
['Content-Type', 'text/plain',
|
||||
'Content-Length', '4']);
|
||||
var onHeadersComplete2 = function(versionMajor, versionMinor, headers, method,
|
||||
url, statusCode, statusMessage, upgrade,
|
||||
shouldKeepAlive) {
|
||||
assert.equal(method, methods.indexOf('POST'));
|
||||
assert.equal(url, '/that');
|
||||
assert.equal(versionMajor, 1);
|
||||
assert.equal(versionMinor, 0);
|
||||
assert.deepEqual(headers,
|
||||
['Content-Type', 'text/plain', 'Content-Length', '4']);
|
||||
};
|
||||
|
||||
var parser = newParser(REQUEST);
|
||||
|
||||
Reference in New Issue
Block a user