12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061(* Bitcoin_cohttp_async.ml
Copyright (c) 2021 Michael Bacarella <m@bacarella.com> *)open!Coreopen!Async(** Offers an implementation of a {!Bitcoin.HTTPCLIENT} using Cohttp's [Cohttp_lwt_async.Client].
*)(********************************************************************************)(** {1 Exceptions} *)(********************************************************************************)exceptionNo_response(********************************************************************************)(** {1 Private modules} *)(********************************************************************************)moduleC=CohttpmoduleCA=Cohttp_asyncmoduleCB=Cohttp_async.Body(********************************************************************************)(** {1 Public modules} *)(********************************************************************************)moduleHttpclient:Bitcoin.HTTPCLIENTwithtype'aMonad.t=('a,exn)Result.tDeferred.t=struct(* Unlike Lwt promises, Async promises don't attach errors to it. So,
we wrap Async promises around a Result.t to satisfy the interface. *)moduleMonad=structtype'at=('a,exn)Result.tDeferred.tletreturnv=Deferred.return(Okv)letfaile=Deferred.return(Errore)letbinddf=d>>=funres->matchreswith|Okv->fv|Errore->Deferred.return(Errore)letcatchfg=f()>>=funres->matchreswith|Okv->Deferred.return(Okv)|Errore->geendletpost_string~headers~inet_addr:_~host~port~urirequest=(* Leaving out the 'connection: close' here causes lingering old connections to pile up. *)letheaders=C.Header.of_list(("connection","close")::headers)inleturi=Uri.make~scheme:"http"~host~port~path:uri()inMonitor.try_with(fun()->Cohttp_async.Client.call~chunked:false~headers~body:(CB.of_stringrequest)`POSTuri)>>=funres->matchreswith|Errorexn->Monad.failexn|Ok(_,b)->CB.to_stringb>>=funbody->Monad.returnbodyend