HTTP_CB(on_message_begin) {
num_fields_ = num_values_ = 0;
url_.Reset();
+ status_message_.Reset();
return 0;
}
}
+ HTTP_DATA_CB(on_status) {
+ status_message_.Update(at, length);
+ return 0;
+ }
+
+
HTTP_DATA_CB(on_header_field) {
if (num_fields_ == num_values_) {
// start of new field name
if (parser_.type == HTTP_RESPONSE) {
message_info->Set(env()->status_code_string(),
Integer::New(parser_.status_code, node_isolate));
+ message_info->Set(env()->status_message_string(),
+ status_message_.ToString());
}
// VERSION
void Save() {
url_.Save();
+ status_message_.Save();
for (int i = 0; i < num_fields_; i++) {
fields_[i].Save();
void Init(enum http_parser_type type) {
http_parser_init(&parser_, type);
url_.Reset();
+ status_message_.Reset();
num_fields_ = 0;
num_values_ = 0;
have_flushed_ = false;
StringPtr fields_[32]; // header fields
StringPtr values_[32]; // header values
StringPtr url_;
+ StringPtr status_message_;
int num_fields_;
int num_values_;
bool have_flushed_;
const struct http_parser_settings Parser::settings = {
Parser::on_message_begin,
Parser::on_url,
+ Parser::on_status,
Parser::on_header_field,
Parser::on_header_value,
Parser::on_headers_complete,
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) {
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, []);
});
--- /dev/null
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var common = require('../common');
+var assert = require('assert');
+var http = require('http');
+var net = require('net');
+
+var testsComplete = 0;
+
+var testCases = [
+ { path: "/200", statusMessage: "OK", response: 'HTTP/1.1 200 OK\r\n\r\n' },
+ { path: "/500", statusMessage: "Internal Server Error", response: 'HTTP/1.1 500 Internal Server Error\r\n\r\n' },
+ { path: "/302", statusMessage: "Moved Temporarily", response: 'HTTP/1.1 302 Moved Temporarily\r\n\r\n' },
+ { path: "/missing", statusMessage: "", response: 'HTTP/1.1 200 \r\n\r\n' },
+ { path: "/missing-no-space", statusMessage: "", response: 'HTTP/1.1 200\r\n\r\n' }
+];
+testCases.findByPath = function(path) {
+ var matching = this.filter(function(testCase) { return testCase.path === path; });
+ if (matching.length === 0) { throw "failed to find test case with path " + path; }
+ return matching[0];
+};
+
+var server = net.createServer(function(connection) {
+ connection.on('data', function(data) {
+ var path = data.toString().match(/GET (.*) HTTP.1.1/)[1];
+ var testCase = testCases.findByPath(path);
+
+ connection.write(testCase.response);
+ connection.end();
+ });
+});
+
+var runTest = function(testCaseIndex) {
+ var testCase = testCases[testCaseIndex];
+
+ http.get({ port: common.PORT, path: testCase.path }, function(response) {
+ console.log('client: expected status message: ' + testCase.statusMessage);
+ console.log('client: actual status message: ' + response.statusMessage);
+ assert.equal(testCase.statusMessage, response.statusMessage);
+
+ response.on('end', function() {
+ testsComplete++;
+
+ if (testCaseIndex + 1 < testCases.length) {
+ runTest(testCaseIndex + 1);
+ } else {
+ server.close();
+ }
+ });
+
+ response.resume();
+ });
+};
+
+server.listen(common.PORT, function() { runTest(0); });
+
+process.on('exit', function() {
+ assert.equal(testCases.length, testsComplete);
+});