package picos_io_cohttp
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=862d61383e2df93a876bedcffb1fd1ddc0f96c50b0e9c07943a2aee1f0e182be
sha512=87805379017ef4a7f2c11b954625a3757a0f1431bb9ba59132202de278b3e41adbe0cdc20e3ab23b7c9a8c5a15faeb7ec79348e7d80f2b14274b00df0893b8c0
doc/picos_io_cohttp/Picos_io_cohttp/index.html
Module Picos_io_cohttp
Source
Minimalistic Cohttp implementation using Picos_io
for Picos
.
⚠️ This library is currently minimalistic and experimental and is highly likely to change. Feedback from potential users is welcome!
Modules
Convenience functions for constructing requests and processing responses.
Convenience functions for processing requests and constructing responses.
Examples
First we open some modules for convenience:
open Cohttp
open Picos_io
open Picos_io_cohttp
open Picos_std_finally
open Picos_std_structured
A server and client
Let's build a simple hello server. We first define a function that creates and configures a socket for the server:
let server_create ?(max_pending_reqs = 8) addr =
let socket =
Unix.socket ~cloexec:true PF_INET SOCK_STREAM 0
in
match
Unix.set_nonblock socket;
Unix.bind socket addr;
Unix.listen socket max_pending_reqs
with
| () -> socket
| exception exn ->
Unix.close socket;
raise exn
The reason for doing it like this, as we'll see later, is that we want the OS to decide the port for our server. Also note that we explicitly set the socket to non-blocking mode, which is what we should do with Picos_io
whenever possible.
Then we'll define a function that runs a server given a socket:
let server_run socket =
let callback _conn _req body =
let body =
Printf.sprintf "Hello, %s!"
(Body.to_string body)
in
Server.respond_string ~status:`OK ~body ()
in
Server.run (Server.make ~callback ()) socket
The idea is that the body of the request is the name to be greeted in the body of the response.
A client then posts to the specified uri and returns the response body:
let client uri name =
let resp, body =
Client.post ~body:(`String name) uri
in
if Response.status resp != `OK then
failwith "Not OK";
Body.to_string body
Now we are ready to put everything together:
# Picos_mux_random.run_on ~n_domains:2 @@ fun () ->
let@ server_socket =
finally Unix.close @@ fun () ->
server_create
Unix.(ADDR_INET (inet_addr_loopback, 0))
in
let server_port =
match Unix.getsockname server_socket with
| ADDR_UNIX _ -> failwith "impossible"
| ADDR_INET (_, port) -> port
in
let server_uri =
Uri.make
~scheme:"http"
~host:"127.0.0.1"
~port:server_port
()
in
Flock.join_after ~on_return:`Terminate @@ fun () ->
Flock.fork begin fun () ->
server_run server_socket
end;
client server_uri "World"
- : string = "Hello, World!"
We first create the server_socket
and obtain the server_port
and ultimately the server_uri
from it — typically one can avoid this complexity and use a fixed port. We then create a flock for running the server as a concurrent fiber, which we arrange to terminate at the end of the scope. Finally we act as the client to get a greeting from the server.