diff options
author | Loïc Hoguin <[email protected]> | 2018-11-04 11:51:35 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2018-11-04 11:58:59 +0100 |
commit | 8c9ad7bf078871295e391f416bfcb10c9156a35f (patch) | |
tree | f92cf4f4ff6f978405cf8171e86b44de27f91265 /src/cowboy_rest.erl | |
parent | bf7ccc8623610d34cf3323db776b280a50275678 (diff) | |
download | cowboy-8c9ad7bf078871295e391f416bfcb10c9156a35f.tar.gz cowboy-8c9ad7bf078871295e391f416bfcb10c9156a35f.tar.bz2 cowboy-8c9ad7bf078871295e391f416bfcb10c9156a35f.zip |
Add the rate_limited/2 REST callback
Diffstat (limited to 'src/cowboy_rest.erl')
-rw-r--r-- | src/cowboy_rest.erl | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/cowboy_rest.erl b/src/cowboy_rest.erl index 512dc5b..8ab576c 100644 --- a/src/cowboy_rest.erl +++ b/src/cowboy_rest.erl @@ -180,6 +180,13 @@ when Req::cowboy_req:req(), State::any(). -optional_callbacks([previously_existed/2]). +-callback rate_limited(Req, State) + -> {{true, non_neg_integer() | calendar:datetime()} | false, Req, State} + | {stop, Req, State} + | {switch_handler(), Req, State} + when Req::cowboy_req:req(), State::any(). +-optional_callbacks([rate_limited/2]). + -callback resource_exists(Req, State) -> {boolean(), Req, State} | {stop, Req, State} @@ -363,7 +370,28 @@ is_authorized(Req, State) -> end. forbidden(Req, State) -> - expect(Req, State, forbidden, false, fun valid_content_headers/2, 403). + expect(Req, State, forbidden, false, fun rate_limited/2, 403). + +rate_limited(Req, State) -> + case call(Req, State, rate_limited) of + no_call -> + valid_content_headers(Req, State); + {stop, Req2, HandlerState} -> + terminate(Req2, State#state{handler_state=HandlerState}); + {Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> + switch_handler(Switch, Req2, HandlerState); + {false, Req2, HandlerState} -> + valid_content_headers(Req2, State#state{handler_state=HandlerState}); + {{true, RetryAfter0}, Req2, HandlerState} -> + RetryAfter = if + is_integer(RetryAfter0), RetryAfter0 >= 0 -> + integer_to_binary(RetryAfter0); + is_tuple(RetryAfter0) -> + cowboy_clock:rfc1123(RetryAfter0) + end, + Req3 = cowboy_req:set_resp_header(<<"retry-after">>, RetryAfter, Req2), + respond(Req3, State#state{handler_state=HandlerState}, 429) + end. valid_content_headers(Req, State) -> expect(Req, State, valid_content_headers, true, |