11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// Tests the ability to minimally request a byte range with respondWithFD
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ciif (!common.hasCrypto)
71cb0ef41Sopenharmony_ci  common.skip('missing crypto');
81cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
91cb0ef41Sopenharmony_ciconst http2 = require('http2');
101cb0ef41Sopenharmony_ciconst assert = require('assert');
111cb0ef41Sopenharmony_ciconst fs = require('fs');
121cb0ef41Sopenharmony_ciconst Countdown = require('../common/countdown');
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst {
151cb0ef41Sopenharmony_ci  HTTP2_HEADER_CONTENT_TYPE,
161cb0ef41Sopenharmony_ci  HTTP2_HEADER_CONTENT_LENGTH
171cb0ef41Sopenharmony_ci} = http2.constants;
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciconst fname = fixtures.path('printA.js');
201cb0ef41Sopenharmony_ciconst data = fs.readFileSync(fname);
211cb0ef41Sopenharmony_ciconst fd = fs.openSync(fname, 'r');
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci// Note: this is not anywhere close to a proper implementation of the range
241cb0ef41Sopenharmony_ci// header.
251cb0ef41Sopenharmony_cifunction getOffsetLength(range) {
261cb0ef41Sopenharmony_ci  if (range === undefined)
271cb0ef41Sopenharmony_ci    return [0, -1];
281cb0ef41Sopenharmony_ci  const r = /bytes=(\d+)-(\d+)/.exec(range);
291cb0ef41Sopenharmony_ci  return [+r[1], +r[2] - +r[1]];
301cb0ef41Sopenharmony_ci}
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ciconst server = http2.createServer();
331cb0ef41Sopenharmony_ciserver.on('stream', (stream, headers) => {
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  const [ offset, length ] = getOffsetLength(headers.range);
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  stream.respondWithFD(fd, {
381cb0ef41Sopenharmony_ci    [HTTP2_HEADER_CONTENT_TYPE]: 'text/plain'
391cb0ef41Sopenharmony_ci  }, {
401cb0ef41Sopenharmony_ci    statCheck: common.mustCall((stat, headers, options) => {
411cb0ef41Sopenharmony_ci      assert.strictEqual(options.length, length);
421cb0ef41Sopenharmony_ci      assert.strictEqual(options.offset, offset);
431cb0ef41Sopenharmony_ci      headers['content-length'] =
441cb0ef41Sopenharmony_ci        Math.min(options.length, stat.size - offset);
451cb0ef41Sopenharmony_ci    }),
461cb0ef41Sopenharmony_ci    offset: offset,
471cb0ef41Sopenharmony_ci    length: length
481cb0ef41Sopenharmony_ci  });
491cb0ef41Sopenharmony_ci});
501cb0ef41Sopenharmony_ciserver.on('close', common.mustCall(() => fs.closeSync(fd)));
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ciserver.listen(0, () => {
531cb0ef41Sopenharmony_ci  const client = http2.connect(`http://localhost:${server.address().port}`);
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  const countdown = new Countdown(2, () => {
561cb0ef41Sopenharmony_ci    client.close();
571cb0ef41Sopenharmony_ci    server.close();
581cb0ef41Sopenharmony_ci  });
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  {
611cb0ef41Sopenharmony_ci    const req = client.request({ range: 'bytes=8-11' });
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci    req.on('response', common.mustCall((headers) => {
641cb0ef41Sopenharmony_ci      assert.strictEqual(headers['content-type'], 'text/plain');
651cb0ef41Sopenharmony_ci      assert.strictEqual(+headers['content-length'], 3);
661cb0ef41Sopenharmony_ci    }));
671cb0ef41Sopenharmony_ci    req.setEncoding('utf8');
681cb0ef41Sopenharmony_ci    let check = '';
691cb0ef41Sopenharmony_ci    req.on('data', (chunk) => check += chunk);
701cb0ef41Sopenharmony_ci    req.on('end', common.mustCall(() => {
711cb0ef41Sopenharmony_ci      assert.strictEqual(check, data.toString('utf8', 8, 11));
721cb0ef41Sopenharmony_ci    }));
731cb0ef41Sopenharmony_ci    req.on('close', common.mustCall(() => countdown.dec()));
741cb0ef41Sopenharmony_ci    req.end();
751cb0ef41Sopenharmony_ci  }
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  {
781cb0ef41Sopenharmony_ci    const req = client.request({ range: 'bytes=8-28' });
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci    req.on('response', common.mustCall((headers) => {
811cb0ef41Sopenharmony_ci      assert.strictEqual(headers[HTTP2_HEADER_CONTENT_TYPE], 'text/plain');
821cb0ef41Sopenharmony_ci      assert.strictEqual(+headers[HTTP2_HEADER_CONTENT_LENGTH], 9);
831cb0ef41Sopenharmony_ci    }));
841cb0ef41Sopenharmony_ci    req.setEncoding('utf8');
851cb0ef41Sopenharmony_ci    let check = '';
861cb0ef41Sopenharmony_ci    req.on('data', (chunk) => check += chunk);
871cb0ef41Sopenharmony_ci    req.on('end', common.mustCall(() => {
881cb0ef41Sopenharmony_ci      assert.strictEqual(check, data.toString('utf8', 8, 28));
891cb0ef41Sopenharmony_ci    }));
901cb0ef41Sopenharmony_ci    req.on('close', common.mustCall(() => countdown.dec()));
911cb0ef41Sopenharmony_ci    req.end();
921cb0ef41Sopenharmony_ci  }
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci});
95