aantron/dream

How to configure CORS?

Opened this issue · 3 comments

I'm getting the following error while using Dream.graphql it with a frontend React app (running in a different port):

01.07.22 01:06:18.720       dream.log  INFO REQ 26 OPTIONS /graphql 127.0.0.1:39404 Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 6
01.07.22 01:06:18.720   dream.graphql ERROR REQ 26 Method OPTIONS; must be GET or POST
01.07.22 01:06:18.720       dream.log  WARN REQ 26 404 in 184 μs
It's from a different port so it will request OPTIONS to the server, but the endpoint is not configured for it

Fixed by adding a cors bypass middleware:

let cors_middleware inner_handler req =
  let new_headers =
    [
      ("Allow", "OPTIONS, GET, HEAD, POST");
      ("Access-Control-Allow-Origin", "*");
      ("Access-Control-Allow-Headers", "*");
    ]
  in
  let+ response = inner_handler req in

  new_headers
  |> List.map (fun (key, value) -> Dream.add_header response key value)
  |> ignore;

  response

and an OPTIONS route

Dream.options "/graphql" (fun _req ->
           Dream.respond ~headers:[ ("Allow", "OPTIONS, GET, HEAD, POST") ] ""); 

Of course, I need to change the allowed origin when changing to production.
I will close this issue if I couldn't find any better solution.

Thank you. I made similar middleware too:

let cors_middleware handler req =
  let handlers =
    [ "Allow", "OPTIONS, GET, HEAD, POST"
    ; "Access-Control-Allow-Origin", "*"
    ; "Access-Control-Allow-Methods", "OPTIONS, GET, HEAD, POST"
    ; "Access-Control-Allow-Headers", "Content-Type"
    ; "Access-Control-Max-Age", "86400"
    ]
  in
  let%lwt res = handler req in
  handlers
  |> List.map (fun (key, value) -> Dream.add_header res key value)
  |> ignore;
  Lwt.return res

Thank you! CORS is something that is probably best handled by Dream by offering an example. It's actually in the examples roadmap, but I haven't had time to create it yet. If some really common patterns emerge, maybe something is worth merging into Dream code.