vpndetection_middleware (vpndetection v3.3.2)
View SourceThe framework-agnostic half of a web middleware: resolve a client address, classify it, and decide whether the condition matched.
An adapter - vpndetection_cowboy is the one we publish - keeps only the parts that are genuinely framework-shaped and shares everything here, so the shared conformance corpus is asserted once for Erlang rather than once per framework.
Blocking is opt-in. Without a block_condition this only enriches: every request carries a lookup() and what it means is the application's decision.
Summary
Functions
Whether a condition was configured at all.
Release the client this core built. A client PASSED IN stays open, because its owner is whoever passed it.
Classify one request.
Build a core, refusing a condition that constrains nothing.
Types
-opaque core()
-type lookup() :: #{blocked := boolean(), ip := binary() | undefined, result := vpndetection_result:result() | undefined, error := vpndetection_error:error() | undefined}.
-type options() :: #{client => vpndetection:client(), api_key => binary() | string(), base_url => binary() | string(), timeout_ms => pos_integer(), retries => non_neg_integer(), ip_selector => vpndetection_selectors:selector(), block_condition => vpndetection_condition:conditions(), fail_closed => boolean(), on_missing_field => warn | error | ignore, on_warn => fun((binary()) -> any())}.
Functions
Whether a condition was configured at all.
-spec close(core()) -> ok.
Release the client this core built. A client PASSED IN stays open, because its owner is whoever passed it.
-spec evaluate(core(), vpndetection_selectors:view()) -> {ok, lookup()} | {error, {missing_members, [binary()], binary()}}.
Classify one request.
A failed LOOKUP is not an error here: it lands on the error key and the request is let through. What CAN fail is a misconfiguration - a condition naming a member the plan does not serve, with on_missing_field set to error.
Build a core, refusing a condition that constrains nothing.