(fn load-from-json [path]
(let [data (iocaine.json.load path)]
(-> (icollect [k _ (pairs data)] k)
table.unpack
iocaine.Patterns)))
(fn string.starts-with [self start]
(= (self:sub 1 (length start)) start))
(local patterns
{:test-1 (iocaine.Patterns "ClaudeBot")
:data (load-from-json "tests/data/scripting/data.json")})
(local regexes
{:test-1 (iocaine.Regex "Firefox \\d\\.\\d")})
(local prefixes
{:test-1 (iocaine.net.Prefixes "207.241.237.0/24")})
(fn user-agent-bad? [request]
(when (= (request:header "user-agent") "iocaine-test::bad-agent")
iocaine.outcome.Garbage))
(fn request-method-invalid? [request]
(when (= request.method "INVALID")
iocaine.outcome.Garbage))
(fn request-path-in-cgi-bin? [request]
(when (request.path:starts-with "cgi-bin/")
iocaine.outcome.Garbage))
(fn capitalism? [request]
(case (request:query "capitalism")
"good" iocaine.outcome.Garbage
"bad" iocaine.outcome.NotForUs
x_ iocaine.outcome.Challenge))
(fn has-tracking-id? [request]
(when (not= (request:cookie "tracking-id") nil)
iocaine.outcome.Garbage))
(fn user-agent-matches-pattern? [request]
(when (patterns.test-1:contains (request:header "user-agent"))
iocaine.outcome.Garbage))
(fn user-agent-matches-regex? [request]
(when (regexes.test-1:matches (request:header "user-agent"))
iocaine.outcome.Garbage))
(fn forwarded-for-bad-network? [request]
(let [xff (request:header "x-forwarded-for")]
(when (and (not= xff nil)
(prefixes.test-1:contains (iocaine.net.Addr xff)))
iocaine.outcome.Garbage)))
(fn user-agent-in-json-data? [request]
(when (patterns.data:contains (request:header "user-agent"))
iocaine.outcome.Garbage))
(local all-tests [user-agent-bad?
request-method-invalid?
request-path-in-cgi-bin?
capitalism?
has-tracking-id?
user-agent-matches-pattern?
user-agent-matches-regex?
forwarded-for-bad-network?
user-agent-in-json-data?])
(fn decide [request]
(-> (accumulate [outcome nil
_ f (ipairs all-tests)
&until (not= outcome nil)]
(f request))
(or iocaine.outcome.NotForUs)))