Browse Source

Add {halt, Req, State} return value to most REST callbacks

Excluding generate_etag, last_modified, expires and variances.
Loïc Hoguin 13 years ago
parent
commit
dee19f11c3
1 changed files with 34 additions and 2 deletions
  1. 34 2
      src/cowboy_http_rest.erl

+ 34 - 2
src/cowboy_http_rest.erl

@@ -89,6 +89,8 @@ known_methods(Req=#http_req{method=Method}, State) ->
 			next(Req, State, fun uri_too_long/2);
 		no_call ->
 			next(Req, State, 501);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{List, Req2, HandlerState} ->
 			State2 = State#state{handler_state=HandlerState},
 			case lists:member(Method, List) of
@@ -107,6 +109,8 @@ allowed_methods(Req=#http_req{method=Method}, State) ->
 			next(Req, State, fun malformed_request/2);
 		no_call ->
 			method_not_allowed(Req, State, ['GET', 'HEAD']);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{List, Req2, HandlerState} ->
 			State2 = State#state{handler_state=HandlerState},
 			case lists:member(Method, List) of
@@ -138,6 +142,8 @@ is_authorized(Req, State) ->
 	case call(Req, State, is_authorized) of
 		no_call ->
 			forbidden(Req, State);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{true, Req2, HandlerState} ->
 			forbidden(Req2, State#state{handler_state=HandlerState});
 		{{false, AuthHead}, Req2, HandlerState} ->
@@ -163,8 +169,12 @@ valid_entity_length(Req, State) ->
 %% If you need to add additional headers to the response at this point,
 %% you should do it directly in the options/2 call using set_resp_headers.
 options(Req=#http_req{method='OPTIONS'}, State) ->
-	{ok, Req2, HandlerState} = call(Req, State, options),
-	respond(Req2, State#state{handler_state=HandlerState}, 200);
+	case call(Req, State, options) of
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
+		{ok, Req2, HandlerState} ->
+			respond(Req2, State#state{handler_state=HandlerState}, 200)
+	end;
 options(Req, State) ->
 	content_types_provided(Req, State).
 
@@ -187,6 +197,8 @@ content_types_provided(Req=#http_req{meta=Meta}, State) ->
 	case call(Req, State, content_types_provided) of
 		no_call ->
 			not_acceptable(Req, State);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{[], Req2, HandlerState} ->
 			not_acceptable(Req2, State#state{handler_state=HandlerState});
 		{CTP, Req2, HandlerState} ->
@@ -281,6 +293,8 @@ languages_provided(Req, State) ->
 	case call(Req, State, languages_provided) of
 		no_call ->
 			charsets_provided(Req, State);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{[], Req2, HandlerState} ->
 			not_acceptable(Req2, State#state{handler_state=HandlerState});
 		{LP, Req2, HandlerState} ->
@@ -342,6 +356,8 @@ charsets_provided(Req, State) ->
 	case call(Req, State, charsets_provided) of
 		no_call ->
 			set_content_type(Req, State);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{[], Req2, HandlerState} ->
 			not_acceptable(Req2, State#state{handler_state=HandlerState});
 		{CP, Req2, HandlerState} ->
@@ -586,6 +602,8 @@ moved_permanently(Req, State, OnFalse) ->
 			respond(Req3, State#state{handler_state=HandlerState}, 301);
 		{false, Req2, HandlerState} ->
 			OnFalse(Req2, State#state{handler_state=HandlerState});
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		no_call ->
 			OnFalse(Req, State)
 	end.
@@ -605,6 +623,8 @@ moved_temporarily(Req, State) ->
 			respond(Req3, State#state{handler_state=HandlerState}, 307);
 		{false, Req2, HandlerState} ->
 			is_post_to_missing_resource(Req2, State#state{handler_state=HandlerState}, 410);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		no_call ->
 			is_post_to_missing_resource(Req, State, 410)
 	end.
@@ -643,6 +663,8 @@ post_is_create(Req, State) ->
 %% (including the leading /).
 create_path(Req=#http_req{meta=Meta}, State) ->
 	case call(Req, State, create_path) of
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{Path, Req2, HandlerState} ->
 			Location = create_path_location(Req2, Path),
 			State2 = State#state{handler_state=HandlerState},
@@ -673,6 +695,8 @@ create_path_location_port(_, Port) ->
 %% and false when it hasn't, in which case a 500 error is sent.
 process_post(Req, State) ->
 	case call(Req, State, process_post) of
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{true, Req2, HandlerState} ->
 			State2 = State#state{handler_state=HandlerState},
 			next(Req2, State2, 201);
@@ -700,6 +724,8 @@ put_resource(Req, State, OnTrue) ->
 	case call(Req, State, content_types_accepted) of
 		no_call ->
 			respond(Req, State, 415);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{CTA, Req2, HandlerState} ->
 			State2 = State#state{handler_state=HandlerState},
 			{ContentType, Req3}
@@ -712,6 +738,8 @@ choose_content_type(Req, State, _OnTrue, _ContentType, []) ->
 choose_content_type(Req, State, OnTrue, ContentType,
 		[{Accepted, Fun}|_Tail]) when ContentType =:= Accepted ->
 	case call(Req, State, Fun) of
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{true, Req2, HandlerState} ->
 			State2 = State#state{handler_state=HandlerState},
 			next(Req2, State2, OnTrue);
@@ -755,6 +783,8 @@ set_resp_body(Req=#http_req{method=Method},
 	end,
 	{Req5, State4} = set_resp_expires(Req4, State3),
 	case call(Req5, State4, Fun) of
+		{halt, Req6, HandlerState} ->
+			terminate(Req6, State4#state{handler_state=HandlerState});
 		{Body, Req6, HandlerState} ->
 			State5 = State4#state{handler_state=HandlerState},
 			{ok, Req7} = case Body of
@@ -842,6 +872,8 @@ expect(Req, State, Callback, Expected, OnTrue, OnFalse) ->
 	case call(Req, State, Callback) of
 		no_call ->
 			next(Req, State, OnTrue);
+		{halt, Req2, HandlerState} ->
+			terminate(Req2, State#state{handler_state=HandlerState});
 		{Expected, Req2, HandlerState} ->
 			next(Req2, State#state{handler_state=HandlerState}, OnTrue);
 		{_Unexpected, Req2, HandlerState} ->