Mercurial > libavformat.hg
comparison http.c @ 5059:a5b8b8cce2dd libavformat
Add support for "chunked" data blocks. Patch by Peter Holik (peter holik at).
| author | rbultje |
|---|---|
| date | Tue, 23 Jun 2009 15:38:53 +0000 |
| parents | 822a36d7ac0a |
| children | f09594ca5f77 |
comparison
equal
deleted
inserted
replaced
| 5058:33a244b7ca65 | 5059:a5b8b8cce2dd |
|---|---|
| 21 | 21 |
| 22 #include "libavutil/base64.h" | 22 #include "libavutil/base64.h" |
| 23 #include "libavutil/avstring.h" | 23 #include "libavutil/avstring.h" |
| 24 #include "avformat.h" | 24 #include "avformat.h" |
| 25 #include <unistd.h> | 25 #include <unistd.h> |
| 26 #include <strings.h> | |
| 26 #include "network.h" | 27 #include "network.h" |
| 27 #include "os_support.h" | 28 #include "os_support.h" |
| 28 | 29 |
| 29 /* XXX: POST protocol is not completely implemented because ffmpeg uses | 30 /* XXX: POST protocol is not completely implemented because ffmpeg uses |
| 30 only a subset of it. */ | 31 only a subset of it. */ |
| 37 typedef struct { | 38 typedef struct { |
| 38 URLContext *hd; | 39 URLContext *hd; |
| 39 unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end; | 40 unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end; |
| 40 int line_count; | 41 int line_count; |
| 41 int http_code; | 42 int http_code; |
| 43 int64_t chunksize; /**< Used if "Transfer-Encoding: chunked" otherwise -1. */ | |
| 42 int64_t off, filesize; | 44 int64_t off, filesize; |
| 43 char location[URL_SIZE]; | 45 char location[URL_SIZE]; |
| 44 } HTTPContext; | 46 } HTTPContext; |
| 45 | 47 |
| 46 static int http_connect(URLContext *h, const char *path, const char *hoststr, | 48 static int http_connect(URLContext *h, const char *path, const char *hoststr, |
| 122 if (!s) { | 124 if (!s) { |
| 123 return AVERROR(ENOMEM); | 125 return AVERROR(ENOMEM); |
| 124 } | 126 } |
| 125 h->priv_data = s; | 127 h->priv_data = s; |
| 126 s->filesize = -1; | 128 s->filesize = -1; |
| 129 s->chunksize = -1; | |
| 127 s->off = 0; | 130 s->off = 0; |
| 128 av_strlcpy(s->location, uri, URL_SIZE); | 131 av_strlcpy(s->location, uri, URL_SIZE); |
| 129 | 132 |
| 130 ret = http_open_cnx(h); | 133 ret = http_open_cnx(h); |
| 131 if (ret != 0) | 134 if (ret != 0) |
| 220 s->off = atoll(p); | 223 s->off = atoll(p); |
| 221 if ((slash = strchr(p, '/')) && strlen(slash) > 0) | 224 if ((slash = strchr(p, '/')) && strlen(slash) > 0) |
| 222 s->filesize = atoll(slash+1); | 225 s->filesize = atoll(slash+1); |
| 223 } | 226 } |
| 224 h->is_streamed = 0; /* we _can_ in fact seek */ | 227 h->is_streamed = 0; /* we _can_ in fact seek */ |
| 228 } else if (!strcmp (tag, "Transfer-Encoding") && !strncasecmp(p, "chunked", 7)) { | |
| 229 s->filesize = -1; | |
| 230 s->chunksize = 0; | |
| 225 } | 231 } |
| 226 } | 232 } |
| 227 return 1; | 233 return 1; |
| 228 } | 234 } |
| 229 | 235 |
| 294 static int http_read(URLContext *h, uint8_t *buf, int size) | 300 static int http_read(URLContext *h, uint8_t *buf, int size) |
| 295 { | 301 { |
| 296 HTTPContext *s = h->priv_data; | 302 HTTPContext *s = h->priv_data; |
| 297 int len; | 303 int len; |
| 298 | 304 |
| 305 if (s->chunksize >= 0) { | |
| 306 if (!s->chunksize) { | |
| 307 char line[32]; | |
| 308 | |
| 309 for(;;) { | |
| 310 do { | |
| 311 if (http_get_line(s, line, sizeof(line)) < 0) | |
| 312 return AVERROR(EIO); | |
| 313 } while (!*line); /* skip CR LF from last chunk */ | |
| 314 | |
| 315 s->chunksize = strtoll(line, NULL, 16); | |
| 316 | |
| 317 dprintf(NULL, "Chunked encoding data size: %"PRId64"'\n", s->chunksize); | |
| 318 | |
| 319 if (!s->chunksize) | |
| 320 return 0; | |
| 321 break; | |
| 322 } | |
| 323 } | |
| 324 size = FFMIN(size, s->chunksize); | |
| 325 } | |
| 299 /* read bytes from input buffer first */ | 326 /* read bytes from input buffer first */ |
| 300 len = s->buf_end - s->buf_ptr; | 327 len = s->buf_end - s->buf_ptr; |
| 301 if (len > 0) { | 328 if (len > 0) { |
| 302 if (len > size) | 329 if (len > size) |
| 303 len = size; | 330 len = size; |
| 304 memcpy(buf, s->buf_ptr, len); | 331 memcpy(buf, s->buf_ptr, len); |
| 305 s->buf_ptr += len; | 332 s->buf_ptr += len; |
| 306 } else { | 333 } else { |
| 307 len = url_read(s->hd, buf, size); | 334 len = url_read(s->hd, buf, size); |
| 308 } | 335 } |
| 309 if (len > 0) | 336 if (len > 0) { |
| 310 s->off += len; | 337 s->off += len; |
| 338 if (s->chunksize > 0) | |
| 339 s->chunksize -= len; | |
| 340 } | |
| 311 return len; | 341 return len; |
| 312 } | 342 } |
| 313 | 343 |
| 314 /* used only when posting data */ | 344 /* used only when posting data */ |
| 315 static int http_write(URLContext *h, uint8_t *buf, int size) | 345 static int http_write(URLContext *h, uint8_t *buf, int size) |
