Go to the documentation of this file.
   23 #include "config_components.h" 
   53 #define BUFFER_SIZE   (MAX_URL_SIZE + HTTP_HEADERS_SIZE) 
   54 #define MAX_REDIRECTS 8 
   55 #define MAX_CACHED_REDIRECTS 32 
   59 #define WHITESPACES " \n\t\r" 
  116     z_stream inflate_stream;
 
  117     uint8_t *inflate_buffer;
 
  142 #define OFFSET(x) offsetof(HTTPContext, x) 
  143 #define D AV_OPT_FLAG_DECODING_PARAM 
  144 #define E AV_OPT_FLAG_ENCODING_PARAM 
  145 #define DEFAULT_USER_AGENT "Lavf/" AV_STRINGIFY(LIBAVFORMAT_VERSION) 
  148     { 
"seekable", 
"control seekability of connection", 
OFFSET(seekable), 
AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, 
D },
 
  149     { 
"chunked_post", 
"use chunked transfer-encoding for posts", 
OFFSET(chunked_post), 
AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, 
E },
 
  155     { 
"multiple_requests", 
"use persistent connections", 
OFFSET(multiple_requests), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 
D | 
E },
 
  159     { 
"cookies", 
"set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", 
OFFSET(cookies), 
AV_OPT_TYPE_STRING, { .str = 
NULL }, 0, 0, 
D },
 
  165     { 
"none", 
"No auth method set, autodetect", 0, 
AV_OPT_TYPE_CONST, { .i64 = 
HTTP_AUTH_NONE }, 0, 0, 
D | 
E, 
"auth_type"},
 
  167     { 
"send_expect_100", 
"Force sending an Expect: 100-continue header for POST", 
OFFSET(send_expect_100), 
AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, 
E },
 
  170     { 
"end_offset", 
"try to limit the request to bytes preceding this offset", 
OFFSET(end_off), 
AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, 
D },
 
  171     { 
"method", 
"Override the HTTP method or set the expected HTTP method from a client", 
OFFSET(method), 
AV_OPT_TYPE_STRING, { .str = 
NULL }, 0, 0, 
D | 
E },
 
  172     { 
"reconnect", 
"auto reconnect after disconnect before EOF", 
OFFSET(reconnect), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 
D },
 
  173     { 
"reconnect_at_eof", 
"auto reconnect at EOF", 
OFFSET(reconnect_at_eof), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 
D },
 
  174     { 
"reconnect_on_network_error", 
"auto reconnect in case of tcp/tls error during connect", 
OFFSET(reconnect_on_network_error), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 
D },
 
  175     { 
"reconnect_on_http_error", 
"list of http status codes to reconnect on", 
OFFSET(reconnect_on_http_error), 
AV_OPT_TYPE_STRING, { .str = 
NULL }, 0, 0, 
D },
 
  176     { 
"reconnect_streamed", 
"auto reconnect streamed / non seekable streams", 
OFFSET(reconnect_streamed), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 
D },
 
  177     { 
"reconnect_delay_max", 
"max reconnect delay in seconds after which to give up", 
OFFSET(reconnect_delay_max), 
AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, 
D },
 
  180     { 
"reply_code", 
"The http status code to return to a client", 
OFFSET(reply_code), 
AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, 
E},
 
  181     { 
"short_seek_size", 
"Threshold to favor readahead over seek.", 
OFFSET(short_seek_size), 
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, 
D },
 
  186                         const char *hoststr, 
const char *auth,
 
  187                         const char *proxyauth);
 
  203     const char *path, *proxy_path, *lower_proto = 
"tcp", *local_path;
 
  204     char *env_http_proxy, *env_no_proxy;
 
  206     char hostname[1024], hoststr[1024], proto[10];
 
  207     char auth[1024], proxyauth[1024] = 
"";
 
  210     int port, use_proxy, err = 0;
 
  214                  hostname, 
sizeof(hostname), &port,
 
  215                  path1, 
sizeof(path1), 
s->location);
 
  219     proxy_path = 
s->http_proxy ? 
s->http_proxy : env_http_proxy;
 
  226     if (!strcmp(proto, 
"https")) {
 
  241     hashmark = strchr(path1, 
'#');
 
  245     if (path1[0] == 
'\0') {
 
  247     } 
else if (path1[0] == 
'?') {
 
  248         snprintf(sanitized_path, 
sizeof(sanitized_path), 
"/%s", path1);
 
  249         path = sanitized_path;
 
  261                      hostname, 
sizeof(hostname), &port, 
NULL, 0, proxy_path);
 
  269                                    h->protocol_whitelist, 
h->protocol_blacklist, 
h);
 
  275         h, path, local_path, hoststr, auth, proxyauth);
 
  280     const char *status_group;
 
  289         status_group = 
