Skip to content

Fails to retrieve the first piece of data when downloading partial content with RetryAgent #2986

@vitalygashkov

Description

@vitalygashkov

Bug Description

When trying to download the file in parts (using RetryAgent), the download of the first part (when first byte of range is equal to zero) fails due to a content-range mismatch error inside RetryHandler onHeaders method.

Reproducible By

Here's a simple example of reproducing the issue:

const { setGlobalDispatcher, RetryAgent, Agent, request } = require('undici');

setGlobalDispatcher(new RetryAgent(new Agent()));

const start = 0;
const end = 26664011;
const size = end - start + 1;
const url =
  'https://cdn.bitmovin.com/content/assets/art-of-motion-dash-hls-progressive/MI201109210084_mpeg-4_hd_high_1080p25_10mbits.mp4';
const options = { headers: { Range: `bytes=${start}-${end}` } };

request(url, options)
  .then((response) => {
    const contentLength = Number(response.headers['content-length']);
    console.log(contentLength === size);
  })
  .catch((e) => {
    console.log(e.message === 'content-range mismatch'); // true
  });

Expected Behavior

I expect the request to successfully execute and return the first piece of data. If you remove RetryAgent from the code example above, the request will succeed:

const { setGlobalDispatcher, Agent, request } = require('undici');

setGlobalDispatcher(new Agent());

const start = 0;
const end = 26664011;
const size = end - start + 1;
const url =
  'https://cdn.bitmovin.com/content/assets/art-of-motion-dash-hls-progressive/MI201109210084_mpeg-4_hd_high_1080p25_10mbits.mp4';
const options = { headers: { Range: `bytes=${start}-${end}` } };

request(url, options)
  .then((response) => {
    const contentLength = Number(response.headers['content-length']);
    console.log(contentLength === size); // true
  })
  .catch((e) => {
    console.log(e.message === 'content-range mismatch');
  });

Logs & Screenshots

AssertionError [ERR_ASSERTION]: content-range mismatch
    at RetryHandler.onHeaders (/Users/user/project/node_modules/undici/lib/handler/retry-handler.js:248:9)
    at Request.onHeaders (/Users/user/project/node_modules/undici/lib/core/request.js:243:29)
    at Parser.onHeadersComplete (/Users/user/project/node_modules/undici/lib/dispatcher/client-h1.js:507:27)
    at wasm_on_headers_complete (/Users/user/project/node_modules/undici/lib/dispatcher/client-h1.js:121:30)
    at wasm://wasm/0003626a:wasm-function[11]:0x494
    at wasm://wasm/0003626a:wasm-function[51]:0x1003
    at wasm://wasm/0003626a:wasm-function[68]:0x6e8e
    at wasm://wasm/0003626a:wasm-function[67]:0x1568
    at wasm://wasm/0003626a:wasm-function[21]:0x552
    at Parser.execute (/Users/user/project/node_modules/undici/lib/dispatcher/client-h1.js:262:22) {
  generatedMessage: false,
  code: 'ERR_ASSERTION',
  actual: false,
  expected: true,
  operator: '=='
}

Environment

macOS Sonoma 14.3.1 (23D60)
Node v20.11.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions