From 4d3989714adcbee1dd70ae0cef020652c80a7b4e Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Sun, 16 Feb 2025 23:11:28 -0500 Subject: [PATCH] wip: cohttp --- dune-project | 11 +++++ nanoev_cohttp.opam | 32 ++++++++++++++ src/cohttp/dune | 11 +++++ src/cohttp/nanoev_cohttp.ml | 85 ++++++++++++++++++++++++++++++++++++ src/cohttp/nanoev_cohttp.mli | 2 + 5 files changed, 141 insertions(+) create mode 100644 nanoev_cohttp.opam create mode 100644 src/cohttp/dune create mode 100644 src/cohttp/nanoev_cohttp.ml create mode 100644 src/cohttp/nanoev_cohttp.mli diff --git a/dune-project b/dune-project index e0cd8bb..b7b502d 100644 --- a/dune-project +++ b/dune-project @@ -37,4 +37,15 @@ (tiny_httpd (>= 0.17))) (tags (nanoev http))) +(package + (name nanoev_cohttp) + (synopsis "Use nanoev as a basis for cohttp") + (depends + ocaml + dune + nanoev + picos + (cohttp (>= 6.0))) + (tags (nanoev http))) + ; See the complete stanza docs at https://dune.readthedocs.io/en/stable/reference/dune-project/index.html diff --git a/nanoev_cohttp.opam b/nanoev_cohttp.opam new file mode 100644 index 0000000..7fdf885 --- /dev/null +++ b/nanoev_cohttp.opam @@ -0,0 +1,32 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "Use nanoev as a basis for cohttp" +maintainer: ["Simon Cruanes"] +authors: ["Simon Cruanes"] +license: "MIT" +tags: ["nanoev" "http"] +homepage: "https://github.com/c-cube/nanoev" +bug-reports: "https://github.com/c-cube/nanoev/issues" +depends: [ + "ocaml" + "dune" {>= "2.7"} + "nanoev" + "picos" + "cohttp" {>= "6.0"} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/c-cube/nanoev.git" diff --git a/src/cohttp/dune b/src/cohttp/dune new file mode 100644 index 0000000..d7902b2 --- /dev/null +++ b/src/cohttp/dune @@ -0,0 +1,11 @@ + +(library + (name nanoev_cohttp) + (public_name nanoev_cohttp) + (libraries + threads + picos + (re_export nanoev) + nanoev.picos + (re_export iostream) + (re_export cohttp))) diff --git a/src/cohttp/nanoev_cohttp.ml b/src/cohttp/nanoev_cohttp.ml new file mode 100644 index 0000000..5be5071 --- /dev/null +++ b/src/cohttp/nanoev_cohttp.ml @@ -0,0 +1,85 @@ +include Cohttp + +open struct + module Slice = Iostream.Slice +end + +module Base = struct + type 'a io = 'a + type 'a with_context = 'a + + type body = + [ `String of string + | `Stream of Iostream.In_buf.t + ] + + let map_context : 'a with_context -> ('a -> 'b) -> 'b with_context = ( |> ) + + (* + type body + + val map_context : 'a with_context -> ('a -> 'b) -> 'b with_context + + val call : + (?headers:Http.Header.t -> + ?body:body -> + ?chunked:bool -> + Http.Method.t -> + Uri.t -> + (Http.Response.t * body) io) + with_context + (** [call ?headers ?body ?chunked meth uri] + + @return + [(response, response_body)] Consume [response_body] in a timely fashion. + Please see {!val:call} about how and why. + @param chunked + use chunked encoding if [true]. The default is [false] for compatibility + reasons. *) + *) +end + +module IO = struct + type 'a t = 'a + + let ( >>= ) = ( |> ) + let return = Fun.id + + type ic = Iostream.In_buf.t + type oc = Iostream.Out_buf.t + type conn = Unix.sockaddr + + let refill (ic : ic) : [ `Eof | `Ok ] = + let slice = Iostream.In_buf.fill_buf ic in + if slice.len = 0 then + `Eof + else + `Ok + + let with_input_buffer (ic : ic) ~f = + let slice = Iostream.In_buf.fill_buf ic in + let res, consumed = + f (Bytes.unsafe_to_string slice.bytes) ~pos:0 ~len:slice.len + in + Iostream.In_buf.consume ic consumed; + res + + let read_line = Iostream.In_buf.input_line + + let read (ic : ic) (n : int) : string = + let bs = Bytes.create n in + let off = ref 0 in + let missing = ref n in + while !missing > 0 do + let n = Iostream.In_buf.input ic bs !off !missing in + off := !off + n; + missing := !missing - n + done; + Bytes.unsafe_to_string bs + + let write = Iostream.Out_buf.output_string + let flush = Iostream.Out_buf.flush +end + +module Client = Cohttp.Generic.Client.Make (Base) (IO) +module Server = Cohttp.Generic.Server.Make (Base) (IO) diff --git a/src/cohttp/nanoev_cohttp.mli b/src/cohttp/nanoev_cohttp.mli new file mode 100644 index 0000000..139597f --- /dev/null +++ b/src/cohttp/nanoev_cohttp.mli @@ -0,0 +1,2 @@ + +