| 1708 | } |
| 1709 | |
| 1710 | static int http_buf_read(URLContext *h, uint8_t *buf, int size) |
| 1711 | { |
| 1712 | HTTPContext *s = h->priv_data; |
| 1713 | int len; |
| 1714 | |
| 1715 | if (!s->hd) |
| 1716 | return AVERROR(EIO); |
| 1717 | |
| 1718 | if (s->chunksize != UINT64_MAX) { |
| 1719 | if (s->chunkend) { |
| 1720 | return AVERROR_EOF; |
| 1721 | } |
| 1722 | if (!s->chunksize) { |
| 1723 | char line[32]; |
| 1724 | int err; |
| 1725 | |
| 1726 | do { |
| 1727 | if ((err = http_get_line(s, line, sizeof(line))) < 0) |
| 1728 | return err; |
| 1729 | } while (!*line); /* skip CR LF from last chunk */ |
| 1730 | |
| 1731 | s->chunksize = strtoull(line, NULL, 16); |
| 1732 | |
| 1733 | av_log(h, AV_LOG_TRACE, |
| 1734 | "Chunked encoding data size: %"PRIu64"\n", |
| 1735 | s->chunksize); |
| 1736 | |
| 1737 | if (!s->chunksize && s->multiple_requests) { |
| 1738 | http_get_line(s, line, sizeof(line)); // read empty chunk |
| 1739 | s->chunkend = 1; |
| 1740 | return 0; |
| 1741 | } |
| 1742 | else if (!s->chunksize) { |
| 1743 | av_log(h, AV_LOG_DEBUG, "Last chunk received, closing conn\n"); |
| 1744 | ffurl_closep(&s->hd); |
| 1745 | return 0; |
| 1746 | } |
| 1747 | else if (s->chunksize == UINT64_MAX) { |
| 1748 | av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n", |
| 1749 | s->chunksize); |
| 1750 | return AVERROR(EINVAL); |
| 1751 | } |
| 1752 | } |
| 1753 | size = FFMIN(size, s->chunksize); |
| 1754 | } |
| 1755 | |
| 1756 | /* read bytes from input buffer first */ |
| 1757 | len = s->buf_end - s->buf_ptr; |
| 1758 | if (len > 0) { |
| 1759 | if (len > size) |
| 1760 | len = size; |
| 1761 | memcpy(buf, s->buf_ptr, len); |
| 1762 | s->buf_ptr += len; |
| 1763 | } else { |
| 1764 | uint64_t file_end = s->end_off ? s->end_off : s->filesize; |
| 1765 | uint64_t target_end = s->range_end ? s->range_end : file_end; |
| 1766 | if ((!s->willclose || s->chunksize == UINT64_MAX) && s->off >= file_end) |
| 1767 | return AVERROR_EOF; |
no test coverage detected