11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors. 21cb0ef41Sopenharmony_ci// 31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a 41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the 51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including 61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish, 71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit 81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the 91cb0ef41Sopenharmony_ci// following conditions: 101cb0ef41Sopenharmony_ci// 111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included 121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software. 131cb0ef41Sopenharmony_ci// 141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE. 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci'use strict'; 231cb0ef41Sopenharmony_ciconst common = require('../common'); 241cb0ef41Sopenharmony_ciconst assert = require('assert'); 251cb0ef41Sopenharmony_ciconst http = require('http'); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci// Simple test of Node's HTTP Client mutable headers 281cb0ef41Sopenharmony_ci// OutgoingMessage.prototype.setHeader(name, value) 291cb0ef41Sopenharmony_ci// OutgoingMessage.prototype.getHeader(name) 301cb0ef41Sopenharmony_ci// OutgoingMessage.prototype.removeHeader(name, value) 311cb0ef41Sopenharmony_ci// ServerResponse.prototype.statusCode 321cb0ef41Sopenharmony_ci// <ClientRequest>.method 331cb0ef41Sopenharmony_ci// <ClientRequest>.path 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_cilet test = 'headers'; 361cb0ef41Sopenharmony_ciconst content = 'hello world\n'; 371cb0ef41Sopenharmony_ciconst cookies = [ 381cb0ef41Sopenharmony_ci 'session_token=; path=/; expires=Sun, 15-Sep-2030 13:48:52 GMT', 391cb0ef41Sopenharmony_ci 'prefers_open_id=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT', 401cb0ef41Sopenharmony_ci]; 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ciconst s = http.createServer(common.mustCall((req, res) => { 431cb0ef41Sopenharmony_ci switch (test) { 441cb0ef41Sopenharmony_ci case 'headers': { 451cb0ef41Sopenharmony_ci // Check that header-related functions work before setting any headers 461cb0ef41Sopenharmony_ci const headers = res.getHeaders(); 471cb0ef41Sopenharmony_ci const exoticObj = Object.create(null); 481cb0ef41Sopenharmony_ci assert.deepStrictEqual(headers, exoticObj); 491cb0ef41Sopenharmony_ci assert.deepStrictEqual(res.getHeaderNames(), []); 501cb0ef41Sopenharmony_ci assert.deepStrictEqual(res.getRawHeaderNames(), []); 511cb0ef41Sopenharmony_ci assert.strictEqual(res.hasHeader('Connection'), false); 521cb0ef41Sopenharmony_ci assert.strictEqual(res.getHeader('Connection'), undefined); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci assert.throws( 551cb0ef41Sopenharmony_ci () => res.setHeader(), 561cb0ef41Sopenharmony_ci { 571cb0ef41Sopenharmony_ci code: 'ERR_INVALID_HTTP_TOKEN', 581cb0ef41Sopenharmony_ci name: 'TypeError', 591cb0ef41Sopenharmony_ci message: 'Header name must be a valid HTTP token ["undefined"]' 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci ); 621cb0ef41Sopenharmony_ci assert.throws( 631cb0ef41Sopenharmony_ci () => res.setHeader('someHeader'), 641cb0ef41Sopenharmony_ci { 651cb0ef41Sopenharmony_ci code: 'ERR_HTTP_INVALID_HEADER_VALUE', 661cb0ef41Sopenharmony_ci name: 'TypeError', 671cb0ef41Sopenharmony_ci message: 'Invalid value "undefined" for header "someHeader"' 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci ); 701cb0ef41Sopenharmony_ci assert.throws( 711cb0ef41Sopenharmony_ci () => res.getHeader(), 721cb0ef41Sopenharmony_ci { 731cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 741cb0ef41Sopenharmony_ci name: 'TypeError', 751cb0ef41Sopenharmony_ci message: 'The "name" argument must be of type string. ' + 761cb0ef41Sopenharmony_ci 'Received undefined' 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci ); 791cb0ef41Sopenharmony_ci assert.throws( 801cb0ef41Sopenharmony_ci () => res.removeHeader(), 811cb0ef41Sopenharmony_ci { 821cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 831cb0ef41Sopenharmony_ci name: 'TypeError', 841cb0ef41Sopenharmony_ci message: 'The "name" argument must be of type string. ' + 851cb0ef41Sopenharmony_ci 'Received undefined' 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci ); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci const arrayValues = [1, 2, 3]; 901cb0ef41Sopenharmony_ci res.setHeader('x-test-header', 'testing'); 911cb0ef41Sopenharmony_ci res.setHeader('X-TEST-HEADER2', 'testing'); 921cb0ef41Sopenharmony_ci res.setHeader('set-cookie', cookies); 931cb0ef41Sopenharmony_ci res.setHeader('x-test-array-header', arrayValues); 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci assert.strictEqual(res.getHeader('x-test-header'), 'testing'); 961cb0ef41Sopenharmony_ci assert.strictEqual(res.getHeader('x-test-header2'), 'testing'); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci const headersCopy = res.getHeaders(); 991cb0ef41Sopenharmony_ci const expected = { 1001cb0ef41Sopenharmony_ci 'x-test-header': 'testing', 1011cb0ef41Sopenharmony_ci 'x-test-header2': 'testing', 1021cb0ef41Sopenharmony_ci 'set-cookie': cookies, 1031cb0ef41Sopenharmony_ci 'x-test-array-header': arrayValues 1041cb0ef41Sopenharmony_ci }; 1051cb0ef41Sopenharmony_ci Object.setPrototypeOf(expected, null); 1061cb0ef41Sopenharmony_ci assert.deepStrictEqual(headersCopy, expected); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci assert.deepStrictEqual(res.getHeaderNames(), 1091cb0ef41Sopenharmony_ci ['x-test-header', 'x-test-header2', 1101cb0ef41Sopenharmony_ci 'set-cookie', 'x-test-array-header']); 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci assert.deepStrictEqual(res.getRawHeaderNames(), 1131cb0ef41Sopenharmony_ci ['x-test-header', 'X-TEST-HEADER2', 1141cb0ef41Sopenharmony_ci 'set-cookie', 'x-test-array-header']); 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci assert.strictEqual(res.hasHeader('x-test-header2'), true); 1171cb0ef41Sopenharmony_ci assert.strictEqual(res.hasHeader('X-TEST-HEADER2'), true); 1181cb0ef41Sopenharmony_ci assert.strictEqual(res.hasHeader('X-Test-Header2'), true); 1191cb0ef41Sopenharmony_ci [ 1201cb0ef41Sopenharmony_ci undefined, 1211cb0ef41Sopenharmony_ci null, 1221cb0ef41Sopenharmony_ci true, 1231cb0ef41Sopenharmony_ci {}, 1241cb0ef41Sopenharmony_ci { toString: () => 'X-TEST-HEADER2' }, 1251cb0ef41Sopenharmony_ci () => { }, 1261cb0ef41Sopenharmony_ci ].forEach((val) => { 1271cb0ef41Sopenharmony_ci assert.throws( 1281cb0ef41Sopenharmony_ci () => res.hasHeader(val), 1291cb0ef41Sopenharmony_ci { 1301cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1311cb0ef41Sopenharmony_ci name: 'TypeError', 1321cb0ef41Sopenharmony_ci message: 'The "name" argument must be of type string.' + 1331cb0ef41Sopenharmony_ci common.invalidArgTypeHelper(val) 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci ); 1361cb0ef41Sopenharmony_ci }); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci res.removeHeader('x-test-header2'); 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci assert.strictEqual(res.hasHeader('x-test-header2'), false); 1411cb0ef41Sopenharmony_ci assert.strictEqual(res.hasHeader('X-TEST-HEADER2'), false); 1421cb0ef41Sopenharmony_ci assert.strictEqual(res.hasHeader('X-Test-Header2'), false); 1431cb0ef41Sopenharmony_ci break; 1441cb0ef41Sopenharmony_ci } 1451cb0ef41Sopenharmony_ci case 'contentLength': 1461cb0ef41Sopenharmony_ci res.setHeader('content-length', content.length); 1471cb0ef41Sopenharmony_ci assert.strictEqual(res.getHeader('Content-Length'), content.length); 1481cb0ef41Sopenharmony_ci break; 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci case 'transferEncoding': 1511cb0ef41Sopenharmony_ci res.setHeader('transfer-encoding', 'chunked'); 1521cb0ef41Sopenharmony_ci assert.strictEqual(res.getHeader('Transfer-Encoding'), 'chunked'); 1531cb0ef41Sopenharmony_ci break; 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci case 'writeHead': 1561cb0ef41Sopenharmony_ci res.statusCode = 404; 1571cb0ef41Sopenharmony_ci res.setHeader('x-foo', 'keyboard cat'); 1581cb0ef41Sopenharmony_ci res.writeHead(200, { 'x-foo': 'bar', 'x-bar': 'baz' }); 1591cb0ef41Sopenharmony_ci break; 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci default: 1621cb0ef41Sopenharmony_ci assert.fail('Unknown test'); 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci res.statusCode = 201; 1661cb0ef41Sopenharmony_ci res.end(content); 1671cb0ef41Sopenharmony_ci}, 4)); 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_cis.listen(0, nextTest); 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_cifunction nextTest() { 1731cb0ef41Sopenharmony_ci if (test === 'end') { 1741cb0ef41Sopenharmony_ci return s.close(); 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci let bufferedResponse = ''; 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci const req = http.get({ 1801cb0ef41Sopenharmony_ci port: s.address().port, 1811cb0ef41Sopenharmony_ci headers: { 'X-foo': 'bar' } 1821cb0ef41Sopenharmony_ci }, common.mustCall((response) => { 1831cb0ef41Sopenharmony_ci switch (test) { 1841cb0ef41Sopenharmony_ci case 'headers': 1851cb0ef41Sopenharmony_ci assert.strictEqual(response.statusCode, 201); 1861cb0ef41Sopenharmony_ci assert.strictEqual(response.headers['x-test-header'], 'testing'); 1871cb0ef41Sopenharmony_ci assert.strictEqual(response.headers['x-test-array-header'], 1881cb0ef41Sopenharmony_ci [1, 2, 3].join(', ')); 1891cb0ef41Sopenharmony_ci assert.deepStrictEqual(cookies, response.headers['set-cookie']); 1901cb0ef41Sopenharmony_ci assert.strictEqual(response.headers['x-test-header2'], undefined); 1911cb0ef41Sopenharmony_ci test = 'contentLength'; 1921cb0ef41Sopenharmony_ci break; 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci case 'contentLength': 1951cb0ef41Sopenharmony_ci assert.strictEqual(+response.headers['content-length'], content.length); 1961cb0ef41Sopenharmony_ci test = 'transferEncoding'; 1971cb0ef41Sopenharmony_ci break; 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci case 'transferEncoding': 2001cb0ef41Sopenharmony_ci assert.strictEqual(response.headers['transfer-encoding'], 'chunked'); 2011cb0ef41Sopenharmony_ci test = 'writeHead'; 2021cb0ef41Sopenharmony_ci break; 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci case 'writeHead': 2051cb0ef41Sopenharmony_ci assert.strictEqual(response.headers['x-foo'], 'bar'); 2061cb0ef41Sopenharmony_ci assert.strictEqual(response.headers['x-bar'], 'baz'); 2071cb0ef41Sopenharmony_ci assert.strictEqual(response.statusCode, 200); 2081cb0ef41Sopenharmony_ci test = 'end'; 2091cb0ef41Sopenharmony_ci break; 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci default: 2121cb0ef41Sopenharmony_ci assert.fail('Unknown test'); 2131cb0ef41Sopenharmony_ci } 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci response.setEncoding('utf8'); 2161cb0ef41Sopenharmony_ci response.on('data', (s) => { 2171cb0ef41Sopenharmony_ci bufferedResponse += s; 2181cb0ef41Sopenharmony_ci }); 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci response.on('end', common.mustCall(() => { 2211cb0ef41Sopenharmony_ci assert.strictEqual(bufferedResponse, content); 2221cb0ef41Sopenharmony_ci common.mustCall(nextTest)(); 2231cb0ef41Sopenharmony_ci })); 2241cb0ef41Sopenharmony_ci })); 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci assert.deepStrictEqual(req.getHeaderNames(), 2271cb0ef41Sopenharmony_ci ['x-foo', 'host']); 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci assert.deepStrictEqual(req.getRawHeaderNames(), 2301cb0ef41Sopenharmony_ci ['X-foo', 'Host']); 2311cb0ef41Sopenharmony_ci} 232