Fix Xbox proxy: Filter REQUEST body instead of response
BREAKING FIX: DeviceProfile is sent FROM client TO server in request body, not returned in response. This was the bug preventing the filter from working. Changes: - Filter DeviceProfile in POST request body before sending to Jellyfin - Add extensive debug logging to track filtering process - Remove unnecessary response filtering (DeviceProfile not in response) - Simplify response handling (always stream) Now logs: - 'Xbox PlaybackInfo request detected' when Xbox client detected - 'Filtering Xbox DeviceProfile in REQUEST' when filtering - 'No DeviceProfile found' if profile missing (debug info)
This commit is contained in:
@@ -73,44 +73,42 @@ def proxy(path):
|
|||||||
headers['X-Forwarded-Host'] = request.host
|
headers['X-Forwarded-Host'] = request.host
|
||||||
headers['X-Real-IP'] = request.remote_addr
|
headers['X-Real-IP'] = request.remote_addr
|
||||||
|
|
||||||
|
# Get request body
|
||||||
|
request_data = request.get_data()
|
||||||
|
|
||||||
|
# Filter REQUEST body for Xbox PlaybackInfo (DeviceProfile is sent TO server)
|
||||||
|
if is_xbox and is_playback_info:
|
||||||
|
logger.info(f"Xbox PlaybackInfo request detected: {path}, User-Agent: {user_agent}")
|
||||||
|
if request_data:
|
||||||
|
try:
|
||||||
|
data = json.loads(request_data)
|
||||||
|
if "DeviceProfile" in data:
|
||||||
|
logger.info(f"Filtering Xbox DeviceProfile in REQUEST")
|
||||||
|
original_profile = data["DeviceProfile"]
|
||||||
|
filtered_profile = filter_codecs(data["DeviceProfile"])
|
||||||
|
data["DeviceProfile"] = filtered_profile
|
||||||
|
request_data = json.dumps(data).encode('utf-8')
|
||||||
|
headers['Content-Length'] = str(len(request_data))
|
||||||
|
logger.info("DeviceProfile filtered successfully in REQUEST")
|
||||||
|
else:
|
||||||
|
logger.warning("No DeviceProfile found in REQUEST body")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error filtering request: {e}", exc_info=True)
|
||||||
|
else:
|
||||||
|
logger.warning("No request body found for PlaybackInfo")
|
||||||
|
|
||||||
resp = requests.request(
|
resp = requests.request(
|
||||||
method=request.method,
|
method=request.method,
|
||||||
url=url,
|
url=url,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
data=request.get_data(),
|
data=request_data,
|
||||||
cookies=request.cookies,
|
cookies=request.cookies,
|
||||||
allow_redirects=False,
|
allow_redirects=False,
|
||||||
stream=True # Support large file streaming
|
stream=True # Support large file streaming
|
||||||
)
|
)
|
||||||
|
|
||||||
# Filter response for Xbox PlaybackInfo requests
|
# Stream all responses (no need to filter response, DeviceProfile only in request)
|
||||||
if is_xbox and is_playback_info and resp.status_code == 200:
|
response = Response(resp.iter_content(chunk_size=8192), status=resp.status_code)
|
||||||
try:
|
|
||||||
# Read full response for JSON manipulation
|
|
||||||
data = resp.json()
|
|
||||||
|
|
||||||
# Filter DeviceProfile in request body (if sent back)
|
|
||||||
if "DeviceProfile" in data:
|
|
||||||
logger.info(f"Filtering Xbox DeviceProfile for User-Agent: {user_agent}")
|
|
||||||
data["DeviceProfile"] = filter_codecs(data["DeviceProfile"])
|
|
||||||
|
|
||||||
# Filter MediaSources DirectPlayProfiles (generated server-side)
|
|
||||||
if "MediaSources" in data:
|
|
||||||
for source in data["MediaSources"]:
|
|
||||||
if "TranscodingUrl" in source:
|
|
||||||
# Already filtered by Jellyfin
|
|
||||||
pass
|
|
||||||
|
|
||||||
response_data = json.dumps(data)
|
|
||||||
response = Response(response_data, status=resp.status_code)
|
|
||||||
response.headers['Content-Type'] = 'application/json'
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Error filtering response: {e}")
|
|
||||||
# Fallback to streaming response
|
|
||||||
response = Response(resp.iter_content(chunk_size=8192), status=resp.status_code)
|
|
||||||
else:
|
|
||||||
# Stream response for large files (videos, etc.)
|
|
||||||
response = Response(resp.iter_content(chunk_size=8192), status=resp.status_code)
|
|
||||||
|
|
||||||
# Copy headers from Jellyfin response
|
# Copy headers from Jellyfin response
|
||||||
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
|
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
|
||||||
|
|||||||
Reference in New Issue
Block a user