diff --git a/CHANGES.md b/CHANGES.md index 5d63a4acc8..42b5ec23a8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,8 @@ when deciding whether to use keep-alive. This allows a handler to decide to close a connection even if the client requested a keep-alive in the request. +- async(server): allow creating a server without using conduit (anuragsoni, #839) + + Add `Cohttp_async.Server.Expert.create` and `Cohttp_async.Server.Expert.create_with_response_action`that can be used to create a server without going through Conduit. This allows creating an async TCP server using the Tcp module from `Async_unix` and lets the user have more control over how the `Reader.t` and `Writer.t` are created. - *Breaking changes* + refactor: move opam metadata to dune-project (rgrinberg #811) + refactor: deprecate Cohttp_async.Io (rgrinberg #807) diff --git a/cohttp-async/src/server.ml b/cohttp-async/src/server.ml index 20e8c778c5..00fb33c8d2 100644 --- a/cohttp-async/src/server.ml +++ b/cohttp-async/src/server.ml @@ -149,3 +149,14 @@ let create ?max_connections ?backlog ?buffer_age_limit ?(mode = `TCP) in create_raw ?max_connections ?backlog ?buffer_age_limit ~on_handler_error ~mode where_to_listen handle_request + +module Expert = struct + let create handle_request addr reader writer = + let handle_request ~body addr request = + handle_request ~body addr request >>| fun r -> `Response r + in + handle_client handle_request addr reader writer + + let create_with_response_action handle_request addr reader writer = + handle_client handle_request addr reader writer +end diff --git a/cohttp-async/src/server.mli b/cohttp-async/src/server.mli index c41e4e4a95..8b93e9afeb 100644 --- a/cohttp-async/src/server.mli +++ b/cohttp-async/src/server.mli @@ -104,3 +104,31 @@ val create : response Async_kernel.Deferred.t) -> ('address, 'listening_on) t Async_kernel.Deferred.t (** Build a HTTP server, based on the [Tcp.Server] interface *) + +module Expert : sig + val create : + (body:Body.t -> 'addr -> Http.Request.t -> response Async_kernel.Deferred.t) -> + 'addr -> + Async_unix.Reader.t -> + Async_unix.Writer.t -> + unit Async_kernel.Deferred.t + (** [create] accepts a user provided cohttp handler, and creates a server + callback that works with user provided socket address, + [Async_unix.Reader.t] and [Async_unix.Writer.t]. This can be useful if + there is a need for more control over how the Reader and Writer get + created. *) + + val create_with_response_action : + (body:Body.t -> + 'addr -> + Http.Request.t -> + response_action Async_kernel.Deferred.t) -> + 'addr -> + Async_unix.Reader.t -> + Async_unix.Writer.t -> + unit Async_kernel.Deferred.t + (** [create_with_response_action] is similar to [create] but the user provided + handler can use [Cohttp_async.Server.response_action], and has access to + using the Expert mode response that can access the underlying + reader/writer pair from within the http handler. *) +end