1'use strict'; 2 3const common = require('../common'); 4if (!common.hasCrypto) 5 common.skip('missing crypto'); 6const assert = require('assert'); 7const h2 = require('http2'); 8 9const server = h2.createServer(); 10 11// We use the lower-level API here 12server.on('stream', common.mustCall(onStream)); 13 14const status101regex = 15 /^HTTP status code 101 \(Switching Protocols\) is forbidden in HTTP\/2$/; 16const afterRespondregex = 17 /^Cannot specify additional headers after response initiated$/; 18 19function onStream(stream, headers, flags) { 20 21 assert.throws(() => stream.additionalHeaders({ ':status': 201 }), 22 { 23 code: 'ERR_HTTP2_INVALID_INFO_STATUS', 24 name: 'RangeError', 25 message: /^Invalid informational status code: 201$/ 26 }); 27 28 assert.throws(() => stream.additionalHeaders({ ':status': 101 }), 29 { 30 code: 'ERR_HTTP2_STATUS_101', 31 name: 'Error', 32 message: status101regex 33 }); 34 35 assert.throws( 36 () => stream.additionalHeaders({ ':method': 'POST' }), 37 { 38 code: 'ERR_HTTP2_INVALID_PSEUDOHEADER', 39 name: 'TypeError', 40 message: '":method" is an invalid pseudoheader or is used incorrectly' 41 } 42 ); 43 44 // Can send more than one 45 stream.additionalHeaders({ ':status': 100 }); 46 stream.additionalHeaders({ ':status': 100 }); 47 48 stream.respond({ 49 'content-type': 'text/html', 50 ':status': 200 51 }); 52 53 assert.throws(() => stream.additionalHeaders({ abc: 123 }), 54 { 55 code: 'ERR_HTTP2_HEADERS_AFTER_RESPOND', 56 name: 'Error', 57 message: afterRespondregex 58 }); 59 60 stream.end('hello world'); 61} 62 63server.listen(0); 64 65server.on('listening', common.mustCall(() => { 66 67 const client = h2.connect(`http://localhost:${server.address().port}`); 68 69 const req = client.request({ ':path': '/' }); 70 71 // The additionalHeaders method does not exist on client stream 72 assert.strictEqual(req.additionalHeaders, undefined); 73 74 // Additional informational headers 75 req.on('headers', common.mustCall((headers) => { 76 assert.notStrictEqual(headers, undefined); 77 assert.strictEqual(headers[':status'], 100); 78 }, 2)); 79 80 // Response headers 81 req.on('response', common.mustCall((headers) => { 82 assert.notStrictEqual(headers, undefined); 83 assert.strictEqual(headers[':status'], 200); 84 assert.strictEqual(headers['content-type'], 'text/html'); 85 })); 86 87 req.resume(); 88 89 req.on('end', common.mustCall(() => { 90 server.close(); 91 client.close(); 92 })); 93 req.end(); 94 95})); 96