Fix listener serving DJ panel instead of listener page

- Block DJ-only files (index.html, script.js, style.css) on listener server
- Disable Flask built-in static handler on listener (static_folder=None)
  to prevent it from serving index.html before custom routes
- Add Cache-Control no-store headers to index route to prevent
  nginx/browser from caching stale index.html for listener URL
This commit is contained in:
ComputerTech 2026-03-09 19:01:42 +00:00
parent 5a7f4e81a4
commit 7c33c678aa
1 changed files with 16 additions and 4 deletions

View File

@ -359,7 +359,11 @@ def setup_shared_routes(app, index_file='index.html'):
@app.route('/')
def index():
return send_from_directory('.', index_file)
response = send_from_directory('.', index_file)
response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '0'
return response
@app.route('/upload', methods=['POST'])
def upload_file():
@ -661,19 +665,27 @@ def dj_audio(data):
_feed_transcoder(bytes(data))
# === LISTENER SERVER ===
listener_app = Flask(__name__, static_folder='.', static_url_path='')
# static_folder=None prevents Flask's built-in static handler from serving
# DJ files (like index.html) at /<path> — all static files go through our
# custom serve_static route which has security checks.
listener_app = Flask(__name__, static_folder=None)
listener_app.config['SECRET_KEY'] = CONFIG_SECRET + '_listener'
listener_app.config['MAX_CONTENT_LENGTH'] = CONFIG_MAX_UPLOAD_MB * 1024 * 1024
setup_shared_routes(listener_app, index_file='listener.html')
# Block write/admin endpoints on the listener server
# Block write/admin endpoints AND DJ-only files on the listener server
@listener_app.before_request
def _restrict_listener_routes():
"""Prevent listeners from accessing DJ-only write endpoints."""
"""Prevent listeners from accessing DJ-only endpoints and files."""
blocked_paths = ('/update_settings', '/upload', '/save_keymaps', '/browse_directories')
if request.path in blocked_paths:
from flask import abort
abort(403)
# Block DJ-only files — prevents serving the DJ panel even via direct URL
dj_only_files = ('/index.html', '/script.js', '/style.css')
if request.path in dj_only_files:
from flask import abort
abort(403)
listener_socketio = SocketIO(
listener_app,
cors_allowed_origins=CONFIG_CORS,