Fix bugs, add log rotation, and optimize hot paths
- Fix AttributeError crash on empty request body in md5, hasher, textdiff,
jwtdecoder, timestamp, passwordgen (get_json without silent=True / or {})
- Fix memory exhaustion in ipcalc: replace list(network.hosts()) with direct
arithmetic — safe for /8 and larger networks
- Fix O(1M) loop in cronexplainer.get_next_runs: rewrite to skip by
month/day/hour instead of iterating every minute
- Fix connection leak in notes.ensure_table: add try/finally around conn.close
- Fix admin._ensure_tables / notes._ensure_table running DDL on every request:
guard with module-level flags (_tables_initialized, _table_ready)
- Fix update_website returning 200 when no row matched; delete_website returning
success when nothing was deleted; add rowcount checks for both
- Add role validation in admin create_user / update_user (_VALID_ROLES guard)
- Add delimiter length guard in csvviewer (csv.reader requires single char)
- Fix loremipsum: wrap int(count) in try/except ValueError → 400 response
- Fix auth/token: use auth_header[7:] instead of fragile .replace()
- Fix app.py: remove duplicate import sys; cache DB liveness check with 30s TTL
to avoid a new TCP connection on every frontend page load; move api/setup
path guard before DB check
- Replace FileHandler with RotatingFileHandler (5 MB / 3 backups) in logger;
fix relative log paths to absolute paths anchored to __file__
- Wrap all DB connections in try/finally conn.close() throughout admin and notes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+22
-11
@@ -1,10 +1,11 @@
|
||||
import os
|
||||
import sys
|
||||
import time as _time
|
||||
|
||||
if __name__ != '__main__':
|
||||
import sys
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
from flask import Flask, send_from_directory, redirect
|
||||
from flask import Flask, send_from_directory, redirect, abort
|
||||
from util.logger import logger
|
||||
from util.db_config import is_configured, load_config, test_connection
|
||||
from util.setup_routes import setup_blueprint
|
||||
@@ -37,7 +38,6 @@ from admin import admin_bp
|
||||
app = Flask(__name__, template_folder="templates")
|
||||
limiter.init_app(app)
|
||||
|
||||
# Blueprints registrieren
|
||||
app.register_blueprint(setup_blueprint)
|
||||
app.register_blueprint(auth_bp)
|
||||
app.register_blueprint(md5_blueprint)
|
||||
@@ -62,24 +62,35 @@ app.register_blueprint(csv_blueprint)
|
||||
app.register_blueprint(notes_blueprint)
|
||||
app.register_blueprint(admin_bp)
|
||||
|
||||
# 🌐 React-Frontend ausliefern
|
||||
# Cache DB liveness check so we don't open a new TCP connection on every page load.
|
||||
_db_check = {"ok": False, "ts": 0.0}
|
||||
_DB_CHECK_TTL = 30.0 # seconds
|
||||
|
||||
|
||||
def _is_db_ready():
|
||||
now = _time.monotonic()
|
||||
if now - _db_check["ts"] > _DB_CHECK_TTL:
|
||||
_db_check["ok"] = is_configured() and bool(test_connection(load_config()))
|
||||
_db_check["ts"] = now
|
||||
return _db_check["ok"]
|
||||
|
||||
|
||||
@app.route('/', defaults={'path': ''})
|
||||
@app.route('/<path:path>')
|
||||
def serve_frontend(path):
|
||||
if not is_configured() or not test_connection(load_config()):
|
||||
return redirect('/setup')
|
||||
|
||||
if path.startswith('setup') or path.startswith('api'):
|
||||
from flask import abort
|
||||
# Unmatched API / setup paths get a clean 404 before any DB work.
|
||||
if path.startswith('api') or path.startswith('setup'):
|
||||
abort(404)
|
||||
|
||||
if not _is_db_ready():
|
||||
return redirect('/setup')
|
||||
|
||||
dist_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'frontend', 'dist'))
|
||||
file_path = os.path.join(dist_dir, path)
|
||||
|
||||
if path and os.path.exists(file_path):
|
||||
return send_from_directory(dist_dir, path)
|
||||
else:
|
||||
return send_from_directory(dist_dir, 'index.html')
|
||||
return send_from_directory(dist_dir, 'index.html')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user