comparison http.c @ 5526:f09594ca5f77 libavformat

Use chunked encoding for HTTP uploads. Patch by Tomas H¸«£rdin <$firstname.$lastname()codemill,se>.
author rbultje
date Tue, 12 Jan 2010 16:36:00 +0000
parents a5b8b8cce2dd
children 2d0a0d3e5df1
comparison
equal deleted inserted replaced
5525:f484a964bed1 5526:f09594ca5f77
254 "Accept: */*\r\n" 254 "Accept: */*\r\n"
255 "Range: bytes=%"PRId64"-\r\n" 255 "Range: bytes=%"PRId64"-\r\n"
256 "Host: %s\r\n" 256 "Host: %s\r\n"
257 "Authorization: Basic %s\r\n" 257 "Authorization: Basic %s\r\n"
258 "Connection: close\r\n" 258 "Connection: close\r\n"
259 "%s"
259 "\r\n", 260 "\r\n",
260 post ? "POST" : "GET", 261 post ? "POST" : "GET",
261 path, 262 path,
262 LIBAVFORMAT_IDENT, 263 LIBAVFORMAT_IDENT,
263 s->off, 264 s->off,
264 hoststr, 265 hoststr,
265 auth_b64); 266 auth_b64,
267 post ? "Transfer-Encoding: chunked\r\n" : "");
266 268
267 av_freep(&auth_b64); 269 av_freep(&auth_b64);
268 if (http_write(h, s->buffer, strlen(s->buffer)) < 0) 270 if (http_write(h, s->buffer, strlen(s->buffer)) < 0)
269 return AVERROR(EIO); 271 return AVERROR(EIO);
270 272
273 s->buf_end = s->buffer; 275 s->buf_end = s->buffer;
274 s->line_count = 0; 276 s->line_count = 0;
275 s->off = 0; 277 s->off = 0;
276 s->filesize = -1; 278 s->filesize = -1;
277 if (post) { 279 if (post) {
280 /* always use chunked encoding for upload data */
281 s->chunksize = 0;
278 return 0; 282 return 0;
279 } 283 }
280 284
281 /* wait for header */ 285 /* wait for header */
282 for(;;) { 286 for(;;) {
342 } 346 }
343 347
344 /* used only when posting data */ 348 /* used only when posting data */
345 static int http_write(URLContext *h, uint8_t *buf, int size) 349 static int http_write(URLContext *h, uint8_t *buf, int size)
346 { 350 {
347 HTTPContext *s = h->priv_data; 351 char temp[11]; /* 32-bit hex + CRLF + nul */
352 int ret;
353 char crlf[] = "\r\n";
354 HTTPContext *s = h->priv_data;
355
356 if (s->chunksize == -1) {
357 /* headers are sent without any special encoding */
348 return url_write(s->hd, buf, size); 358 return url_write(s->hd, buf, size);
359 }
360
361 /* silently ignore zero-size data since chunk encoding that would
362 * signal EOF */
363 if (size > 0) {
364 /* upload data using chunked encoding */
365 snprintf(temp, sizeof(temp), "%x\r\n", size);
366
367 if ((ret = url_write(s->hd, temp, strlen(temp))) < 0 ||
368 (ret = url_write(s->hd, buf, size)) < 0 ||
369 (ret = url_write(s->hd, crlf, sizeof(crlf) - 1)) < 0)
370 return ret;
371 }
372 return size;
349 } 373 }
350 374
351 static int http_close(URLContext *h) 375 static int http_close(URLContext *h)
352 { 376 {
353 HTTPContext *s = h->priv_data; 377 int ret = 0;
378 char footer[] = "0\r\n\r\n";
379 HTTPContext *s = h->priv_data;
380
381 /* signal end of chunked encoding if used */
382 if ((h->flags & URL_WRONLY) && s->chunksize != -1) {
383 ret = url_write(s->hd, footer, sizeof(footer) - 1);
384 ret = ret > 0 ? 0 : ret;
385 }
386
354 url_close(s->hd); 387 url_close(s->hd);
355 av_free(s); 388 av_free(s);
356 return 0; 389 return ret;
357 } 390 }
358 391
359 static int64_t http_seek(URLContext *h, int64_t off, int whence) 392 static int64_t http_seek(URLContext *h, int64_t off, int whence)
360 { 393 {
361 HTTPContext *s = h->priv_data; 394 HTTPContext *s = h->priv_data;