--- ffserver.c | 77 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 27 deletions(-)
diff --git a/ffserver.c b/ffserver.c index 029771c..b7f9616 100644 --- a/ffserver.c +++ b/ffserver.c @@ -138,7 +138,7 @@ typedef struct HTTPContext { int http_error; int post; int chunked_encoding; - int chunk_size; /* 0 if it needs to be read */ + int chunk_size; /* 0 if it needs to be read; negative if reading chunk footer */ struct HTTPContext *next; int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */ int64_t data_count; @@ -2598,36 +2598,37 @@ static int http_receive_data(HTTPContext *c) { HTTPContext *c1; int len, loop_run = 0; + char buf[16]; + int buf_len = 0; + + if (c->chunked_encoding && c->chunk_size == 0) { + for (;;) { + /* read chunk header, if present */ + len = recv(c->fd, buf + buf_len, 1, 0); + buf_len += len; + + if (len < 0) { + if (ff_neterrno() != AVERROR(EAGAIN) && + ff_neterrno() != AVERROR(EINTR)) + /* error : close connection */ + goto fail; + return 0; + } - while (c->chunked_encoding && !c->chunk_size && - c->buffer_end > c->buffer_ptr) { - /* read chunk header, if present */ - len = recv(c->fd, c->buffer_ptr, 1, 0); - - if (len < 0) { - if (ff_neterrno() != AVERROR(EAGAIN) && - ff_neterrno() != AVERROR(EINTR)) - /* error : close connection */ + if (len == 0 || ++loop_run > 10) + /* end of connection or no chunk size : close it */ goto fail; - return 0; - } else if (len == 0) { - /* end of connection : close it */ - goto fail; - } else if (c->buffer_ptr - c->buffer >= 2 && - !memcmp(c->buffer_ptr - 1, "\r\n", 2)) { - c->chunk_size = strtol(c->buffer, 0, 16); - if (c->chunk_size == 0) // end of stream - goto fail; - c->buffer_ptr = c->buffer; - break; - } else if (++loop_run > 10) - /* no chunk header, abort */ - goto fail; - else - c->buffer_ptr++; + + if (buf_len > 1 && !memcmp(buf + buf_len - 2, "\r\n", 2)) { + c->chunk_size = strtol(buf, 0, 16); + if (c->chunk_size == 0) // end of stream + goto fail; + break; + } + } } - if (c->buffer_end > c->buffer_ptr) { + if (c->buffer_end > c->buffer_ptr && c->chunk_size > 0) { len = recv(c->fd, c->buffer_ptr, FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0); if (len < 0) { @@ -2644,6 +2645,28 @@ static int http_receive_data(HTTPContext *c) c->data_count += len; update_datarate(&c->datarate, c->data_count); } + + // Reading of chunk body is done. Now read 2 bytes of chunk footer. + if (!c->chunk_size) + c->chunk_size = -2; + } + + if (c->chunked_encoding && c->chunk_size < 0) { + while (c->chunk_size < 0) { + len = recv(c->fd, buf, 1, 0); + if (len < 0) { + if (ff_neterrno() != AVERROR(EAGAIN) && + ff_neterrno() != AVERROR(EINTR)) + /* error : close connection */ + goto fail; + return 0; + } + if (len == 0) { + goto fail; + } + + c->chunk_size += len; + } } if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) { -- 2.5.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel