Preserve HLS media session cookies
This commit is contained in:
+89
-1
@@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import base64
|
||||
from email.message import Message
|
||||
import http.cookiejar
|
||||
import importlib.util
|
||||
import io
|
||||
import json
|
||||
@@ -4535,7 +4537,9 @@ seg-3.ts
|
||||
def test_curl_fetch_bytes_returns_body_before_status_marker(self):
|
||||
proc = mock.Mock(returncode=0, stdout=b"video-bytes\nKAIZOKU_HTTP_STATUS:200", stderr=b"")
|
||||
|
||||
with mock.patch.object(provider_downloader, "curl_candidates", return_value=["/usr/bin/curl"]), mock.patch.object(
|
||||
with tempfile.TemporaryDirectory() as temp_root, mock.patch.object(
|
||||
provider_downloader, "curl_cookie_file", return_value=Path(temp_root) / "cookies.txt"
|
||||
), mock.patch.object(provider_downloader, "curl_candidates", return_value=["/usr/bin/curl"]), mock.patch.object(
|
||||
provider_downloader.subprocess, "run", return_value=proc
|
||||
) as run:
|
||||
data = provider_downloader.curl_fetch_bytes("https://cdn.example/segment.ts", headers={"Referer": "https://player.example/"})
|
||||
@@ -4543,6 +4547,90 @@ seg-3.ts
|
||||
self.assertEqual(data, b"video-bytes")
|
||||
self.assertIn("--header", run.call_args.args[0])
|
||||
self.assertIn("Referer: https://player.example/", run.call_args.args[0])
|
||||
self.assertIn("--cookie-jar", run.call_args.args[0])
|
||||
|
||||
def test_media_request_preserves_playlist_cookie_for_segments(self):
|
||||
jar = http.cookiejar.CookieJar()
|
||||
cookie = http.cookiejar.Cookie(
|
||||
version=0,
|
||||
name="cdn_session",
|
||||
value="allowed",
|
||||
port=None,
|
||||
port_specified=False,
|
||||
domain="cdn.example",
|
||||
domain_specified=True,
|
||||
domain_initial_dot=False,
|
||||
path="/",
|
||||
path_specified=True,
|
||||
secure=True,
|
||||
expires=None,
|
||||
discard=True,
|
||||
comment=None,
|
||||
comment_url=None,
|
||||
rest={},
|
||||
rfc2109=False,
|
||||
)
|
||||
jar.set_cookie(cookie)
|
||||
|
||||
with mock.patch.object(provider_downloader, "MEDIA_COOKIE_JAR", jar):
|
||||
request = provider_downloader.media_request("https://cdn.example/video/segment.ts")
|
||||
|
||||
self.assertEqual(request.get_header("Cookie"), "cdn_session=allowed")
|
||||
|
||||
def test_fetch_bytes_keeps_set_cookie_for_next_media_request(self):
|
||||
class Response:
|
||||
def __init__(self, url, body, cookie=""):
|
||||
self.url = url
|
||||
self.body = body
|
||||
self.headers = Message()
|
||||
if cookie:
|
||||
self.headers.add_header("Set-Cookie", cookie)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *_args):
|
||||
return False
|
||||
|
||||
def info(self):
|
||||
return self.headers
|
||||
|
||||
def geturl(self):
|
||||
return self.url
|
||||
|
||||
def read(self):
|
||||
return self.body
|
||||
|
||||
requests = []
|
||||
responses = iter(
|
||||
[
|
||||
Response("https://cdn.example/index.m3u8", b"playlist", "cdn_session=allowed; Path=/; Secure"),
|
||||
Response("https://cdn.example/video/segment.ts", b"video"),
|
||||
]
|
||||
)
|
||||
|
||||
def fake_urlopen(request, timeout):
|
||||
requests.append(request)
|
||||
return next(responses)
|
||||
|
||||
with mock.patch.object(provider_downloader, "MEDIA_COOKIE_JAR", http.cookiejar.CookieJar()), mock.patch.object(
|
||||
provider_downloader.urllib.request, "urlopen", side_effect=fake_urlopen
|
||||
):
|
||||
provider_downloader.fetch_bytes("https://cdn.example/index.m3u8")
|
||||
provider_downloader.fetch_bytes("https://cdn.example/video/segment.ts")
|
||||
|
||||
self.assertEqual(requests[1].get_header("Cookie"), "cdn_session=allowed")
|
||||
|
||||
def test_curl_fetch_uses_python_media_session_cookie(self):
|
||||
proc = mock.Mock(returncode=0, stdout=b"video\nKAIZOKU_HTTP_STATUS:200", stderr=b"")
|
||||
with tempfile.TemporaryDirectory() as temp_root, mock.patch.object(
|
||||
provider_downloader, "curl_cookie_file", return_value=Path(temp_root) / "cookies.txt"
|
||||
), mock.patch.object(provider_downloader, "curl_candidates", return_value=["/usr/bin/curl"]), mock.patch.object(
|
||||
provider_downloader, "media_cookie_header", return_value="cdn_session=allowed"
|
||||
), mock.patch.object(provider_downloader.subprocess, "run", return_value=proc) as run:
|
||||
provider_downloader.curl_fetch_bytes("https://cdn.example/segment.ts")
|
||||
|
||||
self.assertIn("Cookie: cdn_session=allowed", run.call_args.args[0])
|
||||
|
||||
def test_curl_request_headers_preserve_browser_wrapper_defaults(self):
|
||||
headers = provider_downloader.curl_request_headers(
|
||||
|
||||
Reference in New Issue
Block a user