mirror of
https://github.com/valitydev/woody_erlang.git
synced 2024-11-06 02:15:19 +00:00
Drop legacy headers support (#144)
This commit is contained in:
parent
33b6991373
commit
42dbb91b2b
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
-define(ERROR_RESP_BODY , <<"parse http response body error">> ).
|
-define(ERROR_RESP_BODY , <<"parse http response body error">> ).
|
||||||
-define(ERROR_RESP_HEADER , <<"parse http response headers error">>).
|
-define(ERROR_RESP_HEADER , <<"parse http response headers error">>).
|
||||||
-define(BAD_RESP_HEADER(Mode) , <<"reason unknown due to bad ", ?HEADER_PREFIX(Mode)/binary, "-error- headers">>).
|
-define(BAD_RESP_HEADER , <<"reason unknown due to bad ", ?HEADER_PREFIX/binary, "-error- headers">>).
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% API
|
%% API
|
||||||
@ -196,16 +196,14 @@ close(Transport) ->
|
|||||||
-spec handle_result(_, woody_state:st()) ->
|
-spec handle_result(_, woody_state:st()) ->
|
||||||
{ok, woody:http_body()} | error().
|
{ok, woody:http_body()} | error().
|
||||||
handle_result({ok, 200, Headers, Ref}, WoodyState) ->
|
handle_result({ok, 200, Headers, Ref}, WoodyState) ->
|
||||||
Mode = woody_util:get_error_headers_mode(Headers),
|
Meta = case check_error_reason(Headers, 200, WoodyState) of
|
||||||
Meta = case check_error_reason(Headers, 200, Mode, WoodyState) of
|
|
||||||
<<>> -> #{};
|
<<>> -> #{};
|
||||||
Reason -> #{reason => Reason}
|
Reason -> #{reason => Reason}
|
||||||
end,
|
end,
|
||||||
_ = log_event(?EV_CLIENT_RECEIVE, WoodyState, Meta#{status => ok, code => 200}),
|
_ = log_event(?EV_CLIENT_RECEIVE, WoodyState, Meta#{status => ok, code => 200}),
|
||||||
get_body(hackney:body(Ref), WoodyState);
|
get_body(hackney:body(Ref), WoodyState);
|
||||||
handle_result({ok, Code, Headers, Ref}, WoodyState) ->
|
handle_result({ok, Code, Headers, Ref}, WoodyState) ->
|
||||||
Mode = woody_util:get_error_headers_mode(Headers),
|
{Class, Details} = check_error_headers(Code, Headers, WoodyState),
|
||||||
{Class, Details} = check_error_headers(Code, Headers, Mode, WoodyState),
|
|
||||||
_ = log_event(?EV_CLIENT_RECEIVE, WoodyState, #{status=>error, code=>Code, reason=>Details}),
|
_ = log_event(?EV_CLIENT_RECEIVE, WoodyState, #{status=>error, code=>Code, reason=>Details}),
|
||||||
%% Free the connection
|
%% Free the connection
|
||||||
case hackney:skip_body(Ref) of
|
case hackney:skip_body(Ref) of
|
||||||
@ -259,12 +257,12 @@ get_body({error, Reason}, WoodyState) ->
|
|||||||
_ = log_internal_error(?ERROR_RESP_BODY, Reason, WoodyState),
|
_ = log_internal_error(?ERROR_RESP_BODY, Reason, WoodyState),
|
||||||
{error, {system, {internal, result_unknown, ?ERROR_RESP_BODY}}}.
|
{error, {system, {internal, result_unknown, ?ERROR_RESP_BODY}}}.
|
||||||
|
|
||||||
-spec check_error_headers(woody:http_code(), woody:http_headers(), woody_util:headers_mode(), woody_state:st()) ->
|
-spec check_error_headers(woody:http_code(), woody:http_headers(), woody_state:st()) ->
|
||||||
{woody_error:class(), woody_error:details()}.
|
{woody_error:class(), woody_error:details()}.
|
||||||
check_error_headers(502, Headers, Mode, WoodyState) ->
|
check_error_headers(502, Headers, WoodyState) ->
|
||||||
check_502_error_class(get_error_class_header_value(Headers, Mode), Headers, Mode, WoodyState);
|
check_502_error_class(get_error_class_header_value(Headers), Headers, WoodyState);
|
||||||
check_error_headers(Code, Headers, Mode, WoodyState) ->
|
check_error_headers(Code, Headers, WoodyState) ->
|
||||||
{get_error_class(Code), check_error_reason(Headers, Code, Mode, WoodyState)}.
|
{get_error_class(Code), check_error_reason(Headers, Code, WoodyState)}.
|
||||||
|
|
||||||
-spec get_error_class(woody:http_code()) ->
|
-spec get_error_class(woody:http_code()) ->
|
||||||
woody_error:class().
|
woody_error:class().
|
||||||
@ -275,40 +273,40 @@ get_error_class(504) ->
|
|||||||
get_error_class(_) ->
|
get_error_class(_) ->
|
||||||
result_unexpected.
|
result_unexpected.
|
||||||
|
|
||||||
-spec check_502_error_class(header_parse_value(), woody:http_headers(), woody_util:headers_mode(), woody_state:st()) ->
|
-spec check_502_error_class(header_parse_value(), woody:http_headers(), woody_state:st()) ->
|
||||||
{woody_error:class(), woody_error:details()}.
|
{woody_error:class(), woody_error:details()}.
|
||||||
check_502_error_class(none, Headers, Mode, WoodyState) ->
|
check_502_error_class(none, Headers, WoodyState) ->
|
||||||
_ = log_event(?EV_TRACE, WoodyState, #{event => woody_util:to_binary([?HEADER_E_CLASS(Mode), " header missing"])}),
|
_ = log_event(?EV_TRACE, WoodyState, #{event => woody_util:to_binary([?HEADER_E_CLASS, " header missing"])}),
|
||||||
{result_unexpected, check_error_reason(Headers, 502, Mode, WoodyState)};
|
{result_unexpected, check_error_reason(Headers, 502, WoodyState)};
|
||||||
check_502_error_class(<<"result unexpected">>, Headers, Mode, WoodyState) ->
|
check_502_error_class(<<"result unexpected">>, Headers, WoodyState) ->
|
||||||
{result_unexpected, check_error_reason(Headers, 502, Mode, WoodyState)};
|
{result_unexpected, check_error_reason(Headers, 502, WoodyState)};
|
||||||
check_502_error_class(<<"resource unavailable">>, Headers, Mode, WoodyState) ->
|
check_502_error_class(<<"resource unavailable">>, Headers, WoodyState) ->
|
||||||
{resource_unavailable, check_error_reason(Headers, 502, Mode, WoodyState)};
|
{resource_unavailable, check_error_reason(Headers, 502, WoodyState)};
|
||||||
check_502_error_class(<<"result unknown">>, Headers, Mode, WoodyState) ->
|
check_502_error_class(<<"result unknown">>, Headers, WoodyState) ->
|
||||||
{result_unknown, check_error_reason(Headers, 502, Mode, WoodyState)};
|
{result_unknown, check_error_reason(Headers, 502, WoodyState)};
|
||||||
check_502_error_class(Bad, _, Mode, WoodyState) ->
|
check_502_error_class(Bad, _, WoodyState) ->
|
||||||
_ = log_internal_error(?ERROR_RESP_HEADER, ["unknown ", ?HEADER_E_CLASS(Mode), " header value: ", Bad], WoodyState),
|
_ = log_internal_error(?ERROR_RESP_HEADER, ["unknown ", ?HEADER_E_CLASS, " header value: ", Bad], WoodyState),
|
||||||
{result_unexpected, ?BAD_RESP_HEADER(Mode)}.
|
{result_unexpected, ?BAD_RESP_HEADER}.
|
||||||
|
|
||||||
-spec check_error_reason(woody:http_headers(), woody:http_code(), woody_util:headers_mode(), woody_state:st()) ->
|
-spec check_error_reason(woody:http_headers(), woody:http_code(), woody_state:st()) ->
|
||||||
woody_error:details().
|
woody_error:details().
|
||||||
check_error_reason(Headers, Code, Mode, WoodyState) ->
|
check_error_reason(Headers, Code, WoodyState) ->
|
||||||
do_check_error_reason(get_header_value(?HEADER_E_REASON(Mode), Headers), Code, Mode, WoodyState).
|
do_check_error_reason(get_header_value(?HEADER_E_REASON, Headers), Code, WoodyState).
|
||||||
|
|
||||||
-spec do_check_error_reason(header_parse_value(), woody:http_code(), woody_util:headers_mode(), woody_state:st()) ->
|
-spec do_check_error_reason(header_parse_value(), woody:http_code(), woody_state:st()) ->
|
||||||
woody_error:details().
|
woody_error:details().
|
||||||
do_check_error_reason(none, 200, _Mode, _WoodyState) ->
|
do_check_error_reason(none, 200, _WoodyState) ->
|
||||||
<<>>;
|
<<>>;
|
||||||
do_check_error_reason(none, Code, Mode, WoodyState) ->
|
do_check_error_reason(none, Code, WoodyState) ->
|
||||||
_ = log_event(?EV_TRACE, WoodyState, #{event => woody_util:to_binary([?HEADER_E_REASON(Mode), " header missing"])}),
|
_ = log_event(?EV_TRACE, WoodyState, #{event => woody_util:to_binary([?HEADER_E_REASON, " header missing"])}),
|
||||||
woody_util:to_binary(["got response with http code ", Code, " and without ", ?HEADER_E_REASON(Mode), " header"]);
|
woody_util:to_binary(["got response with http code ", Code, " and without ", ?HEADER_E_REASON, " header"]);
|
||||||
do_check_error_reason(Reason, _, _, _) ->
|
do_check_error_reason(Reason, _, _) ->
|
||||||
Reason.
|
Reason.
|
||||||
|
|
||||||
-spec get_error_class_header_value(woody:http_headers(), woody_util:headers_mode()) ->
|
-spec get_error_class_header_value(woody:http_headers()) ->
|
||||||
header_parse_value().
|
header_parse_value().
|
||||||
get_error_class_header_value(Headers, Mode) ->
|
get_error_class_header_value(Headers) ->
|
||||||
case get_header_value(?HEADER_E_CLASS(Mode), Headers) of
|
case get_header_value(?HEADER_E_CLASS, Headers) of
|
||||||
None when None =:= none orelse None =:= multiple ->
|
None when None =:= none orelse None =:= multiple ->
|
||||||
None;
|
None;
|
||||||
Value ->
|
Value ->
|
||||||
@ -329,14 +327,11 @@ get_header_value(Name, Headers) ->
|
|||||||
woody:http_headers().
|
woody:http_headers().
|
||||||
make_woody_headers(Context) ->
|
make_woody_headers(Context) ->
|
||||||
add_optional_headers(Context, #{
|
add_optional_headers(Context, #{
|
||||||
<<"content-type">> => ?CONTENT_TYPE_THRIFT,
|
<<"content-type">> => ?CONTENT_TYPE_THRIFT,
|
||||||
<<"accept">> => ?CONTENT_TYPE_THRIFT,
|
<<"accept">> => ?CONTENT_TYPE_THRIFT,
|
||||||
?NORMAL_HEADER_RPC_ROOT_ID => woody_context:get_rpc_id(trace_id , Context),
|
?HEADER_RPC_ROOT_ID => woody_context:get_rpc_id(trace_id , Context),
|
||||||
?NORMAL_HEADER_RPC_ID => woody_context:get_rpc_id(span_id , Context),
|
?HEADER_RPC_ID => woody_context:get_rpc_id(span_id , Context),
|
||||||
?NORMAL_HEADER_RPC_PARENT_ID => woody_context:get_rpc_id(parent_id, Context),
|
?HEADER_RPC_PARENT_ID => woody_context:get_rpc_id(parent_id, Context)
|
||||||
?LEGACY_HEADER_RPC_ROOT_ID => woody_context:get_rpc_id(trace_id , Context),
|
|
||||||
?LEGACY_HEADER_RPC_ID => woody_context:get_rpc_id(span_id , Context),
|
|
||||||
?LEGACY_HEADER_RPC_PARENT_ID => woody_context:get_rpc_id(parent_id, Context)
|
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-spec add_optional_headers(woody_context:ctx(), woody:http_headers()) ->
|
-spec add_optional_headers(woody_context:ctx(), woody:http_headers()) ->
|
||||||
@ -352,10 +347,7 @@ add_metadata_headers(Context, Headers) ->
|
|||||||
-spec add_metadata_header(woody:http_header_name(), woody:http_header_val(), woody:http_headers()) ->
|
-spec add_metadata_header(woody:http_header_name(), woody:http_header_val(), woody:http_headers()) ->
|
||||||
woody:http_headers() | no_return().
|
woody:http_headers() | no_return().
|
||||||
add_metadata_header(H, V, Headers) when is_binary(H) and is_binary(V) ->
|
add_metadata_header(H, V, Headers) when is_binary(H) and is_binary(V) ->
|
||||||
maps:merge(#{
|
maps:put(<<?HEADER_META_PREFIX/binary, H/binary>>, V, Headers);
|
||||||
<< ?NORMAL_HEADER_META_PREFIX/binary, H/binary >> => V,
|
|
||||||
<< ?LEGACY_HEADER_META_PREFIX/binary, H/binary >> => V
|
|
||||||
}, Headers);
|
|
||||||
add_metadata_header(H, V, Headers) ->
|
add_metadata_header(H, V, Headers) ->
|
||||||
error(badarg, [H, V, Headers]).
|
error(badarg, [H, V, Headers]).
|
||||||
|
|
||||||
@ -365,10 +357,7 @@ add_deadline_header(Context, Headers) ->
|
|||||||
do_add_deadline_header(undefined, Headers) ->
|
do_add_deadline_header(undefined, Headers) ->
|
||||||
Headers;
|
Headers;
|
||||||
do_add_deadline_header(Deadline, Headers) ->
|
do_add_deadline_header(Deadline, Headers) ->
|
||||||
maps:merge(#{
|
maps:put(?HEADER_DEADLINE, woody_deadline:to_binary(Deadline), Headers).
|
||||||
?NORMAL_HEADER_DEADLINE => woody_deadline:to_binary(Deadline),
|
|
||||||
?LEGACY_HEADER_DEADLINE => woody_deadline:to_binary(Deadline)
|
|
||||||
}, Headers).
|
|
||||||
|
|
||||||
add_host_header(#hackney_url{netloc = Netloc}, Headers) ->
|
add_host_header(#hackney_url{netloc = Netloc}, Headers) ->
|
||||||
maps:merge(Headers, #{<<"Host">> => Netloc}).
|
maps:merge(Headers, #{<<"Host">> => Netloc}).
|
||||||
|
@ -5,38 +5,15 @@
|
|||||||
-define(CONTENT_TYPE_THRIFT , <<"application/x-thrift">>).
|
-define(CONTENT_TYPE_THRIFT , <<"application/x-thrift">>).
|
||||||
|
|
||||||
%% Woody-specific HTTP headers
|
%% Woody-specific HTTP headers
|
||||||
-define(NORMAL_HEADER_PREFIX , <<"woody.">>).
|
-define(HEADER_PREFIX , <<"woody.">>).
|
||||||
-define(NORMAL_HEADER_RPC_ID , << ?NORMAL_HEADER_PREFIX/binary, "span-id">>).
|
-define(HEADER_RPC_ID , <<?HEADER_PREFIX/binary, "span-id">>).
|
||||||
-define(NORMAL_HEADER_RPC_PARENT_ID , << ?NORMAL_HEADER_PREFIX/binary, "parent-id">>).
|
-define(HEADER_RPC_PARENT_ID , <<?HEADER_PREFIX/binary, "parent-id">>).
|
||||||
-define(NORMAL_HEADER_RPC_ROOT_ID , << ?NORMAL_HEADER_PREFIX/binary, "trace-id">>).
|
-define(HEADER_RPC_ROOT_ID , <<?HEADER_PREFIX/binary, "trace-id">>).
|
||||||
-define(NORMAL_HEADER_E_CLASS , << ?NORMAL_HEADER_PREFIX/binary, "error-class">>).
|
-define(HEADER_E_CLASS , <<?HEADER_PREFIX/binary, "error-class">>).
|
||||||
-define(NORMAL_HEADER_E_REASON , << ?NORMAL_HEADER_PREFIX/binary, "error-reason">>).
|
-define(HEADER_E_REASON , <<?HEADER_PREFIX/binary, "error-reason">>).
|
||||||
-define(NORMAL_HEADER_DEADLINE , << ?NORMAL_HEADER_PREFIX/binary, "deadline">>).
|
-define(HEADER_DEADLINE , <<?HEADER_PREFIX/binary, "deadline">>).
|
||||||
-define(NORMAL_HEADER_META_PREFIX , << ?NORMAL_HEADER_PREFIX/binary, "meta.">>).
|
-define(HEADER_META_PREFIX , <<?HEADER_PREFIX/binary, "meta.">>).
|
||||||
-define(NORMAL_HEADER_META_RE , <<"woody\\.meta\\.">>).
|
-define(HEADER_META_RE , <<"woody\\.meta\\.">>).
|
||||||
|
|
||||||
%% Legacy woody headers
|
|
||||||
-define(LEGACY_HEADER_PREFIX , <<"x-rbk-">>).
|
|
||||||
-define(LEGACY_HEADER_RPC_ID , << ?LEGACY_HEADER_PREFIX/binary, "span-id">>).
|
|
||||||
-define(LEGACY_HEADER_RPC_PARENT_ID , << ?LEGACY_HEADER_PREFIX/binary, "parent-id">>).
|
|
||||||
-define(LEGACY_HEADER_RPC_ROOT_ID , << ?LEGACY_HEADER_PREFIX/binary, "trace-id">>).
|
|
||||||
-define(LEGACY_HEADER_E_CLASS , << ?LEGACY_HEADER_PREFIX/binary, "error-class">>).
|
|
||||||
-define(LEGACY_HEADER_E_REASON , << ?LEGACY_HEADER_PREFIX/binary, "error-reason">>).
|
|
||||||
-define(LEGACY_HEADER_DEADLINE , << ?LEGACY_HEADER_PREFIX/binary, "deadline">>).
|
|
||||||
-define(LEGACY_HEADER_META_PREFIX , << ?LEGACY_HEADER_PREFIX/binary, "meta-">>).
|
|
||||||
-define(LEGACY_HEADER_META_RE , <<"x-rbk-meta-">>).
|
|
||||||
|
|
||||||
%% transition period helpers
|
|
||||||
-define(HEADER(MODE, NORMAL, LEGACY), case MODE of normal -> NORMAL; legacy -> LEGACY end).
|
|
||||||
-define(HEADER_PREFIX(MODE), ?HEADER(MODE, ?NORMAL_HEADER_PREFIX, ?LEGACY_HEADER_PREFIX)).
|
|
||||||
-define(HEADER_RPC_ID(MODE), ?HEADER(MODE, ?NORMAL_HEADER_RPC_ID, ?LEGACY_HEADER_RPC_ID)).
|
|
||||||
-define(HEADER_RPC_PARENT_ID(MODE), ?HEADER(MODE, ?NORMAL_HEADER_RPC_PARENT_ID, ?LEGACY_HEADER_RPC_PARENT_ID)).
|
|
||||||
-define(HEADER_RPC_ROOT_ID(MODE), ?HEADER(MODE, ?NORMAL_HEADER_RPC_ROOT_ID, ?LEGACY_HEADER_RPC_ROOT_ID)).
|
|
||||||
-define(HEADER_E_CLASS(MODE), ?HEADER(MODE, ?NORMAL_HEADER_E_CLASS, ?LEGACY_HEADER_E_CLASS)).
|
|
||||||
-define(HEADER_E_REASON(MODE), ?HEADER(MODE, ?NORMAL_HEADER_E_REASON, ?LEGACY_HEADER_E_REASON)).
|
|
||||||
-define(HEADER_DEADLINE(MODE), ?HEADER(MODE, ?NORMAL_HEADER_DEADLINE, ?LEGACY_HEADER_DEADLINE)).
|
|
||||||
-define(HEADER_META_PREFIX(MODE), ?HEADER(MODE, ?NORMAL_HEADER_META_PREFIX, ?LEGACY_HEADER_META_PREFIX)).
|
|
||||||
-define(HEADER_META_RE(MODE), ?HEADER(MODE, ?NORMAL_HEADER_META_RE, ?LEGACY_HEADER_META_RE)).
|
|
||||||
|
|
||||||
%% Events
|
%% Events
|
||||||
-define(EV_CALL_SERVICE , 'call service').
|
-define(EV_CALL_SERVICE , 'call service').
|
||||||
|
@ -208,7 +208,7 @@ config() ->
|
|||||||
-spec compile_filter_meta() ->
|
-spec compile_filter_meta() ->
|
||||||
re_mp().
|
re_mp().
|
||||||
compile_filter_meta() ->
|
compile_filter_meta() ->
|
||||||
{ok, Re} = re:compile([?NORMAL_HEADER_META_RE], [unicode, caseless]),
|
{ok, Re} = re:compile(?HEADER_META_RE, [unicode, caseless]),
|
||||||
Re.
|
Re.
|
||||||
|
|
||||||
-spec trace_req(true, cowboy_req:req(), woody:ev_handlers(), server_opts()) ->
|
-spec trace_req(true, cowboy_req:req(), woody:ev_handlers(), server_opts()) ->
|
||||||
@ -362,33 +362,31 @@ check_accept(BadAccept, Req1, State) ->
|
|||||||
-spec check_woody_headers(cowboy_req:req(), state()) ->
|
-spec check_woody_headers(cowboy_req:req(), state()) ->
|
||||||
check_result().
|
check_result().
|
||||||
check_woody_headers(Req, State = #{woody_state := WoodyState0}) ->
|
check_woody_headers(Req, State = #{woody_state := WoodyState0}) ->
|
||||||
{Mode, Req0} = woody_util:get_req_headers_mode(Req),
|
case get_rpc_id(Req) of
|
||||||
case get_rpc_id(Req0, Mode) of
|
|
||||||
{ok, RpcId, Req1} ->
|
{ok, RpcId, Req1} ->
|
||||||
WoodyState1 = set_cert(Req1, set_rpc_id(RpcId, WoodyState0)),
|
WoodyState1 = set_cert(Req1, set_rpc_id(RpcId, WoodyState0)),
|
||||||
check_deadline_header(
|
check_deadline_header(
|
||||||
cowboy_req:header(?HEADER_DEADLINE(Mode), Req1),
|
cowboy_req:header(?HEADER_DEADLINE, Req1),
|
||||||
Req1,
|
Req1,
|
||||||
Mode,
|
|
||||||
update_woody_state(State, WoodyState1, Req1)
|
update_woody_state(State, WoodyState1, Req1)
|
||||||
);
|
);
|
||||||
{error, BadRpcId, Req1} ->
|
{error, BadRpcId, Req1} ->
|
||||||
WoodyState1 = set_rpc_id(BadRpcId, WoodyState0),
|
WoodyState1 = set_rpc_id(BadRpcId, WoodyState0),
|
||||||
reply_bad_header(400, woody_util:to_binary(["bad ", ?HEADER_PREFIX(Mode), " id header"]),
|
reply_bad_header(400, woody_util:to_binary(["bad ", ?HEADER_PREFIX, " id header"]),
|
||||||
Req1, update_woody_state(State, WoodyState1, Req1)
|
Req1, update_woody_state(State, WoodyState1, Req1)
|
||||||
)
|
)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec get_rpc_id(cowboy_req:req(), woody_util:headers_mode()) ->
|
-spec get_rpc_id(cowboy_req:req()) ->
|
||||||
{ok | error, woody:rpc_id(), cowboy_req:req()}.
|
{ok | error, woody:rpc_id(), cowboy_req:req()}.
|
||||||
get_rpc_id(Req, Mode) ->
|
get_rpc_id(Req) ->
|
||||||
check_ids(maps:fold(
|
check_ids(maps:fold(
|
||||||
fun get_rpc_id/3,
|
fun get_rpc_id/3,
|
||||||
#{req => Req},
|
#{req => Req},
|
||||||
#{
|
#{
|
||||||
span_id => ?HEADER_RPC_ID(Mode),
|
span_id => ?HEADER_RPC_ID,
|
||||||
trace_id => ?HEADER_RPC_ROOT_ID(Mode),
|
trace_id => ?HEADER_RPC_ROOT_ID,
|
||||||
parent_id => ?HEADER_RPC_PARENT_ID(Mode)
|
parent_id => ?HEADER_RPC_PARENT_ID
|
||||||
}
|
}
|
||||||
)).
|
)).
|
||||||
|
|
||||||
@ -405,22 +403,22 @@ check_ids(Map = #{status := error, req := Req}) ->
|
|||||||
check_ids(Map = #{req := Req}) ->
|
check_ids(Map = #{req := Req}) ->
|
||||||
{ok, maps:without([req], Map), Req}.
|
{ok, maps:without([req], Map), Req}.
|
||||||
|
|
||||||
-spec check_deadline_header(Header, Req, woody_util:headers_mode(), state()) -> cowboy_init_result() when
|
-spec check_deadline_header(Header, Req, state()) -> cowboy_init_result() when
|
||||||
Header :: woody:http_header_val() | undefined, Req :: cowboy_req:req().
|
Header :: woody:http_header_val() | undefined, Req :: cowboy_req:req().
|
||||||
check_deadline_header(undefined, Req, Mode, State) ->
|
check_deadline_header(undefined, Req, State) ->
|
||||||
check_metadata_headers(cowboy_req:headers(Req), Req, Mode, State);
|
check_metadata_headers(cowboy_req:headers(Req), Req, State);
|
||||||
check_deadline_header(DeadlineBin, Req, Mode, State) ->
|
check_deadline_header(DeadlineBin, Req, State) ->
|
||||||
try woody_deadline:from_binary(DeadlineBin) of
|
try woody_deadline:from_binary(DeadlineBin) of
|
||||||
Deadline -> check_deadline(Deadline, Req, Mode, State)
|
Deadline -> check_deadline(Deadline, Req, State)
|
||||||
catch
|
catch
|
||||||
error:{bad_deadline, Error} ->
|
error:{bad_deadline, Error} ->
|
||||||
ErrorDescription = woody_util:to_binary(["bad ", ?HEADER_DEADLINE(Mode), " header: ", Error]),
|
ErrorDescription = woody_util:to_binary(["bad ", ?HEADER_DEADLINE, " header: ", Error]),
|
||||||
reply_bad_header(400, ErrorDescription, Req, State)
|
reply_bad_header(400, ErrorDescription, Req, State)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec check_deadline(woody:deadline(), cowboy_req:req(), woody_util:headers_mode(), state()) ->
|
-spec check_deadline(woody:deadline(), cowboy_req:req(), state()) ->
|
||||||
check_result().
|
check_result().
|
||||||
check_deadline(Deadline, Req, Mode, State = #{url := Url, woody_state := WoodyState}) ->
|
check_deadline(Deadline, Req, State = #{url := Url, woody_state := WoodyState}) ->
|
||||||
case woody_deadline:is_reached(Deadline) of
|
case woody_deadline:is_reached(Deadline) of
|
||||||
true ->
|
true ->
|
||||||
_ = woody_event_handler:handle_event(?EV_SERVER_RECEIVE, WoodyState,
|
_ = woody_event_handler:handle_event(?EV_SERVER_RECEIVE, WoodyState,
|
||||||
@ -430,29 +428,28 @@ check_deadline(Deadline, Req, Mode, State = #{url := Url, woody_state := WoodySt
|
|||||||
false ->
|
false ->
|
||||||
WoodyState1 = set_deadline(Deadline, WoodyState),
|
WoodyState1 = set_deadline(Deadline, WoodyState),
|
||||||
Headers = cowboy_req:headers(Req),
|
Headers = cowboy_req:headers(Req),
|
||||||
check_metadata_headers(Headers, Req, Mode, update_woody_state(State, WoodyState1, Req))
|
check_metadata_headers(Headers, Req, update_woody_state(State, WoodyState1, Req))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec check_metadata_headers(woody:http_headers(), cowboy_req:req(), woody_util:headers_mode(), state()) ->
|
-spec check_metadata_headers(woody:http_headers(), cowboy_req:req(), state()) ->
|
||||||
check_result().
|
check_result().
|
||||||
check_metadata_headers(Headers, Req, Mode, State = #{woody_state := WoodyState, server_opts := ServerOpts}) ->
|
check_metadata_headers(Headers, Req, State = #{woody_state := WoodyState, server_opts := ServerOpts}) ->
|
||||||
WoodyState1 = set_metadata(find_metadata(Headers, Mode, ServerOpts), WoodyState),
|
WoodyState1 = set_metadata(find_metadata(Headers, ServerOpts), WoodyState),
|
||||||
{ok, Req, update_woody_state(State, WoodyState1, Req)}.
|
{ok, Req, update_woody_state(State, WoodyState1, Req)}.
|
||||||
|
|
||||||
-spec find_metadata(woody:http_headers(), woody_util:headers_mode(), server_opts()) ->
|
-spec find_metadata(woody:http_headers(), server_opts()) ->
|
||||||
woody_context:meta().
|
woody_context:meta().
|
||||||
find_metadata(Headers, Mode, #{regexp_meta := _Re}) ->
|
find_metadata(Headers, #{regexp_meta := Re}) ->
|
||||||
%% TODO: Use compiled Re after headers transition ends
|
RpcId = ?HEADER_RPC_ID,
|
||||||
RpcId = ?HEADER_RPC_ID(Mode),
|
RootId = ?HEADER_RPC_ROOT_ID,
|
||||||
RootId = ?HEADER_RPC_ROOT_ID(Mode),
|
ParentId = ?HEADER_RPC_PARENT_ID,
|
||||||
ParentId = ?HEADER_RPC_PARENT_ID(Mode),
|
|
||||||
maps:fold(
|
maps:fold(
|
||||||
fun(H, V, Acc) when
|
fun(H, V, Acc) when
|
||||||
H =/= RpcId andalso
|
H =/= RpcId andalso
|
||||||
H =/= RootId andalso
|
H =/= RootId andalso
|
||||||
H =/= ParentId
|
H =/= ParentId
|
||||||
->
|
->
|
||||||
case re:replace(H, ?HEADER_META_RE(Mode), "", [{return, binary}, anchored]) of
|
case re:replace(H, Re, "", [{return, binary}, anchored]) of
|
||||||
H -> Acc;
|
H -> Acc;
|
||||||
MetaHeader -> Acc#{MetaHeader => V}
|
MetaHeader -> Acc#{MetaHeader => V}
|
||||||
end;
|
end;
|
||||||
@ -556,10 +553,8 @@ handle_error({system, {external, result_unknown, Details}}, Req, WoodyState) ->
|
|||||||
cowboy_req:req().
|
cowboy_req:req().
|
||||||
set_error_headers(Class, Reason, Req) ->
|
set_error_headers(Class, Reason, Req) ->
|
||||||
Headers = #{
|
Headers = #{
|
||||||
?NORMAL_HEADER_E_CLASS => Class,
|
?HEADER_E_CLASS => Class,
|
||||||
?NORMAL_HEADER_E_REASON => Reason,
|
?HEADER_E_REASON => Reason
|
||||||
?LEGACY_HEADER_E_CLASS => Class,
|
|
||||||
?LEGACY_HEADER_E_REASON =>Reason
|
|
||||||
},
|
},
|
||||||
cowboy_req:set_resp_headers(Headers, Req).
|
cowboy_req:set_resp_headers(Headers, Req).
|
||||||
|
|
||||||
|
@ -2,21 +2,14 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(woody_util).
|
-module(woody_util).
|
||||||
-include("woody_defs.hrl").
|
|
||||||
|
|
||||||
-export([get_protocol_handler/2]).
|
-export([get_protocol_handler/2]).
|
||||||
-export([get_mod_opts/1]).
|
-export([get_mod_opts/1]).
|
||||||
-export([to_binary/1]).
|
-export([to_binary/1]).
|
||||||
-export([get_rpc_reply_type/1]).
|
-export([get_rpc_reply_type/1]).
|
||||||
-export([get_req_headers_mode/1]).
|
|
||||||
-export([get_error_headers_mode/1]).
|
|
||||||
|
|
||||||
-export_type([headers_mode/0]).
|
|
||||||
|
|
||||||
-define(DEFAULT_HANDLER_OPTS, undefined).
|
-define(DEFAULT_HANDLER_OPTS, undefined).
|
||||||
|
|
||||||
-type headers_mode() :: normal | legacy.
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Internal API
|
%% Internal API
|
||||||
%%
|
%%
|
||||||
@ -55,60 +48,3 @@ to_binary([Part | T], Reason) ->
|
|||||||
woody:rpc_type().
|
woody:rpc_type().
|
||||||
get_rpc_reply_type(oneway_void) -> cast;
|
get_rpc_reply_type(oneway_void) -> cast;
|
||||||
get_rpc_reply_type(_) -> call.
|
get_rpc_reply_type(_) -> call.
|
||||||
|
|
||||||
-spec get_req_headers_mode(cowboy_req:req()) ->
|
|
||||||
{headers_mode(), cowboy_req:req()}.
|
|
||||||
get_req_headers_mode(Req) ->
|
|
||||||
get_req_headers_mode(application:get_env(woody, server_headers_mode, auto), Req).
|
|
||||||
|
|
||||||
-spec get_error_headers_mode(woody:http_headers()) ->
|
|
||||||
headers_mode().
|
|
||||||
get_error_headers_mode(Headers) ->
|
|
||||||
get_error_headers_mode(application:get_env(woody, client_headers_mode, auto), Headers).
|
|
||||||
|
|
||||||
%%
|
|
||||||
%% Internals
|
|
||||||
%%
|
|
||||||
|
|
||||||
|
|
||||||
apply_mode_rules([], _Rules, Default) ->
|
|
||||||
Default;
|
|
||||||
apply_mode_rules([Name | HeadersTail], Rules, Default) ->
|
|
||||||
case maps:get(Name, Rules, undefined) of
|
|
||||||
undefined ->
|
|
||||||
apply_mode_rules(HeadersTail, Rules, Default);
|
|
||||||
Mode ->
|
|
||||||
Mode
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec get_req_headers_mode(auto | headers_mode(), cowboy_req:req()) ->
|
|
||||||
{headers_mode(), cowboy_req:req()}.
|
|
||||||
get_req_headers_mode(auto, Req) ->
|
|
||||||
Rules = #{
|
|
||||||
?NORMAL_HEADER_RPC_ID => normal,
|
|
||||||
?NORMAL_HEADER_RPC_PARENT_ID => normal,
|
|
||||||
?NORMAL_HEADER_RPC_ROOT_ID => normal
|
|
||||||
},
|
|
||||||
Headers = cowboy_req:headers(Req),
|
|
||||||
{apply_mode_rules(maps:keys(Headers), Rules, legacy), Req};
|
|
||||||
get_req_headers_mode(legacy = Mode, Req) ->
|
|
||||||
{Mode, Req};
|
|
||||||
get_req_headers_mode(normal = Mode, Req) ->
|
|
||||||
{Mode, Req};
|
|
||||||
get_req_headers_mode(Mode, _Req) ->
|
|
||||||
erlang:error(badarg, [Mode]).
|
|
||||||
|
|
||||||
-spec get_error_headers_mode(auto | headers_mode(), woody:http_headers()) ->
|
|
||||||
headers_mode().
|
|
||||||
get_error_headers_mode(auto, Headers) ->
|
|
||||||
Rules = #{
|
|
||||||
?NORMAL_HEADER_E_CLASS => normal,
|
|
||||||
?NORMAL_HEADER_E_REASON => normal
|
|
||||||
},
|
|
||||||
apply_mode_rules(maps:keys(Headers), Rules, legacy);
|
|
||||||
get_error_headers_mode(legacy = Mode, _Headers) ->
|
|
||||||
Mode;
|
|
||||||
get_error_headers_mode(normal = Mode, _Headers) ->
|
|
||||||
Mode;
|
|
||||||
get_error_headers_mode(Mode, _Headers) ->
|
|
||||||
erlang:error(badarg, [Mode]).
|
|
||||||
|
@ -240,11 +240,7 @@
|
|||||||
%%
|
%%
|
||||||
all() ->
|
all() ->
|
||||||
[
|
[
|
||||||
{group, legacy_client_auto_server},
|
{group, client_server},
|
||||||
{group, auto_client_legacy_server},
|
|
||||||
{group, auto_both},
|
|
||||||
{group, normal_both},
|
|
||||||
{group, legacy_both},
|
|
||||||
{group, woody_resolver}
|
{group, woody_resolver}
|
||||||
].
|
].
|
||||||
|
|
||||||
@ -295,11 +291,7 @@ groups() ->
|
|||||||
calls_with_cache
|
calls_with_cache
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{legacy_client_auto_server, [], SpecTests},
|
{client_server, [], SpecTests},
|
||||||
{auto_client_legacy_server, [], SpecTests},
|
|
||||||
{auto_both, [], SpecTests},
|
|
||||||
{normal_both, [], SpecTests},
|
|
||||||
{legacy_both, [], SpecTests},
|
|
||||||
{woody_resolver, [], [
|
{woody_resolver, [], [
|
||||||
woody_resolver_inet,
|
woody_resolver_inet,
|
||||||
woody_resolver_inet6,
|
woody_resolver_inet6,
|
||||||
@ -331,17 +323,7 @@ init_per_suite(C) ->
|
|||||||
|
|
||||||
end_per_suite(C) ->
|
end_per_suite(C) ->
|
||||||
application:unset_env(hackney, mod_metrics), % unset so it won't report metrics next suite
|
application:unset_env(hackney, mod_metrics), % unset so it won't report metrics next suite
|
||||||
[application_stop(App) || App <- proplists:get_value(apps, C)].
|
[application:stop(App) || App <- proplists:get_value(apps, C)].
|
||||||
|
|
||||||
application_stop(App=sasl) ->
|
|
||||||
%% hack for preventing sasl deadlock
|
|
||||||
%% http://erlang.org/pipermail/erlang-questions/2014-May/079012.html
|
|
||||||
error_logger:delete_report_handler(cth_log_redirect),
|
|
||||||
_ = application:stop(App),
|
|
||||||
error_logger:add_report_handler(cth_log_redirect),
|
|
||||||
ok;
|
|
||||||
application_stop(App) ->
|
|
||||||
application:stop(App).
|
|
||||||
|
|
||||||
init_per_testcase(TC, C) when
|
init_per_testcase(TC, C) when
|
||||||
TC =:= try_bad_handler_spec_test ;
|
TC =:= try_bad_handler_spec_test ;
|
||||||
@ -387,46 +369,14 @@ init_per_testcase(_, C) ->
|
|||||||
{ok, _} = start_woody_server(woody_ct, Sup, ['Weapons', 'Powerups']),
|
{ok, _} = start_woody_server(woody_ct, Sup, ['Weapons', 'Powerups']),
|
||||||
[{sup, Sup} | C].
|
[{sup, Sup} | C].
|
||||||
|
|
||||||
init_per_group(legacy_client_auto_server, Config) ->
|
|
||||||
config_headers_mode(legacy, auto, Config);
|
|
||||||
init_per_group(auto_client_legacy_server, Config) ->
|
|
||||||
config_headers_mode(auto, legacy, Config);
|
|
||||||
init_per_group(auto_both, Config) ->
|
|
||||||
config_headers_mode(auto, auto, Config);
|
|
||||||
init_per_group(normal_both, Config) ->
|
|
||||||
config_headers_mode(normal, normal, Config);
|
|
||||||
init_per_group(legacy_both, Config) ->
|
|
||||||
config_headers_mode(legacy, legacy, Config);
|
|
||||||
init_per_group(woody_resolver, Config) ->
|
init_per_group(woody_resolver, Config) ->
|
||||||
Config0 = config_headers_mode(normal, normal, Config),
|
[{env_inet6, inet_db:res_option(inet6)} | Config];
|
||||||
[{env_inet6, inet_db:res_option(inet6)} | Config0];
|
|
||||||
init_per_group(_Name, Config) ->
|
init_per_group(_Name, Config) ->
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_group(Name, _Config) when
|
|
||||||
Name =:= legacy_client_auto_server orelse
|
|
||||||
Name =:= auto_client_legacy_server orelse
|
|
||||||
Name =:= auto_both orelse
|
|
||||||
Name =:= normal_both orelse
|
|
||||||
Name =:= legacy_both orelse
|
|
||||||
Name =:= woody_resolver
|
|
||||||
->
|
|
||||||
ok = application:set_env(woody, client_headers_mode, auto),
|
|
||||||
ok = application:set_env(woody, server_headers_mode, auto),
|
|
||||||
ok;
|
|
||||||
end_per_group(_Name, _Config) ->
|
end_per_group(_Name, _Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
config_headers_mode(Client, Server, Config) ->
|
|
||||||
ok = application:set_env(woody, client_headers_mode, Client),
|
|
||||||
ok = application:set_env(woody, server_headers_mode, Server),
|
|
||||||
[{server_headers_mode, not_auto(Server)}, {client_headers_mode, not_auto(Client)} | Config].
|
|
||||||
|
|
||||||
not_auto(auto) ->
|
|
||||||
normal;
|
|
||||||
not_auto(Mode) ->
|
|
||||||
Mode.
|
|
||||||
|
|
||||||
start_tc_sup() ->
|
start_tc_sup() ->
|
||||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
@ -883,16 +833,15 @@ call_deadline_timeout_test(_) ->
|
|||||||
woody_client:call(Request, Opts, Context)
|
woody_client:call(Request, Opts, Context)
|
||||||
).
|
).
|
||||||
|
|
||||||
server_http_req_validation_test(Config) ->
|
server_http_req_validation_test(_Config) ->
|
||||||
HeadersMode = proplists:get_value(client_headers_mode, Config),
|
|
||||||
Id = <<"server_http_req_validation">>,
|
Id = <<"server_http_req_validation">>,
|
||||||
{Url, _Service} = get_service_endpoint('Weapons'),
|
{Url, _Service} = get_service_endpoint('Weapons'),
|
||||||
Headers = [
|
Headers = [
|
||||||
{?HEADER_RPC_ROOT_ID(HeadersMode) , genlib:to_binary(Id)},
|
{?HEADER_RPC_ROOT_ID , genlib:to_binary(Id)},
|
||||||
{?HEADER_RPC_ID(HeadersMode) , genlib:to_binary(Id)},
|
{?HEADER_RPC_ID , genlib:to_binary(Id)},
|
||||||
{?HEADER_RPC_PARENT_ID(HeadersMode) , genlib:to_binary(?ROOT_REQ_PARENT_ID)},
|
{?HEADER_RPC_PARENT_ID , genlib:to_binary(?ROOT_REQ_PARENT_ID)},
|
||||||
{<<"content-type">> , ?CONTENT_TYPE_THRIFT},
|
{<<"content-type">> , ?CONTENT_TYPE_THRIFT},
|
||||||
{<<"accept">> , ?CONTENT_TYPE_THRIFT}
|
{<<"accept">> , ?CONTENT_TYPE_THRIFT}
|
||||||
],
|
],
|
||||||
|
|
||||||
{ok, _Ref} = timer:kill_after(5000),
|
{ok, _Ref} = timer:kill_after(5000),
|
||||||
|
Loading…
Reference in New Issue
Block a user