470 Commits

Author SHA1 Message Date
Niklas Haas 71c01ff4f6 avformat/http: move ff_http_averror() to header
This is used by rtsp.c (and the upcoming libcurl.c) as well. Moving it to a
header prevents a link failure if http_protocol were to ever
become disabled.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-28 12:49:17 +02:00
Niklas Haas bf77674b3e avformat/http: use explicit AVERROR_ names for fixed error codes
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-28 12:48:23 +02:00
Niklas Haas ee2bc31032 avformat/http: imply keep-alive by default when beneficial
By turning it into a tristate that defaults to -1 (auto). Users can still
force a particular value for debugging.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-28 12:47:40 +02:00
Niklas Haas 1e1e95f1a2 avformat/http: make reconnection message less misleading
If using a keepalive connection, this does not actually reconnect.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-28 12:45:38 +02:00
Niklas Haas 2dbe4517f6 avformat/http: split request size determination to separate function
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-28 12:45:38 +02:00
Niklas Haas a53a9af6c8 avformat/http: organize HTTP context fields into sections (cosmetic)
This is a best-effort attempt at re-organizing these fields a bit to
make it more clear what's used where and why.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-28 12:45:38 +02:00
Niklas Haas e5a3c5e409 avformat/http: accept case-insensitive Connection header value
RFC 9110 defines this as case-insensitive, and some servers (e.g. MythTV)
send it as "Close" instead of "close".

See-Also: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/23222
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-25 15:50:43 +00:00
Niklas Haas bd51105806 avformat/http: infer default s->willclose based on request header
If we send `Connection: close` but don't get any response Connection header
back from the HTTP server, we should still assume the server will close our
connection.

There is a minor bit of ambiguity about what state to assume if the user
overrode the "Connection:" header, but I'm optimistically leaning in
favor of keep-alive as the more likely value for a user to set.

Not updating our internal state tracking as a result of user-provided
headers overriding our own headers is a prior problem with http.c that is
outside the scope of this PR to fix.

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-25 15:50:43 +00:00
Niklas Haas f87323a359 avformat/http: properly fall back on soft seek failure
If the HTTP server still has stale bytes in the TCP receive buffer, but
the underlying conection was already closed, then the http_open_cnx()
call might fail even though we successfully drained the previous request.

In this case, there is no proper fallback to a new connection, leading to
sudden truncation.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-23 20:33:00 +02:00
Niklas Haas 0d0f9a06ab avformat/http: only re-use old connection if valid
Otherwise, this might leak stale bytes that were already drained by the
HTTP soft-seek attempt.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-23 20:33:00 +02:00
Niklas Haas 62006041cc avformat/http: don't return EOF unless we actually read all bytes
Otherwise, this masquerades failure due to I/O as legitimate EOFs.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-23 20:33:00 +02:00
Niklas Haas 557ab6f2ab avformat/http: make short-seek logic more robust
This avoids an underflow if short_seek is negative (which can happen if e.g.
ffurl_get_short_seek() returns AVERROR(ENOSYS)), as well as a possible
underflow if the read position is somehow past `range_end` (e.g. if the HTTP
server malicously lied about the content range but gave us more bytes anyway)

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-23 20:33:00 +02:00
Niklas Haas 8712114200 avformat/http: properly re-set s->range_end before requests
Otherwise this could leak stale values from a previous response.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-23 20:33:00 +02:00
haoyuLiu dd9083cb89 avformat/http: reject request-line tokens not terminated by whitespace
Fixes out of array access

Found-by: Cloud-LHY (@Clouditera-lhy) / VulnForge Security Research Team
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-06-12 16:47:05 +00:00
Niklas Haas 7cb93fb200 avformat/http: return ENOSYS instead of UINT64_MAX for unknown filesize
This matches the behavior of e.g. the pipe: protocol, which returns ENOSYS
on account of ffurl_seek() not being implemented.

