Reputation: 345
I wrote the following OCaml code in order to make POST requests to an https server.
open Lwt
open Cohttp
open Cohttp_lwt_unix
try
let headers = Header.init ()
|> fun h -> Header.add h "content-type" "application/json" in
let body = Client.post
~headers
~body:(body_of_credentials nickname secret)
(uri_of_project project)
>>= fun (response, body) ->
let code = response |> Response.status |> Code.code_of_status in
Printf.printf "Response code: %d\n" code;
Printf.printf "Headers: %s\n" (response |> Response.headers |> Header.to_string);
body |> Cohttp_lwt.Body.to_string >|= fun body ->
Printf.printf "Body of length: %d\n" (String.length body);
body
in
let body = Lwt_main.run body in
print_endline ("Received body\n" ^ body)
with
| Tls_lwt.Tls_alert e ->
print_endline (Tls.Packet.alert_type_to_string e);
exit 1
But when executing it with CONDUIT_TLS=native CONDUIT_DEBUG=true COHTTP_DEBUG=true
I get the following response :
Selected TLS library: Native
Resolver system: https://my_server/auth/tokens/ ((name https) (port 443) (tls true)) -> (TCP ((V4 xx.xxx.xx.xxx) 443))
HANDSHAKE_FAILURE
I've read all the google results (documentation, ocaml/cohttp/ocaml-tls lists and stack overflow questions) I could find about it, but nothing helps, so I would like to start from scratch here.
How can I get more details about this failure ?
In case it helps, I'm using the following opam configuration:
"lwt" {>= "4.1.0"}
"cohttp" {>= "1.1.1"}
"cohttp-lwt"
"cohttp-lwt-unix" {>= "1.1.1"}
"tls" {>= "0.9.2"}
EDIT:
As suggested by @ivg, I tried with CONDUIT_TLS=openssl
but then I get the following error:
Selected TLS library: OpenSSL
Resolver system: https://my_server/auth/tokens/ ((name https) (port 443) (tls true)) -> (TCP ((V4 xx.xxx.xx.xxx) 443))
...: internal error, uncaught exception:
SSL: Method error
EDIT²:
As suggested in the following discussion: github.com/savonet/ocaml-ssl/issues/40 I added an opam pin to ssl-0.5.5
: opam pin add ssl 0.5.5
in order to fix this error. Now I am able to post requests to my https server, but not with the pure ocaml implementation of tls.
Upvotes: 1
Views: 182
Reputation: 35280
You're getting this alert because the handshaking process (authentication) had failed. This alert means, that the peer is not authenticated (either the server or the client) and thus a secure connection could not be established.
To debug the issue, I would suggest first to ensure that everything works fine with conventional tools, e.g., openssl
, wget
, or curl
.
If you're sure that your configuration is fine and this is a problem on the ocaml-tls
part I would suggest to use the low-level interface of the ocaml-tls
library. Apparently, conduit
doesn't expose or use any of the tracing capabilities of ocaml-tls
, so there is no other choice.
The alert type is projected from two more rich fatal
and error
types that bear much more information about the nature of the problem, cf. the following code that creates an alert and consider possible input values that lead to the HANDSHAKE_FAILURE
alert.
To access the particular error or alert I would suggest you to use the Tracing capabilities of ocaml-tls
. There are examples in the source repository that already enable tracing and should provide sufficient information. I hope those examples will fit into your use case.
Upvotes: 2