From 1ee309f247e737962a95868ac025600c77f328c3 Mon Sep 17 00:00:00 2001
From: Maxim Razin <maxim.razin@rumble.com>
Date: Fri, 8 Dec 2023 12:50:50 -0500
Subject: [PATCH] libavformat: Verify HTTP reply headers on POST/PUT
Verify HTTP code when the reply headers arrived during POST/PUT.
The check is done before each write, and at shutdown, whenever the headers arrive.
Fixes https://trac.ffmpeg.org/ticket/10721
---
libavformat/http.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/libavformat/http.c b/libavformat/http.c
index c0fe7c36d9..067034b430 100644
|
a
|
b
|
|
| 21 | 21 | |
| 22 | 22 | #include "config.h" |
| 23 | 23 | #include "config_components.h" |
| | 24 | #include "os_support.h" |
| 24 | 25 | |
| 25 | 26 | #include <time.h> |
| 26 | 27 | #if CONFIG_ZLIB |
| … |
… |
static int http_read(URLContext *h, uint8_t *buf, int size)
|
| 1816 | 1817 | return size; |
| 1817 | 1818 | } |
| 1818 | 1819 | |
| | 1820 | static int http_check_header_available(HTTPContext *s) { |
| | 1821 | int fd; |
| | 1822 | if (s->line_count > 0) { |
| | 1823 | /* already received input headers */ |
| | 1824 | return 0; |
| | 1825 | } |
| | 1826 | fd = ffurl_get_file_handle(s->hd); |
| | 1827 | if (fd < 0) |
| | 1828 | return AVERROR(EIO); |
| | 1829 | struct pollfd p = { .fd = fd, .events = POLLIN }; |
| | 1830 | int ret = poll(&p, 1, 0); |
| | 1831 | if (ret < 0) |
| | 1832 | return AVERROR(errno); |
| | 1833 | if (p.revents & POLLIN) return 1; |
| | 1834 | return 0; |
| | 1835 | } |
| | 1836 | |
| 1819 | 1837 | /* used only when posting data */ |
| 1820 | 1838 | static int http_write(URLContext *h, const uint8_t *buf, int size) |
| 1821 | 1839 | { |
| … |
… |
static int http_write(URLContext *h, const uint8_t *buf, int size)
|
| 1824 | 1842 | char crlf[] = "\r\n"; |
| 1825 | 1843 | HTTPContext *s = h->priv_data; |
| 1826 | 1844 | |
| | 1845 | ret = http_check_header_available(s); |
| | 1846 | if (ret < 0) |
| | 1847 | return ret; |
| | 1848 | if (ret > 0) { |
| | 1849 | av_log(h, AV_LOG_WARNING, "Received reply header, likely server reported error.\n"); |
| | 1850 | ret = http_read_header(h); |
| | 1851 | if (ret < 0) |
| | 1852 | return ret; |
| | 1853 | } |
| | 1854 | |
| 1827 | 1855 | if (!s->chunked_post) { |
| 1828 | 1856 | /* non-chunked data is sent without any special encoding */ |
| 1829 | 1857 | return ffurl_write(s->hd, buf, size); |
| … |
… |
static int http_shutdown(URLContext *h, int flags)
|
| 1868 | 1896 | } |
| 1869 | 1897 | s->end_chunked_post = 1; |
| 1870 | 1898 | } |
| | 1899 | if (ret < 0) |
| | 1900 | return ret; |
| | 1901 | |
| | 1902 | if ((flags & AVIO_FLAG_WRITE) && s->line_count == 0) { |
| | 1903 | av_log(h, AV_LOG_TRACE, "Analyzing reply header after transmission finished.\n"); |
| | 1904 | ret = http_read_header(h); |
| | 1905 | } |
| 1871 | 1906 | |
| 1872 | 1907 | return ret; |
| 1873 | 1908 | } |