Reputation: 241
I'm writing a Suave app and I want to stop if the origin ip is not in the authorized list for the route. For this I've written a small filter:
let RemoteIp (ipList: System.Net.IPAddress List) (x: Http.HttpContext) =
if (ipList |> List.map (fun ip -> x.clientIpTrustProxy.Equals ip ) |> List.contains true)
then
async.Return (Some x)
else
async.Return None
Then I fiter out with
Filters.path "/cache" >=> RemoteIp authorizedIps >=> Filters.GET >=> Successful.OK ""
so I get to process the call only if it comes from an IP in my authorized list, if not it just continues. However what I really want to do is to return 403. Right now I'm just short circuiting the route search.
Is there anything like a branch combinator?
Upvotes: 1
Views: 42
Reputation: 241
I endend writing a Branch function:
let Branch (x:WebPart) (y:WebPart) (z:WebPart): WebPart =
fun arg -> async {
let! res = x arg
match res with
| Some v -> return! y arg
| None -> return! z arg
}
So now I have something like
Filters.path "/cache" >=> Branch (RemoteIp authorizedIps) (Successful.OK "Yea!") (RequestErrors.FORBIDDEN "Nope")
It might come handy sometime, but really, what I should have thought of before is Fyodor's suggestion, which I think is more readable:
Filters.path "/cache" >=> choose [
RemoteIp authorizedIps >=> Successful.OK "Yea!"
RequestErrors.FORBIDDEN "Nope"
]
Upvotes: 2