aantron/dream

Flash message usage?

dbp opened this issue · 3 comments

dbp commented

I'm wondering if I've missed how to use the flash messages, or if. there is some incompatibility with cookie sessions, or...?

I have a (pretty small) application set up as:

Dream.set_log_level "dream.flash" `Debug;
  Dream.run ~interface:"0.0.0.0"
  @@ Dream.logger
  @@ Dream.set_secret (Sys.getenv "COOKIE_KEY")
  @@ Dream.flash
  @@ Dream.cookie_sessions
  @@ Dream.router [
...

In one handler, I set a message and redirect:

let () = Dream.add_flash_message request "Access" "You do not have access to that" in Dream.redirect request "/"

And in the handler for "/", I render them using the snippet from the example. But in the log, it seems like they are gone by the redirect:

09.12.23 22:20:29.068     dream.flash DEBUG REQ 1 Flash messages: Access: You do not have access to that
09.12.23 22:20:29.074       dream.log  INFO REQ 1 303 / in 7954 μs
09.12.23 22:20:29.076       dream.log  INFO REQ 2 GET / 127.0.0.1:62941 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_156
09.12.23 22:20:29.077     dream.flash DEBUG REQ 2 No flash messages.

Is there some configuration I am missing?

The basic flash example seems to work with cookie_sessions, at least for me locally. Could you provide an example that can be compiled, to observe this issue?

dbp commented

It seems like it is an interaction between the flash messages and Dream.get "/**". Here is a reproduction, I changed the flash example to:

let result request =
  <html>
  <body>

%   Dream.flash_messages request |> List.iter (fun (category, text) ->
      <p><%s category %>: <%s text %></p><% ); %>

  </body>
  </html>

let set_flash_middleware handler request =
  Dream.add_flash_message request "Info" "Hello!";
  handler request

let () =
  Dream.set_log_level "dream.flash" `Debug;
  Dream.run
  @@ Dream.logger
  @@ Dream.flash
  @@ Dream.cookie_sessions
  @@ Dream.router [

    Dream.get  "/"
      (fun request ->
        Dream.html (result request));

    Dream.scope "/set" [set_flash_middleware] [
      Dream.get "/**" (fun request -> Dream.redirect request "/")
    ];

  ]

And the log becomes:

12.12.23 14:18:04.285       dream.log  INFO REQ 2 GET /set/ 127.0.0.1:53358 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
12.12.23 14:18:04.288     dream.flash DEBUG REQ 2 Flash messages: Info: Hello!
12.12.23 14:18:04.293       dream.log  INFO REQ 2 303 / in 7638 μs
12.12.23 14:18:04.295       dream.log  INFO REQ 3 GET / 127.0.0.1:53358 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
12.12.23 14:18:04.295     dream.flash DEBUG REQ 3 No flash messages.
12.12.23 14:18:04.302       dream.log  INFO REQ 3 200 in 6174 μs

(I am using this to have access controlled static file serving... so I have middleware that authenticates, sets a flash message and redirects if not authenticated).

Looks like the flash message cookie is transmitted with a Path=/set attribute if ** is used. That seems wrong but I'll have to look into why it's like that. At first glance it looks like I changed the semantics of one of my helpers at some point, essentially reusing its name for a completely different purpose (site prefixes for multiple sites sharing a doman vs. the already-matched path prefix in the router), but I'll have to carefully check all the implications before fixing it. Thanks for the repro case!