Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F116098
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/.travis.yml b/.travis.yml
index bd6e568..8901118 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,50 +1,52 @@
language: elixir
env:
- MIX_ENV=test
matrix:
include:
+ - elixir: 1.5.3
+ otp_release: 18.3
- elixir: 1.5.3
otp_release: 19.3
- elixir: 1.5.3
otp_release: 20.3
- elixir: 1.6.6
otp_release: 19.3
- elixir: 1.6.6
otp_release: 20.3
- elixir: 1.6.6
otp_release: 19.3
- elixir: 1.6.6
otp_release: 20.3
- elixir: 1.6.6
otp_release: 21.3
- elixir: 1.7.4
otp_release: 19.3
- elixir: 1.7.4
otp_release: 20.3
- elixir: 1.7.4
otp_release: 21.3
- elixir: 1.7.4
otp_release: 22.0
- elixir: 1.8.2
otp_release: 20.3
- elixir: 1.8.2
otp_release: 21.3
- elixir: 1.8.2
otp_release: 22.0
- elixir: 1.8.2
otp_release: 22.0
env: MIX_ENV=test LOCKFILE=poison3
- elixir: 1.8.2
otp_release: 22.0
install: skip
script: mix format --check-formatted --dry-run
after_script: skip
- elixir: 1.6.6
otp_release: 21.0
before_script: git remote set-branches origin '*' && git fetch origin v1.0.0-compat && git checkout origin/v1.0.0-compat -- test
env: MIX_ENV=test LABEL=v1.0.0-compat
script: mix coveralls.json
after_script:
- bash <(curl -s https://codecov.io/bash)
- MIX_ENV=docs mix deps.get
- MIX_ENV=docs mix inch.report
diff --git a/lib/tesla/adapter/mint.ex b/lib/tesla/adapter/mint.ex
index 962ae50..c9d599c 100644
--- a/lib/tesla/adapter/mint.ex
+++ b/lib/tesla/adapter/mint.ex
@@ -1,184 +1,182 @@
-if Version.compare(System.version(), "1.5.0") != :lt do
- defmodule Tesla.Adapter.Mint do
- @moduledoc """
- Adapter for [mint](https://github.com/ericmj/mint)
+defmodule Tesla.Adapter.Mint do
+ @moduledoc """
+ Adapter for [mint](https://github.com/ericmj/mint)
- Caution: The minimum supported Elixir version for mint is 1.5.0
+ Caution: The minimum supported Elixir version for mint is 1.5.0
- Remember to add `{:mint, "~> 0.2.0"}` and `{:castore, "~> 0.1.0"}` to dependencies
- Also, you need to recompile tesla after adding `:mint` dependency:
+ Remember to add `{:mint, "~> 0.2.0"}` and `{:castore, "~> 0.1.0"}` to dependencies
+ Also, you need to recompile tesla after adding `:mint` dependency:
- ```
- mix deps.clean tesla
- mix deps.compile tesla
- ```
+ ```
+ mix deps.clean tesla
+ mix deps.compile tesla
+ ```
- ### Example usage
- ```
- # set globally in config/config.exs
- config :tesla, :adapter, Tesla.Adapter.Mint
+ ### Example usage
+ ```
+ # set globally in config/config.exs
+ config :tesla, :adapter, Tesla.Adapter.Mint
- # set per module
- defmodule MyClient do
- use Tesla
+ # set per module
+ defmodule MyClient do
+ use Tesla
- adapter Tesla.Adapter.Mint
- end
+ adapter Tesla.Adapter.Mint
+ end
- # set custom cacert
- config :tesla, :cacert, ["path_to_cacert"]
- """
- @behaviour Tesla.Adapter
- import Tesla.Adapter.Shared, only: [stream_to_fun: 1, next_chunk: 1]
- alias Tesla.Multipart
- alias Mint.HTTP
-
- @doc false
- def call(env, opts) do
- with {:ok, status, headers, body} <- request(env, opts) do
- {:ok, %{env | status: status, headers: format_headers(headers), body: body}}
- end
+ # set custom cacert
+ config :tesla, :cacert, ["path_to_cacert"]
+ """
+ @behaviour Tesla.Adapter
+ import Tesla.Adapter.Shared, only: [stream_to_fun: 1, next_chunk: 1]
+ alias Tesla.Multipart
+ alias Mint.HTTP
+
+ @doc false
+ def call(env, opts) do
+ with {:ok, status, headers, body} <- request(env, opts) do
+ {:ok, %{env | status: status, headers: format_headers(headers), body: body}}
end
+ end
- defp format_headers(headers) do
- for {key, value} <- headers do
- {String.downcase(to_string(key)), to_string(value)}
- end
+ defp format_headers(headers) do
+ for {key, value} <- headers do
+ {String.downcase(to_string(key)), to_string(value)}
end
+ end
- defp request(env, opts) do
- # Break the URI
- %URI{host: host, scheme: scheme, port: port, path: path, query: query} = URI.parse(env.url)
- query = (query || "") |> URI.decode_query() |> Map.to_list()
- path = Tesla.build_url(path, env.query ++ query)
+ defp request(env, opts) do
+ # Break the URI
+ %URI{host: host, scheme: scheme, port: port, path: path, query: query} = URI.parse(env.url)
+ query = (query || "") |> URI.decode_query() |> Map.to_list()
+ path = Tesla.build_url(path, env.query ++ query)
- method =
- case env.method do
- :head -> "GET"
- m -> m |> Atom.to_string() |> String.upcase()
- end
+ method =
+ case env.method do
+ :head -> "GET"
+ m -> m |> Atom.to_string() |> String.upcase()
+ end
- opts =
- if opts |> get_in([:transport_opts, :cacertfile]) |> is_nil() && scheme == "https" &&
- !is_nil(get_default_ca()) do
- transport =
- opts
- |> Access.get(:transport_opts, [])
- |> update_in([:cacertfile], fn _ ->
- get_default_ca()
- end)
-
- update_in(opts, [:transport_opts], fn _ ->
- transport
- end)
- else
+ opts =
+ if opts |> get_in([:transport_opts, :cacertfile]) |> is_nil() && scheme == "https" &&
+ !is_nil(get_default_ca()) do
+ transport =
opts
- end
+ |> Access.get(:transport_opts, [])
+ |> update_in([:cacertfile], fn _ ->
+ get_default_ca()
+ end)
- request(
- method,
- scheme,
- host,
- port,
- path,
- env.headers,
- env.body,
+ update_in(opts, [:transport_opts], fn _ ->
+ transport
+ end)
+ else
opts
- )
- end
+ end
- defp request(method, scheme, host, port, path, headers, %Stream{} = body, opts) do
- fun = stream_to_fun(body)
- request(method, scheme, host, port, path, headers, fun, opts)
- end
+ request(
+ method,
+ scheme,
+ host,
+ port,
+ path,
+ env.headers,
+ env.body,
+ opts
+ )
+ end
- defp request(method, scheme, host, port, path, headers, %Multipart{} = body, opts) do
- headers = headers ++ Multipart.headers(body)
- fun = stream_to_fun(Multipart.body(body))
- request(method, scheme, host, port, path, headers, fun, opts)
- end
+ defp request(method, scheme, host, port, path, headers, %Stream{} = body, opts) do
+ fun = stream_to_fun(body)
+ request(method, scheme, host, port, path, headers, fun, opts)
+ end
- defp request(method, scheme, host, port, path, headers, body, opts) when is_function(body) do
- with {:ok, conn} <- HTTP.connect(String.to_atom(scheme), host, port, opts),
- # FIXME Stream function in Mint will not append the content length after eof
- # This will trigger the failure in unit test
- {:ok, body, length} <- stream_request(body),
- {:ok, conn, _req_ref} <-
- HTTP.request(
- conn,
- method,
- path || "/",
- headers ++ [{"content-length", "#{length}"}],
- body
- ),
- {:ok, _conn, res = %{status: status, headers: headers}} <- stream_response(conn) do
- {:ok, status, headers, Map.get(res, :data)}
- end
- end
+ defp request(method, scheme, host, port, path, headers, %Multipart{} = body, opts) do
+ headers = headers ++ Multipart.headers(body)
+ fun = stream_to_fun(Multipart.body(body))
+ request(method, scheme, host, port, path, headers, fun, opts)
+ end
- defp request(method, scheme, host, port, path, headers, body, opts) do
- with {:ok, conn} <- HTTP.connect(String.to_atom(scheme), host, port, opts),
- {:ok, conn, _req_ref} <- HTTP.request(conn, method, path || "/", headers, body || ""),
- {:ok, _conn, res = %{status: status, headers: headers}} <- stream_response(conn) do
- {:ok, status, headers, Map.get(res, :data)}
- end
+ defp request(method, scheme, host, port, path, headers, body, opts) when is_function(body) do
+ with {:ok, conn} <- HTTP.connect(String.to_atom(scheme), host, port, opts),
+ # FIXME Stream function in Mint will not append the content length after eof
+ # This will trigger the failure in unit test
+ {:ok, body, length} <- stream_request(body),
+ {:ok, conn, _req_ref} <-
+ HTTP.request(
+ conn,
+ method,
+ path || "/",
+ headers ++ [{"content-length", "#{length}"}],
+ body
+ ),
+ {:ok, _conn, res = %{status: status, headers: headers}} <- stream_response(conn) do
+ {:ok, status, headers, Map.get(res, :data)}
end
+ end
- defp get_default_ca() do
- Application.get_env(:tesla, :cacert)
+ defp request(method, scheme, host, port, path, headers, body, opts) do
+ with {:ok, conn} <- HTTP.connect(String.to_atom(scheme), host, port, opts),
+ {:ok, conn, _req_ref} <- HTTP.request(conn, method, path || "/", headers, body || ""),
+ {:ok, _conn, res = %{status: status, headers: headers}} <- stream_response(conn) do
+ {:ok, status, headers, Map.get(res, :data)}
end
+ end
+
+ defp get_default_ca() do
+ Application.get_env(:tesla, :cacert)
+ end
- defp stream_request(fun, body \\ "") do
- case next_chunk(fun) do
- {:ok, item, fun} when is_list(item) ->
- stream_request(fun, body <> List.to_string(item))
+ defp stream_request(fun, body \\ "") do
+ case next_chunk(fun) do
+ {:ok, item, fun} when is_list(item) ->
+ stream_request(fun, body <> List.to_string(item))
- {:ok, item, fun} ->
- stream_request(fun, body <> item)
+ {:ok, item, fun} ->
+ stream_request(fun, body <> item)
- :eof ->
- {:ok, body, byte_size(body)}
- end
+ :eof ->
+ {:ok, body, byte_size(body)}
end
+ end
- defp stream_response(conn, response \\ %{}) do
- receive do
- msg ->
- case HTTP.stream(conn, msg) do
- {:ok, conn, stream} ->
- response =
- Enum.reduce(stream, response, fn x, acc ->
- case x do
- {:status, _req_ref, code} ->
- Map.put(acc, :status, code)
-
- {:headers, _req_ref, headers} ->
- Map.put(acc, :headers, headers)
-
- {:data, _req_ref, data} ->
- Map.put(acc, :data, Map.get(acc, :data, "") <> data)
-
- {:done, _req_ref} ->
- Map.put(acc, :done, true)
-
- _ ->
- acc
- end
- end)
-
- if Map.get(response, :done) do
- {:ok, conn, Map.drop(response, [:done])}
- else
- stream_response(conn, response)
- end
-
- {:error, _conn, error, _res} ->
- {:error, "Encounter Mint error #{inspect(error)}"}
-
- :unknown ->
- {:error, "Encounter unknown error"}
- end
- end
+ defp stream_response(conn, response \\ %{}) do
+ receive do
+ msg ->
+ case HTTP.stream(conn, msg) do
+ {:ok, conn, stream} ->
+ response =
+ Enum.reduce(stream, response, fn x, acc ->
+ case x do
+ {:status, _req_ref, code} ->
+ Map.put(acc, :status, code)
+
+ {:headers, _req_ref, headers} ->
+ Map.put(acc, :headers, headers)
+
+ {:data, _req_ref, data} ->
+ Map.put(acc, :data, Map.get(acc, :data, "") <> data)
+
+ {:done, _req_ref} ->
+ Map.put(acc, :done, true)
+
+ _ ->
+ acc
+ end
+ end)
+
+ if Map.get(response, :done) do
+ {:ok, conn, Map.drop(response, [:done])}
+ else
+ stream_response(conn, response)
+ end
+
+ {:error, _conn, error, _res} ->
+ {:error, "Encounter Mint error #{inspect(error)}"}
+
+ :unknown ->
+ {:error, "Encounter unknown error"}
+ end
end
end
end
diff --git a/mix.exs b/mix.exs
index ee44bf9..9203b6e 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,144 +1,133 @@
defmodule Tesla.Mixfile do
use Mix.Project
@version "1.2.1"
def project do
[
app: :tesla,
version: @version,
description: description(),
package: package(),
source_ref: "v#{@version}",
source_url: "https://github.com/teamon/tesla",
- elixir: "~> 1.4",
+ elixir: "~> 1.5",
elixirc_paths: elixirc_paths(Mix.env()),
deps: deps(),
lockfile: lockfile(System.get_env("LOCKFILE")),
test_coverage: [tool: ExCoveralls],
dialyzer: [
plt_add_apps: [:inets],
plt_add_deps: :project
],
docs: docs()
]
end
# Configuration for the OTP application
#
# Type `mix help compile.app` for more information
def application do
[applications: applications(Mix.env())]
end
def applications(:test), do: applications(:dev) ++ [:httparrot, :hackney, :ibrowse, :gun]
def applications(_), do: [:logger, :ssl, :inets]
defp description do
"HTTP client library, with support for middleware and multiple adapters."
end
defp package do
[
maintainers: ["Tymon Tobolski"],
licenses: ["MIT"],
links: %{"GitHub" => "https://github.com/teamon/tesla"}
]
end
# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
defp lockfile(nil), do: "mix.lock"
defp lockfile(lockfile), do: "test/lockfiles/#{lockfile}.lock"
defp deps do
[
{:mime, "~> 1.0"},
# http clients
{:ibrowse, "~> 4.4.0", optional: true},
{:hackney, "~> 1.6", optional: true},
{:gun, "~> 1.3", optional: true},
{:castore, "~> 0.1.0", optional: true},
{:mint, "~> 0.2.0", optional: true},
# json parsers
{:jason, ">= 1.0.0", optional: true},
{:poison, ">= 1.0.0", optional: true},
{:exjsx, ">= 3.0.0", optional: true},
# other
{:fuse, "~> 2.4", optional: true},
{:telemetry, "~> 0.3", optional: true},
# testing & docs
{:excoveralls, "~> 0.8", only: :test},
{:httparrot, "~> 1.2", only: :test},
{:ex_doc, github: "elixir-lang/ex_doc", only: :dev},
{:mix_test_watch, "~> 0.5", only: :dev},
{:dialyxir, "~> 1.0.0-rc.3", only: [:dev, :test]},
{:inch_ex, "~> 0.5.6", only: :docs}
- ] ++ mint_version_check()
- end
-
- defp mint_version_check() do
- if Version.compare(System.version(), "1.5.0") != :lt do
- [
- {:castore, "~> 0.1.0", optional: true},
- {:mint, "~> 0.2.0", optional: true}
- ]
- else
- []
- end
+ ]
end
defp docs do
[
main: "readme",
extras: ["README.md"],
groups_for_modules: [
Behaviours: [
Tesla.Adapter,
Tesla.Middleware
],
Adapters: [
Tesla.Adapter.Hackney,
Tesla.Adapter.Httpc,
Tesla.Adapter.Ibrowse,
Tesla.Adapter.Gun,
Tesla.Adapter.Mint
],
Middlewares: [
Tesla.Middleware.BaseUrl,
Tesla.Middleware.BasicAuth,
Tesla.Middleware.CompressRequest,
Tesla.Middleware.Compression,
Tesla.Middleware.DecodeJson,
Tesla.Middleware.DecodeRels,
Tesla.Middleware.DecompressResponse,
Tesla.Middleware.DigestAuth,
Tesla.Middleware.EncodeJson,
Tesla.Middleware.FollowRedirects,
Tesla.Middleware.FormUrlencoded,
Tesla.Middleware.Fuse,
Tesla.Middleware.Headers,
Tesla.Middleware.JSON,
Tesla.Middleware.KeepRequest,
Tesla.Middleware.Logger,
Tesla.Middleware.MethodOverride,
Tesla.Middleware.Opts,
Tesla.Middleware.Query,
Tesla.Middleware.Retry,
Tesla.Middleware.Telemetry,
Tesla.Middleware.Timeout
]
],
nest_modules_by_prefix: [
Tesla.Adapter,
Tesla.Middleware
]
]
end
end
diff --git a/test/tesla/adapter/mint_test.exs b/test/tesla/adapter/mint_test.exs
index 3bb22f5..5b8f63b 100644
--- a/test/tesla/adapter/mint_test.exs
+++ b/test/tesla/adapter/mint_test.exs
@@ -1,11 +1,9 @@
-if Version.compare(System.version(), "1.5.0") != :lt do
- defmodule Tesla.Adapter.MintTest do
- use ExUnit.Case
+defmodule Tesla.Adapter.MintTest do
+ use ExUnit.Case
- use Tesla.AdapterCase, adapter: Tesla.Adapter.Mint
- use Tesla.AdapterCase.Basic
- use Tesla.AdapterCase.Multipart
- use Tesla.AdapterCase.StreamRequestBody
- use Tesla.AdapterCase.SSL
- end
+ use Tesla.AdapterCase, adapter: Tesla.Adapter.Mint
+ use Tesla.AdapterCase.Basic
+ use Tesla.AdapterCase.Multipart
+ use Tesla.AdapterCase.StreamRequestBody
+ use Tesla.AdapterCase.SSL
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 30, 8:31 AM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41405
Default Alt Text
(17 KB)
Attached To
Mode
R28 tesla
Attached
Detach File
Event Timeline
Log In to Comment