File shotgun-0.3.0-git.patch of Package shotgun

diff --git a/README.md b/README.md
index 1c09c2e..7123c03 100644
--- a/README.md
+++ b/README.md
@@ -122,14 +122,14 @@ entries:
 response. **It currently only works for GET requests.**. Default value is
 `false`.
 
-- `async_data :: binary | sse`: when `async` is `true` the mode specifies
-how the data received will be processed. `binary` mode treats eat chunk received
+- `async_mode :: binary | sse`: when `async` is `true` the mode specifies
+how the data received will be processed. `binary` mode treats each chunk received
 as raw binary. `sse` mode buffers each chunk, splitting the data received into
 SSE. Default value is `binary`.
 
 - `handle_event :: fun((fin | nofin, reference(), binary()) -> any())`: this function
-will be called each time either a chunk is received (`async_data` = `binary`) or
-an event is parsed (`async_data` = `sse`). If no handle_event function is
+will be called each time either a chunk is received (`async_mode` = `binary`) or
+an event is parsed (`async_mode` = `sse`). If no handle_event function is
 provided the data received is added to a queue, whose values can be obtained
 calling the `shotgun:events/1`. Default value is `undefined`.
 
@@ -181,9 +181,6 @@ rebar3 shell
 ```
 
 ## Contact Us
-For **questions** or **general comments** regarding the use of this library,
-please use our public [hipchat room](http://inaka.net/hipchat).
-
 If you find any **bugs** or have a **problem** while using this library, please
 [open an issue](https://github.com/inaka/shotgun/issues/new) in this repo
 (or a pull request :)).
diff --git a/rebar.config b/rebar.config
index b7cbb8b..1567ee0 100644
--- a/rebar.config
+++ b/rebar.config
@@ -24,8 +24,8 @@
   {test, [
     {deps, [ {katana_test, {git, "https://github.com/inaka/katana-test.git", {tag, "0.0.6"}}}
            , {mixer,       {git, "https://github.com/inaka/mixer.git",       {tag, "0.1.5"}}}
-           , {cowboy,      {git, "https://github.com/ninenines/cowboy.git",  {tag, "2.0.0-pre.3"}}}
-           , {lasse,       {git, "https://github.com/inaka/lasse.git",       {tag, "cowboy2"}}}
+           , {cowboy,      {git, "https://github.com/ninenines/cowboy.git",  {tag, "2.4.0"}}}
+           , {lasse,       {git, "https://github.com/inaka/lasse.git",       {tag, "1.2.0"}}}
     ]}
   ]},
   {shell, [
@@ -63,7 +63,7 @@
 
 %% == Dependencies ==
 
-{deps, [{gun, "1.0.0-pre.1"}]}.
+{deps, [{gun, {git, "https://github.com/ninenines/gun", {tag, "1.3.0"}}}]}.
 
 %% == Dialyzer ==
 
@@ -81,4 +81,4 @@
 
 %% == Shell ==
 
-{shell, [{apps, [sync]}]}.
\ No newline at end of file
+{shell, [{apps, [sync]}]}.
diff --git a/rebar.config.script b/rebar.config.script
new file mode 100644
index 0000000..1317629
--- /dev/null
+++ b/rebar.config.script
@@ -0,0 +1,8 @@
+case erlang:function_exported(rebar3, main, 1) of
+    true -> % rebar3
+        CONFIG;
+    false -> % rebar 2.x
+        [{deps, [
+            {gun, ".*", {git, "https://github.com/ninenines/gun.git", "1.3.0"}}
+        ]} | lists:keydelete(deps, 1, CONFIG)]
+end.
diff --git a/rebar.lock b/rebar.lock
index 7379111..4dfb799 100644
--- a/rebar.lock
+++ b/rebar.lock
@@ -1,3 +1,8 @@
-[{<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.3.0">>},1},
- {<<"gun">>,{pkg,<<"gun">>,<<"1.0.0-pre.1">>},0},
- {<<"ranch">>,{pkg,<<"ranch">>,<<"1.1.0">>},1}].
+[{<<"cowlib">>,
+  {git,"https://github.com/ninenines/cowlib",
+       {ref,"106ba84bb04537879d8ce59321a04e0682110b91"}},
+  1},
+ {<<"gun">>,
+  {git,"https://github.com/ninenines/gun",
+       {ref,"e7dd9f227e46979d8073e71c683395a809b78cb4"}},
+  0}].
diff --git a/src/shotgun.erl b/src/shotgun.erl
index c7b3e93..25a8316 100644
--- a/src/shotgun.erl
+++ b/src/shotgun.erl
@@ -79,12 +79,14 @@
            %% timeout is passed to gun:await_up. Default if not specified
            %% is 5000 ms.
          , timeout => timeout()
+           %% gun_opts are passed to gun:open
+         , gun_opts => gun:opts()
          }.
 
 -type connection() :: pid().
 -type http_verb()  :: get | post | head | delete | patch | put | options.
 -type uri()        :: iodata().
--type headers()    :: #{} | proplists:proplist().
+-type headers()    :: #{_ => _} | proplists:proplist().
 -type body()       :: iodata() | body_chunked.
 -type options()    ::
         #{ async => boolean()
@@ -124,7 +126,7 @@ stop() ->
 -spec start_link(string(), integer(), connection_type(), open_opts()) ->
     {ok, pid()} | ignore | {error, term()}.
 start_link(Host, Port, Type, Opts) ->
-    gen_fsm:start_link(shotgun, [Host, Port, Type, Opts], []).
+    gen_fsm:start_link(shotgun, [{Host, Port, Type, Opts}], []).
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% API
@@ -152,7 +154,9 @@ open(Host, Port, Opts) when is_map(Opts) ->
 %% transport options.
 -spec open(Host :: string(), Port :: integer(), Type :: connection_type(),
            Opts :: open_opts()) ->
-    {ok, pid()} | {error, gun_open_failed, gun_open_timeout}.
+    {ok, pid()} | {ok, pid(), term()} |
+    {error, already_present | {already_started, pid()} |
+            gun_open_failed | gun_open_timeout}.
 open(Host, Port, Type, Opts) ->
     supervisor:start_child(shotgun_sup, [Host, Port, Type, Opts]).
 
@@ -333,24 +337,39 @@ parse_event(EventBin) ->
 %% gen_fsm callbacks
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
--type state() :: #{}.
+-type state() :: #{ async            => boolean()
+                  , async_mode       => false | binary | sse
+                  , buffer           => binary()
+                  , data             => binary()
+                  , from             => term()
+                  , handle_event     => term()
+                  , headers          => term()
+                  , pending_requests => queue:queue() | undefined
+                  , pid              => pid() | undefined
+                  , responses        => queue:queue() | undefined
+                  , status_code      => integer() | undefined
+                  , stream           => reference() | undefined}.
 
 %% @private
--spec init([term()]) ->
+-spec init([{string(), integer(), connection_type(), open_opts()}]) ->
     {ok, at_rest, state()} | {stop, gun_open_timeout} | {stop, gun_open_failed}.
-init([Host, Port, Type, Opts]) ->
+init([{Host, Port, Type, Opts}]) ->
     GunType = case Type of
                   http -> tcp;
                   https -> ssl
               end,
     TransportOpts = maps:get(transport_opts, Opts, []),
-    GunOpts = #{transport      => GunType,
+    PassedGunOpts = maps:get(gun_opts, Opts, #{}),
+    DefaultGunOpts = #{
+                transport      => GunType,
                 retry          => 1,
                 retry_timeout  => 1,
                 transport_opts => TransportOpts
                },
+    GunOpts = maps:merge(DefaultGunOpts, PassedGunOpts),
     Timeout = maps:get(timeout, Opts, 5000),
     {ok, Pid} = gun:open(Host, Port, GunOpts),
+    _ = monitor(process, Pid),
     case gun:await_up(Pid, Timeout) of
       {ok, _} ->
         State = clean_state(),
@@ -362,6 +381,11 @@ init([Host, Port, Type, Opts]) ->
       %gun currently terminates with reason normal if gun:open fails to open
       %the requested connection. This bubbles up through gun:await_up.
       {error, normal} ->
+        {stop, gun_open_failed};
+      %gun can terminate with reason {shutdown, nxdomain}; however, that's not
+      %explicitly specced and makes dialyzer unhappy, so we loosely pattern
+      %match it here.
+      {error, _} ->
         {stop, gun_open_failed}
     end.
 
@@ -416,7 +440,9 @@ terminate(_Reason, _StateName, #{pid := Pid} = _State) ->
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %% @private
--spec at_rest(term(), pid(), term()) -> term().
+-spec at_rest(term(), pid(), state()) ->
+    {stop, {error, any()}, atom(), state()} |
+    {next_state, atom(), state(), timeout()}.
 at_rest(Event, From, State) ->
     enqueue_work_or_stop(at_rest, Event, From, State).
 
@@ -431,12 +457,16 @@ wait_response(Event, From, State) ->
     enqueue_work_or_stop(wait_response, Event, From, State).
 
 %% @private
--spec receive_data(term(), pid(), term()) -> term().
+-spec receive_data(term(), pid(), term()) ->
+    {stop, {error, any()}, atom(), state()} |
+    {next_state, atom(), state(), timeout()}.
 receive_data(Event, From, State) ->
     enqueue_work_or_stop(receive_data, Event, From, State).
 
 %% @private
--spec receive_chunk(term(), pid(), term()) -> term().
+-spec receive_chunk(term(), pid(), term()) ->
+    {stop, {error, any()}, atom(), state()} |
+    {next_state, atom(), state(), timeout()}.
 receive_chunk(Event, From, State) ->
     enqueue_work_or_stop(receive_chunk, Event, From, State).
 
@@ -444,6 +474,8 @@ receive_chunk(Event, From, State) ->
 %If we don't, stay in at_rest.
 %% @private
 -spec at_rest(any(), state()) -> {next_state, atom(), state()}.
+at_rest({'DOWN', _, _, _, Reason}, _State) ->
+    exit(Reason);
 at_rest(timeout, State) ->
     case get_work(State) of
         no_work ->
@@ -480,7 +512,9 @@ at_rest({HttpVerb, {_, _, Body} = Args, From}, State = #{pid := Pid}) ->
     {next_state, wait_response, NewState}.
 
 %% @private
--spec wait_response(term(), term()) -> term().
+-spec wait_response(term(), term()) ->
+    {stop, {error, any()}, atom(), state()} |
+    {next_state, atom(), state(), timeout()}.
 wait_response({'DOWN', _, _, _, Reason}, _State) ->
     exit(Reason);
 wait_response({gun_response, _Pid, _StreamRef, fin, StatusCode, Headers},
@@ -516,7 +550,9 @@ wait_response(Event, State) ->
 
 %% @private
 %% @doc Regular response
--spec receive_data(term(), term()) -> term().
+-spec receive_data(term(), term()) ->
+    {stop, {error, any()}, atom(), state()} |
+    {next_state, atom(), state(), timeout()}.
 receive_data({'DOWN', _, _, _, _Reason}, _State) ->
     error(incomplete);
 receive_data({gun_data, _Pid, StreamRef, nofin, Data},
@@ -539,7 +575,7 @@ receive_data({gun_error, _Pid, StreamRef, _Reason},
 
 %% @private
 %% @doc Chunked data response
--spec receive_chunk(term(), term()) -> term().
+-spec receive_chunk(term(), state()) -> term().
 receive_chunk({'DOWN', _, _, _, _Reason}, _State) ->
     error(incomplete);
 receive_chunk({gun_data, _Pid, StreamRef, IsFin, Data}, State) ->
@@ -558,12 +594,12 @@ receive_chunk({gun_error, _Pid, _StreamRef, _Reason}, State) ->
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %% @private
--spec clean_state() -> map().
+-spec clean_state() -> state().
 clean_state() ->
     clean_state(#{}).
 
 %% @private
--spec clean_state(map()) -> map(); (queue:queue()) -> map().
+-spec clean_state(map()) -> state().
 clean_state(State) ->
     Responses = maps:get(responses, State, queue:new()),
     Requests  = maps:get(pending_requests, State, queue:new()),
@@ -662,7 +698,9 @@ basic_auth_header(Headers) ->
     end.
 
 %% @private
--spec encode_basic_auth(string(), string()) -> binary().
+-type ascii_string() :: [1..255].
+
+-spec encode_basic_auth(ascii_string(), ascii_string()) -> binary().
 encode_basic_auth(Username, Password) ->
     base64:encode(Username ++ [$: | Password]).
 
diff --git a/test/http_server/http_binary_handler.erl b/test/http_server/http_binary_handler.erl
index 1067666..a56b5ab 100644
--- a/test/http_server/http_binary_handler.erl
+++ b/test/http_server/http_binary_handler.erl
@@ -10,9 +10,11 @@
 init(Req, _Opts) ->
   case cowboy_req:method(Req) of
     <<"GET">>  ->
-      Headers = [{<<"content-type">>, <<"text/event-stream">>},
-                 {<<"cache-control">>, <<"no-cache">>}],
-      Req1 = cowboy_req:chunked_reply(200, Headers, Req),
+      Headers = #{
+        <<"content-type">> => <<"text/event-stream">>,
+        <<"cache-control">> => <<"no-cache">>
+      },
+      Req1 = cowboy_req:stream_reply(200, Headers, Req),
       shotgun_test_utils:auto_send(count),
       {cowboy_loop, Req1, 1};
     _OtherMethod ->
@@ -29,7 +31,7 @@ info(count, Req, Count) ->
     true  ->
           {stop, Req, 0};
     false ->
-          ok = cowboy_req:chunk(integer_to_binary(Count), Req),
+          ok = cowboy_req:stream_body(integer_to_binary(Count), nofin, Req),
           shotgun_test_utils:auto_send(count),
          {ok, Req, Count + 1}
   end.
diff --git a/test/http_server/http_server.erl b/test/http_server/http_server.erl
index a2f5aca..80ecb26 100644
--- a/test/http_server/http_server.erl
+++ b/test/http_server/http_server.erl
@@ -41,23 +41,14 @@ start_phase(start_cowboy_http, _StartType, []) ->
         [{ '_'
          , [ {"/",                     http_simple_handler, []}
            , {"/basic-auth",           http_basic_auth_handler, []}
-
            , {"/chunked-sse[/:count]", lasse_handler, [http_sse_handler]}
            , {"/chunked-binary",       http_binary_handler, []}
            ]
          }
         ],
   Dispatch = cowboy_router:compile(Routes),
-  RanchOptions = [{port, Port}],
-  CowboyOptions =
-    [
-     {env,
-      [
-       {dispatch, Dispatch}
-      ]},
-     {compress, true},
-     {timeout, 12000}
-    ],
+  TransportOptions = [{port, Port}],
+  ProtocolOptions = #{env => #{dispatch => Dispatch}},
   {ok, _} =
-    cowboy:start_http(http_server, ListenerCount, RanchOptions, CowboyOptions),
+    cowboy:start_clear(http_server, TransportOptions, ProtocolOptions),
   ok.
diff --git a/test/http_server/http_simple_handler.erl b/test/http_server/http_simple_handler.erl
index ef1f0f3..d96895a 100644
--- a/test/http_server/http_simple_handler.erl
+++ b/test/http_server/http_simple_handler.erl
@@ -42,7 +42,7 @@ handle_get(Req, State) ->
   {Body, Req, State}.
 
 handle_post(Req, State) ->
-  {ok, Data, Req1} = cowboy_req:body(Req),
+  {ok, Data, Req1} = cowboy_req:read_body(Req),
   Method = cowboy_req:method(Req1),
   Body = [Method, <<": ">>, Data],
   Req2 = cowboy_req:set_resp_body(Body, Req1),
diff --git a/test/shotgun_meta_SUITE.erl b/test/shotgun_meta_SUITE.erl
index 87dcce5..6e73d18 100644
--- a/test/shotgun_meta_SUITE.erl
+++ b/test/shotgun_meta_SUITE.erl
@@ -4,5 +4,9 @@
 -mixin([ktn_meta_SUITE]).
 
 -export([init_per_suite/1]).
+-export([end_per_suite/1]).
 
 init_per_suite(Config) -> [{application, shotgun} | Config].
+
+end_per_suite(Config) ->
+  Config.
openSUSE Build Service is sponsored by