Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

sockname and peername access from hackney module #504

Merged
merged 8 commits into from Sep 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 19 additions & 10 deletions README.md
Expand Up @@ -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
```

Expand Down Expand Up @@ -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
Expand All @@ -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 ->
Expand Down Expand Up @@ -186,30 +186,39 @@ 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
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
Expand Down
1 change: 1 addition & 0 deletions THANKS
Expand Up @@ -30,3 +30,4 @@ Mayorov Andrey <avmayorov@platbox.com>
omarkj <omarkj@gmail.com>
Pavel Abalihin <anpavl@gmail.com>
Ilya Khaprov <dead.trickster@gmail.com>
Bikram Chatterjee <razorpeak@gmail.com>
27 changes: 18 additions & 9 deletions doc/README.md
Expand Up @@ -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
```

Expand Down Expand Up @@ -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
Expand All @@ -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 ->
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
20 changes: 18 additions & 2 deletions doc/hackney.md
Expand Up @@ -46,7 +46,7 @@ url() = #hackney_url{} | binary()
length doesn't go over MaxLength.</td></tr><tr><td valign="top"><a href="#cancel_request-1">cancel_request/1</a></td><td>Extract 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.</td></tr><tr><td valign="top"><a href="#close-1">close/1</a></td><td>close the client.</td></tr><tr><td valign="top"><a href="#connect-1">connect/1</a></td><td></td></tr><tr><td valign="top"><a href="#connect-2">connect/2</a></td><td></td></tr><tr><td valign="top"><a href="#connect-3">connect/3</a></td><td>connect a socket and create a client state.</td></tr><tr><td valign="top"><a href="#connect-4">connect/4</a></td><td></td></tr><tr><td valign="top"><a href="#controlling_process-2">controlling_process/2</a></td><td>Assign a new controlling process <em>Pid</em> to <em>Client</em>.</td></tr><tr><td valign="top"><a href="#cookies-1">cookies/1</a></td><td></td></tr><tr><td valign="top"><a href="#finish_send_body-1">finish_send_body/1</a></td><td></td></tr><tr><td valign="top"><a href="#location-1">location/1</a></td><td>return the requested location.</td></tr><tr><td valign="top"><a href="#pause_stream-1">pause_stream/1</a></td><td>pause a response stream, the stream process will hibernate and
be woken later by the resume function.</td></tr><tr><td valign="top"><a href="#redirect_location-1">redirect_location/1</a></td><td></td></tr><tr><td valign="top"><a href="#request-1">request/1</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request-2">request/2</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request-3">request/3</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request-4">request/4</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request-5">request/5</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request_info-1">request_info/1</a></td><td>get request info.</td></tr><tr><td valign="top"><a href="#resume_stream-1">resume_stream/1</a></td><td>resume a paused response stream, the stream process will be
be woken later by the resume function.</td></tr><tr><td valign="top"><a href="#peername-1">peername/1</a></td><td>peername of the client.</td></tr><tr><td valign="top"><a href="#redirect_location-1">redirect_location/1</a></td><td></td></tr><tr><td valign="top"><a href="#request-1">request/1</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request-2">request/2</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request-3">request/3</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request-4">request/4</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request-5">request/5</a></td><td>make a request.</td></tr><tr><td valign="top"><a href="#request_info-1">request_info/1</a></td><td>get request info.</td></tr><tr><td valign="top"><a href="#resume_stream-1">resume_stream/1</a></td><td>resume a paused response stream, the stream process will be
awoken.</td></tr><tr><td valign="top"><a href="#send_body-2">send_body/2</a></td><td>send the request body until eob.</td></tr><tr><td valign="top"><a href="#send_multipart_body-2">send_multipart_body/2</a></td><td>send a multipart body until eof
Possible value are :
<ul>
Expand All @@ -71,7 +71,7 @@ multipart content</li>
multipart content</li>
</ul><p></p>Note: You can calculate the full length of a multipart stream using
the function <code>hackney_multipart:len_mp_stream/2</code> .</td></tr><tr><td valign="top"><a href="#send_request-2">send_request/2</a></td><td>send a request using the current client state.</td></tr><tr><td valign="top"><a href="#send_request-3">send_request/3</a></td><td>send a request using the current client state and pass new
options to it.</td></tr><tr><td valign="top"><a href="#setopts-2">setopts/2</a></td><td>set client options.</td></tr><tr><td valign="top"><a href="#skip_body-1">skip_body/1</a></td><td>skip the full body.</td></tr><tr><td valign="top"><a href="#skip_multipart-1">skip_multipart/1</a></td><td>Stream the response body.</td></tr><tr><td valign="top"><a href="#start_response-1">start_response/1</a></td><td>start a response.</td></tr><tr><td valign="top"><a href="#stop_async-1">stop_async/1</a></td><td>stop to receive asynchronously.</td></tr><tr><td valign="top"><a href="#stream_body-1">stream_body/1</a></td><td>Stream the response body.</td></tr><tr><td valign="top"><a href="#stream_multipart-1">stream_multipart/1</a></td><td>Stream the response body.</td></tr><tr><td valign="top"><a href="#stream_next-1">stream_next/1</a></td><td>continue to the next stream message.</td></tr></table>
options to it.</td></tr><tr><td valign="top"><a href="#setopts-2">setopts/2</a></td><td>set client options.</td></tr><tr><td valign="top"><a href="#skip_body-1">skip_body/1</a></td><td>skip the full body.</td></tr><tr><td valign="top"><a href="#skip_multipart-1">skip_multipart/1</a></td><td>Stream the response body.</td></tr><tr><td valign="top"><a href="#sockname-1">sockname/1</a></td><td>sockname of the client.</td></tr><tr><td valign="top"><a href="#start_response-1">start_response/1</a></td><td>start a response.</td></tr><tr><td valign="top"><a href="#stop_async-1">stop_async/1</a></td><td>stop to receive asynchronously.</td></tr><tr><td valign="top"><a href="#stream_body-1">stream_body/1</a></td><td>Stream the response body.</td></tr><tr><td valign="top"><a href="#stream_multipart-1">stream_multipart/1</a></td><td>Stream the response body.</td></tr><tr><td valign="top"><a href="#stream_next-1">stream_next/1</a></td><td>continue to the next stream message.</td></tr></table>


