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 9// Push a request & response 10 11const pushExpect = 'This is a server-initiated response'; 12const servExpect = 'This is a client-initiated response'; 13 14const server = h2.createServer((request, response) => { 15 assert.strictEqual(response.stream.id % 2, 1); 16 response.write(servExpect); 17 18 // Callback must be specified (and be a function) 19 assert.throws( 20 () => response.createPushResponse({ 21 ':path': '/pushed', 22 ':method': 'GET' 23 }, undefined), 24 { 25 code: 'ERR_INVALID_ARG_TYPE', 26 name: 'TypeError', 27 } 28 ); 29 30 response.stream.on('close', () => { 31 response.createPushResponse({ 32 ':path': '/pushed', 33 ':method': 'GET' 34 }, common.mustCall((error) => { 35 assert.strictEqual(error.code, 'ERR_HTTP2_INVALID_STREAM'); 36 })); 37 }); 38 39 response.createPushResponse({ 40 ':path': '/pushed', 41 ':method': 'GET' 42 }, common.mustSucceed((push) => { 43 assert.strictEqual(push.stream.id % 2, 0); 44 push.end(pushExpect); 45 response.end(); 46 })); 47}); 48 49server.listen(0, common.mustCall(() => { 50 const port = server.address().port; 51 52 const client = h2.connect(`http://localhost:${port}`, common.mustCall(() => { 53 const headers = { 54 ':path': '/', 55 ':method': 'GET', 56 }; 57 58 let remaining = 2; 59 function maybeClose() { 60 if (--remaining === 0) { 61 client.close(); 62 server.close(); 63 } 64 } 65 66 const req = client.request(headers); 67 68 client.on('stream', common.mustCall((pushStream, headers) => { 69 assert.strictEqual(headers[':path'], '/pushed'); 70 assert.strictEqual(headers[':method'], 'GET'); 71 assert.strictEqual(headers[':scheme'], 'http'); 72 assert.strictEqual(headers[':authority'], `localhost:${port}`); 73 74 let actual = ''; 75 pushStream.on('push', common.mustCall((headers) => { 76 assert.strictEqual(headers[':status'], 200); 77 assert(headers.date); 78 })); 79 pushStream.setEncoding('utf8'); 80 pushStream.on('data', (chunk) => actual += chunk); 81 pushStream.on('end', common.mustCall(() => { 82 assert.strictEqual(actual, pushExpect); 83 maybeClose(); 84 })); 85 })); 86 87 req.on('response', common.mustCall((headers) => { 88 assert.strictEqual(headers[':status'], 200); 89 assert(headers.date); 90 })); 91 92 let actual = ''; 93 req.setEncoding('utf8'); 94 req.on('data', (chunk) => actual += chunk); 95 req.on('end', common.mustCall(() => { 96 assert.strictEqual(actual, servExpect); 97 maybeClose(); 98 })); 99 })); 100})); 101