Skip to content

Commit

Permalink
feat: httpc_profile opt and have the client manage the HTTPC profile
Browse files Browse the repository at this point in the history
  • Loading branch information
paulswartz committed Jan 10, 2024
1 parent a23417d commit 462ce3b
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 47 deletions.
39 changes: 4 additions & 35 deletions src/oidcc_http_util.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@

-type request_opts() :: #{
timeout => timeout(),
ssl => [ssl:tls_option()]
ssl => [ssl:tls_option()],
httpc_profile => atom() | pid()
}.
%% See {@link httpc:request/5}
%%
Expand Down Expand Up @@ -85,11 +86,12 @@ when
Accumulator :: term()},
TelemetryOpts :: telemetry_opts(),
RequestOpts :: request_opts().
request(Method, Request0, TelemetryOpts, RequestOpts) ->
request(Method, Request, TelemetryOpts, RequestOpts) ->
TelemetryTopic = maps:get(topic, TelemetryOpts),
TelemetryExtraMeta = maps:get(extra_meta, TelemetryOpts, #{}),
Timeout = maps:get(timeout, RequestOpts, timer:minutes(1)),
SslOpts = maps:get(ssl, RequestOpts, undefined),
HttpProfile = maps:get(httpc_profile, RequestOpts, default),

HttpOpts0 = [{timeout, Timeout}],
HttpOpts =
Expand All @@ -98,21 +100,6 @@ request(Method, Request0, TelemetryOpts, RequestOpts) ->
_Opts -> [{ssl, SslOpts} | HttpOpts0]
end,

%% if we're using special SSL opts, always close the connection after we're
%% done. we do this to work around an issue with httpc where it doesn't take
%% the client certificates into account when pipelining, so if the HTTP
%% implementation changes we should think about undoing this.
{Request, HttpProfile} =
case using_client_certificate(SslOpts) of
false ->
{Request0, default};
true ->
ReqHeaders0 = element(2, Request0),
ReqHeaders1 = [{"connection", "close"} | ReqHeaders0],
ReqHeaders = lists:ukeysort(1, ReqHeaders1),
{setelement(2, Request0, ReqHeaders), oidcc_app:httpc_profile()}
end,

telemetry:span(
TelemetryTopic,
TelemetryExtraMeta,
Expand Down Expand Up @@ -181,21 +168,3 @@ fetch_content_type(Headers) ->
_Other ->
unknown
end.

-spec using_client_certificate([ssl:tls_client_option()] | undefined) -> boolean().
using_client_certificate(undefined) ->
false;
using_client_certificate(SslOpts) ->
lists:foldl(
fun
(_, true) -> true;
({key, _}, _) -> true;
({keyfile, _}, _) -> true;
({cert, _}, _) -> true;
({certfile, _}, _) -> true;
({certs_keys, _}, _) -> true;
(_, Acc) -> Acc
end,
false,
SslOpts
).
15 changes: 3 additions & 12 deletions test/oidcc_http_util_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ client_cert(_Config) ->
)
),

inets:start(httpc, [{profile, idrix_fr}]),

?assertMatch(
{ok, {
{json, #{
Expand All @@ -95,6 +97,7 @@ client_cert(_Config) ->
}},
oidcc_http_util:request(
get, {"https://certauth.idrix.fr/json/", []}, telemetry_opts(), #{
httpc_profile => idrix_fr,
ssl => [
{verify, verify_peer},
{cacerts, public_key:cacerts_get()},
Expand All @@ -104,16 +107,4 @@ client_cert(_Config) ->
)
),

?assertMatch(
{error, {http_error, 403, <<"">>}},
oidcc_http_util:request(
get, {"https://certauth.idrix.fr/json/", []}, telemetry_opts(), #{
ssl => [
{verify, verify_peer},
{cacerts, public_key:cacerts_get()}
]
}
)
),

ok.

0 comments on commit 462ce3b

Please sign in to comment.