<a name="functions"></a>
Expand Down Expand Up @@ -208,6 +208,14 @@ pause_stream(Ref::<a href="#type-client_ref">client_ref()</a>) -&gt; ok | {error
pause a response stream, the stream process will hibernate and
be woken later by the resume function

<a name="peername-1"></a>

### peername/1 ###

`peername(Ref) -> any()`

peername of the client

<a name="redirect_location-1"></a>

### redirect_location/1 ###
Expand Down Expand Up @@ -547,6 +555,14 @@ skip_multipart(Ref::<a href="#type-client_ref">client_ref()</a>) -&gt; ok | {err

Stream the response body.

<a name="sockname-1"></a>

### sockname/1 ###

`sockname(Ref) -> any()`

sockname of the client

<a name="start_response-1"></a>

### start_response/1 ###
Expand Down
18 changes: 17 additions & 1 deletion doc/hackney_connect.md
Expand Up @@ -9,7 +9,7 @@
## Function Index ##


<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#check_or_close-1">check_or_close/1</a></td><td></td></tr><tr><td valign="top"><a href="#close-1">close/1</a></td><td>close the client.</td></tr><tr><td valign="top"><a href="#connect-3">connect/3</a></td><td></td></tr><tr><td valign="top"><a href="#connect-4">connect/4</a></td><td></td></tr><tr><td valign="top"><a href="#connect-5">connect/5</a></td><td></td></tr><tr><td valign="top"><a href="#create_connection-4">create_connection/4</a></td><td>create a connection and return a client state.</td></tr><tr><td valign="top"><a href="#create_connection-5">create_connection/5</a></td><td></td></tr><tr><td valign="top"><a href="#is_pool-1">is_pool/1</a></td><td>get current pool pid or name used by a client if needed.</td></tr><tr><td valign="top"><a href="#maybe_connect-1">maybe_connect/1</a></td><td>connect a socket and create a client state.</td></tr><tr><td valign="top"><a href="#partial_chain-1">partial_chain/1</a></td><td></td></tr><tr><td valign="top"><a href="#reconnect-4">reconnect/4</a></td><td></td></tr><tr><td valign="top"><a href="#set_sockopts-2">set_sockopts/2</a></td><td>add set sockets options in the client.</td></tr><tr><td valign="top"><a href="#ssl_opts-2">ssl_opts/2</a></td><td></td></tr></table>
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#check_or_close-1">check_or_close/1</a></td><td></td></tr><tr><td valign="top"><a href="#close-1">close/1</a></td><td>close the client.</td></tr><tr><td valign="top"><a href="#connect-3">connect/3</a></td><td></td></tr><tr><td valign="top"><a href="#connect-4">connect/4</a></td><td></td></tr><tr><td valign="top"><a href="#connect-5">connect/5</a></td><td></td></tr><tr><td valign="top"><a href="#create_connection-4">create_connection/4</a></td><td>create a connection and return a client state.</td></tr><tr><td valign="top"><a href="#create_connection-5">create_connection/5</a></td><td></td></tr><tr><td valign="top"><a href="#is_pool-1">is_pool/1</a></td><td>get current pool pid or name used by a client if needed.</td></tr><tr><td valign="top"><a href="#maybe_connect-1">maybe_connect/1</a></td><td>connect a socket and create a client state.</td></tr><tr><td valign="top"><a href="#partial_chain-1">partial_chain/1</a></td><td></td></tr><tr><td valign="top"><a href="#peername-1">peername/1</a></td><td>get the address and port for the other end of current connection in the client.</td></tr><tr><td valign="top"><a href="#reconnect-4">reconnect/4</a></td><td></td></tr><tr><td valign="top"><a href="#set_sockopts-2">set_sockopts/2</a></td><td>add set sockets options in the client.</td></tr><tr><td valign="top"><a href="#sockname-1">sockname/1</a></td><td>the local address and port of current socket in the client.</td></tr><tr><td valign="top"><a href="#ssl_opts-2">ssl_opts/2</a></td><td></td></tr></table>


<a name="functions"></a>
Expand Down Expand Up @@ -84,6 +84,14 @@ connect a socket and create a client state.

`partial_chain(Certs) -> any()`

<a name="peername-1"></a>

### peername/1 ###

`peername(Client) -> any()`

get the address and port for the other end of current connection in the client

<a name="reconnect-4"></a>

### reconnect/4 ###
Expand All @@ -98,6 +106,14 @@ connect a socket and create a client state.

add set sockets options in the client

<a name="sockname-1"></a>

### sockname/1 ###

`sockname(Client) -> any()`

the local address and port of current socket in the client

<a name="ssl_opts-2"></a>

### ssl_opts/2 ###
Expand Down
26 changes: 16 additions & 10 deletions doc/overview.edoc
Expand Up @@ -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.

<pre lang="erlang-repl">
1>> application:ensure_all_started(hackney).
<pre lang="erlang">
> application:ensure_all_started(hackney).
ok</pre>

It will start hackney and all of the application it depends on:
Expand Down Expand Up @@ -161,14 +161,14 @@ where `Method', can be any HTTP method in lowercase.

### Read the body

<pre lang="erlang">{ok, Body} = hackney:body(Client).</pre>
<pre lang="erlang">{ok, Body} = hackney:body(ClientRef).</pre>

`hackney:body/1' fetch the body. To fetch it by chunk you can use the
`hackney:stream_body/1' function:

<pre lang="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, &lt;&lt; Acc/binary, Data/binary >>);
done ->
Expand All @@ -194,15 +194,21 @@ couple of requests.
#### To create a connection:

<pre lang="erlang">
Transport = hackney_tcp,
Host = &lt;&lt; "https://friendpaste.com" >>,
Transport = hackney_ssl,
Host = &lt;&lt; "friendpaste.com" >>,
Port = 443,
Options = [],
{ok, ConnRef} = hackney:connect(Transport, Host, Port, Options)</pre>
{ok, ConnRef} = hackney:connect(Transport, Host, Port, Options).</pre>

> 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:

<pre lang="erlang">
> hackney:peername(ConnRef).
> hackney:sockname(ConnRef).</pre>

#### Make a request

Once you created a connection use the `hackney:send_request/2' function
Expand All @@ -213,9 +219,9 @@ ReqBody = &lt;&lt; "{ \"snippet\": \"some snippet\" }" >>,
ReqHeaders = [{&lt;&lt;"Content-Type">>, &lt;&lt;"application/json">>}],
NextPath = &lt;&lt;"/">>,
NextMethod = post,
NextReq = {NextMethod, NextPath, ReqHeaders, ReqBody}
{ok, _, _, ConnRef} = hackney:send_request(ConnRef, NextReq).
{ok, Body1} = hackney:body(ConnRef),</pre>
NextReq = {NextMethod, NextPath, ReqHeaders, ReqBody},
{ok, _, _, ConnRef} = hackney:send_request(ConnRef, NextReq),
{ok, Body1} = hackney:body(ConnRef).</pre>

Here we are posting a JSON payload to '/' on the friendpaste service to
create a paste. Then we close the client connection.
Expand Down
10 changes: 10 additions & 0 deletions src/hackney.erl
Expand Up @@ -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,
Expand Down Expand Up @@ -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) ->
Expand Down
25 changes: 25 additions & 0 deletions src/hackney_connect.erl
Expand Up @@ -12,6 +12,8 @@
set_sockopts/2,
ssl_opts/2,
check_or_close/1,
peername/1,
sockname/1,
close/1,
is_pool/1]).

Expand Down Expand Up @@ -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
%%
%%
Expand Down