Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support profile for httpc adapter #655

Merged
merged 2 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions lib/tesla/adapter/httpc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -55,33 +55,33 @@ defmodule Tesla.Adapter.Httpc do
Enum.map(env.headers, fn {k, v} -> {to_charlist(k), to_charlist(v)} end),
content_type,
env.body,
Keyword.split(opts, @http_opts)
opts
)
)
end

# fix for # see https://github.com/teamon/tesla/issues/147
defp request(:delete, url, headers, content_type, nil, {http_opts, opts}) do
request(:delete, url, headers, content_type, "", {http_opts, opts})
defp request(:delete, url, headers, content_type, nil, opts) do
request(:delete, url, headers, content_type, "", opts)
end

defp request(method, url, headers, _content_type, nil, {http_opts, opts}) do
:httpc.request(method, {url, headers}, http_opts, opts)
defp request(method, url, headers, _content_type, nil, opts) do
:httpc.request(method, {url, headers}, http_opts(opts), adapter_opts(opts), profile(opts))
end

# These methods aren't able to contain a content_type and body
defp request(method, url, headers, _content_type, _body, {http_opts, opts})
defp request(method, url, headers, _content_type, _body, opts)
when method in [:get, :options, :head, :trace] do
:httpc.request(method, {url, headers}, http_opts, opts)
:httpc.request(method, {url, headers}, http_opts(opts), adapter_opts(opts), profile(opts))
end

defp request(method, url, headers, _content_type, %Multipart{} = mp, opts) do
headers = headers ++ Multipart.headers(mp)
headers = for {key, value} <- headers, do: {to_charlist(key), to_charlist(value)}

{content_type, headers} =
case List.keytake(headers, 'content-type', 0) do
nil -> {'text/plain', headers}
case List.keytake(headers, ~c"content-type", 0) do
nil -> {~c"text/plain", headers}
{{_, ct}, headers} -> {ct, headers}
end

Expand All @@ -100,10 +100,22 @@ defmodule Tesla.Adapter.Httpc do
request(method, url, headers, content_type, body, opts)
end

defp request(method, url, headers, content_type, body, {http_opts, opts}) do
:httpc.request(method, {url, headers, content_type, body}, http_opts, opts)
defp request(method, url, headers, content_type, body, opts) do
:httpc.request(
method,
{url, headers, content_type, body},
http_opts(opts),
adapter_opts(opts),
profile(opts)
)
end

defp handle({:error, {:failed_connect, _}}), do: {:error, :econnrefused}
defp handle(response), do: response

defp http_opts(opts), do: opts |> Keyword.take(@http_opts) |> Keyword.delete(:profile)

defp adapter_opts(opts), do: opts |> Keyword.drop(@http_opts) |> Keyword.delete(:profile)

defp profile(opts), do: opts[:profile] || :default
end
24 changes: 24 additions & 0 deletions test/tesla/adapter/httpc_test/profile.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule Tesla.Adapter.HttpcTest.Profile do
@profile :test_profile

use ExUnit.Case
use Tesla.AdapterCase, adapter: {Tesla.Adapter.Httpc, profile: @profile}

alias Tesla.Env

setup do
{:ok, _pid} = :inets.start(:httpc, profile: @profile)

on_exit(fn -> :inets.stop(:httpc, @profile) end)
end

test "a non-default profile is used" do
request = %Env{
method: :get,
url: "#{@http}/ip"
}

assert {:ok, %Env{} = response} = call(request)
assert response.status == 200
end
end
Loading