Skip to content

stream_curl: set stream url to the effective one in case of a redirect#18044

Open
MoSal wants to merge 1 commit into
mpv-player:masterfrom
MoSal:fix_curl_redirect
Open

stream_curl: set stream url to the effective one in case of a redirect#18044
MoSal wants to merge 1 commit into
mpv-player:masterfrom
MoSal:fix_curl_redirect

Conversation

@MoSal
Copy link
Copy Markdown
Contributor

@MoSal MoSal commented May 30, 2026

Without this, there are two issues I've quickly encountered:

  1. (major) HLS segment URLs are broken, because segment lines get appended to the original URL. Not only does this break playback, but it could leak query data (like auth tokens) to a third party.
  2. (medium) HLS master playlists are opened as actual playlists, with an entry per variant stream.

First issue basically broke playback in almost all IPTV use-cases 🫢

To test this. Here is a trivial python script:

Details
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs

class RedirectHandler(BaseHTTPRequestHandler):
    
    def do_GET(self):
        """Handle GET requests."""
        parsed_path = urlparse(self.path)
        path = parsed_path.path
        query_params = parse_qs(parsed_path.query)
        
        # Extract status code from path (e.g., /301, /302)
        if path.startswith('/'):
            status_str = path.lstrip('/').split('/')[0]
            
            try:
                status_code = int(status_str)
            except ValueError:
                self.send_error(400, "Bad Request")
                return
            
            # Validate status code
            if status_code not in [301, 302, 303, 307, 308]:
                self.send_error(400, "Invalid status code")
                return
            
            # Extract target URL from query string
            if 'url' not in query_params:
                self.send_error(400, "Missing 'url' parameter")
                return
            
            target_url = query_params['url'][0]
            
            # Perform redirect
            self.send_response(status_code)
            self.send_header('Location', target_url)
            self.end_headers()
        else:
            self.send_error(404, "Not Found")
    
    def log_message(self, format, *args):
        """Suppress default logging."""
        pass

if __name__ == '__main__':
    server = HTTPServer(('localhost', 8000), RedirectHandler)
    print("Server running on http://localhost:8000")
    print("Usage: http://localhost:8000/301?url=https://example.com")
    print("       http://localhost:8000/302?url=https://example.com")
    print("Press Ctrl+C to stop")
    server.serve_forever()

To trigger the issues:

First Issue

Works

mpv --curl-enabled=no --tls-verify=no 'http://localhost:8000/301?url=https://live-qt-primary.global.ssl.fastly.net/qt/Channel-QT-TX-AWS-virginia-2/Source-QT-10M-2-sn9jy9-BP-07-04-vXxkCqNs5ul_live.m3u8'

Broken

mpv  'http://localhost:8000/301?url=https://live-qt-primary.global.ssl.fastly.net/qt/Channel-QT-TX-AWS-virginia-2/Source-QT-10M-2-sn9jy9-BP-07-04-vXxkCqNs5ul_live.m3u8'

Segment URL's constructed are of the template:

http://localhost:8000/Source-QT-10M-2-sn9jy9-BP-07-04-vXxkCqNs5ul/$<n>.ts

Second issue

Opens as a stream

mpv --curl-enabled=no --tls-verify=no 'http://localhost:8000/301?url=https://bloomberg.com/media-manifest/streams/qt.m3u8'

Opens as a playlist

mpv 'http://localhost:8000/301?url=https://bloomberg.com/media-manifest/streams/qt.m3u8'

 Without this, there are two issues I've quickly encountered:

 1. (major) HLS segment URLs are broken, because segment lines get
    appended to the original URL. Not only does this break playback,
    but it could leak query data (like auth tokens) to a third party.
 2. (medium) HLS master playlists are opened as actual playlists, with
    an entry per variant stream.

Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
Comment thread stream/stream_curl.c
if (effective_url && strcmp(s->url, effective_url)) {
MP_INFO(p, "Redirected:\n");
MP_INFO(p, " (original) %s\n", s->url);
MP_INFO(p, " (redirect) %s\n", effective_url);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a single log and probably MP_VERBOSE at best.

Comment thread stream/stream_curl.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants