fix(webhook): only POST and PUT requests carry Content-Type header and using the original URL as host header

This commit is contained in:
zhouzb 2021-01-14 19:40:44 +08:00 committed by turtleDeng
parent 598207e308
commit 114bf8e048
2 changed files with 25 additions and 29 deletions

View File

@ -5,7 +5,7 @@
## Webhook URL ## Webhook URL
## ##
## Value: String ## Value: String
web.hook.url = http://127.0.0.1:8080 web.hook.url = http://127.0.0.1:80
## HTTP Headers ## HTTP Headers
## ##

View File

@ -295,9 +295,12 @@ create_req(_, Path, Headers, Body) ->
parse_action_params(Params = #{<<"url">> := URL}) -> parse_action_params(Params = #{<<"url">> := URL}) ->
try try
#{path := CommonPath} = uri_string:parse(URL), #{path := CommonPath} = uri_string:parse(URL),
#{method => method(maps:get(<<"method">>, Params, <<"POST">>)), Method = method(maps:get(<<"method">>, Params, <<"POST">>)),
Headers = headers(maps:get(<<"headers">>, Params, undefined)),
NHeaders = ensure_content_type_header(Headers, Method),
#{method => Method,
path => path(filename:join(CommonPath, maps:get(<<"path">>, Params, <<>>))), path => path(filename:join(CommonPath, maps:get(<<"path">>, Params, <<>>))),
headers => headers(maps:get(<<"headers">>, Params, undefined)), headers => NHeaders,
body => maps:get(<<"body">>, Params, <<>>), body => maps:get(<<"body">>, Params, <<>>),
request_timeout => timer:seconds(maps:get(<<"request_timeout">>, Params, 5)), request_timeout => timer:seconds(maps:get(<<"request_timeout">>, Params, 5)),
pool => maps:get(<<"pool">>, Params)} pool => maps:get(<<"pool">>, Params)}
@ -305,6 +308,11 @@ parse_action_params(Params = #{<<"url">> := URL}) ->
throw({invalid_params, Params}) throw({invalid_params, Params})
end. end.
ensure_content_type_header(Headers, Method) when Method =:= post orelse Method =:= put ->
Headers;
ensure_content_type_header(Headers, _Method) ->
lists:keydelete("content-type", 1, Headers).
path(<<>>) -> <<"/">>; path(<<>>) -> <<"/">>;
path(Path) -> Path. path(Path) -> Path.
@ -314,30 +322,31 @@ method(PUT) when PUT == <<"PUT">>; PUT == <<"put">> -> put;
method(DEL) when DEL == <<"DELETE">>; DEL == <<"delete">> -> delete. method(DEL) when DEL == <<"DELETE">>; DEL == <<"delete">> -> delete.
headers(undefined) -> []; headers(undefined) -> [];
headers(Headers) when is_list(Headers) -> Headers;
headers(Headers) when is_map(Headers) -> headers(Headers) when is_map(Headers) ->
maps:fold(fun(K, V, Acc) -> headers(maps:to_list(Headers));
[{str(K), str(V)} | Acc] headers(Headers) when is_list(Headers) ->
end, [], Headers). [{string:to_lower(str(K)), str(V)} || {K, V} <- Headers].
str(Str) when is_list(Str) -> Str; str(Str) when is_list(Str) -> Str;
str(Atom) when is_atom(Atom) -> atom_to_list(Atom); str(Atom) when is_atom(Atom) -> atom_to_list(Atom);
str(Bin) when is_binary(Bin) -> binary_to_list(Bin). str(Bin) when is_binary(Bin) -> binary_to_list(Bin).
pool_opts(Params = #{<<"url">> := URL}) -> pool_opts(Params = #{<<"url">> := URL}) ->
#{host := Host0, #{host := Host,
port := Port, scheme := Scheme} = URIMap = uri_string:parse(URL),
scheme := Scheme} = uri_string:parse(URL), Port = maps:get(port, URIMap, case Scheme of
Host = get_addr(binary_to_list(Host0)), <<"https">> -> 443;
_ -> 80
end),
PoolSize = maps:get(<<"pool_size">>, Params, 32), PoolSize = maps:get(<<"pool_size">>, Params, 32),
ConnectTimeout = timer:seconds(maps:get(<<"connect_timeout">>, Params, 5)), ConnectTimeout = timer:seconds(maps:get(<<"connect_timeout">>, Params, 5)),
IPv6 = case tuple_size(Host) =:= 8 of IPv6 = case inet:getaddr(binary_to_list(Host), inet6) of
true -> [inet6]; {error, _} -> inet;
false -> [] {ok, _} -> inet6
end, end,
MoreOpts = case Scheme of MoreOpts = case Scheme of
<<"http">> -> <<"http">> ->
[{transport_opts, IPv6}]; [{transport_opts, [IPv6]}];
<<"https">> -> <<"https">> ->
KeyFile = maps:get(<<"keyfile">>, Params), KeyFile = maps:get(<<"keyfile">>, Params),
CertFile = maps:get(<<"certfile">>, Params), CertFile = maps:get(<<"certfile">>, Params),
@ -357,7 +366,7 @@ pool_opts(Params = #{<<"url">> := URL}) ->
{ciphers, lists:foldl(fun(TlsVer, Ciphers) -> {ciphers, lists:foldl(fun(TlsVer, Ciphers) ->
Ciphers ++ ssl:cipher_suites(all, TlsVer) Ciphers ++ ssl:cipher_suites(all, TlsVer)
end, [], TlsVers)} | TLSOpts], end, [], TlsVers)} | TLSOpts],
[{transport, ssl}, {transport_opts, NTLSOpts ++ IPv6}] [{transport, ssl}, {transport_opts, [IPv6 | NTLSOpts]}]
end, end,
[{host, Host}, [{host, Host},
{port, Port}, {port, Port},
@ -367,18 +376,5 @@ pool_opts(Params = #{<<"url">> := URL}) ->
{retry, 5}, {retry, 5},
{retry_timeout, 1000}] ++ MoreOpts. {retry_timeout, 1000}] ++ MoreOpts.
get_addr(Hostname) ->
case inet:parse_address(Hostname) of
{ok, {_,_,_,_} = Addr} -> Addr;
{ok, {_,_,_,_,_,_,_,_} = Addr} -> Addr;
{error, einval} ->
case inet:getaddr(Hostname, inet) of
{error, _} ->
{ok, Addr} = inet:getaddr(Hostname, inet6),
Addr;
{ok, Addr} -> Addr
end
end.
pool_name(ResId) -> pool_name(ResId) ->
list_to_atom("webhook:" ++ str(ResId)). list_to_atom("webhook:" ++ str(ResId)).