-
Notifications
You must be signed in to change notification settings - Fork 170
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
Add expert mode for cohttp-lwt #647
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach looks great, and would be of course good to support websockets. I left some comments about the approach in the PR comments.
7b6c52e
to
5cb87e3
Compare
This approach and interface lgtm! Some tests to validate it stays working for websocket would be great before merging if possible. |
Will work on adding tests 👍
The current formulation of type response_action =
[ `Expert of Cohttp.Response.t
+ * Body.t option
* (IO.ic
-> IO.oc
-> unit Lwt.t)
| `Response of Cohttp.Response.t * Body.t ] In general, I would urge that we keep the type I'm a little concerned about this PR snowballing into a lot more changes though, as I'd like to see this PR merged... |
One option is to be explicit with the purpose of the response_action, and have:
Although I'm a little confused as to the purpose of the empty body write in the Async case. What's that actually sending out to the wire -- an empty HTTP chunked encoding ? |
I'm not sure why writing the empty body was part of #488 in the first place. It appears the main goal of that PR was to enable switching protocols, which can work despite writing the empty body when encoding is set to What's written on the wire depends on the encoding set on the response:
Given the above, I have a hard time coming up with a use case for writing providing both Unless I'm missing something, I would suggest to change the semantics for |
Anything I can do to help this move forward? If we can agree on the approach, I'd be happy to continue with implementation and tests (both Async and Lwt). |
I think that changing the semantics of |
Thank you for the comprehensive analysis! I agree with @andreas and @mseri that changing the semantics of Expert in makes more sense. We can merge and cut a major version bump with this change as soon as the PR is ready. |
Great, thanks! I'll proceed with the implementation and tests. |
@andreas when ready, if you merge with the master branch the Travis tests should now be green as well |
5cb87e3
to
b3d8e9b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the code now and added a basic test for both Lwt and Async.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fairly minor review comments from me; I'm happy to merge as soon as you're happy with the PR @andreas!
cohttp-lwt/src/server.ml
Outdated
Lwt.catch | ||
(fun () -> callback conn req body) | ||
(fun exn -> | ||
Format.eprintf "Error handling %a: %s\n%!" Request.pp_hum req (Printexc.to_string exn); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this use Logs
instead of directly printing to stderr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logs
is currently not a dependency of cohttp-lwt
, but I can add it if you want?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I think that would be a good idea - we need to eliminate printf errors from embeddable libraries
5bfc2ca
to
3e039f5
Compare
When ready to merge, if you could push a CHANGES entry that describes the backwards compat breaking change that would be helpful. I can roll several PRs into a major version bump. |
|
Thanks for the contribution! I'll prepare a release after a bit more testing -- in the meanwhile, ensuring that the master branch of cohttp works for your websocket/other libraries that need this feature would be most appreciated. |
Yay, thanks 😀
I have already developed some features against this locally -- I can share the source if it's of interest 😄 |
That would be great! Having more examples to point to in the README is probably one of cohttp's bigger user requests :-) |
It would be nice to be able to add the README as an Introduction page in the odoc/ocamldoc generated documentation. The little tool that broke github (md2mld) was made on purpose to try and do it on ocaml-rpc. Do you know a better way? |
md2mld seems just fine to me -- especially if it had a dune rule that just worked :-) The other place where the README shows up is in the |
…ohttp-top, cohttp-async and cohttp-mirage (2.0.0) CHANGES: Compatibility breaking interface changes: Async: Expert response action no longer writes empty HTTP body (mirage/ocaml-cohttp#647 by @andreas) In cohttp.0.99, a number of subpackages were turned into explicit opam packages to simplify dependency management. To aid migration, some compatability shims were left in place so that the old findlib names would continue to work. They have now been removed as of this release. If you were still using them, then please rename them as follows in your dune or ocamlbuild files: - `cohttp.lwt-core` -> `cohttp-lwt` - `cohttp.lwt` -> `cohttp-lwt-unix` - `cohttp.js` -> `cohttp-lwt-jsoo` - `cohttp.async` -> `cohttp-async` - `cohttp.top` -> `cohttp-top` Other changes and bugfixes: * Lwt, Mirage: Add log warnings for uncaught exceptions (mirage/ocaml-cohttp#592 by @ansiwen) * Log invalid client input and do not catch out of memory exceptions (mirage/ocaml-cohttp#652 @hannesm) * Port opam files to opam2 and add local synopsis and descriptions. * Lwt: Add Expert response action for servers (mirage/ocaml-cohttp#647 by @andreas) * Use the namespaced `js_of_ocaml` interfaces from 3.3.0 onwards (mirage/ocaml-cohttp#654 @avsm) * Use Base64 3.1.0 interfaces (mirage/ocaml-cohttp#655 @avsm) * Clean up redundant conflicts in the `opam` files (@avsm)
…ohttp-top, cohttp-async and cohttp-mirage (2.0.0) (#13388) CHANGES: Compatibility breaking interface changes: Async: Expert response action no longer writes empty HTTP body (mirage/ocaml-cohttp#647 by @andreas) In cohttp.0.99, a number of subpackages were turned into explicit opam packages to simplify dependency management. To aid migration, some compatability shims were left in place so that the old findlib names would continue to work. They have now been removed as of this release. If you were still using them, then please rename them as follows in your dune or ocamlbuild files: - `cohttp.lwt-core` -> `cohttp-lwt` - `cohttp.lwt` -> `cohttp-lwt-unix` - `cohttp.js` -> `cohttp-lwt-jsoo` - `cohttp.async` -> `cohttp-async` - `cohttp.top` -> `cohttp-top` Other changes and bugfixes: * Lwt, Mirage: Add log warnings for uncaught exceptions (mirage/ocaml-cohttp#592 by @ansiwen) * Log invalid client input and do not catch out of memory exceptions (mirage/ocaml-cohttp#652 @hannesm) * Port opam files to opam2 and add local synopsis and descriptions. * Lwt: Add Expert response action for servers (mirage/ocaml-cohttp#647 by @andreas) * Use the namespaced `js_of_ocaml` interfaces from 3.3.0 onwards (mirage/ocaml-cohttp#654 @avsm) * Use Base64 3.1.0 interfaces (mirage/ocaml-cohttp#655 @avsm) * Clean up redundant conflicts in the `opam` files (@avsm)
…ohttp-top, cohttp-async and cohttp-mirage (2.0.0) (#13388) CHANGES: Compatibility breaking interface changes: Async: Expert response action no longer writes empty HTTP body (mirage/ocaml-cohttp#647 by @andreas) In cohttp.0.99, a number of subpackages were turned into explicit opam packages to simplify dependency management. To aid migration, some compatability shims were left in place so that the old findlib names would continue to work. They have now been removed as of this release. If you were still using them, then please rename them as follows in your dune or ocamlbuild files: - `cohttp.lwt-core` -> `cohttp-lwt` - `cohttp.lwt` -> `cohttp-lwt-unix` - `cohttp.js` -> `cohttp-lwt-jsoo` - `cohttp.async` -> `cohttp-async` - `cohttp.top` -> `cohttp-top` Other changes and bugfixes: * Lwt, Mirage: Add log warnings for uncaught exceptions (mirage/ocaml-cohttp#592 by @ansiwen) * Log invalid client input and do not catch out of memory exceptions (mirage/ocaml-cohttp#652 @hannesm) * Port opam files to opam2 and add local synopsis and descriptions. * Lwt: Add Expert response action for servers (mirage/ocaml-cohttp#647 by @andreas) * Use the namespaced `js_of_ocaml` interfaces from 3.3.0 onwards (mirage/ocaml-cohttp#654 @avsm) * Use Base64 3.1.0 interfaces (mirage/ocaml-cohttp#655 @avsm) * Clean up redundant conflicts in the `opam` files (@avsm)
This PR adds "expert mode" to
cohttp-lwt
similar to what exists forcohttp-async
(#488).My primary use case is for websocket support like #488. The changes also relate to other issues regarding streaming though (#534, #529), and this approach could be used to solve those use cases. An
Expert
-response does currently not allow omitting a body (a decision inherited from #488), but if that was permitted, then it could be used to for writing/streaming bigarrays efficiently (mentioned here).I've rewritten the response/response handling, such that it no longer uses
Lwt_stream
. Though the abstraction of mapping a stream of requests to a stream of responses sounds elegant, I think it's actually simpler without it. In particular the use of refs (early_close
) and mutexes (read_m
) is no longer required. I'm happy to receive feedback on the choice though.I've not added any tests, but I'd be happy to if the overall approach is approved.
/cc @mattjbray