The previous behavior of returning s->filesize directly is almost surely a
bug, as s->filesize is UINT64_MAX when never initialized.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-06-04 17:48:12 +02:00
Andreas Rheinhardt 90dae166b5 avformat/http: Fix shadowing
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-03-10 13:52:18 +01:00
Niklas Haas 613925a96e avformat/http: fix Cache-Control header parsing
This was calling atoi() on `p + offset`, which is nonsense (p may point to
the start of the cache-control string, which does not necessarilly coincide
with the location of the max-age value). Based on the code, the intent
was clearly to parse the value *after* the matched substring.
2026-03-04 08:49:53 +00:00
Niklas Haas 7a348f662d avformat/http: close stale connection on wrong seek
If http_seek_internal() gives us an unexpected position, we should
close the connection to avoid leaking reading incorrect bytes on subsequent
reads.
2026-03-04 08:49:53 +00:00
Niklas Haas fcc1a03a0e avformat/http: move retry label (cosmetic)
Move this closer to the corresponding `goto`. From the PoV of the control
flow, these placements are completely identical.
2026-03-04 08:49:53 +00:00
Niklas Haas 142d999fda avformat/http: restore offset on http_open_cnx() failure
The retry path restores this offset, but the failure path does not. This
is especially important for the case of the continuation handler in
http_read_stream(), which may result in subsequent loop iterations (after
repeated failures to read additional data) seeking to the wrong offset.
2026-03-04 08:49:53 +00:00
Niklas Haas f5ddf1c4a8 avformat/http: fix http_connect() offset mismatch error code
This (arbitrarily) returns -1, which happens to be AVERROR(EPERM) on my
machine. Return the more descriptive AVERORR(EIO) instead.

Also add a log message to explain what's going on.
2026-03-04 08:49:53 +00:00
Niklas Haas fb7558dcb0 avformat/http: avoid int overflow
This was meant to accumulate int64_t timestamp values.

Fixes: b8daba42cd
2026-03-04 08:49:53 +00:00
Niklas Haas 2e7078cda6 avformat/http: add -request-size option
It has come to my attention that a way to limit the request range size
would be useful in general, for reasons beyond just speeding up initial
header parsing.

This patch generalizez -initial_request_size to -request_size. I decided
to continue allowing both options to be used simultaneously, so users can
e.g. set -request_size to something large like 10 MiB, but still use a smaller
size for initial header parsing (e.g. 256 KiB).

Fixes: https://github.com/mpv-player/mpv/issues/8655
2026-02-27 09:20:33 +00:00
Niklas Haas 4cefbc54c4 avformat/http: add missing check to connection re-use
Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21685
Fixes: e03b034e45
See-Also: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21693
2026-02-18 12:57:55 +00:00
Michael Niedermayer 82fbb04d07 avformat/http: Also count redirects from the cache
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-02-17 13:43:37 +00:00
Michael Niedermayer ba3639bc90 avformat/http: allow adjusting the redirect limit
Idea from: BapToutatis and also curl and wget have equivalent options

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-02-17 13:43:37 +00:00
Niklas Haas b8daba42cd avformat/http: report connection statistics
Helpful to track the impact of options like -multiple_requests, -probing_size
or -short_seek_size.
2026-02-07 10:02:36 +00:00
Niklas Haas 4f5d91e43f avformat/http: allow limiting initial request size
Sometimes, HTTP sources require a lot of seeking during probing / header
parsing (especially for formats like MXF). Currently, we need to completely
tear down and re-establish the connection most times this happens, which puts
a lot of stress on the network stack and also results in transmission of
possibly many unnecessary bytes.

This patch adds an option to allow FFmpeg to request partial ranges during
the initialization stage. This is done until the initial request size is fully
read, after which we fall back to the normal behavior (i.e. infinite streaming
via an unbounded request).

The usefulness of this is limited without also specifying -multiple_requests 1,
since otherwise there is little point to requesting partial ranges to begin
with. (However, it is semantically independent, so we keep it that way.)
2026-02-07 10:02:36 +00:00
Niklas Haas e03b034e45 avformat/http: re-use keep-alive connection for small seeks
When the previous reply was a partial response (e.g. due to a seek to the
end of the file), and the remaining data from that partial response is
below the short seek size threshold, we can serve this seek by just draining
that data and re-using the existing connection.

This can currently only happen when using keep-alive connections
(-multiple_requests 1) and seeking from the end of the file to somewhere
else, in which case the file's tail can be drained and the connection re-used.

Under other circumstances, however, we still need to force a reconnection,
because we do not yet send partial range requests. (This will be changed in the
following commit)

We need to take special care not to regress the existing fallback logic
for when `http_open_cnx` fails, so here is a quick case analysis:

non-drain path:
- identical to the current

