Skip to content

Commit e655a43

Browse files
committed
http: do not allow multiple instances of certain response headers
Response headers such as ETag and Last-Modified do not permit multiple instances, and therefore the comma-separated syntax is not allowed. When multiple values for these headers are specified, use only the first instance. Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> PR-URL: #3090
1 parent 0094a8d commit e655a43

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

lib/_http_incoming.js

+6
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ IncomingMessage.prototype._addHeaderLine = function(field, value, dest) {
152152
case 'from':
153153
case 'location':
154154
case 'max-forwards':
155+
case 'retry-after':
156+
case 'etag':
157+
case 'last-modified':
158+
case 'server':
159+
case 'age':
160+
case 'expires':
155161
// drop duplicates
156162
if (dest[field] === undefined)
157163
dest[field] = value;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const http = require('http');
5+
const assert = require('assert');
6+
7+
// Test that certain response header fields do not repeat
8+
const norepeat = [
9+
'retry-after',
10+
'etag',
11+
'last-modified',
12+
'server',
13+
'age',
14+
'expires'
15+
];
16+
17+
const server = http.createServer(function(req, res) {
18+
var num = req.headers['x-num'];
19+
if (num == 1) {
20+
for (let name of norepeat) {
21+
res.setHeader(name, ['A', 'B']);
22+
}
23+
res.setHeader('X-A', ['A', 'B']);
24+
} else if (num == 2) {
25+
let headers = {};
26+
for (let name of norepeat) {
27+
headers[name] = ['A', 'B'];
28+
}
29+
headers['X-A'] = ['A', 'B'];
30+
res.writeHead(200, headers);
31+
}
32+
res.end('ok');
33+
});
34+
35+
server.listen(common.PORT, common.mustCall(function() {
36+
for (let n = 1; n <= 2 ; n++) {
37+
// this runs twice, the first time, the server will use
38+
// setHeader, the second time it uses writeHead. The
39+
// result on the client side should be the same in
40+
// either case -- only the first instance of the header
41+
// value should be reported for the header fields listed
42+
// in the norepeat array.
43+
http.get(
44+
{port:common.PORT, headers:{'x-num': n}},
45+
common.mustCall(function(res) {
46+
if (n == 2) server.close();
47+
for (let name of norepeat) {
48+
assert.equal(res.headers[name], 'A');
49+
}
50+
assert.equal(res.headers['x-a'], 'A, B');
51+
})
52+
);
53+
}
54+
}));

0 commit comments

Comments
 (0)