Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
otp: [22.3, 23.3, 24.2]
rebar: [3.17.0]
otp: [21.3, 22.3, 23.3, 24.2]
steps:
- uses: actions/checkout@v2
- uses: erlef/setup-beam@v1
with:
otp-version: ${{matrix.otp}}
rebar3-version: ${{matrix.rebar}}
- name: Tests
run: rebar3 test
run: |
make rebar3
./rebar3 test
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
REBARVER = 3.15.2
ifeq ($(OTPVER),24.0)
REBARVER = 3.17.0
endif

compile:
rebar3 compile

Expand All @@ -18,3 +23,7 @@ clean:
clean-all:
rm -rf _build
rm rebar.lock

rebar3:
wget https://github.com/erlang/rebar3/releases/download/${REBARVER}/rebar3 &&\
chmod u+x rebar3
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Sheep
[![Build Status][gh badge]][gh]
[![Erlang Versions][erlang version badge]][gh]

Cowboy protocol and set of utility funs for building JSON/MsgPack APIs

Expand Down Expand Up @@ -120,3 +122,8 @@ then **GET** and **POST** requests will be processed by list of functions
but **PUT** or **DELETE** will get 204 (no content) response.

See [pipeline_handler.erl](./test/sheep_http_SUITE_data/pipeline_handler.erl) as example.

<!-- Badges -->
[gh]: https://github.com/wgnet/sheep2/actions/workflows/ci.yml
[gh badge]: https://img.shields.io/github/workflow/status/wgnet/sheep2/CI?style=flat-square
[erlang version badge]: https://img.shields.io/badge/erlang-21.3%20to%2024.2-blue.svg?style=flat-square
7 changes: 4 additions & 3 deletions rebar.config
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{minimum_otp_vsn, "21"}.

{erl_opts, [warn_missing_spec]}.

{deps, [
{cowboy, "2.7.0"},
{cowboy, "2.9.0"},
{jiffy, "1.0.8"},
{msgpack, "0.7.0"},
{hackney, "1.17.4"}
{gun, "2.0.0-rc.2"}
]}.

{profiles, [
Expand All @@ -15,7 +17,6 @@
]}
]}.


