summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
Diffstat (limited to 'stream')
-rw-r--r--stream/stream.c4
-rw-r--r--stream/stream_lavf.c25
2 files changed, 24 insertions, 5 deletions
diff --git a/stream/stream.c b/stream/stream.c
index de362a6ee1..1e1c5eee4e 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -157,7 +157,7 @@ void mp_url_unescape_inplace(char *buf)
// ok[0] != '~': additional characters that are not escaped
// ok[0] == '~': do not escape anything but these characters
// (can't override the unreserved characters, which are
-// never escaped, and '%', which is always escaped)
+// never escaped)
char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok)
{
int len = strlen(s);
@@ -167,7 +167,7 @@ char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok)
unsigned char c = s[i];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || strchr("-._~", c) ||
- (ok && ((ok[0] != '~') == !!strchr(ok, c)) && c != '%'))
+ (ok && ((ok[0] != '~') == !!strchr(ok, c))))
{
buf[o++] = c;
} else {
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index 286f9effcc..fd83202632 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -20,7 +20,6 @@
#include <libavformat/avio.h>
#include <libavutil/opt.h>
-#include "config.h"
#include "options/options.h"
#include "options/path.h"
#include "common/msg.h"
@@ -34,8 +33,6 @@
#include "misc/bstr.h"
#include "talloc.h"
-struct stream_lavf_params *stream_lavf_opts;
-
#define OPT_BASE_STRUCT struct stream_lavf_params
struct stream_lavf_params {
char **avopts;
@@ -49,6 +46,8 @@ const struct m_sub_options stream_lavf_conf = {
.size = sizeof(struct stream_lavf_params),
};
+static const char *const http_like[];
+
static int open_f(stream_t *stream);
static struct mp_tags *read_icy(stream_t *stream);
@@ -188,6 +187,21 @@ void mp_setup_av_network_options(AVDictionary **dict, struct mpv_global *global,
talloc_free(temp);
}
+// Escape http URLs with unescaped, invalid characters in them.
+// libavformat's http protocol does not do this, and a patch to add this
+// in a 100% safe case (spaces only) was rejected.
+static char *normalize_url(void *ta_parent, const char *filename)
+{
+ bstr proto = mp_split_proto(bstr0(filename), NULL);
+ for (int n = 0; http_like[n]; n++) {
+ if (bstr_equals0(proto, http_like[n]))
+ // Escape everything but reserved characters.
+ // Also don't double-scape, so include '%'.
+ return mp_url_escape(ta_parent, filename, ":/?#[]@!$&'()*+,;=%");
+ }
+ return (char *)filename;
+}
+
static int open_f(stream_t *stream)
{
struct MPOpts *opts = stream->opts;
@@ -238,6 +252,8 @@ static int open_f(stream_t *stream)
.opaque = stream,
};
+ filename = normalize_url(stream, filename);
+
int err = avio_open2(&avio, filename, flags, &cb, &dict);
if (err < 0) {
if (err == AVERROR_PROTOCOL_NOT_FOUND)
@@ -335,6 +351,9 @@ done:
return res;
}
+static const char *const http_like[] =
+ {"http", "https", "mmsh", "mmshttp", "httproxy", NULL};
+
const stream_info_t stream_info_ffmpeg = {
.name = "ffmpeg",
.open = open_f,