Skip to content

Commit

Permalink
http: unify header treatment
Browse files Browse the repository at this point in the history
PR-URL: #46528
Fixes: #46395
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
  • Loading branch information
marco-ippolito authored and targos committed Mar 13, 2023
1 parent 2eb8875 commit 6f9cb98
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
13 changes: 13 additions & 0 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ function isCookieField(s) {
return s.length === 6 && StringPrototypeToLowerCase(s) === 'cookie';
}

function isContentDispositionField(s) {
return s.length === 19 && StringPrototypeToLowerCase(s) === 'content-disposition';
}

function OutgoingMessage() {
Stream.call(this);

Expand Down Expand Up @@ -569,6 +573,15 @@ function _storeHeader(firstLine, headers) {
function processHeader(self, state, key, value, validate) {
if (validate)
validateHeaderName(key);

// If key is content-disposition and there is content-length
// encode the value in latin1
// https://www.rfc-editor.org/rfc/rfc6266#section-4.3
// Refs: https://github.com/nodejs/node/pull/46528
if (isContentDispositionField(key) && self._contentLength) {
value = Buffer.from(value, 'latin1');
}

if (ArrayIsArray(value)) {
if (
(value.length < 2 || !isCookieField(key)) &&
Expand Down
48 changes: 48 additions & 0 deletions test/parallel/test-http-server-non-utf8-header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';
const common = require('../common');
const http = require('http');
const assert = require('assert');

const nonUtf8Header = 'bår';
const nonUtf8ToLatin1 = Buffer.from(nonUtf8Header).toString('latin1');

{
const server = http.createServer(common.mustCall((req, res) => {
res.writeHead(200, [
'content-disposition',
Buffer.from(nonUtf8Header).toString('binary'),
]);
res.end('hello');
}));

server.listen(0, common.mustCall(() => {
http.get({ port: server.address().port }, (res) => {
assert.strictEqual(res.statusCode, 200);
assert.strictEqual(res.headers['content-disposition'], nonUtf8ToLatin1);
res.resume().on('end', common.mustCall(() => {
server.close();
}));
});
}));
}

{
const server = http.createServer(common.mustCall((req, res) => {
res.writeHead(200, [
'Content-Length', '5',
'content-disposition',
Buffer.from(nonUtf8Header).toString('binary'),
]);
res.end('hello');
}));

server.listen(0, common.mustCall(() => {
http.get({ port: server.address().port }, (res) => {
assert.strictEqual(res.statusCode, 200);
assert.strictEqual(res.headers['content-disposition'], nonUtf8ToLatin1);
res.resume().on('end', common.mustCall(() => {
server.close();
}));
});
}));
}

0 comments on commit 6f9cb98

Please sign in to comment.