{project_plugins, [
{rebar3_lint, "~> 1.0.1"}
]}.
Expand Down
45 changes: 12 additions & 33 deletions rebar.lock
Original file line number Diff line number Diff line change
@@ -1,44 +1,23 @@
{"1.2.0",
[{<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},1},
{<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.7.0">>},0},
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},1},
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},0},
{<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},1},
[{<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},0},
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},1},
{<<"gun">>,{pkg,<<"gun">>,<<"2.0.0-rc.2">>},0},
{<<"jiffy">>,{pkg,<<"jiffy">>,<<"1.0.8">>},0},
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},1},
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},1},
{<<"msgpack">>,{pkg,<<"msgpack">>,<<"0.7.0">>},0},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},1},
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},1},
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},1},
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},1}]}.
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},1}]}.
[
{pkg_hash,[
{<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>},
{<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>},
{<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>},
{<<"hackney">>, <<"99DA4674592504D3FB0CFEF0DB84C3BA02B4508BAE2DFF8C0108BAA0D6E0977C">>},
{<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>},
{<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>},
{<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>},
{<<"gun">>, <<"7C489A32DEDCCB77B6E82D1F3C5A7DADFBFA004EC14E322CDB5E579C438632D2">>},
{<<"jiffy">>, <<"60E36F00BE35E5AC6E6CF2D4CAF3BDF3103D4460AFF385F543A8D7DF2D6D9613">>},
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
{<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>},
{<<"msgpack">>, <<"128AE0A2227C7E7A2847C0F0F73551C268464F8C1EE96BFFB920BC0A5712B295">>},
{<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>},
{<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>},
{<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>},
{<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]},
{<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}]},
{pkg_hash_ext,[
{<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>},
{<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>},
{<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>},
{<<"hackney">>, <<"DE16FF4996556C8548D512F4DBE22DD58A587BF3332E7FD362430A7EF3986B16">>},
{<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>},
{<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>},
{<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>},
{<<"gun">>, <<"6B9D1EAE146410D727140DBF8B404B9631302ECC2066D1D12F22097AD7D254FC">>},
{<<"jiffy">>, <<"F9AE986BA5A0854EB48CF6A76192D9367086DA86C20197DA430630BE7C087A4E">>},
{<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>},
{<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>},
{<<"msgpack">>, <<"4649353DA003E6F438D105E4B1E0F17757F6F5EC8687A6F30875FF3AC4CE2A51">>},
{<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>},
{<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>},
{<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>},
{<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]}
{<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}]}
].
2 changes: 1 addition & 1 deletion src/sheep2.app.src
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{application, sheep2, [
{description, "Cowboy protocol and set of utility funs for building JSON/MsgPack APIs"},
{vsn, "4.3.0"},
{vsn, git},
{registered, []},
{applications, [
kernel,
Expand Down
59 changes: 52 additions & 7 deletions src/sheep_try.erl
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
-module(sheep_try).

-export([run/0, query/4, log/1]).
-export([run/0, log/1]).
-export([init/2, read/2]).
-export([query/1, query/2, query/3, query/4]).

-include("sheep.hrl").

-ifdef(TEST).
-define(PORT, ranch:get_port(sheep_test_server)). %% See sheep_http_SUITE.erl
-else.
-define(PORT, ranch:get_port(?MODULE)).
-endif.

-define(HEADERS, [
{<<"content-type">>, <<"application/json">>},
{<<"accept">>, <<"application/json">>}
]).

-spec run() -> {integer(), list(), binary()}.
run() ->
application:set_env(sheep2, log_callback, fun ?MODULE:log/1),
application:ensure_all_started(cowboy),
application:ensure_all_started(hackney),
application:ensure_all_started(gun),

Routing = cowboy_router:compile([
{"localhost", [
Expand All @@ -31,15 +42,50 @@ run() ->
],
query(get, "/hello", H, <<>>).

-spec query(string()) -> {http_code(), list(), binary()}.
query(Path) ->
query(get, Path).

-spec query(atom(), string()) -> {http_code(), list(), binary()}.
query(Method, Path) ->
query(Method, Path, ?HEADERS).

-spec query(atom(), string(), list()) -> {http_code(), list(), binary()}.
query(Method, Path, Headers) ->
query(Method, Path, Headers, <<>>).

-spec query(atom(), string(), list(), binary()) -> {integer(), list(), binary()}.
query(Method, Path, Headers, Data) ->
Port = integer_to_list(ranch:get_port(?MODULE)),
FullURL = "http://localhost:" ++ Port ++ Path,
{ok, Status, RHeaders, Ref} = hackney:request(Method, FullURL, Headers, Data),
{ok, Body} = hackney:body(Ref),
{ok, Pid} = gun:open("localhost", ?PORT),
{ok, http} = gun:await_up(Pid),
StreamRef = gun:request(Pid, method(Method), Path, Headers, Data),
Opts = #{
pid => Pid,
stream_ref => StreamRef,
acc => <<>>
},
#{status := Status, headers := RHeaders, acc := Body} = get_reponse(Opts),
{Status, RHeaders, Body}.

-spec method(atom()) -> binary().
method(Method) ->
cowboy_bstr:to_upper(erlang:list_to_binary(erlang:atom_to_list(Method))).

get_reponse(#{pid := Pid, stream_ref := StreamRef, acc := Acc} = Opts) ->
case gun:await(Pid, StreamRef) of
{response, fin, Status, Headers} ->
Opts#{status => Status, headers => Headers};
{response, nofin, Status, Headers} ->
get_reponse(Opts#{status => Status, headers => Headers});
{data, nofin, Data} ->
get_reponse(Opts#{acc => <<Acc/binary, Data/binary>>});
{data, fin, Data} ->
Opts#{acc := <<Acc/binary, Data/binary>>};
{error, timeout} = Response ->
Response;
{error, _Reason} = Response->
Response
end.

-spec log({cowboy_req:req(), sheep_request(), sheep_response()}) -> ok.
log({Req, Request, Response}) ->
Expand All @@ -55,7 +101,6 @@ log({Req, Request, Response}) ->
io:format(" Sheep response: ~p~n", [Response]),
ok.


%% Sheep handler

-spec init(cowboy_req:req(), term()) -> tuple().
Expand Down
Loading