Browse Source

Normalize HTTP headers.

"Content-Length" becomes "content-length".
v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
f623fd7658
  1. 9
      lib/http.js
  2. 17
      src/http.cc
  3. 8
      test/mjsunit/test-http.js

9
lib/http.js

@ -109,11 +109,8 @@ exports.parseUri.options = {
}; };
var connection_expression = /Connection/i;
var transfer_encoding_expression = /Transfer-Encoding/i;
var close_expression = /close/i; var close_expression = /close/i;
var chunk_expression = /chunk/i; var chunk_expression = /chunk/i;
var content_length_expression = /Content-Length/i;
/* Abstract base class for ServerRequest and ClientResponse. */ /* Abstract base class for ServerRequest and ClientResponse. */
@ -245,15 +242,15 @@ OutgoingMessage.prototype.sendHeaderLines = function (first_line, headers) {
message_header += field + ": " + value + CRLF; message_header += field + ": " + value + CRLF;
if (connection_expression.exec(field)) { if ("connection" === field) {
sent_connection_header = true; sent_connection_header = true;
if (close_expression.exec(value)) this.closeOnFinish = true; if (close_expression.exec(value)) this.closeOnFinish = true;
} else if (transfer_encoding_expression.exec(field)) { } else if ("transfer-encoding" === field) {
sent_transfer_encoding_header = true; sent_transfer_encoding_header = true;
if (chunk_expression.exec(value)) this.chunked_encoding = true; if (chunk_expression.exec(value)) this.chunked_encoding = true;
} else if (content_length_expression.exec(field)) { } else if ("content-length" === field) {
sent_content_length_header = true; sent_content_length_header = true;
} }

17
src/http.cc

@ -128,12 +128,28 @@ HTTPConnection::on_fragment (http_parser *parser, const char *buf, size_t len)
return 0; return 0;
} }
const static char normalizer[] =
"\0------------------------------"
"-----------------0123456789-----"
"--abcdefghijklmnopqrstuvwxyz----"
"--abcdefghijklmnopqrstuvwxyz----"
"--------------------------------"
"--------------------------------"
"--------------------------------"
"--------------------------------";
int int
HTTPConnection::on_header_field (http_parser *parser, const char *buf, size_t len) HTTPConnection::on_header_field (http_parser *parser, const char *buf, size_t len)
{ {
HandleScope scope; HandleScope scope;
HTTPConnection *connection = static_cast<HTTPConnection*>(parser->data); HTTPConnection *connection = static_cast<HTTPConnection*>(parser->data);
assert(connection->attached_); assert(connection->attached_);
// NORMALIZE
size_t i;
char *nonconstbuf = (char*)buf; // FIXME
for (i = 0; i < len; i++) { nonconstbuf[i] = normalizer[buf[i]]; }
Local<Value> argv[1] = { String::New(buf, len) }; Local<Value> argv[1] = { String::New(buf, len) };
connection->Emit("headerField", 1, argv); connection->Emit("headerField", 1, argv);
return 0; return 0;
@ -145,6 +161,7 @@ HTTPConnection::on_header_value (http_parser *parser, const char *buf, size_t le
HandleScope scope; HandleScope scope;
HTTPConnection *connection = static_cast<HTTPConnection*>(parser->data); HTTPConnection *connection = static_cast<HTTPConnection*>(parser->data);
assert(connection->attached_); assert(connection->attached_);
Local<Value> argv[1] = { String::New(buf, len) }; Local<Value> argv[1] = { String::New(buf, len) };
connection->Emit("headerValue", 1, argv); connection->Emit("headerValue", 1, argv);
return 0; return 0;

8
test/mjsunit/test-http.js

@ -13,11 +13,11 @@ http.createServer(function (req, res) {
assertEquals("/hello", req.uri.path); assertEquals("/hello", req.uri.path);
p(req.headers); p(req.headers);
assertTrue("Accept" in req.headers); assertTrue("accept" in req.headers);
assertEquals("*/*", req.headers["Accept"]); assertEquals("*/*", req.headers["accept"]);
assertTrue("Foo" in req.headers); assertTrue("foo" in req.headers);
assertEquals("bar", req.headers["Foo"]); assertEquals("bar", req.headers["foo"]);
} }
if (responses_sent == 1) { if (responses_sent == 1) {

Loading…
Cancel
Save