summaryrefslogtreecommitdiff
path: root/libavformat/http.c
diff options
context:
space:
mode:
authorTomas Härdin <Tomas.hardin@codemill.se>2010-01-12 16:36:00 +0000
committerRonald S. Bultje <rsbultje@gmail.com>2010-01-12 16:36:00 +0000
commit08f7a8ac327b284e784a00974faed7e5ae929061 (patch)
tree8cbb521c80b4a3e8602c785500669abbfc14b1c3 /libavformat/http.c
parent943f69a6eaf1cbd637e0d426900e88c876041d4d (diff)
Use chunked encoding for HTTP uploads. Patch by Tomas Härdin
<$firstname.$lastname()codemill,se>. Originally committed as revision 21166 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/http.c')
-rw-r--r--libavformat/http.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/libavformat/http.c b/libavformat/http.c
index 35eb89a1e5..d4e961331a 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -256,13 +256,15 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
"Host: %s\r\n"
"Authorization: Basic %s\r\n"
"Connection: close\r\n"
+ "%s"
"\r\n",
post ? "POST" : "GET",
path,
LIBAVFORMAT_IDENT,
s->off,
hoststr,
- auth_b64);
+ auth_b64,
+ post ? "Transfer-Encoding: chunked\r\n" : "");
av_freep(&auth_b64);
if (http_write(h, s->buffer, strlen(s->buffer)) < 0)
@@ -275,6 +277,8 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
s->off = 0;
s->filesize = -1;
if (post) {
+ /* always use chunked encoding for upload data */
+ s->chunksize = 0;
return 0;
}
@@ -344,16 +348,45 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
/* used only when posting data */
static int http_write(URLContext *h, uint8_t *buf, int size)
{
+ char temp[11]; /* 32-bit hex + CRLF + nul */
+ int ret;
+ char crlf[] = "\r\n";
HTTPContext *s = h->priv_data;
+
+ if (s->chunksize == -1) {
+ /* headers are sent without any special encoding */
return url_write(s->hd, buf, size);
+ }
+
+ /* silently ignore zero-size data since chunk encoding that would
+ * signal EOF */
+ if (size > 0) {
+ /* upload data using chunked encoding */
+ snprintf(temp, sizeof(temp), "%x\r\n", size);
+
+ if ((ret = url_write(s->hd, temp, strlen(temp))) < 0 ||
+ (ret = url_write(s->hd, buf, size)) < 0 ||
+ (ret = url_write(s->hd, crlf, sizeof(crlf) - 1)) < 0)
+ return ret;
+ }
+ return size;
}
static int http_close(URLContext *h)
{
+ int ret = 0;
+ char footer[] = "0\r\n\r\n";
HTTPContext *s = h->priv_data;
+
+ /* signal end of chunked encoding if used */
+ if ((h->flags & URL_WRONLY) && s->chunksize != -1) {
+ ret = url_write(s->hd, footer, sizeof(footer) - 1);
+ ret = ret > 0 ? 0 : ret;
+ }
+
url_close(s->hd);
av_free(s);
- return 0;
+ return ret;
}
static int64_t http_seek(URLContext *h, int64_t off, int whence)