"4xx";
 
  293         status_group = 
"5xx";
 
  297         return s->reconnect_on_network_error;
 
  300     if (!
s->reconnect_on_http_error)
 
  303     if (
av_match_list(status_group, 
s->reconnect_on_http_error, 
',') > 0)
 
  306     snprintf(http_code, 
sizeof(http_code), 
"%d", 
s->http_code);
 
  308     return av_match_list(http_code, 
s->reconnect_on_http_error, 
',') > 0;
 
  322     delim = strchr(re->
value, 
';');
 
  328     if (time(
NULL) > expiry) {
 
  357     int ret, attempts = 0, redirects = 0;
 
  358     int reconnect_delay = 0;
 
  377     cur_auth_type       = 
s->auth_state.auth_type;
 
  378     cur_proxy_auth_type = 
s->auth_state.auth_type;
 
  384             reconnect_delay > 
s->reconnect_delay_max)
 
  391         reconnect_delay = 1 + 2 * reconnect_delay;
 
  401     if (
s->http_code == 401) {
 
  409     if (
s->http_code == 407) {
 
  410         if ((cur_proxy_auth_type == 
HTTP_AUTH_NONE || 
s->proxy_auth_state.stale) &&
 
  417     if ((
s->http_code == 301 || 
s->http_code == 302 ||
 
  418          s->http_code == 303 || 
s->http_code == 307 || 
s->http_code == 308) &&
 
  426             s->expires = (
s->http_code == 301 || 
s->http_code == 308) ? INT64_MAX : -1;
 
  434         s->location = 
s->new_location;
 
  435         s->new_location = 
NULL;
 
  439         memset(&
s->auth_state, 0, 
sizeof(
s->auth_state));
 
  462     char hostname1[1024], hostname2[1024], proto1[10], proto2[10];
 
  466         !(!strcmp(
h->prot->name, 
"http") ||
 
  467           !strcmp(
h->prot->name, 
"https")))
 
  471                  hostname1, 
sizeof(hostname1), &port1,
 
  472                  NULL, 0, 
s->location);
 
  474                  hostname2, 
sizeof(hostname2), &port2,
 
  476     if (port1 != port2 || strncmp(hostname1, hostname2, 
sizeof(hostname2)) != 0) {
 
  477         av_log(
h, 
AV_LOG_ERROR, 
"Cannot reuse HTTP connection for different host: %s:%d != %s:%d\n",
 
  484     if (!
s->end_chunked_post) {
 
  493     s->end_chunked_post = 0;
 
  496     s->icy_data_read = 0;
 
  519     switch (status_code) {
 
  526     if (status_code >= 400 && status_code <= 499)
 
  528     else if (status_code >= 500)
 
  531         return default_averror;
 
  536     int ret, 
body = 0, reply_code, message_len;
 
  537     const char *reply_text, *content_type;
 
  540     content_type = 
"text/plain";
 
  544     switch (status_code) {
 
  548         reply_text = 
"Bad Request";
 
  553         reply_text = 
"Forbidden";
 
  558         reply_text = 
"Not Found";
 
  563         content_type = 
s->content_type ? 
s->content_type : 
"application/octet-stream";
 
  568         reply_text = 
"Internal server error";
 
  576                  "HTTP/1.1 %03d %s\r\n" 
  577                  "Content-Type: %s\r\n" 
  585                  strlen(reply_text) + 6, 
 
  586                  s->headers ? 
s->headers : 
"",
 
  592                  "HTTP/1.1 %03d %s\r\n" 
  593                  "Content-Type: %s\r\n" 
  594                  "Transfer-Encoding: chunked\r\n" 
  600                  s->headers ? 
s->headers : 
"");
 
  654     char hostname[1024], proto[10];
 
  656     const char *lower_proto = 
"tcp";
 
  658     av_url_split(proto, 
sizeof(proto), 
NULL, 0, hostname, 
sizeof(hostname), &port,
 
  660     if (!strcmp(proto, 
"https"))
 
  662     ff_url_join(lower_url, 
sizeof(lower_url), lower_proto, 
NULL, hostname, port,
 
  668                                     h->protocol_whitelist, 
h->protocol_blacklist, 
h 
  688     if( 
s->seekable == 1 )
 
  693     s->filesize = UINT64_MAX;
 
  707         int len = strlen(
s->headers);
 
  708         if (
len < 2 || strcmp(
"\r\n", 
s->headers + 
len - 2)) {
 
  710                    "No trailing CRLF found in HTTP header. Adding it.\n");
 
  714             s->headers[
len]     = 
'\r';
 
  715             s->headers[
len + 1] = 
'\n';
 
  716             s->headers[
len + 2] = 
'\0';
 
  746     cc = (*c)->priv_data;
 
  762     if (
s->buf_ptr >= 
s->buf_end) {
 
  766         } 
else if (
len == 0) {
 
  769             s->buf_ptr = 
s->buffer;
 
  770             s->buf_end = 
s->buffer + 
len;
 
  773     return *
s->buf_ptr++;
 
  788             if (q > 
line && q[-1] == 
'\r')
 
  794             if ((q - 
line) < line_size - 1)
 
  805     if (http_code >= 400 && http_code < 600 &&
 
  807         (http_code != 407 || 
s->proxy_auth_state.auth_type != 
HTTP_AUTH_NONE)) {
 
  821     s->new_location = 
av_strdup(redirected_location);
 
  822     if (!
s->new_location)
 
  833     if (!strncmp(p, 
"bytes ", 6)) {
 
  835         s->off = strtoull(p, 
NULL, 10);
 
  836         if ((slash = strchr(p, 
'/')) && strlen(slash) > 0)
 
  837             s->filesize_from_content_range = strtoull(slash + 1, 
NULL, 10);
 
  839     if (
s->seekable == -1 && (!
s->is_akamai || 
s->filesize != 2147483647))
 
  851         inflateEnd(&
s->inflate_stream);
 
  852         if (inflateInit2(&
s->inflate_stream, 32 + 15) != Z_OK) {
 
  854                    s->inflate_stream.msg);
 
  857         if (zlibCompileFlags() & (1 << 17)) {
 
  859                    "Your zlib was compiled without gzip support.\n");
 
  864                "Compressed (%s) content, need zlib with gzip support\n", p);
 
  879     int len = 4 + strlen(p) + strlen(
tag);
 
  880     int is_first = !
s->icy_metadata_headers;
 
  885     if (
s->icy_metadata_headers)
 
  886         len += strlen(
s->icy_metadata_headers);
 
  892         *
s->icy_metadata_headers = 
'\0';
 
  906     for (
i = 0, j = 0; exp_str[
i] != 
'\0' && j < exp_buf_len; 
i++) {
 
  907         if ((exp_str[
i] >= 
'0' && exp_str[
i] <= 
'9') ||
 
  908             (exp_str[
i] >= 
'A' && exp_str[
i] <= 
'Z') ||
 
  909             (exp_str[
i] >= 
'a' && exp_str[
i] <= 
'z')) {
 
  910             exp_buf[j] = exp_str[
i];
 
  918     while ((*expiry < '0' || *expiry > 
'9') && *expiry != 
'\0')
 
  926     char *param, *next_param, *cstr, *back;
 
  927     char *saveptr = 
NULL;
 
  936     back = &cstr[strlen(cstr)-1];
 
  945     while ((param = 
av_strtok(next_param, 
";", &saveptr))) {
 
  973     if (!cookie_entry || !cookie_entry->
value) {
 
  980         struct tm new_tm = {0};
 
  992             if (e2 && e2->
value) {
 
  996                     if (e2 && e2->
value) {
 
  997                         struct tm old_tm = {0};
 
 1014     if (!(eql = strchr(p, 
'='))) 
return AVERROR(EINVAL);
 
 1034     if (*cookies) 
av_free(*cookies);
 
 1036     if (!*cookies) 
return AVERROR(ENOMEM);
 
 1086     char *
tag, *p, *end, *method, *resource, *
version;
 
 1090     if (
line[0] == 
'\0') {
 
 1096     if (line_count == 0) {
 
 1097         if (
s->is_connected_server) {
 
 1106                     av_log(
h, 
AV_LOG_ERROR, 
"Received and expected HTTP method do not match. (%s expected, %s received)\n",
 
 1115                            "(%s autodetected %s received)\n", auto_method, method);
 
 1148             while (*p != 
'/' && *p != 
'\0')
 
 1158             s->http_code = strtol(p, &end, 10);
 
 1166         while (*p != 
'\0' && *p != 
':')
 
 1180                    s->filesize == UINT64_MAX) {
 
 1181             s->filesize = strtoull(p, 
NULL, 10);
 
 1185                    !strncmp(p, 
"bytes", 5) &&
 
 1186                    s->seekable == -1) {
 
 1190             s->filesize  = UINT64_MAX;
 
 1199             if (!strcmp(p, 
"close"))
 
 1205                 s->is_mediagateway = 1;
 
 1214             s->icy_metaint = strtoull(p, 
NULL, 10);
 
 1244     char *cookie, *set_cookies, *next;
 
 1245     char *saveptr = 
NULL;
 
 1258     while ((cookie = 
av_strtok(next, 
"\n", &saveptr)) && !
ret) {
 
 1273         if (!cookie_entry || !cookie_entry->
value)
 
 1278             struct tm tm_buf = {0};
 
 1288             int domain_offset = strlen(domain) - strlen(e->
value);
 
 1289             if (domain_offset < 0)
 
 1306             char *
tmp = *cookies;
 
 1338     s->chunksize = UINT64_MAX;
 
 1339     s->filesize_from_content_range = UINT64_MAX;
 
 1356     if (
s->filesize_from_content_range != UINT64_MAX)
 
 1357         s->filesize = 
s->filesize_from_content_range;
 
 1359     if (
s->seekable == -1 && 
s->is_mediagateway && 
s->filesize == 2000000000)
 
 1378 #define NEEDS_ESCAPE(ch) \ 
 1379     ((ch) <= ' ' || (ch) >= '\x7f' || \ 
 1380      (ch) == '"' || (ch) == '%' || (ch) == '<' || (ch) == '>' || (ch) == '\\' || \ 
 1381      (ch) == '^' || (ch) == '`' || (ch) == '{' || (ch) == '}' || (ch) == '|') 
 1385         while (*path && q - buf < 
sizeof(buf) - 4) {
 
 1391                 q += 
snprintf(q, 4, 
"%%%02X", (uint8_t)*path++);
 
 1401                         const char *hoststr, 
const char *auth,
 
 1402                         const char *proxyauth)
 
 1407     char *authstr = 
NULL, *proxyauthstr = 
NULL;
 
 1408     uint64_t off = 
s->off;
 
 1410     int send_expect_100 = 0;
 
 1421         s->chunked_post = 0;
 
 1427         method = post ? 
"POST" : 
"GET";
 
 1430                                                 local_path, method);
 
 1432                                                 local_path, method);
 
 1434      if (post && !
s->post_data) {
 
 1435         if (
s->send_expect_100 != -1) {
 
 1436             send_expect_100 = 
s->send_expect_100;
 
 1438             send_expect_100 = 0;
 
 1443             if (auth && *auth &&
 
 1445                 s->http_code != 401)
 
 1446                 send_expect_100 = 1;
 
 1454     if (post && 
s->chunked_post)
 
 1455         av_bprintf(&request, 
"Transfer-Encoding: chunked\r\n");
 
 1458         av_bprintf(&request, 
"User-Agent: %s\r\n", 
s->user_agent);
 
 1462             av_bprintf(&request, 
"Referer: %s\r\n", 
s->referer);
 
 1469     if (!
has_header(
s->headers, 
"\r\nRange: ") && !post && (
s->off > 0 || 
s->end_off || 
s->seekable != 0)) {
 
 1470         av_bprintf(&request, 
"Range: bytes=%"PRIu64
"-", 
s->off);
 
 1475     if (send_expect_100 && !
has_header(
s->headers, 
"\r\nExpect: "))
 
 1476         av_bprintf(&request, 
"Expect: 100-continue\r\n");
 
 1479         av_bprintf(&request, 
"Connection: %s\r\n", 
s->multiple_requests ? 
"keep-alive" : 
"close");
 
 1482         av_bprintf(&request, 
"Host: %s\r\n", hoststr);
 
 1483     if (!
has_header(
s->headers, 
"\r\nContent-Length: ") && 
s->post_data)
 
 1484         av_bprintf(&request, 
"Content-Length: %d\r\n", 
s->post_datalen);
 
 1486     if (!
has_header(
s->headers, 
"\r\nContent-Type: ") && 
s->content_type)
 
 1487         av_bprintf(&request, 
"Content-Type: %s\r\n", 
s->content_type);
 
 1488     if (!
has_header(
s->headers, 
"\r\nCookie: ") && 
s->cookies) {
 
 1489         char *cookies = 
NULL;
 
 1490         if (!
get_cookies(
s, &cookies, path, hoststr) && cookies) {
 
 1491             av_bprintf(&request, 
"Cookie: %s\r\n", cookies);
 
 1495     if (!
has_header(
s->headers, 
"\r\nIcy-MetaData: ") && 
s->icy)
 
 1505         av_bprintf(&request, 
"Proxy-%s", proxyauthstr);
 
 1516     if ((err = 
ffurl_write(
s->hd, request.str, request.len)) < 0)
 
 1520         if ((err = 
ffurl_write(
s->hd, 
s->post_data, 
s->post_datalen)) < 0)
 
 1524     s->buf_ptr          = 
s->buffer;
 
 1525     s->buf_end          = 
s->buffer;
 
 1528     s->icy_data_read    = 0;
 
 1529     s->filesize         = UINT64_MAX;
 
 1531     s->end_chunked_post = 0;
 
 1536     if (post && !
s->post_data && !send_expect_100) {
 
 1550     if (
s->new_location)
 
 1553     err = (off == 
s->off) ? 0 : -1;
 
 1565     if (
s->chunksize != UINT64_MAX) {
 
 1569         if (!
s->chunksize) {
 
 1578             s->chunksize = strtoull(
line, 
NULL, 16);
 
 1581                    "Chunked encoding data size: %"PRIu64
"\n",
 
 1584             if (!
s->chunksize && 
s->multiple_requests) {
 
 1589             else if (!
s->chunksize) {
 
 1594             else if (
s->chunksize == UINT64_MAX) {
 
 1604     len = 
s->buf_end - 
s->buf_ptr;
 
 1608         memcpy(buf, 
s->buf_ptr, 
len);
 
 1611         uint64_t target_end = 
s->end_off ? 
s->end_off : 
s->filesize;
 
 1612         if ((!
s->willclose || 
s->chunksize == UINT64_MAX) && 
s->off >= target_end)
 
 1616             (!
s->willclose || 
s->chunksize == UINT64_MAX) && 
s->off < target_end) {
 
 1618                    "Stream ends prematurely at %"PRIu64
", should be %"PRIu64
"\n",
 
 1626         if (
s->chunksize > 0 && 
s->chunksize != UINT64_MAX) {
 
 1628             s->chunksize -= 
len;
 
 1635 #define DECOMPRESS_BUF_SIZE (256 * 1024) 
 1636 static int http_buf_read_compressed(
URLContext *
h, uint8_t *buf, 
int size)
 
 1641     if (!
s->inflate_buffer) {
 
 1642         s->inflate_buffer = 
av_malloc(DECOMPRESS_BUF_SIZE);
 
 1643         if (!
s->inflate_buffer)
 
 1647     if (
s->inflate_stream.avail_in == 0) {
 
 1651         s->inflate_stream.next_in  = 
s->inflate_buffer;
 
 1652         s->inflate_stream.avail_in = 
read;
 
 1655     s->inflate_stream.avail_out = 
size;
 
 1656     s->inflate_stream.next_out  = buf;
 
 1659     if (
ret != Z_OK && 
ret != Z_STREAM_END)
 
 1661                ret, 
s->inflate_stream.msg);
 
 1663     return size - 
s->inflate_stream.avail_out;
 
 1674     int reconnect_delay = 0;
 
 1679     if (
s->end_chunked_post && !
s->end_header) {
 
 1687         return http_buf_read_compressed(
h, buf, 
size);
 
 1690     while (read_ret < 0) {
 
 1691         uint64_t target = 
h->is_streamed ? 0 : 
s->off;
 
 1696         if (
h->is_streamed && !
s->reconnect_streamed)
 
 1699         if (!(
s->reconnect && 
s->filesize > 0 && 
s->off < 
s->filesize) &&
 
 1703         if (reconnect_delay > 
s->reconnect_delay_max)
 
 1708         if (err != 
AVERROR(ETIMEDOUT))
 
 1710         reconnect_delay = 1 + 2*reconnect_delay;
 
 1712         if (seek_ret >= 0 && seek_ret != target) {
 
 1750         end = strstr(
val, 
"';");
 
 1771     if (
s->icy_metaint < 
s->icy_data_read)
 
 1773     remaining = 
s->icy_metaint - 
s->icy_data_read;
 
 1785             char data[255 * 16 + 1];
 
 1796         s->icy_data_read = 0;
 
 1797         remaining        = 
s->icy_metaint;
 
 1807     if (
s->icy_metaint > 0) {
 
 1815         s->icy_data_read += 
size;
 
 1824     char crlf[] = 
"\r\n";
 
 1827     if (!
s->chunked_post) {
 
 1849     char footer[] = 
"0\r\n\r\n";
 
 1864             if (read_ret < 0 && read_ret != 
AVERROR(EAGAIN)) {
 
 1869         s->end_chunked_post = 1;
 
 1881     inflateEnd(&
s->inflate_stream);
 
 1885     if (
s->hd && !
s->end_chunked_post)
 
 1903     uint64_t old_off = 
s->off;
 
 1905     int old_buf_size, 
ret;
 
 1910     else if (!force_reconnect &&
 
 1911              ((whence == SEEK_CUR && off == 0) ||
 
 1912               (whence == SEEK_SET && off == 
s->off)))
 
 1914     else if ((
s->filesize == UINT64_MAX && whence == SEEK_END))
 
 1917     if (whence == SEEK_CUR)
 
 1919     else if (whence == SEEK_END)
 
 1921     else if (whence != SEEK_SET)
 
 1927     if (
s->off && 
h->is_streamed)
 
 1931     if (
s->end_off || 
s->filesize != UINT64_MAX) {
 
 1932         uint64_t end_pos = 
s->end_off ? 
s->end_off : 
s->filesize;
 
 1933         if (
s->off >= end_pos)
 
 1938     if (strcmp(
s->uri, 
s->location)) {
 
 1944         s->location = new_uri;
 
 1948     old_buf_size = 
s->buf_end - 
s->buf_ptr;
 
 1949     memcpy(old_buf, 
s->buf_ptr, old_buf_size);
 
 1955         memcpy(
s->buffer, old_buf, old_buf_size);
 
 1956         s->buf_ptr = 
s->buffer;
 
 1957         s->buf_end = 
s->buffer + old_buf_size;
 
 1981     if (
s->short_seek_size >= 1)
 
 1982         return s->short_seek_size;
 
 1986 #define HTTP_CLASS(flavor)                          \ 
 1987 static const AVClass flavor ## _context_class = {   \ 
 1988     .class_name = # flavor,                         \ 
 1989     .item_name  = av_default_item_name,             \ 
 1990     .option     = options,                          \ 
 1991     .version    = LIBAVUTIL_VERSION_INT,            \ 
 1994 #if CONFIG_HTTP_PROTOCOL 
 2010     .priv_data_class     = &http_context_class,
 
 2012     .default_whitelist   = 
"http,https,tls,rtp,tcp,udp,crypto,httpproxy,data" 
 2016 #if CONFIG_HTTPS_PROTOCOL 
 2030     .priv_data_class     = &https_context_class,
 
 2032     .default_whitelist   = 
"http,https,tls,rtp,tcp,udp,crypto,httpproxy" 
 2036 #if CONFIG_HTTPPROXY_PROTOCOL 
 2048     char hostname[1024], hoststr[1024];
 
 2049     char auth[1024], pathbuf[1024], *path;
 
 2050     char lower_url[100];
 
 2051     int port, 
ret = 0, attempts = 0;
 
 2055     if( 
s->seekable == 1 )
 
 2060     av_url_split(
NULL, 0, auth, 
sizeof(auth), hostname, 
sizeof(hostname), &port,
 
 2061                  pathbuf, 
sizeof(pathbuf), uri);
 
 2067     ff_url_join(lower_url, 
sizeof(lower_url), 
"tcp", 
NULL, hostname, port,
 
 2071                                &
h->interrupt_callback, 
NULL,
 
 2072                                h->protocol_whitelist, 
h->protocol_blacklist, 
h);
 
 2079              "CONNECT %s HTTP/1.1\r\n" 
 2081              "Connection: close\r\n" 
 2086              authstr ? 
"Proxy-" : 
"", authstr ? authstr : 
"");
 
 2092     s->buf_ptr    = 
s->buffer;
 
 2093     s->buf_end    = 
s->buffer;
 
 2095     s->filesize   = UINT64_MAX;
 
 2096     cur_auth_type = 
s->proxy_auth_state.auth_type;
 
 2112     if (
s->http_code == 407 &&
 
 2119     if (
s->http_code < 400)
 
 2124     http_proxy_close(
h);
 
 2128 static int http_proxy_write(
URLContext *
h, 
const uint8_t *buf, 
int size)
 
 2135     .
name                = 
"httpproxy",
 
 2136     .url_open            = http_proxy_open,
 
 2138     .url_write           = http_proxy_write,
 
 2139     .url_close           = http_proxy_close,
 
  
static char * redirect_cache_get(HTTPContext *s)
 
static void error(const char *err)
 
@ HTTP_AUTH_BASIC
HTTP 1.0 Basic auth from RFC 1945 (also in RFC 2617)
 
static av_const int av_isxdigit(int c)
Locale-independent conversion of ASCII isxdigit.
 
#define AV_LOG_WARNING
Something somehow does not look correct.
 
static int http_open_cnx(URLContext *h, AVDictionary **options)
 
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
 
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
 
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
 
#define AV_OPT_FLAG_READONLY
The option may not be set through the AVOptions API, only read.
 
static int http_write_reply(URLContext *h, int status_code)
 
#define URL_PROTOCOL_FLAG_NETWORK
 
#define AVERROR_HTTP_OTHER_4XX
 
static int parse_icy(HTTPContext *s, const char *tag, const char *p)
 
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
 
#define AVERROR_EOF
End of file.
 
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
 
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
 
static void bprint_escaped_path(AVBPrint *bp, const char *path)
Escape unsafe characters in path in order to pass them safely to the HTTP request.
 
static int http_listen(URLContext *h, const char *uri, int flags, AVDictionary **options)
 
char * av_asprintf(const char *fmt,...)
 
static int ffurl_write(URLContext *h, const uint8_t *buf, int size)
Write size bytes from buf to the resource accessed by h.
 
int seekable
Control seekability, 0 = disable, 1 = enable, -1 = probe.
 
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
 
static av_const int av_isspace(int c)
Locale-independent conversion of ASCII isspace.
 
static int http_read(URLContext *h, uint8_t *buf, int size)
 
static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect)
 
static void parse_cache_control(HTTPContext *s, const char *p)
 
#define AVERROR_HTTP_SERVER_ERROR
 
#define AVSEEK_SIZE
ORing this as the "whence" parameter to a seek function causes it to return the filesize without seek...
 
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
 
#define AV_LOG_VERBOSE
Detailed information.
 
static void freeenv_utf8(char *var)
 
static int http_get_line(HTTPContext *s, char *line, int line_size)
 
int ffurl_close(URLContext *h)
 
AVDictionary * chained_options
 
static int parse_location(HTTPContext *s, const char *p)
 
static int http_read_stream(URLContext *h, uint8_t *buf, int size)
 
char * ff_http_auth_create_response(HTTPAuthState *state, const char *auth, const char *path, const char *method)
 
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
 
const URLProtocol ff_httpproxy_protocol
 
#define AVERROR_HTTP_UNAUTHORIZED
 
static int get_cookies(HTTPContext *s, char **cookies, const char *path, const char *domain)
Create a string containing cookie values for use as a HTTP cookie header field value for a particular...
 
@ AV_OPT_TYPE_BINARY
offset must point to a pointer immediately followed by an int for the length
 
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
Init a print buffer using a pre-existing buffer.
 
int ffurl_get_short_seek(void *urlcontext)
Return the current short seek threshold value for this URL.
 
static int check_http_code(URLContext *h, int http_code, const char *end)
 
#define DEFAULT_USER_AGENT
 
static void inflate(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord, int maxc)
 
static int cookie_string(AVDictionary *dict, char **cookies)
 
static int has_header(const char *str, const char *header)
 
static int redirect_cache_set(HTTPContext *s, const char *source, const char *dest, int64_t expiry)
 
static double val(void *priv, double ch)
 
time_t av_timegm(struct tm *tm)
Convert the decomposed UTC time in tm to a time_t value.
 
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
 
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
 
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
 
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
 
#define AVERROR_HTTP_NOT_FOUND
 
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
 
int av_opt_set_dict(void *obj, AVDictionary **options)
Set all the options from a given dictionary on an object.
 
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist, URLContext *parent)
Create an URLContext for accessing to the resource indicated by url, and open it.
 
char * cookies
holds newline ( ) delimited Set-Cookie header field values (without the "Set-Cookie: " field name)
 
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
 
int ff_url_join(char *str, int size, const char *proto, const char *authorization, const char *hostname, int port, const char *fmt,...)
 
#define av_assert0(cond)
assert() equivalent, that is always enabled.
 
#define AVIO_FLAG_WRITE
write-only
 
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
 
static int process_line(URLContext *h, char *line, int line_count)
 
int reconnect_on_network_error
 
int av_stristart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str independent of case.
 
static int parse_cookie(HTTPContext *s, const char *p, AVDictionary **cookies)
 
int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
 
void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, const char *value)
 
static int parse_content_encoding(URLContext *h, const char *p)
 
static void handle_http_errors(URLContext *h, int error)
 
unsigned char buffer[BUFFER_SIZE]
 
int ff_http_do_new_request(URLContext *h, const char *uri)
Send a new HTTP request, reusing the old connection.
 
int ffurl_accept(URLContext *s, URLContext **c)
Accept an URLContext c on an URLContext s.
 
static int http_read_stream_all(URLContext *h, uint8_t *buf, int size)
 
Describe the class of an AVClass context structure.
 
static int http_get_short_seek(URLContext *h)
 
int av_match_list(const char *name, const char *list, char separator)
Check if a name is in a list.
 
void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
Initialize the authentication state based on another HTTP URLContext.
 
int ff_http_do_new_request2(URLContext *h, const char *uri, AVDictionary **opts)
Send a new HTTP request, reusing the old connection.
 
HTTPAuthState proxy_auth_state
 
static char * getenv_utf8(const char *varname)
 
static int http_buf_read(URLContext *h, uint8_t *buf, int size)
 
static int http_shutdown(URLContext *h, int flags)
 
static void parse_content_range(URLContext *h, const char *p)
 
#define AVERROR_HTTP_BAD_REQUEST
 
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
 
HTTP Authentication state structure.
 
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a source
 
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i http
 
int ff_http_averror(int status_code, int default_averror)
 
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
 
uint64_t filesize_from_content_range
 
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
 
static void parse_expires(HTTPContext *s, const char *p)
 
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
 
static int http_write(URLContext *h, const uint8_t *buf, int size)
 
static const uint8_t header[24]
 
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
 
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
 
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
 
char * icy_metadata_packet
 
const URLProtocol ff_http_protocol
 
static int parse_set_cookie_expiry_time(const char *exp_str, struct tm *buf)
 
#define AV_LOG_INFO
Standard information.
 
static void update_metadata(URLContext *h, char *data)
 
int ffurl_alloc(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb)
Create a URLContext for accessing to the resource indicated by url, but do not initiate the connectio...
 
static int http_should_reconnect(HTTPContext *s, int err)
 
static int http_handshake(URLContext *c)
 
@ HTTP_AUTH_NONE
No authentication specified.
 
static int http_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
 
#define i(width, name, range_min, range_max)
 
static int http_connect(URLContext *h, const char *path, const char *local_path, const char *hoststr, const char *auth, const char *proxyauth)
 
int ff_network_sleep_interruptible(int64_t timeout, AVIOInterruptCB *int_cb)
Waits for up to 'timeout' microseconds.
 
static int parse_set_cookie(const char *set_cookie, AVDictionary **dict)
 
static int64_t http_seek(URLContext *h, int64_t off, int whence)
 
static const AVOption options[]
 
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
 
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
 
static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
 
static int http_close(URLContext *h)
 
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
 
HandshakeState handshake_step
 
const URLProtocol ff_https_protocol
 
AVIOInterruptCB interrupt_callback
 
void av_bprintf(AVBPrint *buf, const char *fmt,...)
 
AVDictionary * cookie_dict
 
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
 
char * av_small_strptime(const char *p, const char *fmt, struct tm *dt)
Simplified version of strptime.
 
#define AV_OPT_FLAG_EXPORT
The option is intended for exporting values to the caller.
 
FFmpeg currently uses a custom build this text attempts to document some of its obscure features and options Makefile the full command issued by make and its output will be shown on the screen DBG Preprocess x86 external assembler files to a dbg asm file in the object which then gets compiled Helps in developing those assembler files DESTDIR Destination directory for the install useful to prepare packages or install FFmpeg in cross environments GEN Set to ‘1’ to generate the missing or mismatched references Makefile builds all the libraries and the executables fate Run the fate test note that you must have installed it fate list List all fate regression test targets install Install headers
 
static int http_read_header(URLContext *h)
 
char * av_get_token(const char **buf, const char *term)
Unescape the given string until a non escaped terminating char, and return the token corresponding to...
 
#define AVERROR_HTTP_FORBIDDEN
 
#define HTTP_CLASS(flavor)
 
static void body(uint32_t ABCD[4], const uint8_t *src, size_t nblocks)
 
static int http_get_file_handle(URLContext *h)
 
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the and we are assuming vf_foobar is as well We are also assuming vf_foobar is not an edge detector so you can update the boilerplate with your credits Doxy Next chunk is the Doxygen about the file See https
 
int64_t av_gettime(void)
Get the current time in microseconds.
 
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
 
HTTPAuthType
Authentication types, ordered from weakest to strongest.
 
#define AVIO_FLAG_READ
read-only
 
char * av_strdup(const char *s)
Duplicate a string.
 
int ffurl_handshake(URLContext *c)
Perform one step of the protocol handshake to accept a new client.
 
int ff_make_absolute_url(char *buf, int size, const char *base, const char *rel)
Convert a relative url into an absolute url, given a base url.
 
#define MAX_CACHED_REDIRECTS
 
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
 
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
 
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
 
static int http_getc(HTTPContext *s)
 
static int http_accept(URLContext *s, URLContext **c)
 
#define flags(name, subs,...)
 
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
 
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
 
char * icy_metadata_headers
 
char * av_strndup(const char *s, size_t len)
Duplicate a substring of a string.
 
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
 
AVDictionary * redirect_cache
 
static int store_icy(URLContext *h, int size)
 
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
 
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
 
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
 
static uint32_t BS_FUNC() read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
 
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
 
char * reconnect_on_http_error
 
static int ffurl_read(URLContext *h, uint8_t *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf.