Skip to content

avformat/libcurl: no error is ever retried when opening with offset > 0 (HLS byte-range segments, resumed opens) #73

Description

@ronag

Summary

http_error_is_recoverable() and curl_error_is_recoverable() both start with a guard meant for "mid-stream on a non-seekable resource":

    if (!c->seekable && c->request_start > 0 && !c->reconnect_streamed)
        return 0;

Before the first reply has been probed, c->seekable is still 0 (meaning "unknown") and c->request_start == offset. So every open with offset > 0 is classified as "non-seekable, already streaming", and nothing is retried: not 429/503 from the default reconnect_on_http_error list, and not recoverable curl errors. The main victims are HLS EXT-X-BYTERANGE segments, where hls.c passes offset/end_offset, and applications resuming a download with offset.

Location

  • static int http_error_is_recoverable(CurlContext *c, long http_status)
    {
    if (!c->reconnect_on_http_error || !http_status)
    return 0;
    if (!c->seekable && c->request_start > 0 && !c->reconnect_streamed)
    return 0;
  • static int curl_error_is_recoverable(CurlContext *c, CURLcode code)
    {
    if (!c->seekable && c->request_start > 0 && !c->reconnect_streamed)
    return 0;

Reproduction

Server answers the first request with 503 + Retry-After: 1, then 206 (harness from #71):

$ t libcurl:http://127.0.0.1:18080/once503ra-b offset=1000
open: -1482175992 (Server returned 5XX Server Error reply)

The server sees a single request (Range: bytes=1000-), so no retry was attempted. The same resource with offset=0 does enter the retry path (which then fails for the reason in #71).

Suggested fix

Only apply the guard once the resource has actually been probed: if (c->probed && !c->seekable && c->request_start > 0 && !c->reconnect_streamed). Alternatively, key it on "bytes already delivered to the caller" rather than on request_start.

Activity

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingfork-regressionRegression introduced by a fork-specific commitlibcurllibcurl-based HTTP(S) protocol (libavformat/libcurl.c)prio:medium

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions