diff options
Diffstat (limited to 'test/http_SUITE_data')
21 files changed, 533 insertions, 0 deletions
diff --git a/test/http_SUITE_data/http_body_qs.erl b/test/http_SUITE_data/http_body_qs.erl new file mode 100644 index 0000000..2280981 --- /dev/null +++ b/test/http_SUITE_data/http_body_qs.erl @@ -0,0 +1,39 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_body_qs). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +init({_, http}, Req, _) -> + {ok, Req, undefined}. + +handle(Req, State) -> + {Method, Req2} = cowboy_req:method(Req), + HasBody = cowboy_req:has_body(Req2), + {ok, Req3} = maybe_echo(Method, HasBody, Req2), + {ok, Req3, State}. + +maybe_echo(<<"POST">>, true, Req) -> + case cowboy_req:body_qs(Req) of + {error,badlength} -> + echo(badlength, Req); + {ok, PostVals, Req2} -> + echo(proplists:get_value(<<"echo">>, PostVals), Req2) + end; + +maybe_echo(<<"POST">>, false, Req) -> + cowboy_req:reply(400, [], <<"Missing body.">>, Req); +maybe_echo(_, _, Req) -> + %% Method not allowed. + cowboy_req:reply(405, Req). + +echo(badlength, Req) -> + cowboy_req:reply(413, [], <<"POST body bigger than 16000 bytes">>, Req); +echo(undefined, Req) -> + cowboy_req:reply(400, [], <<"Missing echo parameter.">>, Req); +echo(Echo, Req) -> + cowboy_req:reply(200, + [{<<"content-encoding">>, <<"utf-8">>}], Echo, Req). + +terminate(_, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_chunked.erl b/test/http_SUITE_data/http_chunked.erl new file mode 100644 index 0000000..447c0f6 --- /dev/null +++ b/test/http_SUITE_data/http_chunked.erl @@ -0,0 +1,19 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_chunked). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +init({_Transport, http}, Req, _Opts) -> + {ok, Req, undefined}. + +handle(Req, State) -> + {ok, Req2} = cowboy_req:chunked_reply(200, Req), + timer:sleep(100), + cowboy_req:chunk("chunked_handler\r\n", Req2), + timer:sleep(100), + cowboy_req:chunk("works fine!", Req2), + {ok, Req2, State}. + +terminate(_, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_echo_body.erl b/test/http_SUITE_data/http_echo_body.erl new file mode 100644 index 0000000..014e05a --- /dev/null +++ b/test/http_SUITE_data/http_echo_body.erl @@ -0,0 +1,45 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_echo_body). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +init({_, http}, Req, _) -> + {ok, Req, undefined}. + +handle(Req, State) -> + true = cowboy_req:has_body(Req), + {ok, Req3} = case cowboy_req:body(1000000, Req) of + {error, chunked} -> handle_chunked(Req); + {error, badlength} -> handle_badlength(Req); + {ok, Body, Req2} -> handle_body(Req2, Body) + end, + {ok, Req3, State}. + +handle_chunked(Req) -> + {ok, Data, Req2} = read_body(Req, <<>>, 1000000), + {ok, Req3} = cowboy_req:reply(200, [], Data, Req2), + {ok, Req3}. + +handle_badlength(Req) -> + {ok, Req2} = cowboy_req:reply(413, [], <<"Request entity too large">>, Req), + {ok, Req2}. + +handle_body(Req, Body) -> + {Size, Req2} = cowboy_req:body_length(Req), + Size = byte_size(Body), + {ok, Req3} = cowboy_req:reply(200, [], Body, Req2), + {ok, Req3}. + +terminate(_, _, _) -> + ok. + +% Read chunked request content +read_body(Req, Acc, BodyLengthRemaining) -> + case cowboy_req:stream_body(Req) of + {ok, Data, Req2} -> + BodyLengthRem = BodyLengthRemaining - byte_size(Data), + read_body(Req2, << Acc/binary, Data/binary >>, BodyLengthRem); + {done, Req2} -> + {ok, Acc, Req2} + end. diff --git a/test/http_SUITE_data/http_errors.erl b/test/http_SUITE_data/http_errors.erl new file mode 100644 index 0000000..8831362 --- /dev/null +++ b/test/http_SUITE_data/http_errors.erl @@ -0,0 +1,40 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_errors). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +init({_Transport, http}, Req, _Opts) -> + {Case, Req1} = cowboy_req:qs_val(<<"case">>, Req), + case_init(Case, Req1). + +case_init(<<"init_before_reply">> = Case, _Req) -> + erlang:error(Case); + +case_init(<<"init_after_reply">> = Case, Req) -> + {ok, _Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req), + erlang:error(Case); + +case_init(<<"init_reply_handle_error">> = Case, Req) -> + {ok, Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req), + {ok, Req1, Case}; + +case_init(<<"handle_before_reply">> = Case, Req) -> + {ok, Req, Case}; + +case_init(<<"handle_after_reply">> = Case, Req) -> + {ok, Req, Case}. + + +handle(_Req, <<"init_reply_handle_error">> = Case) -> + erlang:error(Case); + +handle(_Req, <<"handle_before_reply">> = Case) -> + erlang:error(Case); + +handle(Req, <<"handle_after_reply">> = Case) -> + {ok, _Req1} = cowboy_req:reply(200, [], "http_handler_crashes", Req), + erlang:error(Case). + +terminate(_, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_handler.erl b/test/http_SUITE_data/http_handler.erl new file mode 100644 index 0000000..e1f1665 --- /dev/null +++ b/test/http_SUITE_data/http_handler.erl @@ -0,0 +1,19 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_handler). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +-record(state, {headers, body}). + +init({_Transport, http}, Req, Opts) -> + Headers = proplists:get_value(headers, Opts, []), + Body = proplists:get_value(body, Opts, "http_handler"), + {ok, Req, #state{headers=Headers, body=Body}}. + +handle(Req, State=#state{headers=Headers, body=Body}) -> + {ok, Req2} = cowboy_req:reply(200, Headers, Body, Req), + {ok, Req2, State}. + +terminate(_, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_init_shutdown.erl b/test/http_SUITE_data/http_init_shutdown.erl new file mode 100644 index 0000000..1445569 --- /dev/null +++ b/test/http_SUITE_data/http_init_shutdown.erl @@ -0,0 +1,17 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_init_shutdown). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +init({_Transport, http}, Req, _Opts) -> + {ok, Req2} = cowboy_req:reply(<<"666 Init Shutdown Testing">>, + [{<<"connection">>, <<"close">>}], Req), + {shutdown, Req2, undefined}. + +handle(Req, State) -> + {ok, Req2} = cowboy_req:reply(200, [], "Hello world!", Req), + {ok, Req2, State}. + +terminate(_, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_long_polling.erl b/test/http_SUITE_data/http_long_polling.erl new file mode 100644 index 0000000..ad4e66e --- /dev/null +++ b/test/http_SUITE_data/http_long_polling.erl @@ -0,0 +1,24 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_long_polling). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, info/3, terminate/3]). + +init({_Transport, http}, Req, _Opts) -> + erlang:send_after(500, self(), timeout), + {loop, Req, 5, 5000, hibernate}. + +handle(_Req, _State) -> + exit(badarg). + +info(timeout, Req, 0) -> + {ok, Req2} = cowboy_req:reply(102, Req), + {ok, Req2, 0}; +info(timeout, Req, State) -> + erlang:send_after(500, self(), timeout), + {loop, Req, State - 1, hibernate}. + +terminate({normal, shutdown}, _, _) -> + ok; +terminate({error, overflow}, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_loop_recv.erl b/test/http_SUITE_data/http_loop_recv.erl new file mode 100644 index 0000000..d0577f0 --- /dev/null +++ b/test/http_SUITE_data/http_loop_recv.erl @@ -0,0 +1,18 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_loop_recv). +-behaviour(cowboy_loop_handler). +-export([init/3, info/3, terminate/3]). + +init({_, http}, Req, _) -> + self() ! recv_timeout, + {loop, Req, undefined, 500, hibernate}. + +info(recv_timeout, Req, State) -> + {ok, Body, Req1} = cowboy_req:body(Req), + 100000 = byte_size(Body), + {ok, Req2} = cowboy_req:reply(200, Req1), + {ok, Req2, State}. + +terminate({normal, shutdown}, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_loop_timeout.erl b/test/http_SUITE_data/http_loop_timeout.erl new file mode 100644 index 0000000..dd3472c --- /dev/null +++ b/test/http_SUITE_data/http_loop_timeout.erl @@ -0,0 +1,16 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_loop_timeout). +-behaviour(cowboy_loop_handler). +-export([init/3, info/3, terminate/3]). + +init({_, http}, Req, _) -> + erlang:send_after(1000, self(), error_timeout), + {loop, Req, undefined, 500, hibernate}. + +info(error_timeout, Req, State) -> + {ok, Req2} = cowboy_req:reply(500, Req), + {ok, Req2, State}. + +terminate({normal, timeout}, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_multipart.erl b/test/http_SUITE_data/http_multipart.erl new file mode 100644 index 0000000..c94739f --- /dev/null +++ b/test/http_SUITE_data/http_multipart.erl @@ -0,0 +1,29 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_multipart). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +init({_Transport, http}, Req, []) -> + {ok, Req, {}}. + +handle(Req, State) -> + {Result, Req2} = acc_multipart(Req), + {ok, Req3} = cowboy_req:reply(200, [], term_to_binary(Result), Req2), + {ok, Req3, State}. + +terminate(_, _, _) -> + ok. + +acc_multipart(Req) -> + acc_multipart(cowboy_req:multipart_data(Req), []). + +acc_multipart({headers, Headers, Req}, Acc) -> + acc_multipart(cowboy_req:multipart_data(Req), [{Headers, []}|Acc]); +acc_multipart({body, Data, Req}, [{Headers, BodyAcc}|Acc]) -> + acc_multipart(cowboy_req:multipart_data(Req), [{Headers, [Data|BodyAcc]}|Acc]); +acc_multipart({end_of_part, Req}, [{Headers, BodyAcc}|Acc]) -> + acc_multipart(cowboy_req:multipart_data(Req), + [{Headers, list_to_binary(lists:reverse(BodyAcc))}|Acc]); +acc_multipart({eof, Req}, Acc) -> + {lists:reverse(Acc), Req}. diff --git a/test/http_SUITE_data/http_set_resp.erl b/test/http_SUITE_data/http_set_resp.erl new file mode 100644 index 0000000..821cc1d --- /dev/null +++ b/test/http_SUITE_data/http_set_resp.erl @@ -0,0 +1,31 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_set_resp). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +init({_Transport, http}, Req, Opts) -> + Headers = proplists:get_value(headers, Opts, []), + Body = proplists:get_value(body, Opts, <<"http_handler_set_resp">>), + Req2 = lists:foldl(fun({Name, Value}, R) -> + cowboy_req:set_resp_header(Name, Value, R) + end, Req, Headers), + Req3 = cowboy_req:set_resp_body(Body, Req2), + Req4 = cowboy_req:set_resp_header(<<"x-cowboy-test">>, <<"ok">>, Req3), + Req5 = cowboy_req:set_resp_cookie(<<"cake">>, <<"lie">>, [], Req4), + {ok, Req5, undefined}. + +handle(Req, State) -> + case cowboy_req:has_resp_header(<<"x-cowboy-test">>, Req) of + false -> {ok, Req, State}; + true -> + case cowboy_req:has_resp_body(Req) of + false -> {ok, Req, State}; + true -> + {ok, Req2} = cowboy_req:reply(200, Req), + {ok, Req2, State} + end + end. + +terminate(_, _, _) -> + ok. diff --git a/test/http_SUITE_data/http_stream_body.erl b/test/http_SUITE_data/http_stream_body.erl new file mode 100644 index 0000000..4f45656 --- /dev/null +++ b/test/http_SUITE_data/http_stream_body.erl @@ -0,0 +1,28 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(http_stream_body). +-behaviour(cowboy_http_handler). +-export([init/3, handle/2, terminate/3]). + +-record(state, {headers, body, reply}). + +init({_Transport, http}, Req, Opts) -> + Headers = proplists:get_value(headers, Opts, []), + Body = proplists:get_value(body, Opts, "http_handler_stream_body"), + Reply = proplists:get_value(reply, Opts), + {ok, Req, #state{headers=Headers, body=Body, reply=Reply}}. + +handle(Req, State=#state{headers=_Headers, body=Body, reply=Reply}) -> + SFun = fun(Socket, Transport) -> Transport:send(Socket, Body) end, + Req2 = case Reply of + set_resp -> + SLen = iolist_size(Body), + cowboy_req:set_resp_body_fun(SLen, SFun, Req); + set_resp_close -> + cowboy_req:set_resp_body_fun(SFun, Req) + end, + {ok, Req3} = cowboy_req:reply(200, Req2), + {ok, Req3, State}. + +terminate(_, _, _) -> + ok. diff --git a/test/http_SUITE_data/rest_empty_resource.erl b/test/http_SUITE_data/rest_empty_resource.erl new file mode 100644 index 0000000..7e7c00a --- /dev/null +++ b/test/http_SUITE_data/rest_empty_resource.erl @@ -0,0 +1,5 @@ +-module(rest_empty_resource). +-export([init/3]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. diff --git a/test/http_SUITE_data/rest_expires.erl b/test/http_SUITE_data/rest_expires.erl new file mode 100644 index 0000000..4209041 --- /dev/null +++ b/test/http_SUITE_data/rest_expires.erl @@ -0,0 +1,22 @@ +-module(rest_expires). + +-export([init/3]). +-export([content_types_provided/2]). +-export([get_text_plain/2]). +-export([expires/2]). +-export([last_modified/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +content_types_provided(Req, State) -> + {[{{<<"text">>, <<"plain">>, []}, get_text_plain}], Req, State}. + +get_text_plain(Req, State) -> + {<<"This is REST!">>, Req, State}. + +expires(Req, State) -> + {{{2012, 9, 21}, {22, 36, 14}}, Req, State}. + +last_modified(Req, State) -> + {{{2012, 9, 21}, {22, 36, 14}}, Req, State}. diff --git a/test/http_SUITE_data/rest_forbidden_resource.erl b/test/http_SUITE_data/rest_forbidden_resource.erl new file mode 100644 index 0000000..287ff62 --- /dev/null +++ b/test/http_SUITE_data/rest_forbidden_resource.erl @@ -0,0 +1,31 @@ +-module(rest_forbidden_resource). +-export([init/3, rest_init/2, allowed_methods/2, forbidden/2, + content_types_provided/2, content_types_accepted/2, + to_text/2, from_text/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +rest_init(Req, [Forbidden]) -> + {ok, Req, Forbidden}. + +allowed_methods(Req, State) -> + {[<<"GET">>, <<"HEAD">>, <<"POST">>], Req, State}. + +forbidden(Req, State=true) -> + {true, Req, State}; +forbidden(Req, State=false) -> + {false, Req, State}. + +content_types_provided(Req, State) -> + {[{{<<"text">>, <<"plain">>, []}, to_text}], Req, State}. + +content_types_accepted(Req, State) -> + {[{{<<"text">>, <<"plain">>, []}, from_text}], Req, State}. + +to_text(Req, State) -> + {<<"This is REST!">>, Req, State}. + +from_text(Req, State) -> + {Path, Req2} = cowboy_req:path(Req), + {Path, Req2, State}. diff --git a/test/http_SUITE_data/rest_missing_callbacks.erl b/test/http_SUITE_data/rest_missing_callbacks.erl new file mode 100644 index 0000000..171c856 --- /dev/null +++ b/test/http_SUITE_data/rest_missing_callbacks.erl @@ -0,0 +1,21 @@ +-module(rest_missing_callbacks). +-export([init/3]). +-export([allowed_methods/2]). +-export([content_types_accepted/2]). +-export([content_types_provided/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +allowed_methods(Req, State) -> + {[<<"GET">>, <<"PUT">>], Req, State}. + +content_types_accepted(Req, State) -> + {[ + {<<"application/json">>, put_application_json} + ], Req, State}. + +content_types_provided(Req, State) -> + {[ + {<<"text/plain">>, get_text_plain} + ], Req, State}. diff --git a/test/http_SUITE_data/rest_nodelete_resource.erl b/test/http_SUITE_data/rest_nodelete_resource.erl new file mode 100644 index 0000000..9f9670c --- /dev/null +++ b/test/http_SUITE_data/rest_nodelete_resource.erl @@ -0,0 +1,17 @@ +-module(rest_nodelete_resource). +-export([init/3, allowed_methods/2, content_types_provided/2, + get_text_plain/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +allowed_methods(Req, State) -> + {[<<"GET">>, <<"HEAD">>, <<"DELETE">>], Req, State}. + + +content_types_provided(Req, State) -> + {[{{<<"text">>, <<"plain">>, []}, get_text_plain}], Req, State}. + +get_text_plain(Req, State) -> + {<<"This is REST!">>, Req, State}. + diff --git a/test/http_SUITE_data/rest_param_all.erl b/test/http_SUITE_data/rest_param_all.erl new file mode 100644 index 0000000..09b8cd3 --- /dev/null +++ b/test/http_SUITE_data/rest_param_all.erl @@ -0,0 +1,36 @@ +-module(rest_param_all). + +-export([init/3]). +-export([allowed_methods/2]). +-export([content_types_provided/2]). +-export([get_text_plain/2]). +-export([content_types_accepted/2]). +-export([put_text_plain/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +allowed_methods(Req, State) -> + {[<<"GET">>, <<"PUT">>], Req, State}. + +content_types_provided(Req, State) -> + {[{{<<"text">>, <<"plain">>, '*'}, get_text_plain}], Req, State}. + +get_text_plain(Req, State) -> + {{_, _, Param}, Req2} = + cowboy_req:meta(media_type, Req, {{<<"text">>, <<"plain">>}, []}), + Body = if + Param == '*' -> + <<"'*'">>; + Param == [] -> + <<"[]">>; + Param /= [] -> + iolist_to_binary([[Key, $=, Value] || {Key, Value} <- Param]) + end, + {Body, Req2, State}. + +content_types_accepted(Req, State) -> + {[{{<<"text">>, <<"plain">>, '*'}, put_text_plain}], Req, State}. + +put_text_plain(Req, State) -> + {true, Req, State}. diff --git a/test/http_SUITE_data/rest_patch_resource.erl b/test/http_SUITE_data/rest_patch_resource.erl new file mode 100644 index 0000000..e265f6f --- /dev/null +++ b/test/http_SUITE_data/rest_patch_resource.erl @@ -0,0 +1,34 @@ +-module(rest_patch_resource). +-export([init/3, allowed_methods/2, content_types_provided/2, get_text_plain/2, + content_types_accepted/2, patch_text_plain/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +allowed_methods(Req, State) -> + {[<<"HEAD">>, <<"GET">>, <<"PATCH">>], Req, State}. + +content_types_provided(Req, State) -> + {[{{<<"text">>, <<"plain">>, []}, get_text_plain}], Req, State}. + +get_text_plain(Req, State) -> + {<<"This is REST!">>, Req, State}. + +content_types_accepted(Req, State) -> + case cowboy_req:method(Req) of + {<<"PATCH">>, Req0} -> + {[{{<<"text">>, <<"plain">>, []}, patch_text_plain}], Req0, State}; + {_, Req0} -> + {[], Req0, State} + end. + +patch_text_plain(Req, State) -> + case cowboy_req:body(Req) of + {ok, <<"halt">>, Req0} -> + {ok, Req1} = cowboy_req:reply(400, Req0), + {halt, Req1, State}; + {ok, <<"false">>, Req0} -> + {false, Req0, State}; + {ok, _Body, Req0} -> + {true, Req0, State} + end. diff --git a/test/http_SUITE_data/rest_resource_etags.erl b/test/http_SUITE_data/rest_resource_etags.erl new file mode 100644 index 0000000..43f1e05 --- /dev/null +++ b/test/http_SUITE_data/rest_resource_etags.erl @@ -0,0 +1,30 @@ +-module(rest_resource_etags). +-export([init/3, generate_etag/2, content_types_provided/2, get_text_plain/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +generate_etag(Req, State) -> + case cowboy_req:qs_val(<<"type">>, Req) of + %% Correct return values from generate_etag/2. + {<<"tuple-weak">>, Req2} -> + {{weak, <<"etag-header-value">>}, Req2, State}; + {<<"tuple-strong">>, Req2} -> + {{strong, <<"etag-header-value">>}, Req2, State}; + %% Backwards compatible return values from generate_etag/2. + {<<"binary-weak-quoted">>, Req2} -> + {<<"W/\"etag-header-value\"">>, Req2, State}; + {<<"binary-strong-quoted">>, Req2} -> + {<<"\"etag-header-value\"">>, Req2, State}; + %% Invalid return values from generate_etag/2. + {<<"binary-strong-unquoted">>, Req2} -> + {<<"etag-header-value">>, Req2, State}; + {<<"binary-weak-unquoted">>, Req2} -> + {<<"W/etag-header-value">>, Req2, State} + end. + +content_types_provided(Req, State) -> + {[{{<<"text">>, <<"plain">>, []}, get_text_plain}], Req, State}. + +get_text_plain(Req, State) -> + {<<"This is REST!">>, Req, State}. diff --git a/test/http_SUITE_data/rest_simple_resource.erl b/test/http_SUITE_data/rest_simple_resource.erl new file mode 100644 index 0000000..97145dd --- /dev/null +++ b/test/http_SUITE_data/rest_simple_resource.erl @@ -0,0 +1,12 @@ +-module(rest_simple_resource). +-export([init/3, content_types_provided/2, get_text_plain/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +content_types_provided(Req, State) -> + {[{{<<"text">>, <<"plain">>, []}, get_text_plain}], Req, State}. + +get_text_plain(Req, State) -> + {<<"This is REST!">>, Req, State}. + |