EndPointBlank.OutboundUrl (end_point_blank_elixir v0.9.0)

Copy Markdown View Source

The part of a caller's outbound URL the SDK may keep, send to intake, or log: scheme and host (both lowercased; IPv6 in brackets), port when it is not the scheme's default (:443 for https, :80 for http), and path. Userinfo, query and fragment are removed (sc-1469). An empty port (https://api.test:/x) counts as none. Refused: any scheme other than http or https, and a port that is not a number from 1 to 65535.

The caller controls the URL passed to EndPointBlank.Authorization.header/1, and any of those three parts can carry a secret. intake needs none of them -- its base-URL normalizer refuses a URL carrying any of them, even an empty ? or #, and answers 422 -- so sending them would both leak them and guarantee the mint fails. Built from the parsed parts rather than by splitting the string, so an empty ? or # cannot slip through.

The same rule as the Ruby SDK's TargetUrl.strip (rails#43) and the JS, Python and Java SDKs' equivalents.

Summary

Functions

Returns {:ok, stripped}, or {:error, :invalid_base_url} when url is not a non-empty string, does not parse, has no host, has a scheme other than http or https, or has a port outside 1..65535. An error means no request may be made for it.

Functions

strip(url)

@spec strip(term()) :: {:ok, String.t()} | {:error, :invalid_base_url}

Returns {:ok, stripped}, or {:error, :invalid_base_url} when url is not a non-empty string, does not parse, has no host, has a scheme other than http or https, or has a port outside 1..65535. An error means no request may be made for it.

iex> EndPointBlank.OutboundUrl.strip("https://u:p@api.test:8443/v1/things?key=s#frag")
{:ok, "https://api.test:8443/v1/things"}

The path is kept raw, exactly as written; it is not downcased or decoded.