]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/http.c
avformat/hlsenc: move the segment files handler close to before temp flags process
[ffmpeg] / libavformat / http.c
index 13f3be42271095425a837deaf75ab522572b4a28..293a8a720437e1743ec658ca249248daf3263828 100644 (file)
@@ -1011,6 +1011,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     int len = 0;
     const char *method;
     int send_expect_100 = 0;
+    int ret;
 
     /* send http header */
     post = h->flags & AVIO_FLAG_WRITE;
@@ -1107,7 +1108,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     if (s->headers)
         av_strlcpy(headers + len, s->headers, sizeof(headers) - len);
 
-    snprintf(s->buffer, sizeof(s->buffer),
+    ret = snprintf(s->buffer, sizeof(s->buffer),
              "%s %s HTTP/1.1\r\n"
              "%s"
              "%s"
@@ -1123,6 +1124,14 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
 
     av_log(h, AV_LOG_DEBUG, "request: %s\n", s->buffer);
 
+    if (strlen(headers) + 1 == sizeof(headers) ||
+        ret >= sizeof(s->buffer)) {
+        av_log(h, AV_LOG_ERROR, "overlong headers\n");
+        err = AVERROR(EINVAL);
+        goto done;
+    }
+
+
     if ((err = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
         goto done;
 
@@ -1168,6 +1177,34 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
 {
     HTTPContext *s = h->priv_data;
     int len;
+
+    if (s->chunksize != UINT64_MAX) {
+        if (!s->chunksize) {
+            char line[32];
+            int err;
+
+            do {
+                if ((err = http_get_line(s, line, sizeof(line))) < 0)
+                    return err;
+            } while (!*line);    /* skip CR LF from last chunk */
+
+            s->chunksize = strtoull(line, NULL, 16);
+
+            av_log(h, AV_LOG_TRACE,
+                   "Chunked encoding data size: %"PRIu64"'\n",
+                    s->chunksize);
+
+            if (!s->chunksize)
+                return 0;
+            else if (s->chunksize == UINT64_MAX) {
+                av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",
+                       s->chunksize);
+                return AVERROR(EINVAL);
+            }
+        }
+        size = FFMIN(size, s->chunksize);
+    }
+
     /* read bytes from input buffer first */
     len = s->buf_end - s->buf_ptr;
     if (len > 0) {
@@ -1190,8 +1227,10 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
     }
     if (len > 0) {
         s->off += len;
-        if (s->chunksize > 0)
+        if (s->chunksize > 0) {
+            av_assert0(s->chunksize >= len);
             s->chunksize -= len;
+        }
     }
     return len;
 }
@@ -1246,31 +1285,6 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size)
             return err;
     }
 
-    if (s->chunksize != UINT64_MAX) {
-        if (!s->chunksize) {
-            char line[32];
-
-                do {
-                    if ((err = http_get_line(s, line, sizeof(line))) < 0)
-                        return err;
-                } while (!*line);    /* skip CR LF from last chunk */
-
-                s->chunksize = strtoull(line, NULL, 16);
-
-                av_log(h, AV_LOG_TRACE,
-                       "Chunked encoding data size: %"PRIu64"'\n",
-                        s->chunksize);
-
-                if (!s->chunksize)
-                    return 0;
-                else if (s->chunksize == UINT64_MAX) {
-                    av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",
-                           s->chunksize);
-                    return AVERROR(EINVAL);
-                }
-        }
-        size = FFMIN(size, s->chunksize);
-    }
 #if CONFIG_ZLIB
     if (s->compressed)
         return http_buf_read_compressed(h, buf, size);
@@ -1519,6 +1533,12 @@ static int http_get_file_handle(URLContext *h)
     return ffurl_get_file_handle(s->hd);
 }
 
+static int http_get_short_seek(URLContext *h)
+{
+    HTTPContext *s = h->priv_data;
+    return ffurl_get_short_seek(s->hd);
+}
+
 #define HTTP_CLASS(flavor)                          \
 static const AVClass flavor ## _context_class = {   \
     .class_name = # flavor,                         \
@@ -1540,6 +1560,7 @@ const URLProtocol ff_http_protocol = {
     .url_seek            = http_seek,
     .url_close           = http_close,
     .url_get_file_handle = http_get_file_handle,
+    .url_get_short_seek  = http_get_short_seek,
     .url_shutdown        = http_shutdown,
     .priv_data_size      = sizeof(HTTPContext),
     .priv_data_class     = &http_context_class,
@@ -1559,6 +1580,7 @@ const URLProtocol ff_https_protocol = {
     .url_seek            = http_seek,
     .url_close           = http_close,
     .url_get_file_handle = http_get_file_handle,
+    .url_get_short_seek  = http_get_short_seek,
     .url_shutdown        = http_shutdown,
     .priv_data_size      = sizeof(HTTPContext),
     .priv_data_class     = &https_context_class,