soft drain fails: (ffurl_read error path)
- s->hd = old_hd = NULL
- http_open_cnx() always opens a new connection
- on failure, old buffer is restored and s->hd remains NULL

soft drain succeeds, http_open_cnx() fails:
- s->hd is set to NULL by http_open_cnx() failure path
- old_hd was never set, so remains NULL
- old buffer is restored, s->hd remains NULL

In either case, the outcome that any (previously valid) buffer is left as-is,
the offset is unchanged, and the connection ends up closed (s->hd == NULL).
This is okay to do after the previous change to http_buf_read, which allows
it to internally re-open the connection if needed.
2026-02-07 10:02:36 +00:00
Niklas Haas bf1722a9c6 avformat/http: request more data after partial response
If the Content-Range indicates a smaller range than what we expected,
we should send a new request for the remainder before attempting to read
more.

Again, this commit is theoretically non-functional on its own, since any
conforming HTTP server should give us the entire range we asked for in the
first place, but it is semantically independent from and prepares us for the
following changes.
2026-02-07 10:02:36 +00:00
Niklas Haas 6336fa3335 avformat/http: return EIO if s->hd is NULL
This could conceivably happen currently if the user tries reading more
bytes after the last chunk has already been received. In this case,
we currently segfault - but simply returning AVERROR(EIO) seems more
reasonable and lets the higher end retry the connection in this case.
2026-02-07 10:02:36 +00:00
Niklas Haas ca2c5ff412 avformat/http: parse range size from Content-Range header
In the event that the range returned is smaller than the true filesize, we
should only expect to receive that many bytes - not the entire rest of the
file.

This commit is theoretically non-functional on its own, since any conforming
HTTP server will always return us the full file range, but I wanted to split
it off from the subsequent changes in order to make review easier.
2026-02-07 10:02:36 +00:00
Niklas Haas 19cae9151c avformat/http: print error on HTTP response failure
This currently fails silently with zero indication of what the problem might
be, which tripped me up a bit while debugging.
2026-02-07 10:02:36 +00:00
Niklas Haas 5f95a1e714 avformat/http: fix noop seek check
This fails to consider the case of whence == SEEK_END and the resulting
offset happening to exactly match the current position.

Reorder the check to compute the target position first, then compare.
2026-02-07 10:02:36 +00:00
Michael Niedermayer 23c8123d5b avformat/http: Check white and blacklists on redirects
Noticed while fixing the previous

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-01-13 21:56:14 +00:00
Michael Niedermayer b9227d49ea avformat/http: Check that the protocol of redirects is http or https
Fixes: #YWH-PGM40646-10

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-01-13 21:56:14 +00:00
Andreas Rheinhardt 5d9270df7f libavutil/internal: Remove {SIZE,PTRDIFF}_SPECIFIER
Possible since 222127418b.

Reviewed-by: Kacper Michajłow <kasper93@gmail.com>
Reviewed-by: Lynne <dev@lynne.ee>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-12-03 11:52:54 +01:00
Michael Niedermayer b518c027a0 avformat/http: Fix off by 1 error
Fixes: out of array access
Fixes: zeropath/off-by-one-one-byte

Found-by: Joshua Rogers <joshua@joshua.hu>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2025-11-08 02:26:36 +01:00
Marvin Scholz 5cb6d2221a avformat/http: Handle IPv6 Zone ID in hostname
When using a literal IPv6 address as hostname, it can contain a Zone ID
especially in the case of link-local addresses. Sending this to the
server in the Host header is not useful to the server and in some cases
servers refuse such requests.

To prevent any such issues, strip the Zone ID from the address if it's
an IPv6 address. This also removes it for the Cookies lookup.

Based on a patch by: Daniel N Pettersson <danielnp@axis.com>
2025-09-24 12:03:13 +00:00
Timo Rothenpieler 262d41c804 all: fix typos found by codespell 2025-08-03 13:48:47 +02:00
Jack Lau 167e343bbe avformat/whip: Add WHIP muxer support for subsecond latency streaming
0. WHIP Version 3.
1. The WHIP muxer has been renamed and refined,
    with improved logging context and error messages for SSL, DTLS, and RTC.
2. Magic numbers have been replaced with macros and extracted to functions,
    and log levels have been altered for better clarity.
3. DTLS curve list has been updated,
    and SRTP profile names have been refined for FFmpeg and OpenSSL.
