Fix 404 on the header logo caused by an encoded query string
base.html passed the cache-busting query string INSIDE the filename argument:
url_for('static', filename='uploads/header_logo.png?v=1')
Flask percent-encodes the '?' to '%3F', producing a request for a file
literally named "header_logo.png%3Fv=1", which does not exist. Every
authenticated page therefore logged:
GET /static/uploads/header_logo.png%3Fv=1 404
The logo silently stayed hidden too, because the element carries
onerror="this.style.display='none'".
Changes:
- base.html / login.html: append "?v=..." OUTSIDE url_for(), matching what
admin/customize_logos.html already did correctly.
- Inject logo_version from a context processor instead of hardcoding it.
It is derived from the newest logo's mtime, so uploading a new logo in
Admin -> Customize Logos is reflected immediately. The previous value was
a literal 1, which defeated cache-busting entirely; login.html used
range(1, 999999) | random, which changed on every request and made the
logo uncacheable.
Verified: /, /content/ and /players/ now render
/static/uploads/header_logo.png?v=<mtime> (HTTP 200), and no %3F requests
appear in the logs.
This commit is contained in:
+20
@@ -191,9 +191,29 @@ def register_context_processors(app):
|
|||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_config():
|
def inject_config():
|
||||||
"""Inject configuration variables into all templates"""
|
"""Inject configuration variables into all templates"""
|
||||||
|
# Cache-busting token for the uploadable logos.
|
||||||
|
#
|
||||||
|
# Must be appended OUTSIDE url_for(): passing 'logo.png?v=1' as the
|
||||||
|
# filename makes Flask percent-encode the '?' into '%3F', which asks
|
||||||
|
# for a file literally named "logo.png%3Fv=1" and 404s.
|
||||||
|
#
|
||||||
|
# Derived from the newest logo's mtime so that uploading a new logo in
|
||||||
|
# Admin → Customize Logos is picked up immediately, rather than reusing
|
||||||
|
# a hardcoded value the browser has already cached.
|
||||||
|
logo_version = 1
|
||||||
|
for _logo_name in ('header_logo.png', 'login_logo.png'):
|
||||||
|
try:
|
||||||
|
_mtime = int(os.path.getmtime(
|
||||||
|
os.path.join(app.config['UPLOAD_FOLDER'], _logo_name)))
|
||||||
|
logo_version = max(logo_version, _mtime)
|
||||||
|
except OSError:
|
||||||
|
# Logo not uploaded yet — keep the current token.
|
||||||
|
pass
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'server_version': app.config['SERVER_VERSION'],
|
'server_version': app.config['SERVER_VERSION'],
|
||||||
'build_date': app.config['BUILD_DATE'],
|
'build_date': app.config['BUILD_DATE'],
|
||||||
|
'logo_version': logo_version,
|
||||||
'logo_exists': os.path.exists(
|
'logo_exists': os.path.exists(
|
||||||
os.path.join(app.root_path, app.config['UPLOAD_FOLDERLOGO'], 'logo.png')
|
os.path.join(app.root_path, app.config['UPLOAD_FOLDERLOGO'], 'logo.png')
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -181,7 +181,7 @@
|
|||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<!-- Logo Section (Left - 2/3) -->
|
<!-- Logo Section (Left - 2/3) -->
|
||||||
<div class="logo-section">
|
<div class="logo-section">
|
||||||
<img src="{{ url_for('static', filename='uploads/login_logo.png') }}?v={{ range(1, 999999) | random }}"
|
<img src="{{ url_for('static', filename='uploads/login_logo.png') }}?v={{ logo_version }}"
|
||||||
alt="DigiServer Logo"
|
alt="DigiServer Logo"
|
||||||
onerror="this.style.display='none';">
|
onerror="this.style.display='none';">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -376,7 +376,7 @@
|
|||||||
<header>
|
<header>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>
|
<h1>
|
||||||
<img src="{{ url_for('static', filename='uploads/header_logo.png?v=1') }}" alt="DigiServer" style="height: 32px; width: auto; margin-right: 8px;" onerror="this.style.display='none';" onload="this.style.display='inline';">
|
<img src="{{ url_for('static', filename='uploads/header_logo.png') }}?v={{ logo_version }}" alt="DigiServer" style="height: 32px; width: auto; margin-right: 8px;" onerror="this.style.display='none';" onload="this.style.display='inline';">
|
||||||
DigiServer
|
DigiServer
|
||||||
</h1>
|
</h1>
|
||||||
<nav>
|
<nav>
|
||||||
|
|||||||
Reference in New Issue
Block a user