Initial implementation of yt-dlp HLS proxy server
- Flask app with HLS proxy routes (/hls, /player, /) - yt-dlp integration with 365-day in-memory cache - URL validation with allowed domains (youtube, pornhub, etc) - HTML5 HLS player with hls.js - Unit tests: URL validation, cache, error handling - Integration tests: ffmpeg-generated test video, full proxy chain - Environment-based configuration (PORT, CACHE_TTL, LOG_LEVEL) - MIT license
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
import pytest
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from utils import is_valid_url, extract_video_id, sanitize_path, get_error_message
|
||||
import dlp
|
||||
|
||||
|
||||
class TestURLValidation:
|
||||
def test_valid_youtube_url(self):
|
||||
assert is_valid_url("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
||||
assert is_valid_url("https://youtu.be/dQw4w9WgXcQ")
|
||||
|
||||
def test_valid_youtu_be(self):
|
||||
assert is_valid_url("https://youtu.be/abc123")
|
||||
|
||||
def test_valid_pornhub_url(self):
|
||||
assert is_valid_url("https://www.pornhub.com/view_video.php?viewkey=abc123")
|
||||
|
||||
def test_invalid_url(self):
|
||||
assert not is_valid_url("")
|
||||
assert not is_valid_url("not-a-url")
|
||||
|
||||
def test_disallowed_domain(self):
|
||||
os.environ["VALIDATION_ENABLED"] = "true"
|
||||
assert not is_valid_url("https://evil.com/video")
|
||||
|
||||
|
||||
class TestVideoIDExtraction:
|
||||
def test_extract_youtube_id(self):
|
||||
assert extract_video_id("https://www.youtube.com/watch?v=dQw4w9WgXcQ") == "dQw4w9WgXcQ"
|
||||
assert extract_video_id("https://youtu.be/dQw4w9WgXcQ") == "dQw4w9WgXcQ"
|
||||
|
||||
def test_extract_pornhub_id(self):
|
||||
result = extract_video_id("https://www.pornhub.com/view_video.php?viewkey=ph123456")
|
||||
assert result == "ph123456"
|
||||
|
||||
def test_extract_invalid(self):
|
||||
assert extract_video_id("https://example.com/video") == ""
|
||||
|
||||
|
||||
class TestPathSanitization:
|
||||
def test_sanitize_normal_path(self):
|
||||
assert sanitize_path("path/to/file") == "path/to/file"
|
||||
|
||||
def test_sanitize_prevents_traversal(self):
|
||||
assert sanitize_path("../etc/passwd") == "etc/passwd"
|
||||
assert sanitize_path("path/../etc/passwd") == "path/etc/passwd"
|
||||
|
||||
|
||||
class TestCacheMechanics:
|
||||
def test_cache_basic(self):
|
||||
dlp._session_cache.clear()
|
||||
dlp._cache_timestamps.clear()
|
||||
|
||||
test_data = {"test": "data"}
|
||||
dlp._set_cached_session("http://test.com/video", test_data)
|
||||
|
||||
cached = dlp._get_cached_session("http://test.com/video")
|
||||
assert cached == test_data
|
||||
|
||||
def test_cache_expiry(self):
|
||||
dlp.CACHE_TTL = 1
|
||||
dlp._session_cache.clear()
|
||||
dlp._cache_timestamps.clear()
|
||||
|
||||
dlp._set_cached_session("http://test.com/video", {"data": "test"})
|
||||
import time
|
||||
time.sleep(1.1)
|
||||
|
||||
assert dlp._is_cache_expired("http://test.com/video") is True
|
||||
|
||||
dlp.CACHE_TTL = 31536000
|
||||
|
||||
|
||||
class TestErrorMessages:
|
||||
def test_get_error_message(self):
|
||||
assert "Bad Request" in get_error_message(400)
|
||||
assert "Forbidden" in get_error_message(403)
|
||||
assert "Not Found" in get_error_message(404)
|
||||
assert "Internal Server Error" in get_error_message(500)
|
||||
|
||||
|
||||
class TestFlaskApp:
|
||||
def test_index_route(self):
|
||||
from app import app
|
||||
with app.test_client() as client:
|
||||
response = client.get("/")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_player_route_missing_url(self):
|
||||
from app import app
|
||||
with app.test_client() as client:
|
||||
response = client.get("/player")
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_player_route_invalid_url(self):
|
||||
from app import app
|
||||
with app.test_client() as client:
|
||||
response = client.get("/player?url=https://evil.com/video")
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_hls_proxy_invalid_path(self):
|
||||
from app import app
|
||||
with app.test_client() as client:
|
||||
response = client.get("/hls")
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v"])
|
||||
Reference in New Issue
Block a user