Skip to content

avformat/libcurl: stalled transfers are never detected or retried #78

Description

@ronag

Summary

The only timeout libcurl.c configures is CURLOPT_CONNECTTIMEOUT_MS. It sets no CURLOPT_LOW_SPEED_LIMIT/CURLOPT_LOW_SPEED_TIME, and rw_timeout isn't mapped to anything curl knows about. So if a server or middlebox stops sending mid-body without closing the connection, the transfer stays open forever. CURLE_OPERATION_TIMEDOUT is in the recoverable list, but only a connect timeout can produce it, so the reconnect/retry machinery never runs for a stall.

Location

  • if (c->connect_timeout > 0)
    curl_easy_setopt(e, CURLOPT_CONNECTTIMEOUT_MS,
    (long)c->connect_timeout * 1000);
  • switch (code) {
    case CURLE_RECV_ERROR:
    case CURLE_SEND_ERROR:
    case CURLE_PARTIAL_FILE:
    case CURLE_OPERATION_TIMEDOUT:
    case CURLE_GOT_NOTHING:
    case CURLE_HTTP2:
    case CURLE_HTTP2_STREAM:
    return 1;

Reproduction

Server sends headers and 64 KiB of a 1 MiB body, then stalls without closing (harness from #71):

  • Default options: avio_read() blocks indefinitely (killed by timeout 8).
  • rw_timeout=2000000: avio gives up after ~2.7 s with a generic AVERROR(EIO) (total=65536 last=-5), and no reconnect is attempted (the server saw a single request).

Suggested fix

Map rw_timeout (or a dedicated option, e.g. stall_timeout, defaulting to something like 10–30 s) to CURLOPT_LOW_SPEED_LIMIT = 1 + CURLOPT_LOW_SPEED_TIME. A stall then surfaces as CURLE_OPERATION_TIMEDOUT in on_done() and goes through the existing retry path at the current logical_pos, with backoff and max_retries, instead of hanging or failing hard.

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 workinglibcurllibcurl-based HTTP(S) protocol (libavformat/libcurl.c)prio:mediumupstreamAlso present in upstream FFmpeg

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions