From 556f8d0d0799bd05f38cfb454fdb80de85dd2f7c Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Wed, 26 Aug 2009 15:45:59 +0100 Subject: Add a user agent & protocol hack to allow viewing of Apple film trailers. --- src/demuxers/demux_qt.c | 9 +++++++-- src/input/http_helper.c | 17 +++++++++++++++-- src/input/http_helper.h | 13 ++++++++++++- src/input/input_http.c | 12 +++++++++--- src/input/mms.c | 2 +- src/input/mmsh.c | 2 +- 6 files changed, 45 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index 5aba5b479..2039e54d3 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -1620,6 +1620,7 @@ static qt_error parse_reference_atom (reference_t *ref, if (current_atom == RDRF_ATOM) { size_t string_size = _X_BE_32(&ref_atom[i + 12]); size_t url_offset = 0; + int http = 0; if (string_size >= current_atom_size || string_size >= ref_atom_size - i) return QT_NOT_A_VALID_FILE; @@ -1628,7 +1629,11 @@ static qt_error parse_reference_atom (reference_t *ref, if ( memcmp(&ref_atom[i + 16], "http://", 7) && memcmp(&ref_atom[i + 16], "rtsp://", 7) && base_mrl ) - url_offset = strlen(base_mrl); + { + /* We need a "qt" prefix hack for Apple trailers */ + http = !strncasecmp (base_mrl, "http://", 7); + url_offset = strlen(base_mrl) + 2 * http; + } if (url_offset >= 0x80000000) return QT_NOT_A_VALID_FILE; @@ -1638,7 +1643,7 @@ static qt_error parse_reference_atom (reference_t *ref, ref->url = xine_xmalloc(string_size + 1); if ( url_offset ) - strcpy(ref->url, base_mrl); + sprintf (ref->url, "%s%s", http ? "qt" : "", base_mrl); memcpy(ref->url + url_offset, &ref_atom[i + 16], _X_BE_32(&ref_atom[i + 12])); diff --git a/src/input/http_helper.c b/src/input/http_helper.c index 279d3ff05..d7f9a93ff 100644 --- a/src/input/http_helper.c +++ b/src/input/http_helper.c @@ -29,8 +29,18 @@ #include "xine_internal.h" #include "http_helper.h" + +const char *_x_url_user_agent (const char *url) +{ + if (!strncasecmp (url, "qthttp://", 9)) + return "QuickTime"; /* needed for Apple trailers */ + return NULL; +} + int _x_parse_url (char *url, char **proto, char** host, int *port, - char **user, char **password, char **uri) { + char **user, char **password, char **uri, + const char **user_agent) +{ char *start = NULL; char *authcolon = NULL; char *at = NULL; @@ -63,6 +73,9 @@ int _x_parse_url (char *url, char **proto, char** host, int *port, end = start + strlen(start) - 1; *proto = strndup(url, start - url); + if (user_agent) + *user_agent = _x_url_user_agent (url); + /* user:password */ start += 3; at = strchr(start, '@'); @@ -257,7 +270,7 @@ static int check_url(char *url, int ok) { printf("--------------------------------\n"); printf("url=%s\n", url); res = _x_parse_url (url, - &proto, &host, &port, &user, &password, &uri); + &proto, &host, &port, &user, &password, &uri, NULL); if (res) { printf("proto=%s, host=%s, port=%d, user=%s, password=%s, uri=%s\n", proto, host, port, user, password, uri); diff --git a/src/input/http_helper.h b/src/input/http_helper.h index 3ce3f2b7c..68299a2ea 100644 --- a/src/input/http_helper.h +++ b/src/input/http_helper.h @@ -23,6 +23,16 @@ #ifndef HTTP_HELPER_H #define HTTP_HELPER_H +/* + * user agent finder, using modified protcol names + * {proto}://... + * e.g. "qthttp://example.com/foo.mov" → "QuickTime" + * + * return: + * NULL or user agent prefix + */ +const char *_x_url_user_agent (const char *url); + /* * url parser * {proto}://{user}:{password}@{host}:{port}{uri} @@ -33,7 +43,8 @@ * 1 valid url */ int _x_parse_url (char *url, char **proto, char** host, int *port, - char **user, char **password, char **uri); + char **user, char **password, char **uri, + const char **user_agent); /* * canonicalise url, given base diff --git a/src/input/input_http.c b/src/input/input_http.c index c831dfc59..4eece116f 100644 --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -91,6 +91,8 @@ typedef struct { char *host; int port; char *uri; + + const char *user_agent; char preview[MAX_PREVIEW_SIZE]; off_t preview_size; @@ -689,7 +691,8 @@ static int http_plugin_open (input_plugin_t *this_gen ) { if (!_x_parse_url(this->mrl, &this->proto, &this->host, &this->port, - &this->user, &this->password, &this->uri)) { + &this->user, &this->password, &this->uri, + &this->user_agent)) { _x_message(this->stream, XINE_MSG_GENERAL_WARNING, "malformed url", NULL); return 0; } @@ -788,10 +791,12 @@ static int http_plugin_open (input_plugin_t *this_gen ) { } buflen += snprintf(this->buf + buflen, BUFSIZE - buflen, - "User-Agent: xine/%s\015\012" + "User-Agent: %s%sxine/%s\015\012" "Accept: */*\015\012" "Icy-MetaData: 1\015\012" "\015\012", + this->user_agent ? this->user_agent : "", + this->user_agent ? " " : "", VERSION); if (_x_io_tcp_write (this->stream, this->fh, this->buf, buflen) != buflen) { _x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "couldn't send request", NULL); @@ -1029,7 +1034,8 @@ static input_plugin_t *http_class_get_instance (input_class_t *cls_gen, xine_str if (strncasecmp (mrl, "http://", 7) && strncasecmp (mrl, "unsv://", 7) && - strncasecmp (mrl, "peercast://pls/", 15)) { + strncasecmp (mrl, "peercast://pls/", 15) && + !_x_url_user_agent (mrl) /* user agent hacks */) { return NULL; } this = calloc(1, sizeof(http_input_plugin_t)); diff --git a/src/input/mms.c b/src/input/mms.c index b2d00a46e..8ba33e704 100644 --- a/src/input/mms.c +++ b/src/input/mms.c @@ -698,7 +698,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) { report_progress (stream, 0); if (!_x_parse_url (this->url, &this->proto, &this->host, &this->port, - &this->user, &this->password, &this->uri)) { + &this->user, &this->password, &this->uri, NULL)) { lprintf ("invalid url\n"); goto fail; } diff --git a/src/input/mmsh.c b/src/input/mmsh.c index 4ee7ed07d..2cc27c3b1 100644 --- a/src/input/mmsh.c +++ b/src/input/mmsh.c @@ -649,7 +649,7 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) { report_progress (stream, 0); if (!_x_parse_url (this->url, &this->proto, &this->host, &this->port, - &this->user, &this->password, &this->uri)) { + &this->user, &this->password, &this->uri, NULL)) { xine_log (this->stream->xine, XINE_LOG_MSG, _("invalid url\n")); goto fail; } -- cgit v1.2.3