What is the simplest way to check that an incoming request contains a certain header value
Asked Answered
P

1

6

I have a simple Suave.io server in the form:

let Ok o = o |> JsonConvert.SerializeObject |> Successful.OK
let NotOk o = o |> JsonConvert.SerializeObject |> RequestErrors.BAD_REQUEST

type Result<'T> =
| Success of 'T
| Failure of string

let DoThing someParam anotherParam =
    let stats = Success(999) // <- business code here
    match stats with
    | Success s -> s |> Ok
    | Failure m -> m |> NotOk
...
        let app =
            choose
                [ GET >=> choose
                    [
                        pathScan "/someroute/%i/%i" (fun (p1, p2) -> 
                                DoThing p1 p2)
                    ] 
                ]
        startWebServer config app
        0

I would like to check that the request contains a header with a certain name and value and return NotOk when it is absent or incorrect. What's the simplest way to achieve this?

I'm a newcomer to Suave.io's compositional style.

Pounce answered 30/6, 2016 at 14:31 Comment(1)
you can look at: #31672610. I think you can than examine the request. Note: type WebPart = HttpContext -> Async<HttpContext option> and type HttpContext = { request: HttpRequest; response: HttpResponse }. So you need to unwrap the WebPart.Shaduf
S
4

I think that this would do what you need:

#r "Newtonsoft.Json.dll"
#r "Suave.dll"
#r "Suave.Testing.dll"
#r "System.Net.Http.dll"
#r "Fuchu.dll"

open System.Net
open System.Net.Http

open Suave
open Suave.Operators
open Newtonsoft.Json
open Suave.Filters
open Suave.Testing

let Ok o = o |> JsonConvert.SerializeObject |> Successful.OK
let NotOk o = o |> JsonConvert.SerializeObject |> RequestErrors.BAD_REQUEST

type Result<'T> =
| Success of 'T
| Failure of string

let DoThing someParam anotherParam =
    let stats = Success(999) // <- business code here
    match stats with
    | Success s -> s |> Ok
    | Failure m -> m |> NotOk

let checkHeader ctx =
    asyncOption {
        match "key" |> ctx.request.header with
        | Choice1Of2 k1 ->
            printfn "Header k1: %s" k1
            return ctx
        | Choice2Of2 k2 ->
            printfn "Header k2: %s" k2
            return { ctx with
                        response = { ctx.response with
                                        status = HTTP_400 } } }

let app =
    choose
        [ GET >=> choose
            [
                pathScan "/someroute/%i/%i" (fun (p1, p2) ->
                        DoThing p1 p2)
                >=> checkHeader
            ]
        ]

let emptyCont = new ByteArrayContent([||]) |> Some

runWith defaultConfig app
|> reqResp HttpMethod.GET 
           "/someroute/1/2" "" 
           None 
           None 
           DecompressionMethods.None
           id
           id

Make sure that you have the required libs in the same directory as this script and you can run it. Because there is no key header, the result will be a BAD_REQUEST with content 999.

The checkHeader does the trick.

Shaduf answered 1/7, 2016 at 17:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.