diff --git a/doc/buoy.md b/doc/buoy.md
deleted file mode 100644
index bea2ff4..0000000
--- a/doc/buoy.md
+++ /dev/null
@@ -1,352 +0,0 @@
-
-
-# Module buoy #
-* [Data Types](#types)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-
-
-## Data Types ##
-
-
-
-
-### backlog_size() ###
-
-
-
-backlog_size() = pos_integer() | infinity
-
-
-
-
-
-### body() ###
-
-
-
-body() = undefined | iodata()
-
-
-
-
-
-### buoy_opts() ###
-
-
-
-buoy_opts() = #{headers => headers(), body => body(), pid => pid(), timeout => non_neg_integer()}
-
-
-
-
-
-### buoy_resp() ###
-
-
-
-buoy_resp() = #buoy_resp{state = body | done, body = undefined | binary(), content_length = undefined | non_neg_integer() | chunked, headers = undefined | [binary()], reason = undefined | binary(), status_code = undefined | 100..505}
-
-
-
-
-
-### buoy_url() ###
-
-
-
-buoy_url() = #buoy_url{host = host(), hostname = hostname(), path = path(), port = inet:port_number(), protocol = protocol_http()}
-
-
-
-
-
-### client_option() ###
-
-
-
-client_option() = {init_options, init_options()} | {ip, inet:ip_address() | inet:hostname()} | {port, inet:port_number()} | {protocol, protocol()} | {reconnect, boolean()} | {reconnect_time_max, time() | infinity} | {reconnect_time_min, time()} | {socket_options, [gen_tcp:connect_option() | gen_udp:option()]}
-
-
-
-
-
-### client_options() ###
-
-
-
-client_options() = [client_option()]
-
-
-
-
-
-### error() ###
-
-
-
-error() = {error, term()}
-
-
-
-
-
-### headers() ###
-
-
-
-headers() = [{iodata(), iodata()}]
-
-
-
-
-
-### host() ###
-
-
-
-host() = binary()
-
-
-
-
-
-### hostname() ###
-
-
-
-hostname() = binary()
-
-
-
-
-
-### init_options() ###
-
-
-
-init_options() = term()
-
-
-
-
-
-### method() ###
-
-
-
-method() = get | post | put | {custom, binary()}
-
-
-
-
-
-### path() ###
-
-
-
-path() = binary()
-
-
-
-
-
-### pool_option() ###
-
-
-
-pool_option() = {backlog_size, backlog_size()} | {pool_size, pool_size()} | {pool_strategy, pool_strategy()}
-
-
-
-
-
-### pool_options() ###
-
-
-
-pool_options() = [pool_option()]
-
-
-
-
-
-### pool_size() ###
-
-
-
-pool_size() = pos_integer()
-
-
-
-
-
-### pool_strategy() ###
-
-
-
-pool_strategy() = random | round_robin
-
-
-
-
-
-### protocol() ###
-
-
-
-protocol() = shackle_ssl | shackle_tcp | shackle_udp
-
-
-
-
-
-### protocol_http() ###
-
-
-
-protocol_http() = http | https
-
-
-
-
-
-### request_id() ###
-
-
-
-request_id() = {server_name(), reference()}
-
-
-
-
-
-### server_name() ###
-
-
-
-server_name() = atom()
-
-
-
-
-
-### time() ###
-
-
-
-time() = pos_integer()
-
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### async_custom/3 ###
-
-
-async_custom(Verb::binary(), Url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, shackle:request_id()} | error()
-
-
-
-
-
-### async_get/2 ###
-
-
-async_get(Url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, shackle:request_id()} | error()
-
-
-
-
-
-### async_post/2 ###
-
-
-async_post(Url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, shackle:request_id()} | error()
-
-
-
-
-
-### async_put/2 ###
-
-
-async_put(Url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, shackle:request_id()} | error()
-
-
-
-
-
-### async_request/3 ###
-
-
-async_request(Method::method(), Buoy_url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, shackle:request_id()} | error()
-
-
-
-
-
-### custom/3 ###
-
-
-custom(Verb::binary(), Url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, buoy_resp()} | error()
-
-
-
-
-
-### get/2 ###
-
-
-get(Url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, buoy_resp()} | error()
-
-
-
-
-
-### post/2 ###
-
-
-post(Url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, buoy_resp()} | error()
-
-
-
-
-
-### put/2 ###
-
-
-put(Url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, buoy_resp()} | error()
-
-
-
-
-
-### receive_response/1 ###
-
-
-receive_response(RequestId::request_id()) -> {ok, term()} | error()
-
-
-
-
-
-### request/3 ###
-
-
-request(Method::method(), Buoy_url::buoy_url(), BuoyOpts::buoy_opts()) -> {ok, buoy_resp()} | error()
-
-
-
diff --git a/doc/buoy_app.md b/doc/buoy_app.md
deleted file mode 100644
index f4b1216..0000000
--- a/doc/buoy_app.md
+++ /dev/null
@@ -1,241 +0,0 @@
-
-
-# Module buoy_app #
-* [Data Types](#types)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-__Behaviours:__ [`application`](application.md).
-
-
-
-## Data Types ##
-
-
-
-
-### backlog_size() ###
-
-
-
-backlog_size() = pos_integer() | infinity
-
-
-
-
-
-### buoy_resp() ###
-
-
-
-buoy_resp() = #buoy_resp{state = body | done, body = undefined | binary(), content_length = undefined | non_neg_integer() | chunked, headers = undefined | [binary()], reason = undefined | binary(), status_code = undefined | 100..505}
-
-
-
-
-
-### buoy_url() ###
-
-
-
-buoy_url() = #buoy_url{host = host(), hostname = hostname(), path = path(), port = inet:port_number(), protocol = protocol_http()}
-
-
-
-
-
-### client_option() ###
-
-
-
-client_option() = {init_options, init_options()} | {ip, inet:ip_address() | inet:hostname()} | {port, inet:port_number()} | {protocol, protocol()} | {reconnect, boolean()} | {reconnect_time_max, time() | infinity} | {reconnect_time_min, time()} | {socket_options, [gen_tcp:connect_option() | gen_udp:option()]}
-
-
-
-
-
-### client_options() ###
-
-
-
-client_options() = [client_option()]
-
-
-
-
-
-### host() ###
-
-
-
-host() = binary()
-
-
-
-
-
-### hostname() ###
-
-
-
-hostname() = binary()
-
-
-
-
-
-### init_options() ###
-
-
-
-init_options() = term()
-
-
-
-
-
-### path() ###
-
-
-
-path() = binary()
-
-
-
-
-
-### pool_option() ###
-
-
-
-pool_option() = {backlog_size, backlog_size()} | {pool_size, pool_size()} | {pool_strategy, pool_strategy()}
-
-
-
-
-
-### pool_options() ###
-
-
-
-pool_options() = [pool_option()]
-
-
-
-
-
-### pool_size() ###
-
-
-
-pool_size() = pos_integer()
-
-
-
-
-
-### pool_strategy() ###
-
-
-
-pool_strategy() = random | round_robin
-
-
-
-
-
-### protocol() ###
-
-
-
-protocol() = shackle_ssl | shackle_tcp | shackle_udp
-
-
-
-
-
-### protocol_http() ###
-
-
-
-protocol_http() = http | https
-
-
-
-
-
-### request_id() ###
-
-
-
-request_id() = {server_name(), reference()}
-
-
-
-
-
-### server_name() ###
-
-
-
-server_name() = atom()
-
-
-
-
-
-### time() ###
-
-
-
-time() = pos_integer()
-
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### start/0 ###
-
-
-start() -> {ok, [atom()]}
-
-
-
-
-
-### start/2 ###
-
-
-start(StartType::application:start_type(), StartArgs::term()) -> {ok, pid()}
-
-
-
-
-
-### stop/0 ###
-
-
-stop() -> ok | {error, {not_started, buoy}}
-
-
-
-
-
-### stop/1 ###
-
-
-stop(State::term()) -> ok
-
-
-
diff --git a/doc/buoy_client.md b/doc/buoy_client.md
deleted file mode 100644
index c941b9c..0000000
--- a/doc/buoy_client.md
+++ /dev/null
@@ -1,258 +0,0 @@
-
-
-# Module buoy_client #
-* [Data Types](#types)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-
-
-## Data Types ##
-
-
-
-
-### backlog_size() ###
-
-
-
-backlog_size() = pos_integer() | infinity
-
-
-
-
-
-### buoy_resp() ###
-
-
-
-buoy_resp() = #buoy_resp{state = body | done, body = undefined | binary(), content_length = undefined | non_neg_integer() | chunked, headers = undefined | [binary()], reason = undefined | binary(), status_code = undefined | 100..505}
-
-
-
-
-
-### buoy_url() ###
-
-
-
-buoy_url() = #buoy_url{host = host(), hostname = hostname(), path = path(), port = inet:port_number(), protocol = protocol_http()}
-
-
-
-
-
-### client_option() ###
-
-
-
-client_option() = {init_options, init_options()} | {ip, inet:ip_address() | inet:hostname()} | {port, inet:port_number()} | {protocol, protocol()} | {reconnect, boolean()} | {reconnect_time_max, time() | infinity} | {reconnect_time_min, time()} | {socket_options, [gen_tcp:connect_option() | gen_udp:option()]}
-
-
-
-
-
-### client_options() ###
-
-
-
-client_options() = [client_option()]
-
-
-
-
-
-### host() ###
-
-
-
-host() = binary()
-
-
-
-
-
-### hostname() ###
-
-
-
-hostname() = binary()
-
-
-
-
-
-### init_options() ###
-
-
-
-init_options() = term()
-
-
-
-
-
-### path() ###
-
-
-
-path() = binary()
-
-
-
-
-
-### pool_option() ###
-
-
-
-pool_option() = {backlog_size, backlog_size()} | {pool_size, pool_size()} | {pool_strategy, pool_strategy()}
-
-
-
-
-
-### pool_options() ###
-
-
-
-pool_options() = [pool_option()]
-
-
-
-
-
-### pool_size() ###
-
-
-
-pool_size() = pos_integer()
-
-
-
-
-
-### pool_strategy() ###
-
-
-
-pool_strategy() = random | round_robin
-
-
-
-
-
-### protocol() ###
-
-
-
-protocol() = shackle_ssl | shackle_tcp | shackle_udp
-
-
-
-
-
-### protocol_http() ###
-
-
-
-protocol_http() = http | https
-
-
-
-
-
-### request_id() ###
-
-
-
-request_id() = {server_name(), reference()}
-
-
-
-
-
-### server_name() ###
-
-
-
-server_name() = atom()
-
-
-
-
-
-### state() ###
-
-
-
-state() = #state{bin_patterns = tuple(), buffer = binary(), requests_in = non_neg_integer(), requests_out = non_neg_integer(), response = undefined | buoy_resp()}
-
-
-
-
-
-### time() ###
-
-
-
-time() = pos_integer()
-
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### handle_data/2 ###
-
-
-handle_data(Data::binary(), State::state()) -> {ok, [{pos_integer(), term()}], state()} | {error, atom(), state()}
-
-
-
-
-
-### handle_request/2 ###
-
-
-handle_request(X1::term(), State::state()) -> {ok, non_neg_integer(), iodata(), state()}
-
-
-
-
-
-### init/1 ###
-
-
-init(Opts::undefined) -> {ok, state()}
-
-
-
-
-
-### setup/2 ###
-
-
-setup(Socket::inet:socket(), State::state()) -> {ok, state()}
-
-
-
-
-
-### terminate/1 ###
-
-
-terminate(State::state()) -> ok
-
-
-
diff --git a/doc/buoy_pool.md b/doc/buoy_pool.md
deleted file mode 100644
index b8cb550..0000000
--- a/doc/buoy_pool.md
+++ /dev/null
@@ -1,268 +0,0 @@
-
-
-# Module buoy_pool #
-* [Data Types](#types)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-
-
-## Data Types ##
-
-
-
-
-### backlog_size() ###
-
-
-
-backlog_size() = pos_integer() | infinity
-
-
-
-
-
-### buoy_resp() ###
-
-
-
-buoy_resp() = #buoy_resp{state = body | done, body = undefined | binary(), content_length = undefined | non_neg_integer() | chunked, headers = undefined | [binary()], reason = undefined | binary(), status_code = undefined | 100..505}
-
-
-
-
-
-### buoy_url() ###
-
-
-
-buoy_url() = #buoy_url{host = host(), hostname = hostname(), path = path(), port = inet:port_number(), protocol = protocol_http()}
-
-
-
-
-
-### client_option() ###
-
-
-
-client_option() = {init_options, init_options()} | {ip, inet:ip_address() | inet:hostname()} | {port, inet:port_number()} | {protocol, protocol()} | {reconnect, boolean()} | {reconnect_time_max, time() | infinity} | {reconnect_time_min, time()} | {socket_options, [gen_tcp:connect_option() | gen_udp:option()]}
-
-
-
-
-
-### client_options() ###
-
-
-
-client_options() = [client_option()]
-
-
-
-
-
-### host() ###
-
-
-
-host() = binary()
-
-
-
-
-
-### hostname() ###
-
-
-
-hostname() = binary()
-
-
-
-
-
-### init_options() ###
-
-
-
-init_options() = term()
-
-
-
-
-
-### option() ###
-
-
-
-option() = {backlog_size, pos_integer()} | {pool_size, pos_integer()} | {pool_strategy, random | round_robin} | {reconnect, boolean()} | {reconnect_time_max, pos_integer() | infinity} | {reconnect_time_min, pos_integer()}
-
-
-
-
-
-### options() ###
-
-
-
-options() = [option()]
-
-
-
-
-
-### path() ###
-
-
-
-path() = binary()
-
-
-
-
-
-### pool_option() ###
-
-
-
-pool_option() = {backlog_size, backlog_size()} | {pool_size, pool_size()} | {pool_strategy, pool_strategy()}
-
-
-
-
-
-### pool_options() ###
-
-
-
-pool_options() = [pool_option()]
-
-
-
-
-
-### pool_size() ###
-
-
-
-pool_size() = pos_integer()
-
-
-
-
-
-### pool_strategy() ###
-
-
-
-pool_strategy() = random | round_robin
-
-
-
-
-
-### protocol() ###
-
-
-
-protocol() = shackle_ssl | shackle_tcp | shackle_udp
-
-
-
-
-
-### protocol_http() ###
-
-
-
-protocol_http() = http | https
-
-
-
-
-
-### request_id() ###
-
-
-
-request_id() = {server_name(), reference()}
-
-
-
-
-
-### server_name() ###
-
-
-
-server_name() = atom()
-
-
-
-
-
-### time() ###
-
-
-
-time() = pos_integer()
-
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### init/0 ###
-
-
-init() -> ok
-
-
-
-
-
-### lookup/3 ###
-
-
-lookup(Protocol::protocol_http(), Hostname::hostname(), Port::inet:port_number()) -> {ok, atom()} | {error, pool_not_started}
-
-
-
-
-
-### start/1 ###
-
-
-start(Url::buoy_url()) -> ok | {error, pool_already_started | shackle_not_started}
-
-
-
-
-
-### start/2 ###
-
-
-start(Buoy_url::buoy_url(), Options::options()) -> ok | {error, pool_already_started | shackle_not_started}
-
-
-
-
-
-### stop/1 ###
-
-
-stop(Buoy_url::buoy_url()) -> ok | {error, shackle_not_started | pool_not_started}
-
-
-
diff --git a/doc/buoy_protocol.md b/doc/buoy_protocol.md
deleted file mode 100644
index f05fa9a..0000000
--- a/doc/buoy_protocol.md
+++ /dev/null
@@ -1,298 +0,0 @@
-
-
-# Module buoy_protocol #
-* [Data Types](#types)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-
-
-## Data Types ##
-
-
-
-
-### backlog_size() ###
-
-
-
-backlog_size() = pos_integer() | infinity
-
-
-
-
-
-### bin_patterns() ###
-
-
-
-bin_patterns() = #bin_patterns{rn = binary:cp(), rnrn = binary:cp()}
-
-
-
-
-
-### body() ###
-
-
-
-body() = undefined | iodata()
-
-
-
-
-
-### buoy_resp() ###
-
-
-
-buoy_resp() = #buoy_resp{state = body | done, body = undefined | binary(), content_length = undefined | non_neg_integer() | chunked, headers = undefined | [binary()], reason = undefined | binary(), status_code = undefined | 100..505}
-
-
-
-
-
-### buoy_url() ###
-
-
-
-buoy_url() = #buoy_url{host = host(), hostname = hostname(), path = path(), port = inet:port_number(), protocol = protocol_http()}
-
-
-
-
-
-### client_option() ###
-
-
-
-client_option() = {init_options, init_options()} | {ip, inet:ip_address() | inet:hostname()} | {port, inet:port_number()} | {protocol, protocol()} | {reconnect, boolean()} | {reconnect_time_max, time() | infinity} | {reconnect_time_min, time()} | {socket_options, [gen_tcp:connect_option() | gen_udp:option()]}
-
-
-
-
-
-### client_options() ###
-
-
-
-client_options() = [client_option()]
-
-
-
-
-
-### error() ###
-
-
-
-error() = {error, term()}
-
-
-
-
-
-### headers() ###
-
-
-
-headers() = [{iodata(), iodata()}]
-
-
-
-
-
-### host() ###
-
-
-
-host() = binary()
-
-
-
-
-
-### hostname() ###
-
-
-
-hostname() = binary()
-
-
-
-
-
-### init_options() ###
-
-
-
-init_options() = term()
-
-
-
-
-
-### method() ###
-
-
-
-method() = get | post | put | {custom, binary()}
-
-
-
-
-
-### path() ###
-
-
-
-path() = binary()
-
-
-
-
-
-### pool_option() ###
-
-
-
-pool_option() = {backlog_size, backlog_size()} | {pool_size, pool_size()} | {pool_strategy, pool_strategy()}
-
-
-
-
-
-### pool_options() ###
-
-
-
-pool_options() = [pool_option()]
-
-
-
-
-
-### pool_size() ###
-
-
-
-pool_size() = pos_integer()
-
-
-
-
-
-### pool_strategy() ###
-
-
-
-pool_strategy() = random | round_robin
-
-
-
-
-
-### protocol() ###
-
-
-
-protocol() = shackle_ssl | shackle_tcp | shackle_udp
-
-
-
-
-
-### protocol_http() ###
-
-
-
-protocol_http() = http | https
-
-
-
-
-
-### request_id() ###
-
-
-
-request_id() = {server_name(), reference()}
-
-
-
-
-
-### server_name() ###
-
-
-
-server_name() = atom()
-
-
-
-
-
-### time() ###
-
-
-
-time() = pos_integer()
-
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### bin_patterns/0 ###
-
-
-bin_patterns() -> bin_patterns()
-
-
-
-
-
-### headers/1 ###
-
-
-headers(Buoy_resp::buoy_resp()) -> {ok, headers()} | {error, invalid_headers}
-
-
-
-
-
-### request/5 ###
-
-
-request(Method::method(), Path::path(), Headers::headers(), Host::host(), Body::body()) -> iolist()
-
-
-
-
-
-### response/1 ###
-
-
-response(Data::binary()) -> {ok, buoy_resp(), binary()} | error()
-
-
-
-
-
-### response/3 ###
-
-
-response(Data::binary(), Buoy_resp::undefined | buoy_resp(), BinPatterns::bin_patterns()) -> {ok, buoy_resp(), binary()} | error()
-
-
-
diff --git a/doc/buoy_sup.md b/doc/buoy_sup.md
deleted file mode 100644
index 96b894c..0000000
--- a/doc/buoy_sup.md
+++ /dev/null
@@ -1,223 +0,0 @@
-
-
-# Module buoy_sup #
-* [Data Types](#types)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-__Behaviours:__ [`supervisor`](supervisor.md).
-
-
-
-## Data Types ##
-
-
-
-
-### backlog_size() ###
-
-
-
-backlog_size() = pos_integer() | infinity
-
-
-
-
-
-### buoy_resp() ###
-
-
-
-buoy_resp() = #buoy_resp{state = body | done, body = undefined | binary(), content_length = undefined | non_neg_integer() | chunked, headers = undefined | [binary()], reason = undefined | binary(), status_code = undefined | 100..505}
-
-
-
-
-
-### buoy_url() ###
-
-
-
-buoy_url() = #buoy_url{host = host(), hostname = hostname(), path = path(), port = inet:port_number(), protocol = protocol_http()}
-
-
-
-
-
-### client_option() ###
-
-
-
-client_option() = {init_options, init_options()} | {ip, inet:ip_address() | inet:hostname()} | {port, inet:port_number()} | {protocol, protocol()} | {reconnect, boolean()} | {reconnect_time_max, time() | infinity} | {reconnect_time_min, time()} | {socket_options, [gen_tcp:connect_option() | gen_udp:option()]}
-
-
-
-
-
-### client_options() ###
-
-
-
-client_options() = [client_option()]
-
-
-
-
-
-### host() ###
-
-
-
-host() = binary()
-
-
-
-
-
-### hostname() ###
-
-
-
-hostname() = binary()
-
-
-
-
-
-### init_options() ###
-
-
-
-init_options() = term()
-
-
-
-
-
-### path() ###
-
-
-
-path() = binary()
-
-
-
-
-
-### pool_option() ###
-
-
-
-pool_option() = {backlog_size, backlog_size()} | {pool_size, pool_size()} | {pool_strategy, pool_strategy()}
-
-
-
-
-
-### pool_options() ###
-
-
-
-pool_options() = [pool_option()]
-
-
-
-
-
-### pool_size() ###
-
-
-
-pool_size() = pos_integer()
-
-
-
-
-
-### pool_strategy() ###
-
-
-
-pool_strategy() = random | round_robin
-
-
-
-
-
-### protocol() ###
-
-
-
-protocol() = shackle_ssl | shackle_tcp | shackle_udp
-
-
-
-
-
-### protocol_http() ###
-
-
-
-protocol_http() = http | https
-
-
-
-
-
-### request_id() ###
-
-
-
-request_id() = {server_name(), reference()}
-
-
-
-
-
-### server_name() ###
-
-
-
-server_name() = atom()
-
-
-
-
-
-### time() ###
-
-
-
-time() = pos_integer()
-
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### init/1 ###
-
-
-init(X1::[]) -> {ok, {{one_for_one, 5, 10}, []}}
-
-
-
-
-
-### start_link/0 ###
-
-
-start_link() -> {ok, pid()}
-
-
-
diff --git a/doc/buoy_utils.md b/doc/buoy_utils.md
deleted file mode 100644
index d08c315..0000000
--- a/doc/buoy_utils.md
+++ /dev/null
@@ -1,212 +0,0 @@
-
-
-# Module buoy_utils #
-* [Data Types](#types)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-
-
-## Data Types ##
-
-
-
-
-### backlog_size() ###
-
-
-
-backlog_size() = pos_integer() | infinity
-
-
-
-
-
-### buoy_resp() ###
-
-
-
-buoy_resp() = #buoy_resp{state = body | done, body = undefined | binary(), content_length = undefined | non_neg_integer() | chunked, headers = undefined | [binary()], reason = undefined | binary(), status_code = undefined | 100..505}
-
-
-
-
-
-### buoy_url() ###
-
-
-
-buoy_url() = #buoy_url{host = host(), hostname = hostname(), path = path(), port = inet:port_number(), protocol = protocol_http()}
-
-
-
-
-
-### client_option() ###
-
-
-
-client_option() = {init_options, init_options()} | {ip, inet:ip_address() | inet:hostname()} | {port, inet:port_number()} | {protocol, protocol()} | {reconnect, boolean()} | {reconnect_time_max, time() | infinity} | {reconnect_time_min, time()} | {socket_options, [gen_tcp:connect_option() | gen_udp:option()]}
-
-
-
-
-
-### client_options() ###
-
-
-
-client_options() = [client_option()]
-
-
-
-
-
-### host() ###
-
-
-
-host() = binary()
-
-
-
-
-
-### hostname() ###
-
-
-
-hostname() = binary()
-
-
-
-
-
-### init_options() ###
-
-
-
-init_options() = term()
-
-
-
-
-
-### path() ###
-
-
-
-path() = binary()
-
-
-
-
-
-### pool_option() ###
-
-
-
-pool_option() = {backlog_size, backlog_size()} | {pool_size, pool_size()} | {pool_strategy, pool_strategy()}
-
-
-
-
-
-### pool_options() ###
-
-
-
-pool_options() = [pool_option()]
-
-
-
-
-
-### pool_size() ###
-
-
-
-pool_size() = pos_integer()
-
-
-
-
-
-### pool_strategy() ###
-
-
-
-pool_strategy() = random | round_robin
-
-
-
-
-
-### protocol() ###
-
-
-
-protocol() = shackle_ssl | shackle_tcp | shackle_udp
-
-
-
-
-
-### protocol_http() ###
-
-
-
-protocol_http() = http | https
-
-
-
-
-
-### request_id() ###
-
-
-
-request_id() = {server_name(), reference()}
-
-
-
-
-
-### server_name() ###
-
-
-
-server_name() = atom()
-
-
-
-
-
-### time() ###
-
-
-
-time() = pos_integer()
-
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### parse_url/1 ###
-
-
-parse_url(X1::binary()) -> buoy_url() | {error, invalid_url}
-
-
-
diff --git a/doc/edoc-info b/doc/edoc-info
deleted file mode 100644
index baff42f..0000000
--- a/doc/edoc-info
+++ /dev/null
@@ -1,4 +0,0 @@
-%% encoding: UTF-8
-{application,buoy}.
-{modules,[buoy,buoy_app,buoy_client,buoy_pool,buoy_protocol,buoy_sup,
- buoy_utils]}.
diff --git a/include/buoy.hrl b/include/buoy.hrl
index 8d2b041..e87e523 100644
--- a/include/buoy.hrl
+++ b/include/buoy.hrl
@@ -9,38 +9,16 @@
}).
-record(buoy_url, {
- host :: host(),
- hostname :: hostname(),
- path :: path(),
+ host :: buoy:host(),
+ hostname :: buoy:hostname(),
+ path :: buoy:path(),
port :: inet:port_number(),
- protocol :: protocol_http()
+ protocol :: buoy_pool:protocol()
}).
-%% types
--type body() :: undefined | iodata().
--type buoy_opts() :: #{headers => headers(),
- body => body(),
- pid => pid(),
- timeout => non_neg_integer()}.
--type buoy_resp() :: #buoy_resp {}.
--type buoy_url() :: #buoy_url {}.
--type error() :: {error, term()}.
--type headers() :: [{iodata(), iodata()}].
--type host() :: binary().
--type hostname() :: binary().
--type method() :: get | head | post | put | {custom, binary()}.
--type option() :: {backlog_size, pos_integer()} |
- {pool_size, pos_integer()} |
- {pool_strategy, random | round_robin} |
- {reconnect, boolean()} |
- {reconnect_time_max, pos_integer() | infinity} |
- {reconnect_time_min, pos_integer()} |
- {socket_options, [gen_tcp:connect_option() | ssl:tls_client_option()]}.
--type options() :: [option()].
--type path() :: binary().
--type protocol_http() :: http | https.
-
--export_type([
- buoy_resp/0,
- buoy_url/0
-]).
+-record(buoy_req, {
+ method :: buoy:method(),
+ url :: buoy:url(),
+ headers :: buoy:headers(),
+ body :: buoy:body()
+}).
diff --git a/include/buoy_internal.hrl b/include/buoy_internal.hrl
index a45da3f..e8a0f4b 100644
--- a/include/buoy_internal.hrl
+++ b/include/buoy_internal.hrl
@@ -1,6 +1,3 @@
--include("buoy.hrl").
--include_lib("shackle/include/shackle.hrl").
-
%% macros
-define(APP, buoy).
-define(CLIENT, buoy_client).
diff --git a/rebar.config b/rebar.config
index a70b2eb..c17bae2 100644
--- a/rebar.config
+++ b/rebar.config
@@ -2,20 +2,23 @@
{foil, ".*",
{git, "https://github.com/lpgauth/foil.git", {tag, "0.1.2"}}},
{shackle, ".*",
- {git, "https://github.com/lpgauth/shackle.git", {tag, "0.6.19"}}}
+ {git, "https://github.com/rkallos/shackle.git", {ref, "3da046743a9ba83ee0e54dbdd2e158b937244eeb"}}}
]}.
+{plugins, [rebar3_hex, rebar3_ex_doc]}.
+
{dialyzer, [{plt_extra_apps, [public_key]}]}.
+{hex, [
+ {doc, #{provider => ex_doc}}
+]}.
-{edoc_opts, [
- {app_default, "http://www.erlang.org/doc/man"},
- {doclet, edown_doclet},
- {image, ""},
- {includes, ["include"]},
- {preprocess, true},
- {stylesheet, ""},
- {title, "anchor"}
+{ex_doc, [
+ {api_reference, false},
+ {extras, ["README.md"]},
+ {main, "readme"},
+ {prefix_ref_vsn_with_v, false},
+ {source_url, "https://github.com/lpgauth/buoy"}
]}.
{erl_opts, [
@@ -36,12 +39,6 @@
warn_unused_vars
]}
]},
- {edoc, [
- {deps, [
- {edown,
- {git, "https://github.com/uwiger/edown.git", {tag, "0.7"}}}
- ]}
- ]},
{test, [
{deps, [
{cowboy,
diff --git a/rebar.lock b/rebar.lock
index d09ed63..c9ebd50 100644
--- a/rebar.lock
+++ b/rebar.lock
@@ -9,12 +9,15 @@
1},
{<<"metal">>,{pkg,<<"metal">>,<<"0.1.1">>},1},
{<<"shackle">>,
- {git,"https://github.com/lpgauth/shackle.git",
- {ref,"a4f7d82d10115cf0d676582b638a56260be685d5"}},
- 0}]}.
+ {git,"https://github.com/rkallos/shackle.git",
+ {ref,"3da046743a9ba83ee0e54dbdd2e158b937244eeb"}},
+ 0},
+ {<<"telemetry">>,{pkg,<<"telemetry">>,<<"1.2.1">>},1}]}.
[
{pkg_hash,[
- {<<"metal">>, <<"5D3D1322DA7BCD34B94FED5486F577973685298883954F7A3E517EF5EF6953F5">>}]},
+ {<<"metal">>, <<"5D3D1322DA7BCD34B94FED5486F577973685298883954F7A3E517EF5EF6953F5">>},
+ {<<"telemetry">>, <<"68FDFE8D8F05A8428483A97D7AAB2F268AAFF24B49E0F599FAA091F1D4E7F61C">>}]},
{pkg_hash_ext,[
- {<<"metal">>, <<"88B82B634998A1A768DEDCD372C2F7E657B19445325C0AF5CCBAC62C77210F1D">>}]}
+ {<<"metal">>, <<"88B82B634998A1A768DEDCD372C2F7E657B19445325C0AF5CCBAC62C77210F1D">>},
+ {<<"telemetry">>, <<"DAD9CE9D8EFFC621708F99EAC538EF1CBE05D6A874DD741DE2E689C47FEAFED5">>}]}
].
diff --git a/src/buoy.erl b/src/buoy.erl
index 1c1d842..aa31395 100644
--- a/src/buoy.erl
+++ b/src/buoy.erl
@@ -1,4 +1,5 @@
-module(buoy).
+-include("buoy.hrl").
-include("buoy_internal.hrl").
-compile(inline).
@@ -20,53 +21,86 @@
request/3
]).
+%% types
+-type body() :: undefined | iodata().
+-type error() :: {error, term()}.
+-type headers() :: [{iodata(), iodata()}].
+-type host() :: binary().
+-type hostname() :: binary().
+-type method() :: get | head | post | put | {custom, binary()}.
+-type opts() :: #{headers => headers(),
+ body => body(),
+ pid => pid(),
+ timeout => non_neg_integer()}.
+-type path() :: binary().
+-type req() :: #buoy_req {}.
+-type resp() :: #buoy_resp {}.
+-type url() :: #buoy_url {}.
+
+-export_type([
+ body/0,
+ error/0,
+ headers/0,
+ host/0,
+ hostname/0,
+ method/0,
+ opts/0,
+ path/0,
+ req/0,
+ resp/0,
+ url/0
+]).
+
%% public
--spec async_custom(binary(), buoy_url(), buoy_opts()) ->
+-spec async_custom(binary(), url(), opts()) ->
{ok, shackle:request_id()} | error().
async_custom(Verb, Url, BuoyOpts) ->
async_request({custom, Verb}, Url, BuoyOpts).
--spec async_get(buoy_url(), buoy_opts()) ->
+-spec async_get(url(), opts()) ->
{ok, shackle:request_id()} | error().
async_get(Url, BuoyOpts) ->
async_request(get, Url, BuoyOpts).
--spec async_head(buoy_url(), buoy_opts()) ->
+-spec async_head(url(), opts()) ->
{ok, shackle:request_id()} | error().
async_head(Url, BuoyOpts) ->
async_request(head, Url, BuoyOpts).
--spec async_post(buoy_url(), buoy_opts()) ->
+-spec async_post(url(), opts()) ->
{ok, shackle:request_id()} | error().
async_post(Url, BuoyOpts) ->
async_request(post, Url, BuoyOpts).
--spec async_put(buoy_url(), buoy_opts()) ->
+-spec async_put(url(), opts()) ->
{ok, shackle:request_id()} | error().
async_put(Url, BuoyOpts) ->
async_request(put, Url, BuoyOpts).
--spec async_request(method(), buoy_url(), buoy_opts()) ->
+-spec async_request(method(), url(), opts()) ->
{ok, shackle:request_id()} | error().
async_request(Method, #buoy_url {
protocol = Protocol,
- host = Host,
hostname = Hostname,
- port = Port,
- path = Path
- }, BuoyOpts) ->
+ port = Port
+ } = Url, BuoyOpts) ->
case buoy_pool:lookup(Protocol, Hostname, Port) of
{ok, PoolName} ->
Headers = buoy_opts(headers, BuoyOpts),
Body = buoy_opts(body, BuoyOpts),
- Request = {request, Method, Path, Headers, Host, Body},
+ Request = #buoy_req{
+ method = Method,
+ url = Url,
+ headers = Headers,
+ body = Body
+ },
Pid = buoy_opts(pid, BuoyOpts),
Timeout = buoy_opts(timeout, BuoyOpts),
shackle:cast(PoolName, Request, Pid, Timeout);
@@ -74,58 +108,61 @@ async_request(Method, #buoy_url {
E
end.
--spec custom(binary(), buoy_url(), buoy_opts()) ->
- {ok, buoy_resp()} | error().
+-spec custom(binary(), url(), opts()) ->
+ {ok, resp()} | error().
custom(Verb, Url, BuoyOpts) ->
request({custom, Verb}, Url, BuoyOpts).
--spec get(buoy_url(), buoy_opts()) ->
- {ok, buoy_resp()} | error().
+-spec get(url(), opts()) ->
+ {ok, resp()} | error().
get(Url, BuoyOpts) ->
request(get, Url, BuoyOpts).
--spec head(buoy_url(), buoy_opts()) ->
- {ok, buoy_resp()} | error().
+-spec head(url(), opts()) ->
+ {ok, resp()} | error().
head(Url, BuoyOpts) ->
request(head, Url, BuoyOpts).
--spec post(buoy_url(), buoy_opts()) ->
- {ok, buoy_resp()} | error().
+-spec post(url(), opts()) ->
+ {ok, resp()} | error().
post(Url, BuoyOpts) ->
request(post, Url, BuoyOpts).
--spec put(buoy_url(), buoy_opts()) ->
- {ok, buoy_resp()} | error().
+-spec put(url(), opts()) ->
+ {ok, resp()} | error().
put(Url, BuoyOpts) ->
request(put, Url, BuoyOpts).
--spec receive_response(request_id()) ->
+-spec receive_response(shackle:request_id()) ->
{ok, term()} | error().
receive_response(RequestId) ->
shackle:receive_response(RequestId).
--spec request(method(), buoy_url(), buoy_opts()) ->
- {ok, buoy_resp()} | error().
+-spec request(method(), url(), opts()) ->
+ {ok, resp()} | error().
request(Method, #buoy_url {
protocol = Protocol,
- host = Host,
hostname = Hostname,
- port = Port,
- path = Path
- }, BuoyOpts) ->
+ port = Port
+ } = Url, BuoyOpts) ->
case buoy_pool:lookup(Protocol, Hostname, Port) of
{ok, PoolName} ->
Headers = buoy_opts(headers, BuoyOpts),
Body = buoy_opts(body, BuoyOpts),
- Request = {request, Method, Path, Headers, Host, Body},
+ Request = #buoy_req{
+ method = Method,
+ url = Url,
+ headers = Headers,
+ body = Body
+ },
Timeout = buoy_opts(timeout, BuoyOpts),
shackle:call(PoolName, Request, Timeout);
{error, _} = E ->
diff --git a/src/buoy_client.erl b/src/buoy_client.erl
index e77bacf..c044405 100644
--- a/src/buoy_client.erl
+++ b/src/buoy_client.erl
@@ -1,5 +1,5 @@
-module(buoy_client).
--include("buoy_internal.hrl").
+-include("buoy.hrl").
-compile(inline).
-compile({inline_size, 512}).
@@ -18,7 +18,7 @@
buffer = <<>> :: binary(),
queue :: queue:queue(),
request_id = 0 :: non_neg_integer(),
- response :: undefined | buoy_resp()
+ response :: undefined | buoy:resp()
}).
-type state() :: #state {}.
@@ -42,15 +42,20 @@ setup(_Socket, State) ->
-spec handle_request(term(), state()) ->
{ok, non_neg_integer(), iodata(), state()}.
-handle_request({request, Method, Path, Headers, Host, Body}, #state {
+handle_request(#buoy_req{
+ method = Method,
+ url = #buoy_url{host = Host, path = Path},
+ headers = Headers, body = Body
+ } = Request,
+ #state {
queue = Queue,
request_id = RequestId
} = State) ->
- Request = buoy_protocol:request(Method, Path, Headers, Host, Body),
+ RequestData = buoy_protocol:request(Method, Path, Headers, Host, Body),
- {ok, RequestId, Request, State#state {
- queue = queue:in({RequestId, Method}, Queue),
+ {ok, RequestId, RequestData, State#state {
+ queue = queue:in({RequestId, Request}, Queue),
request_id = RequestId + 1
}}.
@@ -87,7 +92,7 @@ terminate(_State) ->
responses(<<>>, Queue, Response, _BinPatterns, Responses) ->
{ok, Queue, Response, Responses, <<>>};
responses(Data, Queue, Response, BinPatterns, Responses) ->
- {value, {_, Method}} = queue:peek(Queue),
+ {value, {_, #buoy_req{method = Method}}} = queue:peek(Queue),
case buoy_protocol:response(Data, Method, Response, BinPatterns) of
{ok, #buoy_resp {state = done} = Response2, Rest} ->
{{value, {RequestId, _}}, Queue2} = queue:out(Queue),
diff --git a/src/buoy_pool.erl b/src/buoy_pool.erl
index 709862c..da70b70 100644
--- a/src/buoy_pool.erl
+++ b/src/buoy_pool.erl
@@ -1,4 +1,5 @@
-module(buoy_pool).
+-include("buoy.hrl").
-include("buoy_internal.hrl").
-export([
@@ -10,6 +11,22 @@
terminate/0
]).
+%% types
+-type option() :: {backlog_size, pos_integer()} |
+ {pool_size, pos_integer()} |
+ {pool_strategy, random | round_robin} |
+ {reconnect, boolean()} |
+ {reconnect_time_max, pos_integer() | infinity} |
+ {reconnect_time_min, pos_integer()} |
+ {socket_options, [gen_tcp:connect_option() | ssl:tls_client_option()]}.
+-type options() :: [option()].
+-type protocol() :: http | https.
+
+-export_type([
+ options/0,
+ protocol/0
+]).
+
%% public
-spec init() ->
ok.
@@ -18,7 +35,7 @@ init() ->
foil:new(?MODULE),
foil:load(?MODULE).
--spec lookup(protocol_http(), hostname(), inet:port_number()) ->
+-spec lookup(protocol(), buoy:hostname(), inet:port_number()) ->
{ok, atom()} | {error, pool_not_started | buoy_not_started}.
lookup(Protocol, Hostname, Port) ->
@@ -31,13 +48,13 @@ lookup(Protocol, Hostname, Port) ->
{error, buoy_not_started}
end.
--spec start(buoy_url()) ->
+-spec start(buoy:url()) ->
ok | {error, pool_already_started | buoy_not_started}.
start(Url) ->
start(Url, ?DEFAULT_POOL_OPTIONS).
--spec start(buoy_url(), options()) ->
+-spec start(buoy:url(), options()) ->
ok | {error, pool_already_started | buoy_not_started}.
start(#buoy_url {
@@ -61,7 +78,7 @@ start(#buoy_url {
{error, buoy_not_started}
end.
--spec stop(buoy_url()) ->
+-spec stop(buoy:url()) ->
ok | {error, pool_not_started | buoy_not_started}.
stop(#buoy_url {
diff --git a/src/buoy_protocol.erl b/src/buoy_protocol.erl
index a2806b3..2354bfc 100644
--- a/src/buoy_protocol.erl
+++ b/src/buoy_protocol.erl
@@ -1,5 +1,5 @@
-module(buoy_protocol).
--include("buoy_internal.hrl").
+-include("buoy.hrl").
-compile(inline).
-compile({inline_size, 512}).
@@ -29,13 +29,13 @@ bin_patterns() ->
rnrn = binary:compile_pattern(<<"\r\n\r\n">>)
}.
--spec headers(buoy_resp()) ->
- {ok, headers()} | {error, invalid_headers}.
+-spec headers(buoy:resp()) ->
+ {ok, buoy:headers()} | {error, invalid_headers}.
headers(#buoy_resp {headers = Headers}) ->
parse_headers(Headers, []).
--spec request(method(), path(), headers(), host(), body()) ->
+-spec request(buoy:method(), buoy:path(), buoy:headers(), buoy:host(), buoy:body()) ->
iolist().
request(Method, Path, Headers, Host, undefined) ->
@@ -58,13 +58,13 @@ request(Method, Path, Headers, Host, Body) ->
Body].
-spec response(binary()) ->
- {ok, buoy_resp(), binary()} | error().
+ {ok, buoy:resp(), binary()} | buoy:error().
response(Data) ->
response(Data, get, undefined, bin_patterns()).
--spec response(binary(), method(), undefined | buoy_resp(), bin_patterns()) ->
- {ok, buoy_resp(), binary()} | error().
+-spec response(binary(), buoy:method(), undefined | buoy:resp(), bin_patterns()) ->
+ {ok, buoy:resp(), binary()} | buoy:error().
response(Data, Method, undefined, BinPatterns) ->
case parse_status_line(Data, BinPatterns) of
diff --git a/src/buoy_utils.erl b/src/buoy_utils.erl
index 0249694..25d6006 100644
--- a/src/buoy_utils.erl
+++ b/src/buoy_utils.erl
@@ -1,5 +1,5 @@
-module(buoy_utils).
--include("buoy_internal.hrl").
+-include("buoy.hrl").
-compile(inline).
-compile({inline_size, 512}).
@@ -10,7 +10,7 @@
%% public
-spec parse_url(binary()) ->
- buoy_url() | {error, invalid_url}.
+ buoy:url() | {error, invalid_url}.
parse_url(<<"http://", Rest/binary>>) ->
parse_url(http, Rest);