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.mustCall((error, push) => { 44 assert.ifError(error); 45 assert.strictEqual(push.stream.id % 2, 0); 46 push.end(pushExpect); 47 response.end(); 48 })); 49}); 50 51server.listen(0, common.mustCall(() => { 52 const port = server.address().port; 53 54 const client = h2.connect(`http://localhost:${port}`, common.mustCall(() => { 55 const headers = { 56 ':path': '/', 57 ':method': 'GET', 58 }; 59 60 let remaining = 2; 61 function maybeClose() { 62 if (--remaining === 0) { 63 client.close(); 64 server.close(); 65 } 66 } 67 68 const req = client.request(headers); 69 70 client.on('stream', common.mustCall((pushStream, headers) => { 71 assert.strictEqual(headers[':path'], '/pushed'); 72 assert.strictEqual(headers[':method'], 'GET'); 73 assert.strictEqual(headers[':scheme'], 'http'); 74 assert.strictEqual(headers[':authority'], `localhost:${port}`); 75 76 let actual = ''; 77 pushStream.on('push', common.mustCall((headers) => { 78 assert.strictEqual(headers[':status'], 200); 79 assert(headers.date); 80 })); 81 pushStream.setEncoding('utf8'); 82 pushStream.on('data', (chunk) => actual += chunk); 83 pushStream.on('end', common.mustCall(() => { 84 assert.strictEqual(actual, pushExpect); 85 maybeClose(); 86 })); 87 })); 88 89 req.on('response', common.mustCall((headers) => { 90 assert.strictEqual(headers[':status'], 200); 91 assert(headers.date); 92 })); 93 94 let actual = ''; 95 req.setEncoding('utf8'); 96 req.on('data', (chunk) => actual += chunk); 97 req.on('end', common.mustCall(() => { 98 assert.strictEqual(actual, servExpect); 99 maybeClose(); 100 })); 101 })); 102})); 103