-module(kafein). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/kafein.gleam"). -export([default_options/0, send_builder/2, send/2, shutdown/1, 'receive'/2, receive_exact/3, receive_next_packet_as_message/1, select_ssl_messages/2, unsafe_cast/1, wrap/2]). -export_type([ssl_socket/0, tls_alert_kind/0, error/0, protocol_version/0, verification_type/0, certificate/0, wrap_options/0, ssl_message/0, connect_options/0, gen_tcp_option/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type ssl_socket() :: any(). -type tls_alert_kind() :: close_notify | unexpected_message | bad_record_mac | record_overflow | handshake_failure | bad_certificate | unsupported_certificate | certificate_revoked | certificate_expired | certificate_unknown | illegal_parameter | unknown_ca | access_denied | decode_error | decrypt_error | export_restriction | protocol_version | insufficient_security | internal_error | inappropriate_fallback | user_canceled | no_renegotiation | unsupported_extension | certificate_unobtainable | unrecognized_name | bad_certificate_status_response | bad_certificate_hash_value | unknown_psk_identity | no_application_protocol. -type error() :: closed | {options, gleam@dynamic:dynamic_()} | {other, gleam@dynamic:dynamic_()} | {tcp_error, mug:error()} | {cipher_suite_not_recognized, binary()} | {tls_alert, tls_alert_kind(), binary()}. -type protocol_version() :: tlsv1 | tlsv1m1 | tlsv1m2 | tlsv1m3. -type verification_type() :: verify_none | verify_peer. -type certificate() :: {certificate, binary(), binary(), gleam@option:option(fun(() -> binary()))}. -type wrap_options() :: {wrap_options, list(protocol_version()), list(binary()), gleam@option:option(binary()), list(binary()), integer(), verification_type(), list(certificate())}. -type ssl_message() :: {packet, ssl_socket(), bitstring()} | {socket_closed, ssl_socket()} | {ssl_error, ssl_socket(), error()}. -type connect_options() :: {versions, list(gleam@erlang@atom:atom_())} | {cacerts, gleam@dynamic:dynamic_()} | {depth, integer()} | {verify, verification_type()} | {ciphers, list(gleam@dynamic:dynamic_())} | {alpn_advertised_protocols, list(binary())} | {cacertfile, binary()} | {certs_keys, list(gleam@dict:dict(binary(), gleam@dynamic:dynamic_()))}. -type gen_tcp_option() :: {active, gleam@erlang@atom:atom_()}. -file("src/kafein.gleam", 113). ?DOC(" Default options when wrapping\n"). -spec default_options() -> wrap_options(). default_options() -> {wrap_options, [tlsv1m2, tlsv1m3], [], none, [], 100, verify_peer, []}. -file("src/kafein.gleam", 182). -spec send_builder(ssl_socket(), gleam@bytes_tree:bytes_tree()) -> {ok, nil} | {error, mug:error()}. send_builder(Socket, Data) -> kafein_ffi:send(Socket, Data). -file("src/kafein.gleam", 177). -spec send(ssl_socket(), bitstring()) -> {ok, nil} | {error, mug:error()}. send(Socket, Data) -> kafein_ffi:send(Socket, gleam@bytes_tree:from_bit_array(Data)). -file("src/kafein.gleam", 223). -spec shutdown(ssl_socket()) -> {ok, nil} | {error, mug:error()}. shutdown(Socket) -> kafein_ffi:shutdown(Socket). -file("src/kafein.gleam", 187). -spec 'receive'(ssl_socket(), integer()) -> {ok, bitstring()} | {error, mug:error()}. 'receive'(Socket, Timeout) -> ssl:recv(Socket, 0, Timeout). -file("src/kafein.gleam", 194). -spec receive_exact(ssl_socket(), integer(), integer()) -> {ok, bitstring()} | {error, mug:error()}. receive_exact(Socket, Size, Timeout) -> ssl:recv(Socket, Size, Timeout). -file("src/kafein.gleam", 202). -spec receive_next_packet_as_message(ssl_socket()) -> nil. receive_next_packet_as_message(Socket) -> ssl:setopts( Socket, [begin _pipe = erlang:binary_to_atom(<<"once"/utf8>>), {active, _pipe} end] ), nil. -file("src/kafein.gleam", 250). -spec optional(boolean(), fun(() -> HZJ)) -> list(HZJ). optional(Cond, Value) -> case Cond of true -> [Value()]; false -> [] end. -file("src/kafein.gleam", 207). -spec select_ssl_messages( gleam@erlang@process:selector(HZB), fun((ssl_message()) -> HZB) ) -> gleam@erlang@process:selector(HZB). select_ssl_messages(Selector, Mapper) -> Ssl = erlang:binary_to_atom(<<"ssl"/utf8>>), Closed = erlang:binary_to_atom(<<"ssl_closed"/utf8>>), Error = erlang:binary_to_atom(<<"ssl_error"/utf8>>), Map_message = fun(Msg) -> Mapper(kafein_ffi:coerce_ssl_message(Msg)) end, _pipe = Selector, _pipe@1 = gleam@erlang@process:select_record(_pipe, Ssl, 2, Map_message), _pipe@2 = gleam@erlang@process:select_record( _pipe@1, Closed, 1, Map_message ), gleam@erlang@process:select_record(_pipe@2, Error, 2, Map_message). -file("src/kafein.gleam", 273). -spec unsafe_cast(any()) -> any(). unsafe_cast(Value) -> kafein_ffi:unsafe_cast(Value). -file("src/kafein.gleam", 128). ?DOC( " Upgrades a TCP connection to SSL connection.\n" "\n" " Returns an error if upgrading was failed.\n" ). -spec wrap(mug:socket(), wrap_options()) -> {ok, ssl_socket()} | {error, error()}. wrap(Socket, Opts) -> gleam@result:'try'( kafein_ffi:strs_to_suites(erlang:element(5, Opts)), fun(Ciphers) -> Connect_options = lists:append( [[{versions, gleam@list:map( erlang:element(2, Opts), fun(Ver) -> erlang:binary_to_atom(case Ver of tlsv1 -> <<"tlsv1"/utf8>>; tlsv1m1 -> <<"tlsv1.1"/utf8>>; tlsv1m2 -> <<"tlsv1.2"/utf8>>; tlsv1m3 -> <<"tlsv1.3"/utf8>> end) end )}, {cacerts, public_key:cacerts_get()}, {depth, erlang:element(6, Opts)}, {verify, erlang:element(7, Opts)}, {certs_keys, gleam@list:map( erlang:element(8, Opts), fun(Cert) -> _pipe = maps:new(), _pipe@2 = gleam@dict:insert( _pipe, <<"certfile"/utf8>>, begin _pipe@1 = erlang:element(2, Cert), gleam_stdlib:identity(_pipe@1) end ), _pipe@4 = gleam@dict:insert( _pipe@2, <<"keyfile"/utf8>>, begin _pipe@3 = erlang:element(3, Cert), gleam_stdlib:identity(_pipe@3) end ), (fun(D) -> case erlang:element(4, Cert) of {some, Func} -> _pipe@5 = D, gleam@dict:insert( _pipe@5, <<"password"/utf8>>, begin _pipe@6 = Func, kafein_ffi:unsafe_cast( _pipe@6 ) end ); none -> D end end)(_pipe@4) end )}], optional( gleam@option:is_some(erlang:element(4, Opts)), fun() -> Path@1 = case erlang:element(4, Opts) of {some, Path} -> Path; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"kafein"/utf8>>, function => <<"wrap"/utf8>>, line => 165, value => _assert_fail, start => 4202, 'end' => 4241, pattern_start => 4213, pattern_end => 4223}) end, {cacertfile, Path@1} end ), optional( not gleam@list:is_empty(Ciphers), fun() -> {ciphers, Ciphers} end ), optional( not gleam@list:is_empty(erlang:element(3, Opts)), fun() -> {alpn_advertised_protocols, erlang:element(3, Opts)} end )] ), kafein_ffi:wrap(Socket, Connect_options) end ).