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