Hi guys,
First attempt at a small refactoring of the http protocol handler.
The first patch separates the initialization from the actual
connection, which will enable delayed connections using the internal
api.
Second patch adds in capability to write custom HTTP headers. Any
custom headers will overwrite all defaults after the HTTP/1.1 line. If
we only want to replace headers selectively, we need to figure out a
clean way to do that.
Josh
diff --git a/libavformat/http.c b/libavformat/http.c
index e697578..f76e995 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -26,6 +26,7 @@
#include "internal.h"
#include "network.h"
#include "os_support.h"
+#include "http.h"
#include "httpauth.h"
/* XXX: POST protocol is not completely implemented because ffmpeg uses
@@ -53,7 +54,7 @@ static int http_write(URLContext *h, uint8_t *buf, int size);
/* return non zero if error */
-static int http_open_cnx(URLContext *h)
+int ff_http_connect(URLContext *h)
{
const char *path, *proxy_path;
char hostname[1024], hoststr[1024];
@@ -120,10 +121,9 @@ static int http_open_cnx(URLContext *h)
return AVERROR(EIO);
}
-static int http_open(URLContext *h, const char *uri, int flags)
+int ff_http_init(URLContext *h, const char *uri, int flags)
{
HTTPContext *s;
- int ret;
h->is_streamed = 1;
@@ -138,11 +138,23 @@ static int http_open(URLContext *h, const char *uri, int flags)
memset(&s->auth_state, 0, sizeof(s->auth_state));
av_strlcpy(s->location, uri, URL_SIZE);
- ret = http_open_cnx(h);
+ return 0;
+}
+
+static int http_open(URLContext *h, const char *uri, int flags)
+{
+ int ret;
+
+ ret = ff_http_init(h, uri, flags);
if (ret != 0)
- av_free (s);
+ return ret;
+
+ ret = ff_http_connect(h);
+ if (ret != 0)
+ av_free (h->priv_data);
return ret;
}
+
static int http_getc(HTTPContext *s)
{
int len;
@@ -425,7 +437,7 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence)
s->off = off;
/* if it fails, continue on old connection */
- if (http_open_cnx(h) < 0) {
+ if (ff_http_connect(h) < 0) {
memcpy(s->buffer, old_buf, old_buf_size);
s->buf_ptr = s->buffer;
s->buf_end = s->buffer + old_buf_size;
diff --git a/libavformat/http.h b/libavformat/http.h
new file mode 100644
index 0000000..25ae18b
--- /dev/null
+++ b/libavformat/http.h
@@ -0,0 +1,44 @@
+/*
+ * HTTP definitions
+ * Copyright (c) 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef AVFORMAT_HTTP_H
+#define AVFORMAT_HTTP_H
+
+/**
+ * Initializes the private HTTP context.
+ *
+ * @param h URL context for this HTTP connection
+ * @param uri Target uri for the request
+ * @param flags Indicates whether to POST or GET
+ *
+ * @return nonzero if error, 0 on success.
+ */
+int ff_http_init(URLContext *h, const char *uri, int flags);
+
+/**
+ * Opens the connection using an initialized HTTP context.
+ *
+ * @param h URL context for this HTTP connecton
+ *
+ * @return nonzero if error, 0 on success.
+ */
+int ff_http_connect(URLContext *h);
+
+#endif
diff --git a/libavformat/http.c b/libavformat/http.c
index f76e995..f4ddcae 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -46,12 +46,18 @@ typedef struct {
int64_t off, filesize;
char location[URL_SIZE];
HTTPAuthState auth_state;
+ unsigned char headers[BUFFER_SIZE];
} HTTPContext;
static int http_connect(URLContext *h, const char *path, const char *hoststr,
const char *auth, int *new_location);
static int http_write(URLContext *h, uint8_t *buf, int size);
+void ff_http_set_headers(URLContext *h, const char *headers)
+{
+ HTTPContext *s = h->priv_data;
+ snprintf(s->headers, sizeof(s->headers), "%s", headers);
+}
/* return non zero if error */
int ff_http_connect(URLContext *h)
@@ -135,6 +141,7 @@ int ff_http_init(URLContext *h, const char *uri, int flags)
s->filesize = -1;
s->chunksize = -1;
s->off = 0;
+ *s->headers = '\0';
memset(&s->auth_state, 0, sizeof(s->auth_state));
av_strlcpy(s->location, uri, URL_SIZE);
@@ -272,8 +279,9 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
post = h->flags & URL_WRONLY;
authstr = ff_http_auth_create_response(&s->auth_state, auth, path,
post ? "POST" : "GET");
- snprintf(s->buffer, sizeof(s->buffer),
- "%s %s HTTP/1.1\r\n"
+ if(!strlen(s->headers))
+ {
+ snprintf(s->headers, sizeof(s->headers),
"User-Agent: %s\r\n"
"Accept: */*\r\n"
"Range: bytes=%"PRId64"-\r\n"
@@ -282,13 +290,20 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
"Connection: close\r\n"
"%s"
"\r\n",
- post ? "POST" : "GET",
- path,
LIBAVFORMAT_IDENT,
s->off,
hoststr,
authstr ? authstr : "",
post ? "Transfer-Encoding: chunked\r\n" : "");
+ }
+
+ snprintf(s->buffer, sizeof(s->buffer),
+ "%s %s HTTP/1.1\r\n"
+ "%s"
+ "\r\n",
+ post ? "POST" : "GET",
+ path,
+ s->headers);
av_freep(&authstr);
if (http_write(h, s->buffer, strlen(s->buffer)) < 0)
diff --git a/libavformat/http.h b/libavformat/http.h
index 25ae18b..1e78ec7 100644
--- a/libavformat/http.h
+++ b/libavformat/http.h
@@ -41,4 +41,12 @@ int ff_http_init(URLContext *h, const char *uri, int flags);
*/
int ff_http_connect(URLContext *h);
+/**
+ * Sets custom HTTP headers. Note this overwrites all the default options.
+ *
+ * @param h URL context for this HTTP connection
+ * @param headers New headers to use for future requests.
+ */
+void ff_http_set_headers(URLContext *h, const char *headers);
+
#endif
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc