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) |