Skip to content

Commit 69da5fd

Browse files
committed
modified: .github/workflows/main_ballotlens.yml
modified: webapp/Smart_Elections_Parser_Webapp.py
1 parent e2f8c71 commit 69da5fd

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

.github/workflows/main_ballotlens.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ jobs:
206206
HEADLESS_DEFAULT="True" \
207207
ENABLE_FINGERPRINT_SESSION_RECOVERY="0" \
208208
DISABLE_HTML_FALLBACK="1" \
209+
LOG_REDIRECT_HEADERS="True" \
210+
LOG_REDIRECT_HEADERS_TTL_SEC="300" \
209211
SENTENCE_TRANSFORMER_LOCAL_PATH="/models/sentence/all-MiniLM-L6-v2" \
210212
TRANSFORMERS_OFFLINE="1" \
211213
HUGGINGFACE_HUB_OFFLINE="1" \

webapp/Smart_Elections_Parser_Webapp.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,13 +1291,18 @@ def get_session_enums() -> Response:
12911291
app.config["SESSION_COOKIE_SECURE"] = os.environ.get("FLASK_COOKIE_SECURE", "False").lower() == "true"
12921292
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 31536000
12931293

1294+
# Throttle redirect header diagnostics (per host+path)
1295+
_REDIRECT_HEADER_LOG_LAST: dict[str, float] = {}
1296+
12941297
@app.before_request
12951298
def redirect_to_https_www():
12961299
"""
12971300
Enforce HTTPS and www subdomain for production domain.
12981301
- Redirects http:// to https://
12991302
- Redirects electionpulse.org to www.electionpulse.org
13001303
"""
1304+
# Optional diagnostic logging for forwarded headers (guarded to avoid noise)
1305+
log_forwarded = os.environ.get("LOG_REDIRECT_HEADERS", "").lower() in {"1", "true", "yes"}
13011306
# Prefer forwarded host when behind a proxy/CDN (Azure Front Door/App Service)
13021307
forwarded_host = request.headers.get("X-Forwarded-Host")
13031308
raw_host = (forwarded_host or request.host or "").split(",")[0].strip().lower()
@@ -1307,6 +1312,34 @@ def redirect_to_https_www():
13071312
else:
13081313
host_only = raw_host.split(":", 1)[0]
13091314

1315+
if log_forwarded:
1316+
forwarded_proto = request.headers.get("X-Forwarded-Proto")
1317+
forwarded_port = request.headers.get("X-Forwarded-Port")
1318+
log_triggered = request.path == "/robots.txt" or not forwarded_host or not forwarded_proto
1319+
ttl_raw = os.environ.get("LOG_REDIRECT_HEADERS_TTL_SEC", "300")
1320+
try:
1321+
ttl_sec = max(0, int(ttl_raw))
1322+
except ValueError:
1323+
ttl_sec = 300
1324+
host_key = host_only or raw_host or "unknown"
1325+
log_key = f"{host_key}|{request.path}"
1326+
now = time.time()
1327+
last_ts = _REDIRECT_HEADER_LOG_LAST.get(log_key)
1328+
should_log = log_triggered and (ttl_sec == 0 or last_ts is None or (now - last_ts) >= ttl_sec)
1329+
if should_log:
1330+
logger.info({
1331+
"level": "INFO",
1332+
"type": "status",
1333+
"message": "[RedirectHeaders] Incoming request headers snapshot",
1334+
"path": request.path,
1335+
"host": request.host,
1336+
"forwarded_host": forwarded_host,
1337+
"forwarded_proto": forwarded_proto,
1338+
"forwarded_port": forwarded_port,
1339+
"session_id": None,
1340+
})
1341+
_REDIRECT_HEADER_LOG_LAST[log_key] = now
1342+
13101343
# Skip redirects for local development (handle localhost with/without port, IPv4, IPv6)
13111344
if (host_only in ('localhost', '127.0.0.1', '::1') or
13121345
raw_host.startswith('localhost:') or

0 commit comments

Comments
 (0)