Switched to connection tracking by url instead of parameter and 301 redirect instead of 302.

This commit is contained in:
SergeantPanda 2025-08-12 14:48:35 -05:00
parent a5db9d98e9
commit be51be7872
2 changed files with 33 additions and 15 deletions

View file

@ -4,7 +4,11 @@ from . import views
app_name = 'vod_proxy'
urlpatterns = [
# Generic VOD streaming (supports movies, episodes, series)
# Generic VOD streaming with session ID in path (for compatibility)
path('<str:content_type>/<uuid:content_id>/<str:session_id>', views.VODStreamView.as_view(), name='vod_stream_with_session'),
path('<str:content_type>/<uuid:content_id>/<str:session_id>/<int:profile_id>/', views.VODStreamView.as_view(), name='vod_stream_with_session_and_profile'),
# Generic VOD streaming (supports movies, episodes, series) - legacy patterns
path('<str:content_type>/<uuid:content_id>', views.VODStreamView.as_view(), name='vod_stream'),
path('<str:content_type>/<uuid:content_id>/<int:profile_id>/', views.VODStreamView.as_view(), name='vod_stream_with_profile'),

View file

@ -24,16 +24,17 @@ logger = logging.getLogger(__name__)
class VODStreamView(View):
"""Handle VOD streaming requests with M3U profile support"""
def get(self, request, content_type, content_id, profile_id=None):
def get(self, request, content_type, content_id, session_id=None, profile_id=None):
"""
Stream VOD content (movies or series episodes) with session-based connection reuse
Args:
content_type: 'movie', 'series', or 'episode'
content_id: ID of the content
session_id: Optional session ID from URL path (for persistent connections)
profile_id: Optional M3U profile ID for authentication
"""
logger.info(f"[VOD-REQUEST] Starting VOD stream request: {content_type}/{content_id}, profile: {profile_id}")
logger.info(f"[VOD-REQUEST] Starting VOD stream request: {content_type}/{content_id}, session: {session_id}, profile: {profile_id}")
logger.info(f"[VOD-REQUEST] Full request path: {request.get_full_path()}")
logger.info(f"[VOD-REQUEST] Request method: {request.method}")
logger.info(f"[VOD-REQUEST] Request headers: {dict(request.headers)}")
@ -55,8 +56,8 @@ class VODStreamView(View):
elif 'time' in request.GET:
offset = request.GET.get('time')
# Extract session ID for connection reuse
session_id = request.GET.get('session_id')
# Session ID now comes from URL path parameter
# Remove legacy query parameter extraction since we're using path-based routing
# Extract Range header for seeking support
range_header = request.META.get('HTTP_RANGE')
@ -108,22 +109,35 @@ class VODStreamView(View):
logger.info(f"[VOD-CLIENT] Client info - IP: {client_ip}, User-Agent: {user_agent[:50]}...")
# If no session ID, create one and redirect
# If no session ID, create one and redirect to path-based URL
if not session_id:
session_id = f"vod_{int(time.time() * 1000)}_{random.randint(1000, 9999)}"
logger.info(f"[VOD-SESSION] Creating new session: {session_id}")
new_session_id = f"vod_{int(time.time() * 1000)}_{random.randint(1000, 9999)}"
logger.info(f"[VOD-SESSION] Creating new session: {new_session_id}")
# Build redirect URL with session ID and preserve all parameters
from urllib.parse import urlencode
# Build redirect URL with session ID in path, preserve query parameters
path_parts = request.path.rstrip('/').split('/')
# Construct new path: /vod/movie/UUID/SESSION_ID or /vod/movie/UUID/SESSION_ID/PROFILE_ID/
if profile_id:
new_path = f"{'/'.join(path_parts)}/{new_session_id}/{profile_id}/"
else:
new_path = f"{'/'.join(path_parts)}/{new_session_id}"
# Preserve any query parameters (except session_id)
query_params = dict(request.GET)
query_params['session_id'] = session_id
query_string = urlencode(query_params, doseq=True)
query_params.pop('session_id', None) # Remove if present
redirect_url = f"{request.path}?{query_string}"
logger.info(f"[VOD-SESSION] Redirecting to: {redirect_url}")
if query_params:
from urllib.parse import urlencode
query_string = urlencode(query_params, doseq=True)
redirect_url = f"{new_path}?{query_string}"
else:
redirect_url = new_path
logger.info(f"[VOD-SESSION] Redirecting to path-based URL: {redirect_url}")
return HttpResponse(
status=302,
status=301,
headers={'Location': redirect_url}
)