diff --git a/README.md b/README.md index 438bdb47..4073588a 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,9 @@ $ ./rebar3 shell It is suggested that you install rebar3 user-wide as described [here](http://blog.erlware.org/rebar3-features-part-1-local-install-and-upgrade/). This fixes zsh (and maybe other shells) escript-related bugs. Also this should speed things up. -```erlang-repl +```erlang -1>> application:ensure_all_started(hackney). +> application:ensure_all_started(hackney). ok ``` @@ -149,7 +149,7 @@ where `Method`, can be any HTTP method in lowercase. ### Read the body ```erlang -{ok, Body} = hackney:body(Client). +{ok, Body} = hackney:body(ClientRef). ``` `hackney:body/1` fetch the body. To fetch it by chunk you can use the @@ -158,7 +158,7 @@ where `Method`, can be any HTTP method in lowercase. ```erlang read_body(MaxLength, Ref, Acc) when MaxLength > byte_size(Acc) -> - case stream_body(Ref) of + case hackney:stream_body(Ref) of {ok, Data} -> read_body(MaxLength, Ref, << Acc/binary, Data/binary >>); done -> @@ -186,16 +186,25 @@ couple of requests. ```erlang -Transport = hackney_tcp, -Host = << "https://friendpaste.com" >>, +Transport = hackney_ssl, +Host = << "friendpaste.com" >>, Port = 443, Options = [], -{ok, ConnRef} = hackney:connect(Transport, Host, Port, Options) +{ok, ConnRef} = hackney:connect(Transport, Host, Port, Options). ``` > To create a connection that will use an HTTP proxy use > `hackney_http_proxy:connect_proxy/5` instead. + +#### To get local and remote ip and port information of a connection: + +```erlang + +> hackney:peername(ConnRef). +> hackney:sockname(ConnRef). +``` + #### Make a request Once you created a connection use the `hackney:send_request/2` function @@ -203,13 +212,13 @@ to make a request: ```erlang -ReqBody = << "{ \"snippet\": \"some snippet\" }" >>, +ReqBody = << "{\"snippet\": \"some snippet\"}" >>, ReqHeaders = [{<<"Content-Type">>, <<"application/json">>}], NextPath = <<"/">>, NextMethod = post, -NextReq = {NextMethod, NextPath, ReqHeaders, ReqBody} +NextReq = {NextMethod, NextPath, ReqHeaders, ReqBody}, {ok, _, _, ConnRef} = hackney:send_request(ConnRef, NextReq). -{ok, Body1} = hackney:body(ConnRef), +{ok, Body1} = hackney:body(ConnRef). ``` Here we are posting a JSON payload to '/' on the friendpaste service to diff --git a/THANKS b/THANKS index 13e49942..39aad6de 100644 --- a/THANKS +++ b/THANKS @@ -30,3 +30,4 @@ Mayorov Andrey omarkj Pavel Abalihin Ilya Khaprov +Bikram Chatterjee \ No newline at end of file diff --git a/doc/README.md b/doc/README.md index 4f4ba577..30df0f4e 100644 --- a/doc/README.md +++ b/doc/README.md @@ -100,9 +100,9 @@ $ ./rebar3 shell It is suggested that you install rebar3 user-wide as described [here](http://blog.erlware.org/rebar3-features-part-1-local-install-and-upgrade/). This fixes zsh (and maybe other shells) escript-related bugs. Also this should speed things up. -```erlang-repl +```erlang -1>> application:ensure_all_started(hackney). +> application:ensure_all_started(hackney). ok ``` @@ -149,7 +149,7 @@ where `Method`, can be any HTTP method in lowercase. ### Read the body ```erlang -{ok, Body} = hackney:body(Client). +{ok, Body} = hackney:body(ClientRef). ``` `hackney:body/1` fetch the body. To fetch it by chunk you can use the @@ -158,7 +158,7 @@ where `Method`, can be any HTTP method in lowercase. ```erlang read_body(MaxLength, Ref, Acc) when MaxLength > byte_size(Acc) -> - case stream_body(Ref) of + case hackney:stream_body(Ref) of {ok, Data} -> read_body(MaxLength, Ref, << Acc/binary, Data/binary >>); done -> @@ -186,16 +186,25 @@ couple of requests. ```erlang -Transport = hackney_tcp, -Host = << "https://friendpaste.com" >>, +Transport = hackney_ssl, +Host = << "friendpaste.com" >>, Port = 443, Options = [], -{ok, ConnRef} = hackney:connect(Transport, Host, Port, Options) +{ok, ConnRef} = hackney:connect(Transport, Host, Port, Options). ``` > To create a connection that will use an HTTP proxy use > `hackney_http_proxy:connect_proxy/5` instead. + +#### To get local and remote ip and port information of a connection: + +```erlang + +> hackney:peername(ConnRef). +> hackney:sockname(ConnRef). +``` + #### Make a request Once you created a connection use the `hackney:send_request/2` function @@ -207,9 +216,9 @@ ReqBody = << "{ \"snippet\": \"some snippet\" }" >>, ReqHeaders = [{<<"Content-Type">>, <<"application/json">>}], NextPath = <<"/">>, NextMethod = post, -NextReq = {NextMethod, NextPath, ReqHeaders, ReqBody} +NextReq = {NextMethod, NextPath, ReqHeaders, ReqBody}, {ok, _, _, ConnRef} = hackney:send_request(ConnRef, NextReq). -{ok, Body1} = hackney:body(ConnRef), +{ok, Body1} = hackney:body(ConnRef). ``` Here we are posting a JSON payload to '/' on the friendpaste service to diff --git a/doc/hackney.md b/doc/hackney.md index 007539c9..0c41456b 100644 --- a/doc/hackney.md +++ b/doc/hackney.md @@ -46,7 +46,7 @@ url() = #hackney_url{} | binary() length doesn't go over MaxLength.cancel_request/1Extract raw informations from the client context This feature can be useful when you want to create a simple proxy, rerouting on the headers and the status line and continue to forward the connection for example.close/1close the client.connect/1connect/2connect/3connect a socket and create a client state.connect/4controlling_process/2Assign a new controlling process Pid to Client.cookies/1finish_send_body/1location/1return the requested location.pause_stream/1pause a response stream, the stream process will hibernate and -be woken later by the resume function.redirect_location/1request/1make a request.request/2make a request.request/3make a request.request/4make a request.request/5make a request.request_info/1get request info.resume_stream/1resume a paused response stream, the stream process will be +be woken later by the resume function.peername/1peername of the client.redirect_location/1request/1make a request.request/2make a request.request/3make a request.request/4make a request.request/5make a request.request_info/1get request info.resume_stream/1resume a paused response stream, the stream process will be awoken.send_body/2send the request body until eob.send_multipart_body/2send a multipart body until eof Possible value are :
    @@ -71,7 +71,7 @@ multipart content multipart content

Note: You can calculate the full length of a multipart stream using the function hackney_multipart:len_mp_stream/2 .send_request/2send a request using the current client state.send_request/3send a request using the current client state and pass new -options to it.setopts/2set client options.skip_body/1skip the full body.skip_multipart/1Stream the response body.start_response/1start a response.stop_async/1stop to receive asynchronously.stream_body/1Stream the response body.stream_multipart/1Stream the response body.stream_next/1continue to the next stream message. +options to it.setopts/2set client options.skip_body/1skip the full body.skip_multipart/1Stream the response body.sockname/1sockname of the client.start_response/1start a response.stop_async/1stop to receive asynchronously.stream_body/1Stream the response body.stream_multipart/1Stream the response body.stream_next/1continue to the next stream message. @@ -208,6 +208,14 @@ pause_stream(Ref::client_ref()) -> ok | {error pause a response stream, the stream process will hibernate and be woken later by the resume function + + +### peername/1 ### + +`peername(Ref) -> any()` + +peername of the client + ### redirect_location/1 ### @@ -547,6 +555,14 @@ skip_multipart(Ref::client_ref()) -> ok | {err Stream the response body. + + +### sockname/1 ### + +`sockname(Ref) -> any()` + +sockname of the client + ### start_response/1 ### diff --git a/doc/hackney_connect.md b/doc/hackney_connect.md index 11f24950..e49e94eb 100644 --- a/doc/hackney_connect.md +++ b/doc/hackney_connect.md @@ -9,7 +9,7 @@ ## Function Index ## -
check_or_close/1
close/1close the client.
connect/3
connect/4
connect/5
create_connection/4create a connection and return a client state.
create_connection/5
is_pool/1get current pool pid or name used by a client if needed.
maybe_connect/1connect a socket and create a client state.
partial_chain/1
reconnect/4
set_sockopts/2add set sockets options in the client.
ssl_opts/2
+
check_or_close/1
close/1close the client.
connect/3
connect/4
connect/5
create_connection/4create a connection and return a client state.
create_connection/5
is_pool/1get current pool pid or name used by a client if needed.
maybe_connect/1connect a socket and create a client state.
partial_chain/1
peername/1get the address and port for the other end of current connection in the client.
reconnect/4
set_sockopts/2add set sockets options in the client.
sockname/1the local address and port of current socket in the client.
ssl_opts/2
@@ -84,6 +84,14 @@ connect a socket and create a client state. `partial_chain(Certs) -> any()` + + +### peername/1 ### + +`peername(Client) -> any()` + +get the address and port for the other end of current connection in the client + ### reconnect/4 ### @@ -98,6 +106,14 @@ connect a socket and create a client state. add set sockets options in the client + + +### sockname/1 ### + +`sockname(Client) -> any()` + +the local address and port of current socket in the client + ### ssl_opts/2 ### diff --git a/doc/overview.edoc b/doc/overview.edoc index 9398fa99..12b82bbe 100644 --- a/doc/overview.edoc +++ b/doc/overview.edoc @@ -118,8 +118,8 @@ $ ./rebar3 shell It is suggested that you install rebar3 user-wide as described [here](http://blog.erlware.org/rebar3-features-part-1-local-install-and-upgrade/). This fixes zsh (and maybe other shells) escript-related bugs. Also this should speed things up. -
-1>> application:ensure_all_started(hackney).
+
+> application:ensure_all_started(hackney).
 ok
It will start hackney and all of the application it depends on: @@ -161,14 +161,14 @@ where `Method', can be any HTTP method in lowercase. ### Read the body -
{ok, Body} = hackney:body(Client).
+
{ok, Body} = hackney:body(ClientRef).
`hackney:body/1' fetch the body. To fetch it by chunk you can use the `hackney:stream_body/1' function:
 read_body(MaxLength, Ref, Acc) when MaxLength > byte_size(Acc) ->
-	case stream_body(Ref) of
+	case hackney:stream_body(Ref) of
 		{ok, Data} ->
 			read_body(MaxLength, Ref, << Acc/binary, Data/binary >>);
 		done ->
@@ -194,15 +194,21 @@ couple of requests.
 #### To create a connection:
 
 
-Transport = hackney_tcp,
-Host = << "https://friendpaste.com" >>,
+Transport = hackney_ssl,
+Host = << "friendpaste.com" >>,
 Port = 443,
 Options = [],
-{ok, ConnRef} = hackney:connect(Transport, Host, Port, Options)
+{ok, ConnRef} = hackney:connect(Transport, Host, Port, Options).
> To create a connection that will use an HTTP proxy use > `hackney_http_proxy:connect_proxy/5' instead. +#### To get local and remote ip and port information of a connection: + +
+> hackney:peername(ConnRef).
+> hackney:sockname(ConnRef).
+ #### Make a request Once you created a connection use the `hackney:send_request/2' function @@ -213,9 +219,9 @@ ReqBody = << "{ \"snippet\": \"some snippet\" }" >>, ReqHeaders = [{<<"Content-Type">>, <<"application/json">>}], NextPath = <<"/">>, NextMethod = post, -NextReq = {NextMethod, NextPath, ReqHeaders, ReqBody} -{ok, _, _, ConnRef} = hackney:send_request(ConnRef, NextReq). -{ok, Body1} = hackney:body(ConnRef),
+NextReq = {NextMethod, NextPath, ReqHeaders, ReqBody}, +{ok, _, _, ConnRef} = hackney:send_request(ConnRef, NextReq), +{ok, Body1} = hackney:body(ConnRef). Here we are posting a JSON payload to '/' on the friendpaste service to create a paste. Then we close the client connection. diff --git a/src/hackney.erl b/src/hackney.erl index 6af74124..d8026f78 100644 --- a/src/hackney.erl +++ b/src/hackney.erl @@ -8,6 +8,8 @@ -export([connect/1, connect/2, connect/3, connect/4, close/1, + peername/1, + sockname/1, request_info/1, location/1, request/1, request/2, request/3, request/4, request/5, @@ -116,6 +118,14 @@ close(Ref) -> hackney_connect:close(Ref). +%% @doc peername of the client +peername(Ref) -> + hackney_connect:peername(Ref). + +%% @doc sockname of the client +sockname(Ref) -> + hackney_connect:sockname(Ref). + %% @doc get request info -spec request_info(client_ref()) -> list(). request_info(Ref) -> diff --git a/src/hackney_connect.erl b/src/hackney_connect.erl index 620199cd..c4470118 100644 --- a/src/hackney_connect.erl +++ b/src/hackney_connect.erl @@ -12,6 +12,8 @@ set_sockopts/2, ssl_opts/2, check_or_close/1, + peername/1, + sockname/1, close/1, is_pool/1]). @@ -135,6 +137,29 @@ set_sockopts(#client{transport=Transport, socket=Skt}, Options) -> Transport:setopts(Skt, Options). +%% @doc get the address and port for the other end of current connection in the client +peername(#client{transport=Transport, socket=Socket}) -> + Transport:peername(Socket); +peername(Ref) when is_reference(Ref) -> + case hackney_manager:get_state(Ref) of + req_not_found -> + req_not_found; + Client -> + peername(Client) + end. + + +%% @doc the local address and port of current socket in the client +sockname(#client{transport=Transport, socket=Socket}) -> + Transport:sockname(Socket); +sockname(Ref) when is_reference(Ref) -> + case hackney_manager:get_state(Ref) of + req_not_found -> + req_not_found; + Client -> + sockname(Client) + end. + %% @doc close the client %% %%