Plug.Parsers was trying to parse protobuf bodies as JSON, failing with 400 errors before the request reached the controller. Changes: - Added custom BodyReader to endpoint that skips parsing for protobuf - When Content-Type is application/x-protobuf, return empty body to parser - Controller reads the raw body directly for protobuf requests - Added error handling for protobuf decode failures in heartbeat endpoint This fixes the 400 errors agents were seeing on heartbeat requests.
79 lines
2.4 KiB
Elixir
79 lines
2.4 KiB
Elixir
defmodule ToweropsWeb.Endpoint do
|
|
use Phoenix.Endpoint, otp_app: :towerops
|
|
|
|
# The session will be stored in the cookie and signed,
|
|
# this means its contents can be read but not tampered with.
|
|
# Set :encryption_salt if you would also like to encrypt it.
|
|
@session_options [
|
|
store: :cookie,
|
|
key: "_towerops_key",
|
|
signing_salt: "hrDZxLhd",
|
|
same_site: "Lax"
|
|
]
|
|
|
|
socket "/live", Phoenix.LiveView.Socket,
|
|
websocket: [connect_info: [session: @session_options]],
|
|
longpoll: [connect_info: [session: @session_options]]
|
|
|
|
# Serve at "/" the static files from "priv/static" directory.
|
|
#
|
|
# When code reloading is disabled (e.g., in production),
|
|
# the `gzip` option is enabled to serve compressed
|
|
# static files generated by running `phx.digest`.
|
|
plug Plug.Static,
|
|
at: "/",
|
|
from: :towerops,
|
|
gzip: not code_reloading?,
|
|
only: ToweropsWeb.static_paths(),
|
|
raise_on_missing_only: code_reloading?
|
|
|
|
# Code reloading can be explicitly enabled under the
|
|
# :code_reloader configuration of your endpoint.
|
|
if code_reloading? do
|
|
socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
|
|
plug Phoenix.LiveReloader
|
|
plug Phoenix.CodeReloader
|
|
plug Phoenix.Ecto.CheckRepoStatus, otp_app: :towerops
|
|
end
|
|
|
|
plug Phoenix.LiveDashboard.RequestLogger,
|
|
param_key: "request_logger",
|
|
cookie_key: "request_logger"
|
|
|
|
plug Plug.RequestId
|
|
|
|
plug Plug.Telemetry,
|
|
event_prefix: [:phoenix, :endpoint],
|
|
log: {__MODULE__, :log_level, []}
|
|
|
|
plug Plug.Parsers,
|
|
parsers: [:urlencoded, :multipart, :json],
|
|
pass: ["*/*"],
|
|
body_reader: {ToweropsWeb.Endpoint.BodyReader, :read_body, []},
|
|
json_decoder: Phoenix.json_library()
|
|
|
|
# Custom body reader that skips parsing for protobuf content type
|
|
defmodule BodyReader do
|
|
@moduledoc false
|
|
def read_body(conn, opts) do
|
|
case Plug.Conn.get_req_header(conn, "content-type") do
|
|
["application/x-protobuf" | _] ->
|
|
# Don't parse protobuf, let the controller handle it
|
|
{:ok, "", conn}
|
|
|
|
_ ->
|
|
# Use default body reader for other content types
|
|
Plug.Conn.read_body(conn, opts)
|
|
end
|
|
end
|
|
end
|
|
|
|
plug Plug.MethodOverride
|
|
plug Plug.Head
|
|
plug Plug.Session, @session_options
|
|
plug ToweropsWeb.Router
|
|
|
|
# Disable logging for health check endpoint to reduce log noise from K8s probes
|
|
def log_level(%{path_info: ["health"]}), do: false
|
|
def log_level(_), do: :info
|
|
end
|