mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-15 12:40:25 +00:00
allow POST rest handling to specify path after accepting content
This commit is contained in:
parent
a59c5d6e91
commit
8a798014e9
3 changed files with 69 additions and 0 deletions
|
@ -670,6 +670,8 @@ post_is_create(Req, State) ->
|
||||||
%% (including the leading /).
|
%% (including the leading /).
|
||||||
create_path(Req, State) ->
|
create_path(Req, State) ->
|
||||||
case call(Req, State, create_path) of
|
case call(Req, State, create_path) of
|
||||||
|
no_call ->
|
||||||
|
put_resource(Req, State, fun created_path/2);
|
||||||
{halt, Req2, HandlerState} ->
|
{halt, Req2, HandlerState} ->
|
||||||
terminate(Req2, State#state{handler_state=HandlerState});
|
terminate(Req2, State#state{handler_state=HandlerState});
|
||||||
{Path, Req2, HandlerState} ->
|
{Path, Req2, HandlerState} ->
|
||||||
|
@ -681,6 +683,23 @@ create_path(Req, State) ->
|
||||||
State2, 303)
|
State2, 303)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% Called after content_types_accepted is called for POST methods
|
||||||
|
%% when create_path did not exist. Expects the full path to
|
||||||
|
%% be returned and MUST exist in the case that create_path
|
||||||
|
%% does not.
|
||||||
|
created_path(Req, State) ->
|
||||||
|
case call(Req, State, created_path) of
|
||||||
|
{halt, Req2, HandlerState} ->
|
||||||
|
terminate(Req2, State#state{handler_state=HandlerState});
|
||||||
|
{Path, Req2, HandlerState} ->
|
||||||
|
{HostURL, Req3} = cowboy_req:host_url(Req2),
|
||||||
|
State2 = State#state{handler_state=HandlerState},
|
||||||
|
Req4 = cowboy_req:set_resp_header(
|
||||||
|
<<"Location">>, << HostURL/binary, Path/binary >>, Req3),
|
||||||
|
respond(cowboy_req:set_meta(put_path, Path, Req4),
|
||||||
|
State2, 303)
|
||||||
|
end.
|
||||||
|
|
||||||
%% process_post should return true when the POST body could be processed
|
%% process_post should return true when the POST body could be processed
|
||||||
%% and false when it hasn't, in which case a 500 error is sent.
|
%% and false when it hasn't, in which case a 500 error is sent.
|
||||||
process_post(Req, State) ->
|
process_post(Req, State) ->
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
-export([onresponse_reply/1]).
|
-export([onresponse_reply/1]).
|
||||||
-export([pipeline/1]).
|
-export([pipeline/1]).
|
||||||
-export([rest_bad_accept/1]).
|
-export([rest_bad_accept/1]).
|
||||||
|
-export([rest_created_path/1]).
|
||||||
-export([rest_expires/1]).
|
-export([rest_expires/1]).
|
||||||
-export([rest_keepalive/1]).
|
-export([rest_keepalive/1]).
|
||||||
-export([rest_keepalive_post/1]).
|
-export([rest_keepalive_post/1]).
|
||||||
|
@ -112,6 +113,7 @@ groups() ->
|
||||||
nc_zero,
|
nc_zero,
|
||||||
pipeline,
|
pipeline,
|
||||||
rest_bad_accept,
|
rest_bad_accept,
|
||||||
|
rest_created_path,
|
||||||
rest_expires,
|
rest_expires,
|
||||||
rest_keepalive,
|
rest_keepalive,
|
||||||
rest_keepalive_post,
|
rest_keepalive_post,
|
||||||
|
@ -334,6 +336,7 @@ init_dispatch(Config) ->
|
||||||
{"/missing_put_callbacks", rest_missing_callbacks, []},
|
{"/missing_put_callbacks", rest_missing_callbacks, []},
|
||||||
{"/nodelete", rest_nodelete_resource, []},
|
{"/nodelete", rest_nodelete_resource, []},
|
||||||
{"/patch", rest_patch_resource, []},
|
{"/patch", rest_patch_resource, []},
|
||||||
|
{"/created_path", rest_created_path_resource, []},
|
||||||
{"/resetags", rest_resource_etags, []},
|
{"/resetags", rest_resource_etags, []},
|
||||||
{"/rest_expires", rest_expires, []},
|
{"/rest_expires", rest_expires, []},
|
||||||
{"/loop_timeout", http_handler_loop_timeout, []},
|
{"/loop_timeout", http_handler_loop_timeout, []},
|
||||||
|
@ -763,6 +766,18 @@ rest_bad_accept(Config) ->
|
||||||
Client),
|
Client),
|
||||||
{ok, 400, _, _} = cowboy_client:response(Client2).
|
{ok, 400, _, _} = cowboy_client:response(Client2).
|
||||||
|
|
||||||
|
rest_created_path(Config) ->
|
||||||
|
Headers = [{<<"content-type">>, <<"text/plain">>}],
|
||||||
|
Body = <<"Whatever">>,
|
||||||
|
Client = ?config(client, Config),
|
||||||
|
URL = build_url("/created_path", Config),
|
||||||
|
{ok, Client2} = cowboy_client:request(<<"POST">>, URL, Headers,
|
||||||
|
Body, Client),
|
||||||
|
{ok, 303, ResHeaders, _} = cowboy_client:response(Client2),
|
||||||
|
{<<"location">>, _Location} =
|
||||||
|
lists:keyfind(<<"location">>, 1, ResHeaders),
|
||||||
|
ok.
|
||||||
|
|
||||||
rest_expires(Config) ->
|
rest_expires(Config) ->
|
||||||
Client = ?config(client, Config),
|
Client = ?config(client, Config),
|
||||||
{ok, Client2} = cowboy_client:request(<<"GET">>,
|
{ok, Client2} = cowboy_client:request(<<"GET">>,
|
||||||
|
|
35
test/rest_created_path_resource.erl
Normal file
35
test/rest_created_path_resource.erl
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
-module(rest_created_path_resource).
|
||||||
|
-export([init/3]).
|
||||||
|
-export([allowed_methods/2]).
|
||||||
|
-export([content_types_provided/2]).
|
||||||
|
-export([get_text_plain/2]).
|
||||||
|
-export([post_is_create/2]).
|
||||||
|
-export([content_types_accepted/2]).
|
||||||
|
-export([post_text_plain/2]).
|
||||||
|
-export([created_path/2]).
|
||||||
|
|
||||||
|
init(_Transport, _Req, _Opts) ->
|
||||||
|
{upgrade, protocol, cowboy_rest}.
|
||||||
|
|
||||||
|
allowed_methods(Req, State) ->
|
||||||
|
{[<<"HEAD">>, <<"GET">>, <<"POST">>], Req, State}.
|
||||||
|
|
||||||
|
content_types_provided(Req, State) ->
|
||||||
|
{[{{<<"text">>, <<"plain">>, []}, get_text_plain}], Req, State}.
|
||||||
|
|
||||||
|
get_text_plain(Req, State) ->
|
||||||
|
{<<"This is REST!">>, Req, State}.
|
||||||
|
|
||||||
|
post_is_create(Req, State) ->
|
||||||
|
{true, Req, State}.
|
||||||
|
|
||||||
|
content_types_accepted(Req, State) ->
|
||||||
|
{[{{<<"text">>, <<"plain">>, []}, post_text_plain}], Req, State}.
|
||||||
|
|
||||||
|
post_text_plain(Req, State) ->
|
||||||
|
{true, Req, State}.
|
||||||
|
|
||||||
|
created_path(Req, State) ->
|
||||||
|
{<<"/created">>, Req, State}.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue