mirage / ocaml-cohttp

An OCaml library for HTTP clients and servers using Lwt or Async
Other
713 stars 174 forks source link

Is it possible to use cohttp with my own io functions? #751

Closed hbr closed 3 years ago

hbr commented 3 years ago

I would like to use cohttp to make http and https requests. But the input/output shall go via my own io functions. I.e. I would like to initiate the tcp connection and let cohttp just work on buffers to send and receive messages from the peer, to do the tls encoding and http header parsing.

Is there a kind of a raw module in cohttp that makes this possible?

mseri commented 3 years ago

Yes, you need to implement a module with the signature of https://github.com/mirage/ocaml-cohttp/blob/c3a59cd11fae2ccf084fbfc3eb02b75773511d25/cohttp/src/s.ml#L22 Then you can make custom request and response modules with

module Request = struct
  include Cohttp.Request
  include (Make (Io) : module type of Make (Io) with type t := t)
  end

module Response = struct
  include Cohttp.Response
  include (Make (Io) : module type of Make (Io) with type t := t)
  end

You will also need to use/write the Net module and client or server depending on what you need. You can use https://github.com/mirage/ocaml-cohttp/blob/master/cohttp-lwt/src/s.ml to get an idea of the signature and either of async or lwt-unix implementations for how to plumb everything together.

hbr commented 3 years ago

Thanks. Where can I find the signature for the Net module?

mseri commented 3 years ago

It depends if you intend to use lwt, async, or something else. For seample, for lwt is here: https://github.com/mirage/ocaml-cohttp/blob/c3a59cd11fae2ccf084fbfc3eb02b75773511d25/cohttp-lwt/src/s.ml#L20

avsm commented 3 years ago

I assume the context here is for a Nodejs binding @hbr. For that, you almost certainly want to use the Lwt Net module signature that @mseri links to above. You can create a cohttp-lwt-node backend use instantiates the Cohttp_lwt functor -- have a look at how cohttp-mirage or cohttp-lwt-unix apply it for a template for the Node backend.

hbr commented 3 years ago

Thanks for the hints. If I need it, I have enough information to look into the pattern you have linked.

avsm commented 3 years ago

And of course, do feel free to PR your cohttp changes here; it's a reasonable thing to maintain a cohttp-node backend in this repository (we already have a client JavaScript implementation but no server)

avsm commented 3 years ago

And of course, do feel free to PR your cohttp changes here; it's a reasonable thing to maintain a cohttp-node backend in this repository (we already have a client JavaScript implementation but no server)

hbr commented 3 years ago

I don't understand your comment. What is the value added to have cohttp running in the browser or in node. The browser and node have already the builtin functionality to sent http(s) requests and node is able to act as a http(s) server.

I am interested in cohttp in order to have a http client and sever functionality in ocaml native and I am thinking to create a common interface (i.e module type) which can be implemented either by using the browser or node or natively via cohttp. Goal: The user code using http clients or servers is a functor which gets the browser/node implementation or the ocaml native implementation.