1'use strict'; 2 3const common = require('../common'); 4if (!common.hasCrypto) 5 common.skip('missing crypto'); 6const fixtures = require('../common/fixtures'); 7const assert = require('assert'); 8const http2 = require('http2'); 9const { inspect } = require('util'); 10 11const optionsWithTypeError = { 12 offset: 'number', 13 length: 'number', 14 statCheck: 'function' 15}; 16 17const types = { 18 boolean: true, 19 function: () => {}, 20 number: 1, 21 object: {}, 22 array: [], 23 null: null, 24 symbol: Symbol('test') 25}; 26 27const fname = fixtures.path('elipses.txt'); 28 29const server = http2.createServer(); 30 31server.on('stream', common.mustCall((stream) => { 32 33 // Check for all possible TypeError triggers on options 34 Object.keys(optionsWithTypeError).forEach((option) => { 35 Object.keys(types).forEach((type) => { 36 if (type === optionsWithTypeError[option]) { 37 return; 38 } 39 40 assert.throws( 41 () => stream.respondWithFile(fname, { 42 'content-type': 'text/plain' 43 }, { 44 [option]: types[type] 45 }), 46 { 47 name: 'TypeError', 48 code: 'ERR_INVALID_OPT_VALUE', 49 message: `The value "${inspect(types[type])}" is invalid ` + 50 `for option "${option}"` 51 } 52 ); 53 }); 54 }); 55 56 // Should throw if :status 204, 205 or 304 57 [204, 205, 304].forEach((status) => assert.throws( 58 () => stream.respondWithFile(fname, { 59 'content-type': 'text/plain', 60 ':status': status, 61 }), 62 { 63 code: 'ERR_HTTP2_PAYLOAD_FORBIDDEN', 64 message: `Responses with ${status} status must not have a payload` 65 } 66 )); 67 68 // Should throw if headers already sent 69 stream.respond({ ':status': 200 }); 70 assert.throws( 71 () => stream.respondWithFile(fname, { 72 'content-type': 'text/plain' 73 }), 74 { 75 code: 'ERR_HTTP2_HEADERS_SENT', 76 message: 'Response has already been initiated.' 77 } 78 ); 79 80 // Should throw if stream already destroyed 81 stream.destroy(); 82 assert.throws( 83 () => stream.respondWithFile(fname, { 84 'content-type': 'text/plain' 85 }), 86 { 87 code: 'ERR_HTTP2_INVALID_STREAM', 88 message: 'The stream has been destroyed' 89 } 90 ); 91})); 92 93server.listen(0, common.mustCall(() => { 94 const client = http2.connect(`http://localhost:${server.address().port}`); 95 const req = client.request(); 96 97 req.on('close', common.mustCall(() => { 98 client.close(); 99 server.close(); 100 })); 101 req.end(); 102})); 103