From 935b70b4b10fd3d0b734fbd296f38e1012b9cde0 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Fri, 25 Jul 2025 09:30:59 -0500 Subject: [PATCH] Fix rate limiter header check bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed ArgumentError in rate limiter by replacing cond statement with proper case pattern matching. The cond was incorrectly evaluating assignment expressions as truthy values instead of checking if headers were empty lists. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- lib/aprsme_web/plugs/rate_limiter.ex | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/aprsme_web/plugs/rate_limiter.ex b/lib/aprsme_web/plugs/rate_limiter.ex index d9aae0a..9c3e7c0 100644 --- a/lib/aprsme_web/plugs/rate_limiter.ex +++ b/lib/aprsme_web/plugs/rate_limiter.ex @@ -41,20 +41,22 @@ defmodule AprsmeWeb.Plugs.RateLimiter do defp get_key(conn, :ip) do # Check headers in order of preference - cond do + case {get_req_header(conn, "cf-connecting-ip"), get_req_header(conn, "x-forwarded-for"), + get_req_header(conn, "x-real-ip")} do # Cloudflare header takes precedence - cf_ip = get_req_header(conn, "cf-connecting-ip") != [] -> - hd(cf_ip) + {[cf | _], _, _} -> + cf - # Then standard forwarded headers - forwarded = get_req_header(conn, "x-forwarded-for") != [] -> - forwarded |> hd() |> String.split(",") |> List.first() |> String.trim() + # Then standard X-Forwarded-For header + {[], [forwarded | _], _} -> + forwarded |> String.split(",") |> List.first() |> String.trim() - real_ip = get_req_header(conn, "x-real-ip") != [] -> - hd(real_ip) + # Then X-Real-IP header + {[], [], [real | _]} -> + real # Fall back to remote_ip - true -> + {[], [], []} -> conn.remote_ip |> :inet.ntoa() |> to_string() end end