Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:20
shotgun
shotgun-0.3.0-git.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
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.
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor