[FFmpeg-devel,v2,1/1] avformat/http: flushing tcp receive buffer when it is write only mode

Submitted by Dixit, Vishwanath on April 4, 2018, 11:08 a.m.

Details

Message ID 1522840098-27481-1-git-send-email-vdixit@akamai.com
State Accepted
Commit 30940be3593aee6144a9d238f25eef1aa4575c41
Headers show

Commit Message

Dixit, Vishwanath April 4, 2018, 11:08 a.m.
From: Vishwanath Dixit <vdixit@akamai.com>

In write only mode, the TCP receive buffer's data keeps growing with
http response messages and the buffer eventually becomes full.
This results in zero tcp window size, which in turn causes unwanted
issues, like, terminated tcp connection. The issue is apparent when
http persistent connection is enabled in hls/dash live streaming use
cases. To overcome this issue, the logic here reads the buffer data
when a file transfer is completed, so that any accumulated data in
the recieve buffer gets flushed out.
---
 libavformat/http.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Steven Liu April 4, 2018, 11:50 a.m.
> On 4 Apr 2018, at 19:08, vdixit@akamai.com wrote:
> 
> From: Vishwanath Dixit <vdixit@akamai.com>
> 
> In write only mode, the TCP receive buffer's data keeps growing with
> http response messages and the buffer eventually becomes full.
> This results in zero tcp window size, which in turn causes unwanted
> issues, like, terminated tcp connection. The issue is apparent when
> http persistent connection is enabled in hls/dash live streaming use
> cases. To overcome this issue, the logic here reads the buffer data
> when a file transfer is completed, so that any accumulated data in
> the recieve buffer gets flushed out.
> ---
> libavformat/http.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
> 
> diff --git a/libavformat/http.c b/libavformat/http.c
> index 983034f..0c39e9c 100644
> --- a/libavformat/http.c
> +++ b/libavformat/http.c
> @@ -1627,6 +1627,18 @@ static int http_shutdown(URLContext *h, int flags)
>         ((flags & AVIO_FLAG_READ) && s->chunked_post && s->listen)) {
>         ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
>         ret = ret > 0 ? 0 : ret;
> +        /* flush the receive buffer when it is write only mode */
> +        if (!(flags & AVIO_FLAG_READ)) {
> +            char buf[1024];
> +            int read_ret;
> +            s->hd->flags |= AVIO_FLAG_NONBLOCK;
> +            read_ret = ffurl_read(s->hd, buf, sizeof(buf));
> +            s->hd->flags &= ~AVIO_FLAG_NONBLOCK;
> +            if (read_ret < 0 && read_ret != AVERROR(EAGAIN)) {
> +                av_log(h, AV_LOG_ERROR, "URL read error:  %d\n", read_ret);
> +                ret = read_ret;
> +            }
> +        }
>         s->end_chunked_post = 1;
>     }
> 
> -- 
> 1.9.1
> 

LGTM, but i cannot sure the buf and read_ret define in the paragraph is a good style.

Thanks
Steven
kjeyapal@akamai.com April 20, 2018, 6:40 a.m.
´╗┐On 4/4/18, 4:38 PM, "vdixit@akamai.com" <vdixit@akamai.com> wrote:
>

>From: Vishwanath Dixit <vdixit@akamai.com>

>

>In write only mode, the TCP receive buffer's data keeps growing with

>http response messages and the buffer eventually becomes full.

>This results in zero tcp window size, which in turn causes unwanted

>issues, like, terminated tcp connection. The issue is apparent when

>http persistent connection is enabled in hls/dash live streaming use

>cases. To overcome this issue, the logic here reads the buffer data

>when a file transfer is completed, so that any accumulated data in

>the recieve buffer gets flushed out.

>---

> libavformat/http.c | 12 ++++++++++++

> 1 file changed, 12 insertions(+)

>

>diff --git a/libavformat/http.c b/libavformat/http.c

>index 983034f..0c39e9c 100644

>--- a/libavformat/http.c

>+++ b/libavformat/http.c

>@@ -1627,6 +1627,18 @@ static int http_shutdown(URLContext *h, int flags)

>         ((flags & AVIO_FLAG_READ) && s->chunked_post && s->listen)) {

>         ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);

>         ret = ret > 0 ? 0 : ret;

>+        /* flush the receive buffer when it is write only mode */

>+        if (!(flags & AVIO_FLAG_READ)) {

>+            char buf[1024];

>+            int read_ret;

>+            s->hd->flags |= AVIO_FLAG_NONBLOCK;

>+            read_ret = ffurl_read(s->hd, buf, sizeof(buf));

>+            s->hd->flags &= ~AVIO_FLAG_NONBLOCK;

>+            if (read_ret < 0 && read_ret != AVERROR(EAGAIN)) {

>+                av_log(h, AV_LOG_ERROR, "URL read error:  %d\n", read_ret);

>+                ret = read_ret;

>+            }

>+        }

>         s->end_chunked_post = 1;

>     }

Pushed.

Patch hide | download patch | download mbox

diff --git a/libavformat/http.c b/libavformat/http.c
index 983034f..0c39e9c 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1627,6 +1627,18 @@  static int http_shutdown(URLContext *h, int flags)
         ((flags & AVIO_FLAG_READ) && s->chunked_post && s->listen)) {
         ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
         ret = ret > 0 ? 0 : ret;
+        /* flush the receive buffer when it is write only mode */
+        if (!(flags & AVIO_FLAG_READ)) {
+            char buf[1024];
+            int read_ret;
+            s->hd->flags |= AVIO_FLAG_NONBLOCK;
+            read_ret = ffurl_read(s->hd, buf, sizeof(buf));
+            s->hd->flags &= ~AVIO_FLAG_NONBLOCK;
+            if (read_ret < 0 && read_ret != AVERROR(EAGAIN)) {
+                av_log(h, AV_LOG_ERROR, "URL read error:  %d\n", read_ret);
+                ret = read_ret;
+            }
+        }
         s->end_chunked_post = 1;
     }