Fix Xbox proxy: Add proper header forwarding and streaming support
- Add query parameter forwarding (?api_key=... etc.) - Add X-Forwarded-* headers for client IP tracking - Exclude problematic headers (content-length, transfer-encoding, etc.) - Add streaming support for large files (8KB chunks) - Add root route handler - Properly forward all HTTP methods
This commit is contained in:
@@ -47,6 +47,7 @@ def filter_codecs(profile):
|
||||
|
||||
return profile
|
||||
|
||||
@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
|
||||
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
|
||||
def proxy(path):
|
||||
"""Proxy all requests to Jellyfin, filter Xbox responses"""
|
||||
@@ -54,9 +55,23 @@ def proxy(path):
|
||||
is_xbox = 'xbox' in user_agent.lower()
|
||||
is_playback_info = 'PlaybackInfo' in path and request.method == 'POST'
|
||||
|
||||
# Forward request to Jellyfin
|
||||
# Build full URL with query parameters
|
||||
url = f"{JELLYFIN_URL}/{path}"
|
||||
headers = {key: value for key, value in request.headers if key.lower() != 'host'}
|
||||
if request.query_string:
|
||||
url += f"?{request.query_string.decode('utf-8')}"
|
||||
|
||||
# Copy headers, exclude problematic ones
|
||||
headers = {}
|
||||
excluded = ['host', 'connection', 'content-length', 'content-encoding', 'transfer-encoding']
|
||||
for key, value in request.headers:
|
||||
if key.lower() not in excluded:
|
||||
headers[key] = value
|
||||
|
||||
# Add X-Forwarded-* headers for proper client tracking
|
||||
headers['X-Forwarded-For'] = request.remote_addr
|
||||
headers['X-Forwarded-Proto'] = request.scheme
|
||||
headers['X-Forwarded-Host'] = request.host
|
||||
headers['X-Real-IP'] = request.remote_addr
|
||||
|
||||
resp = requests.request(
|
||||
method=request.method,
|
||||
@@ -64,12 +79,14 @@ def proxy(path):
|
||||
headers=headers,
|
||||
data=request.get_data(),
|
||||
cookies=request.cookies,
|
||||
allow_redirects=False
|
||||
allow_redirects=False,
|
||||
stream=True # Support large file streaming
|
||||
)
|
||||
|
||||
# Filter response for Xbox PlaybackInfo requests
|
||||
if is_xbox and is_playback_info and resp.status_code == 200:
|
||||
try:
|
||||
# Read full response for JSON manipulation
|
||||
data = resp.json()
|
||||
|
||||
# Filter DeviceProfile in request body (if sent back)
|
||||
@@ -89,9 +106,11 @@ def proxy(path):
|
||||
response.headers['Content-Type'] = 'application/json'
|
||||
except Exception as e:
|
||||
logger.error(f"Error filtering response: {e}")
|
||||
response = Response(resp.content, status=resp.status_code)
|
||||
# Fallback to streaming response
|
||||
response = Response(resp.iter_content(chunk_size=8192), status=resp.status_code)
|
||||
else:
|
||||
response = Response(resp.content, status=resp.status_code)
|
||||
# Stream response for large files (videos, etc.)
|
||||
response = Response(resp.iter_content(chunk_size=8192), status=resp.status_code)
|
||||
|
||||
# Copy headers from Jellyfin response
|
||||
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
|
||||
|
||||
Reference in New Issue
Block a user