• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22'use strict';
23// Verify that the HTTP server implementation handles multiple instances
24// of the same header as per RFC2616: joining the handful of fields by ', '
25// that support it, and dropping duplicates for other fields.
26
27require('../common');
28const assert = require('assert');
29const http = require('http');
30
31const multipleAllowed = [
32  'Accept',
33  'Accept-Charset',
34  'Accept-Encoding',
35  'Accept-Language',
36  'Connection',
37  'Cookie',
38  'DAV', // GH-2750
39  'Pragma', // GH-715
40  'Link', // GH-1187
41  'WWW-Authenticate', // GH-1083
42  'Proxy-Authenticate', // GH-4052
43  'Sec-Websocket-Extensions', // GH-2764
44  'Sec-Websocket-Protocol', // GH-2764
45  'Via', // GH-6660
46
47  // not a special case, just making sure it's parsed correctly
48  'X-Forwarded-For',
49
50  // Make sure that unspecified headers is treated as multiple
51  'Some-Random-Header',
52  'X-Some-Random-Header',
53];
54
55const multipleForbidden = [
56  'Content-Type',
57  'User-Agent',
58  'Referer',
59  'Host',
60  'Authorization',
61  'Proxy-Authorization',
62  'If-Modified-Since',
63  'If-Unmodified-Since',
64  'From',
65  'Location',
66  'Max-Forwards',
67
68  // Special case, tested differently
69  // 'Content-Length',
70];
71
72const server = http.createServer(function(req, res) {
73  multipleForbidden.forEach(function(header) {
74    assert.strictEqual(req.headers[header.toLowerCase()], 'foo',
75                       `header parsed incorrectly: ${header}`);
76  });
77  multipleAllowed.forEach(function(header) {
78    const sep = (header.toLowerCase() === 'cookie' ? '; ' : ', ');
79    assert.strictEqual(req.headers[header.toLowerCase()], `foo${sep}bar`,
80                       `header parsed incorrectly: ${header}`);
81  });
82
83  res.writeHead(200, { 'Content-Type': 'text/plain' });
84  res.end('EOF');
85
86  server.close();
87});
88
89function makeHeader(value) {
90  return function(header) {
91    return [header, value];
92  };
93}
94
95const headers = []
96  .concat(multipleAllowed.map(makeHeader('foo')))
97  .concat(multipleForbidden.map(makeHeader('foo')))
98  .concat(multipleAllowed.map(makeHeader('bar')))
99  .concat(multipleForbidden.map(makeHeader('bar')));
100
101server.listen(0, function() {
102  http.get({
103    host: 'localhost',
104    port: this.address().port,
105    path: '/',
106    headers: headers,
107  });
108});
109