diff --git a/src/core/http/hb_http.erl b/src/core/http/hb_http.erl index e8541f767..be4b56ba0 100644 --- a/src/core/http/hb_http.erl +++ b/src/core/http/hb_http.erl @@ -481,14 +481,10 @@ prepare_request(Format, Method, Peer, Path, RawMessage, Opts) -> %% @doc Reply to the client's HTTP request with a message. reply(Req, TABMReq, Message, Opts) -> - Status = - case hb_maps:get(<<"status">>, Message, not_found, Opts) of - not_found -> 200; - S-> S - end, + Status = http_status(hb_maps:get(<<"status">>, Message, not_found, Opts)), reply(Req, TABMReq, Status, Message, Opts). reply(Req, TABMReq, BinStatus, RawMessage, Opts) when is_binary(BinStatus) -> - reply(Req, TABMReq, binary_to_integer(BinStatus), RawMessage, Opts); + reply(Req, TABMReq, http_status(BinStatus), RawMessage, Opts); reply(InitReq, TABMReq, RawStatus, RawMessage, Opts) -> ReplyStartTime = os:system_time(millisecond), KeyNormMessage = hb_ao:normalize_keys(RawMessage, Opts), @@ -561,6 +557,17 @@ reply(InitReq, TABMReq, RawStatus, RawMessage, Opts) -> ), {ok, PostStreamReq, no_state}. +%% @doc Interpret a message's `status' as an HTTP status only when it is a +%% valid status code. Devices may also use this field for application-level +%% statuses such as `ok', which should be returned with HTTP 200. +http_status(not_found) -> 200; +http_status(Status) when is_integer(Status), Status >= 100, Status =< 599 -> Status; +http_status(Status) when is_binary(Status) -> + try http_status(binary_to_integer(Status)) + catch error:badarg -> 200 + end; +http_status(_Status) -> 200. + %% @doc Determine if the stream should be finalized. should_finalize_stream(429, _EncodedBody) -> true; should_finalize_stream(_, _EncodedBody) -> false. @@ -1235,6 +1242,12 @@ simple_ao_resolve_signed_test() -> ), ?assertEqual(<<"Value1">>, Res). +http_status_test() -> + ?assertEqual(200, http_status(<<"ok">>)), + ?assertEqual(200, http_status(not_found)), + ?assertEqual(200, http_status(<<"200">>)), + ?assertEqual(404, http_status(404)). + paranoid_http_result_test() -> % The `http_result' topic verifies each response at the reply boundary (in % `encode_reply', before wire conversion): a validly committed result