Hey! I recorded two video courses!
If you like this article, you will also like the courses! Check them out here!
Today’s post is a tiny one. I recently added a configuration option to Phx2ban that allows users to define routes that should be excluded from the Web Application Firewall (WAF) rules of Phx2ban. Basically, any request to any of the given routes should be ignored.
I wanted to allow the user to define the routes as strings (/my-path/foo
) but also as regex (~r/my-path/*
). We use NimbleOptions to validate the Phx2ban config, but it does not define a regex
type, so I was at a loss about how to allow both strings and regexes as a NimbleOption.
Luckily, I realized pretty quickly that the notation ~r/foo/
simply returns a Regex
struct, although it’s kind of hidden because of the way the Regex is printed out:
iex> IO.inspect(~r/foo/)
~r/foo/
However, I also learned that you can print out all information about a data type using the i/1
helper function. This revealed that the shorthand notation ~r/foo/
is simply a Regex
-struct!
iex> i ~r/foo/
Term
~r/foo/
Data type
Regex
Description
This is a struct representing a regular expression. It is commonly
represented using the `~r` sigil syntax, that is
defined in the `Kernel.sigil_r/2` macro.
Raw representation
%Regex{
re_pattern: {...},
source: "foo",
opts: [],
re_version: {"8.44 2020-02-12", :little}
}
Reference modules
Regex, :re
Implemented protocols
IEx.Info, Inspect
This meant that I could allow a regex in my NimbleOptions field with the type definition: {:struct, Regex}
.
This was my final type definition:
definition =
NimbleOptions.new!(
routes_to_ignore: [
default: [],
type: {:list, {:or, [:string, {:struct, Regex}]}}
]
)
Now, I was able to validate that the new configuration field only receives strings and regexes as input values:
iex> NimbleOptions.validate(%{routes_to_ignore: ["/wp-admin.php", ~r/django/]}, definition)
{:ok, %{routes_to_ignore: ["/wp-admin.php", ~r/django/]}}
🔗 Conclusion
And that’s it! I hope you enjoyed this article! If you want to support me, you can buy my firewall for Phoenix Phx2Ban or my book or video courses (one and two). Follow me on Bluesky or subscribe to my newsletter below if you want to get notified when I publish the next blog post. Until next time! Cheerio 👋