#include "libavutil/avstring.h"
#include "avformat.h"
-#include <unistd.h>
#include "internal.h"
#include "network.h"
#include "http.h"
/* XXX: POST protocol is not completely implemented because avconv uses
only a subset of it. */
-/* used for protocol handling */
-#define BUFFER_SIZE 1024
+/* The IO buffer size is unrelated to the max URL size in itself, but needs
+ * to be large enough to fit the full request headers (including long
+ * path names).
+ */
+#define BUFFER_SIZE MAX_URL_SIZE
#define MAX_REDIRECTS 8
typedef struct {
#define D AV_OPT_FLAG_DECODING_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
-{"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.dbl = 1}, 0, 1, E },
+{"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
{"headers", "custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
-{"multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, D|E },
+{"multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
{"post_data", "custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D|E },
{NULL}
};
const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
char hostname[1024], hoststr[1024], proto[10];
char auth[1024], proxyauth[1024] = "";
- char path1[1024];
- char buf[1024], urlbuf[1024];
+ char path1[MAX_URL_SIZE];
+ char buf[1024], urlbuf[MAX_URL_SIZE];
int port, use_proxy, err, location_changed = 0, redirects = 0, attempts = 0;
HTTPAuthType cur_auth_type, cur_proxy_auth_type;
HTTPContext *s = h->priv_data;
- URLContext *hd = NULL;
proxy_path = getenv("http_proxy");
use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL);
if (!s->hd) {
- err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE,
+ err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
&h->interrupt_callback, NULL);
if (err < 0)
goto fail;
-
- s->hd = hd;
}
cur_auth_type = s->auth_state.auth_type;
if (s->http_code == 401) {
if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) &&
s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
- ffurl_close(hd);
- s->hd = hd = NULL;
+ ffurl_close(s->hd);
+ s->hd = NULL;
goto redo;
} else
goto fail;
if (s->http_code == 407) {
if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
- ffurl_close(hd);
- s->hd = hd = NULL;
+ ffurl_close(s->hd);
+ s->hd = NULL;
goto redo;
} else
goto fail;
if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307)
&& location_changed == 1) {
/* url moved, get next */
- ffurl_close(hd);
- s->hd = hd = NULL;
+ ffurl_close(s->hd);
+ s->hd = NULL;
if (redirects++ >= MAX_REDIRECTS)
return AVERROR(EIO);
/* Restart the authentication process with the new target, which
}
return 0;
fail:
- if (hd)
- ffurl_close(hd);
+ if (s->hd)
+ ffurl_close(s->hd);
s->hd = NULL;
return AVERROR(EIO);
}
while (isspace(*p))
p++;
if (!av_strcasecmp(tag, "Location")) {
- strcpy(s->location, p);
+ av_strlcpy(s->location, p, sizeof(s->location));
*new_location = 1;
} else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
- s->filesize = atoll(p);
+ s->filesize = strtoll(p, NULL, 10);
} else if (!av_strcasecmp (tag, "Content-Range")) {
/* "bytes $from-$to/$document_size" */
const char *slash;
if (!strncmp (p, "bytes ", 6)) {
p += 6;
- s->off = atoll(p);
+ s->off = strtoll(p, NULL, 10);
if ((slash = strchr(p, '/')) && strlen(slash) > 0)
- s->filesize = atoll(slash+1);
+ s->filesize = strtoll(slash+1, NULL, 10);
}
h->is_streamed = 0; /* we _can_ in fact seek */
} else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
static int http_read_header(URLContext *h, int *new_location)
{
HTTPContext *s = h->priv_data;
- char line[1024];
+ char line[MAX_URL_SIZE];
int err = 0;
+ s->chunksize = -1;
+
for (;;) {
if ((err = http_get_line(s, line, sizeof(line))) < 0)
return err;
s->http_code = 200;
return 0;
}
- s->chunksize = -1;
/* wait for header */
err = http_read_header(h, new_location);
HTTPContext *s = h->priv_data;
int err, new_location;
- if (s->end_chunked_post) {
- if (!s->end_header) {
- err = http_read_header(h, &new_location);
- if (err < 0)
- return err;
- }
+ if (!s->hd)
+ return AVERROR_EOF;
- return http_buf_read(h, buf, size);
+ if (s->end_chunked_post && !s->end_header) {
+ err = http_read_header(h, &new_location);
+ if (err < 0)
+ return err;
}
if (s->chunksize >= 0) {
.url_seek = http_seek,
.url_close = http_close,
.url_get_file_handle = http_get_file_handle,
+ .url_shutdown = http_shutdown,
.priv_data_size = sizeof(HTTPContext),
.priv_data_class = &https_context_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,