Skip to content

Commit

Permalink
add path_encode_fun option to request
Browse files Browse the repository at this point in the history
This function allows the users to bypass default hackney strict PATH encoding
similar chromium algorithm. So they can handle servers that need a specific
encoding.

fix #277; #272, #246
  • Loading branch information
benoitc committed Mar 21, 2016
1 parent 32f092d commit 0cd3496
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
4 changes: 4 additions & 0 deletions doc/hackney.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ When {async, once} is used the response will be received only once. To
receive the other messages use the function
`hackney:stream_next/1`

* `{path_encode_fun, fun()}`: function used to encode the path. if
not set it will use `hackney_url:path_encode/1` the function takes the
binary path as entry and return a new encoded path.

* `{stream_to, pid()}`: If async is true or once, the response
messages will be sent to this PID.

Expand Down
22 changes: 20 additions & 2 deletions doc/hackney_url.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ qs_vals() = [{binary(), binary() | true}]


<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#fix_path-1">fix_path/1</a></td><td></td></tr><tr><td valign="top"><a href="#make_url-3">make_url/3</a></td><td> construct an url from a base url, a path and a list of
properties to give to the url.</td></tr><tr><td valign="top"><a href="#normalize-1">normalize/1</a></td><td>Normalizes the encoding of a Url.</td></tr><tr><td valign="top"><a href="#parse_qs-1">parse_qs/1</a></td><td></td></tr><tr><td valign="top"><a href="#parse_url-1">parse_url/1</a></td><td>Parse an url and return a #hackney_url record.</td></tr><tr><td valign="top"><a href="#pathencode-1">pathencode/1</a></td><td>encode a URL path.</td></tr><tr><td valign="top"><a href="#qs-1">qs/1</a></td><td>encode query properties to binary.</td></tr><tr><td valign="top"><a href="#transport_scheme-1">transport_scheme/1</a></td><td></td></tr><tr><td valign="top"><a href="#unparse_url-1">unparse_url/1</a></td><td></td></tr><tr><td valign="top"><a href="#urldecode-1">urldecode/1</a></td><td>Decode a URL encoded binary.</td></tr><tr><td valign="top"><a href="#urldecode-2">urldecode/2</a></td><td>Decode a URL encoded binary.</td></tr><tr><td valign="top"><a href="#urlencode-1">urlencode/1</a></td><td>URL encode a string binary.</td></tr><tr><td valign="top"><a href="#urlencode-2">urlencode/2</a></td><td>URL encode a string binary.</td></tr></table>
properties to give to the url.</td></tr><tr><td valign="top"><a href="#normalize-1">normalize/1</a></td><td>Normalizes the encoding of a Url
use the hackney_url:pathencode/1 to encode an url.</td></tr><tr><td valign="top"><a href="#normalize-2">normalize/2</a></td><td>Normalizes the encoding of a Url.</td></tr><tr><td valign="top"><a href="#parse_qs-1">parse_qs/1</a></td><td></td></tr><tr><td valign="top"><a href="#parse_url-1">parse_url/1</a></td><td>Parse an url and return a #hackney_url record.</td></tr><tr><td valign="top"><a href="#pathencode-1">pathencode/1</a></td><td>encode a URL path.</td></tr><tr><td valign="top"><a href="#qs-1">qs/1</a></td><td>encode query properties to binary.</td></tr><tr><td valign="top"><a href="#transport_scheme-1">transport_scheme/1</a></td><td></td></tr><tr><td valign="top"><a href="#unparse_url-1">unparse_url/1</a></td><td></td></tr><tr><td valign="top"><a href="#urldecode-1">urldecode/1</a></td><td>Decode a URL encoded binary.</td></tr><tr><td valign="top"><a href="#urldecode-2">urldecode/2</a></td><td>Decode a URL encoded binary.</td></tr><tr><td valign="top"><a href="#urlencode-1">urlencode/1</a></td><td>URL encode a string binary.</td></tr><tr><td valign="top"><a href="#urlencode-2">urlencode/2</a></td><td>URL encode a string binary.</td></tr></table>


<a name="functions"></a>
Expand Down Expand Up @@ -57,7 +58,24 @@ properties to give to the url.

### normalize/1 ###

`normalize(Url) -> any()`
<pre><code>
normalize(URL) -&gt; NormalizedUrl
</code></pre>

<ul class="definitions"><li><code>URL = binary() | list() | <a href="#type-hackney_url">hackney_url()</a></code></li><li><code>NormalizedUrl = <a href="#type-hackney_url">hackney_url()</a></code></li></ul>

Normalizes the encoding of a Url
use the hackney_url:pathencode/1 to encode an url

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

### normalize/2 ###

<pre><code>
normalize(URL, Fun) -&gt; NormalizedUrl
</code></pre>

<ul class="definitions"><li><code>URL = binary() | list() | <a href="#type-hackney_url">hackney_url()</a></code></li><li><code>Fun = function()</code></li><li><code>NormalizedUrl = <a href="#type-hackney_url">hackney_url()</a></code></li></ul>

Normalizes the encoding of a Url

Expand Down
9 changes: 8 additions & 1 deletion src/hackney.erl
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ request(Method, URL, Headers, Body) ->
%% receive the other messages use the function
%% `hackney:stream_next/1'
%% </li>
%% <li>`{path_encode_fun, fun()}': function used to encode the path. if
%% not set it will use `hackney_url:path_encode/1' the function takes the
%% binary path as entry and return a new encoded path.</li>
%%
%% <li>`{stream_to, pid()}': If async is true or once, the response
%% messages will be sent to this PID.</li>
Expand Down Expand Up @@ -295,8 +298,12 @@ request(Method, URL, Headers, Body) ->
| {ok, client_ref()}
| {error, term()}.
request(Method, #hackney_url{}=URL0, Headers, Body, Options0) ->
PathEncodeFun = proplists:get_value(path_encode_fun, Options0,
fun hackney_url:encodepath/1),


%% normalize the url encoding
URL = hackney_url:normalize(URL0),
URL = hackney_url:normalize(URL0, PathEncodeFun),

?report_trace("request", [{method, Method},
{url, URL},
Expand Down
20 changes: 16 additions & 4 deletions src/hackney_url.erl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
make_url/3,
fix_path/1,
pathencode/1,
normalize/1]).
normalize/1, normalize/2]).

-include("hackney_lib.hrl").

Expand Down Expand Up @@ -61,9 +61,21 @@ parse_url(URL, S) ->
end.

%% @doc Normalizes the encoding of a Url
normalize(Url) when is_list(Url) orelse is_binary(Url) ->
normalize(parse_url(Url));
normalize(#hackney_url{}=Url) ->
%% use the hackney_url:pathencode/1 to encode an url
-spec normalize(URL) -> NormalizedUrl when
URL :: binary() | list() | hackney_url(),
NormalizedUrl :: hackney_url().
normalize(Url) ->
normalize(Url, fun hackney_url:pathencode/1).

%% @doc Normalizes the encoding of a Url
-spec normalize(URL, Fun) -> NormalizedUrl when
URL :: binary() | list() | hackney_url(),
Fun :: fun(),
NormalizedUrl :: hackney_url().
normalize(Url, Fun) when is_list(Url) orelse is_binary(Url) ->
normalize(parse_url(Url), Fun);
normalize(#hackney_url{}=Url, Fun) when is_function(Fun, 1) ->
#hackney_url{scheme=Scheme,
host = Host0,
port = Port,
Expand Down

0 comments on commit 0cd3496

Please sign in to comment.