Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cohttp-eio: response body not flushed? #1004

Open
smondet opened this issue Nov 6, 2023 · 2 comments
Open

Cohttp-eio: response body not flushed? #1004

smondet opened this issue Nov 6, 2023 · 2 comments
Labels

Comments

@smondet
Copy link

smondet commented Nov 6, 2023

Using the current master branch.

I have server code that hangs with:

Server.respond_string ~body:"Not found, sorry" ~status:`Not_found ()

"hangs" = curl client hangs, the ~stop argument of the server (the _ Promise.t) does not stop the server but the server logs show that it can handle more than one request.

It seems better with:

    Server.respond
      ~body:(Eio.Flow.string_source "Not found, sorry")
      ~status:`Not_found ()

"better = at least the client is "unlocked" and the ~stop argument (the _ Promise.t) does it's job. But the body is not actually transmitted.

It seems that this loop in cohttp-eio/src/utils.ml exits before sending any bytes:

let flow_to_writer flow writer write_body =
  let input = Eio.Buf_read.of_flow ~max_size:max_int flow in
  let rec loop () =
    let () =
      let () = Eio.Buf_read.ensure input 1 in
      let contents = Eio.Buf_read.(take (buffered_bytes input) input) in
      let () =
        Logs.debug (fun m -> m "send %d bytes of body" (String.length contents))
      in
      write_body writer contents
    in
    loop ()
  in
  try loop ()
  with End_of_file ->
    let () = Logs.debug (fun m -> m "end of outbound body") in
    ()

This is the debug output (in both cases of ~body: argument):

main.exe: [DEBUG] send headers
main.exe: [DEBUG] send body
main.exe: [DEBUG] end of outbound body

Any ideas?

(Eio 0.13, OCaml 5.1)

@mseri mseri added the Bug label Nov 6, 2023
@smondet
Copy link
Author

smondet commented Nov 7, 2023

Ok the "bug" was on my side.

For the historians: I had something that worked with 6.0.0~alpha1 and an earlier Eio that included being able to log the body of the response before sending it; with master since it's an Eio.Flow.t logging it, even with Eio.Flow.copy, consumes the stream so it is empty when flow_to_writer is called.

@talex5 should Eio.Flow.copy be called transfer or move instead?

@talex5
Copy link
Contributor

talex5 commented Nov 12, 2023

That's an interesting point about the name. However, it's not always a more (e.g. if the source is a file then the file data isn't deleted).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants