11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciif (!common.hasCrypto) 41cb0ef41Sopenharmony_ci common.skip('missing crypto'); 51cb0ef41Sopenharmony_ciconst assert = require('assert'); 61cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures'); 71cb0ef41Sopenharmony_ciconst http2 = require('http2'); 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci// This test assesses whether long-running writes can complete 101cb0ef41Sopenharmony_ci// or timeout because the session or stream are not aware that the 111cb0ef41Sopenharmony_ci// backing stream is still writing. 121cb0ef41Sopenharmony_ci// To simulate a slow client, we write a really large chunk and 131cb0ef41Sopenharmony_ci// then proceed through the following cycle: 141cb0ef41Sopenharmony_ci// 1) Receive first 'data' event and record currently written size 151cb0ef41Sopenharmony_ci// 2) Once we've read up to currently written size recorded above, 161cb0ef41Sopenharmony_ci// we pause the stream and wait longer than the server timeout 171cb0ef41Sopenharmony_ci// 3) Socket.prototype._onTimeout triggers and should confirm 181cb0ef41Sopenharmony_ci// that the backing stream is still active and writing 191cb0ef41Sopenharmony_ci// 4) Our timer fires, we resume the socket and start at 1) 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciconst writeSize = 3000000; 221cb0ef41Sopenharmony_ciconst minReadSize = 500000; 231cb0ef41Sopenharmony_ciconst serverTimeout = common.platformTimeout(500); 241cb0ef41Sopenharmony_cilet offsetTimeout = common.platformTimeout(100); 251cb0ef41Sopenharmony_cilet didReceiveData = false; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciconst server = http2.createSecureServer({ 281cb0ef41Sopenharmony_ci key: fixtures.readKey('agent1-key.pem'), 291cb0ef41Sopenharmony_ci cert: fixtures.readKey('agent1-cert.pem') 301cb0ef41Sopenharmony_ci}); 311cb0ef41Sopenharmony_ciserver.on('stream', common.mustCall((stream) => { 321cb0ef41Sopenharmony_ci const content = Buffer.alloc(writeSize, 0x44); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci stream.respond({ 351cb0ef41Sopenharmony_ci 'Content-Type': 'application/octet-stream', 361cb0ef41Sopenharmony_ci 'Content-Length': content.length.toString(), 371cb0ef41Sopenharmony_ci 'Vary': 'Accept-Encoding' 381cb0ef41Sopenharmony_ci }); 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci stream.write(content); 411cb0ef41Sopenharmony_ci stream.setTimeout(serverTimeout); 421cb0ef41Sopenharmony_ci stream.on('timeout', () => { 431cb0ef41Sopenharmony_ci assert.ok(!didReceiveData, 'Should not timeout'); 441cb0ef41Sopenharmony_ci }); 451cb0ef41Sopenharmony_ci stream.end(); 461cb0ef41Sopenharmony_ci})); 471cb0ef41Sopenharmony_ciserver.setTimeout(serverTimeout); 481cb0ef41Sopenharmony_ciserver.on('timeout', () => { 491cb0ef41Sopenharmony_ci assert.ok(!didReceiveData, 'Should not timeout'); 501cb0ef41Sopenharmony_ci}); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => { 531cb0ef41Sopenharmony_ci const client = http2.connect(`https://localhost:${server.address().port}`, 541cb0ef41Sopenharmony_ci { rejectUnauthorized: false }); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci const req = client.request({ ':path': '/' }); 571cb0ef41Sopenharmony_ci req.end(); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci const resume = () => req.resume(); 601cb0ef41Sopenharmony_ci let receivedBufferLength = 0; 611cb0ef41Sopenharmony_ci let firstReceivedAt; 621cb0ef41Sopenharmony_ci req.on('data', common.mustCallAtLeast((buf) => { 631cb0ef41Sopenharmony_ci if (receivedBufferLength === 0) { 641cb0ef41Sopenharmony_ci didReceiveData = false; 651cb0ef41Sopenharmony_ci firstReceivedAt = Date.now(); 661cb0ef41Sopenharmony_ci } 671cb0ef41Sopenharmony_ci receivedBufferLength += buf.length; 681cb0ef41Sopenharmony_ci if (receivedBufferLength >= minReadSize && 691cb0ef41Sopenharmony_ci receivedBufferLength < writeSize) { 701cb0ef41Sopenharmony_ci didReceiveData = true; 711cb0ef41Sopenharmony_ci receivedBufferLength = 0; 721cb0ef41Sopenharmony_ci req.pause(); 731cb0ef41Sopenharmony_ci setTimeout( 741cb0ef41Sopenharmony_ci resume, 751cb0ef41Sopenharmony_ci serverTimeout + offsetTimeout - (Date.now() - firstReceivedAt) 761cb0ef41Sopenharmony_ci ); 771cb0ef41Sopenharmony_ci offsetTimeout = 0; 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci }, 1)); 801cb0ef41Sopenharmony_ci req.on('end', common.mustCall(() => { 811cb0ef41Sopenharmony_ci client.close(); 821cb0ef41Sopenharmony_ci server.close(); 831cb0ef41Sopenharmony_ci })); 841cb0ef41Sopenharmony_ci})); 85