Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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