4. ICE STUN magic number has been refined,
    and RTP payload types have been updated based on Chrome's definition.
5. Fixed frame size has been refined to rtc->audio_par->frame_size,
    and h264_mp4toannexb is now used to convert MP4/ISOM to annexb.
6. OPUS timestamp issue has been addressed,
    and marker setting has been corrected after utilizing BSF.
7. DTLS handshake and ICE handling have been optimized for improved performance,
    with a single handshake timeout and server role to prevent ARQ.
8. Consolidated ICE request/response handling and DTLS handshake into a single function,
    and fixed OpenSSL build errors to work with Pion.
9. Merge TLS & DTLS implementation, shared BIO callbacks, read, write,
    print_ssl_error, openssl_init_ca_key_cert,
    init_bio_method function and shared same data structure
10. Modify configure that whip is enabled only dtls is
    enabled(just support openssl for now) to fix build error

Co-authored-by: winlin <winlinvip@gmail.com>
Co-authored-by: yangrtc <yangrtc@aliyun.com>
Co-authored-by: cloudwebrtc <duanweiwei1982@gmail.com>
Co-authored-by: Haibo Chen <495810242@qq.com>
Co-authored-by: Steven Liu <lq@chinaffmpeg.org>
Co-authored-by: Jun Zhao <barryjzhao@tencent.com>
Signed-off-by: Jack Lau <jacklau1222@qq.com>
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
2025-06-04 11:17:07 +08:00
Zhao Zhili 9187f40e92 avformat/http: Ensure same protocol in ff_http_do_new_request2
This can happen for HLS with AES-128 at the middle of m3u8, so old
protocol is https while new protocol is crypt+https.

And change the log level from ERROR to INFO when protocol/host/port
don't match. User should prepared for this function to fail and
retry with new connection.

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2025-04-29 15:25:46 +08:00
Ulrik 1306e5c7d3 avformat/http: Return EIO for prematurely broken connection
Currently, a prematurely broken connection normally leads to the same
EOF, as a completed successful transfer. However, enabling reconnect
changes this logic, and leads to the return of EIO.

This patch unifies that logic, leading to the return of EIO for premature
disconnect, regardless of setting of "reconnect".
2025-02-26 14:52:15 +01:00
Andreas Rheinhardt f3d206d25f fftools, avfilter, avformat: Simplify check for "is dictionary empty?"
Reviewed-by: epirat07@gmail.com
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-05-20 13:52:41 +02:00
Derek Buitenhuis 2d5fa816fb avformat/http: Add support for Retry-After header
429 and 503 codes can, and often do (e.g. all Google Cloud
Storage URLs can), return a Retry-After header with the error,
indicating how long to wait, asd either a date, or in seconds,
before retrying again. If it is not respected by, for example,
using our default backoff stratetgy instead, chances of success
are very unlikely.

Some references:
    * https://datatracker.ietf.org/doc/html/rfc6585
    * https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.3

This adds an AVOption to respect that header.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
2024-04-25 15:21:25 +01:00
Derek Buitenhuis 6d89fd4c27 avformat/http: Rename parse_set_cookie_expiry_time to parse_http_date
That is what it actually does, and it will be needed for more
than the Expiry header soon.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
2024-04-25 15:21:25 +01:00
Derek Buitenhuis 31de02cf31 avformat/http: Add option to limit total reconnect delay
The existing option only allows users to set the max delay for a
single attempt, rather than the total allowed delay, which is both
pretty unintitive, and only applicable when exponential backoff is
used.

The default for this option is set to 256, which is just above the
effective total delay accomplished by the the existing
reconnect_delay_max default of 120.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
2024-04-25 14:19:50 +01:00
Derek Buitenhuis 10374ab5ed avformat/http: Add options to set the max number of connection retries
Not every use case benefits from setting retries in terms of the backoff.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
2024-04-25 14:17:33 +01:00
Derek Buitenhuis a776d524e1 avformat/http: Rename attempts to auth_attempts
This accurately reflects what it does, as per
e75bbcf493.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
2024-04-25 14:15:32 +01:00
Derek Buitenhuis fa00624693 avformat/http: Don't bail on parsing headers on "bad" HTTP codes
Many "bad" HTTP codes like 429 and 503 may include important info in
their headers.

Also, in general, there is no purpose in bailing here.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
2024-04-25 14:15:08 +01:00