Commit 86b2fe94 authored by Marton Balint's avatar Marton Balint

avformat/http: use AVBPrint to construct HTTP request

v2: Use s->buffer for creating request (as the old code did) instead of
the AVBPrint internal buffer. Some minor cosmetics.
Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
parent a3d8875d
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/bprint.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/time.h" #include "libavutil/time.h"
#include "libavutil/parseutils.h" #include "libavutil/parseutils.h"
...@@ -1184,13 +1185,13 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, ...@@ -1184,13 +1185,13 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
{ {
HTTPContext *s = h->priv_data; HTTPContext *s = h->priv_data;
int post, err; int post, err;
char headers[HTTP_HEADERS_SIZE] = ""; AVBPrint request;
char *authstr = NULL, *proxyauthstr = NULL; char *authstr = NULL, *proxyauthstr = NULL;
uint64_t off = s->off; uint64_t off = s->off;
int len = 0;
const char *method; const char *method;
int send_expect_100 = 0; int send_expect_100 = 0;
int ret;
av_bprint_init_for_buffer(&request, s->buffer, sizeof(s->buffer));
/* send http header */ /* send http header */
post = h->flags & AVIO_FLAG_WRITE; post = h->flags & AVIO_FLAG_WRITE;
...@@ -1233,95 +1234,71 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, ...@@ -1233,95 +1234,71 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
s->user_agent = av_strdup(s->user_agent_deprecated); s->user_agent = av_strdup(s->user_agent_deprecated);
} }
#endif #endif
av_bprintf(&request, "%s %s HTTP/1.1\r\n", method, path);
if (post && s->chunked_post)
av_bprintf(&request, "Transfer-Encoding: chunked\r\n");
/* set default headers if needed */ /* set default headers if needed */
if (!has_header(s->headers, "\r\nUser-Agent: ")) if (!has_header(s->headers, "\r\nUser-Agent: "))
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "User-Agent: %s\r\n", s->user_agent);
"User-Agent: %s\r\n", s->user_agent);
if (s->referer) { if (s->referer) {
/* set default headers if needed */ /* set default headers if needed */
if (!has_header(s->headers, "\r\nReferer: ")) if (!has_header(s->headers, "\r\nReferer: "))
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "Referer: %s\r\n", s->referer);
"Referer: %s\r\n", s->referer);
} }
if (!has_header(s->headers, "\r\nAccept: ")) if (!has_header(s->headers, "\r\nAccept: "))
len += av_strlcpy(headers + len, "Accept: */*\r\n", av_bprintf(&request, "Accept: */*\r\n");
sizeof(headers) - len);
// Note: we send this on purpose even when s->off is 0 when we're probing, // Note: we send this on purpose even when s->off is 0 when we're probing,
// since it allows us to detect more reliably if a (non-conforming) // since it allows us to detect more reliably if a (non-conforming)
// server supports seeking by analysing the reply headers. // server supports seeking by analysing the reply headers.
if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->end_off || s->seekable == -1)) { if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->end_off || s->seekable == -1)) {
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "Range: bytes=%"PRIu64"-", s->off);
"Range: bytes=%"PRIu64"-", s->off);
if (s->end_off) if (s->end_off)
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "%"PRId64, s->end_off - 1);
"%"PRId64, s->end_off - 1); av_bprintf(&request, "\r\n");
len += av_strlcpy(headers + len, "\r\n",
sizeof(headers) - len);
} }
if (send_expect_100 && !has_header(s->headers, "\r\nExpect: ")) if (send_expect_100 && !has_header(s->headers, "\r\nExpect: "))
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "Expect: 100-continue\r\n");
"Expect: 100-continue\r\n");
if (!has_header(s->headers, "\r\nConnection: ")) { if (!has_header(s->headers, "\r\nConnection: "))
if (s->multiple_requests) av_bprintf(&request, "Connection: %s\r\n", s->multiple_requests ? "keep-alive" : "close");
len += av_strlcpy(headers + len, "Connection: keep-alive\r\n",
sizeof(headers) - len);
else
len += av_strlcpy(headers + len, "Connection: close\r\n",
sizeof(headers) - len);
}
if (!has_header(s->headers, "\r\nHost: ")) if (!has_header(s->headers, "\r\nHost: "))
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "Host: %s\r\n", hoststr);
"Host: %s\r\n", hoststr);
if (!has_header(s->headers, "\r\nContent-Length: ") && s->post_data) if (!has_header(s->headers, "\r\nContent-Length: ") && s->post_data)
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "Content-Length: %d\r\n", s->post_datalen);
"Content-Length: %d\r\n", s->post_datalen);
if (!has_header(s->headers, "\r\nContent-Type: ") && s->content_type) if (!has_header(s->headers, "\r\nContent-Type: ") && s->content_type)
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "Content-Type: %s\r\n", s->content_type);
"Content-Type: %s\r\n", s->content_type);
if (!has_header(s->headers, "\r\nCookie: ") && s->cookies) { if (!has_header(s->headers, "\r\nCookie: ") && s->cookies) {
char *cookies = NULL; char *cookies = NULL;
if (!get_cookies(s, &cookies, path, hoststr) && cookies) { if (!get_cookies(s, &cookies, path, hoststr) && cookies) {
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "Cookie: %s\r\n", cookies);
"Cookie: %s\r\n", cookies);
av_free(cookies); av_free(cookies);
} }
} }
if (!has_header(s->headers, "\r\nIcy-MetaData: ") && s->icy) if (!has_header(s->headers, "\r\nIcy-MetaData: ") && s->icy)
len += av_strlcatf(headers + len, sizeof(headers) - len, av_bprintf(&request, "Icy-MetaData: 1\r\n");
"Icy-MetaData: %d\r\n", 1);
/* now add in custom headers */ /* now add in custom headers */
if (s->headers) if (s->headers)
av_strlcpy(headers + len, s->headers, sizeof(headers) - len); av_bprintf(&request, "%s", s->headers);
ret = snprintf(s->buffer, sizeof(s->buffer), if (authstr)
"%s %s HTTP/1.1\r\n" av_bprintf(&request, "%s", authstr);
"%s" if (proxyauthstr)
"%s" av_bprintf(&request, "Proxy-%s", proxyauthstr);
"%s" av_bprintf(&request, "\r\n");
"%s%s"
"\r\n",
method,
path,
post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "",
headers,
authstr ? authstr : "",
proxyauthstr ? "Proxy-" : "", proxyauthstr ? proxyauthstr : "");
av_log(h, AV_LOG_DEBUG, "request: %s\n", s->buffer); av_log(h, AV_LOG_DEBUG, "request: %s\n", request.str);
if (strlen(headers) + 1 == sizeof(headers) || if (!av_bprint_is_complete(&request)) {
ret >= sizeof(s->buffer)) {
av_log(h, AV_LOG_ERROR, "overlong headers\n"); av_log(h, AV_LOG_ERROR, "overlong headers\n");
err = AVERROR(EINVAL); err = AVERROR(EINVAL);
goto done; goto done;
} }
if ((err = ffurl_write(s->hd, request.str, request.len)) < 0)
if ((err = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
goto done; goto done;
if (s->post_data) if (s->post_data)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment