diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f30fb6..31981c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Switch some flag positions in the generated cURL command - Some bugfixes regarding the constructed Req.Request struct when multiple request steps have to be set - [BREAKING]: From cURL to Req the body gets encoded in the specified encoding and set in the correct Req option +- New `CurlReq.Request` module for an internal representation ## 0.99.0 diff --git a/lib/curl_req/curl.ex b/lib/curl_req/curl.ex index 065be7b..c1eb218 100644 --- a/lib/curl_req/curl.ex +++ b/lib/curl_req/curl.ex @@ -33,7 +33,8 @@ defmodule CurlReq.Curl do proxy: :string, proxy_user: :string, netrc: :boolean, - netrc_file: :string + netrc_file: :string, + insecure: :boolean ], aliases: [ H: :header, @@ -46,7 +47,8 @@ defmodule CurlReq.Curl do u: :user, x: :proxy, U: :proxy_user, - n: :netrc + n: :netrc, + k: :insecure ] ) @@ -85,6 +87,7 @@ defmodule CurlReq.Curl do |> add_auth(options) |> add_compression(options) |> add_proxy(options) + |> add_insecure(options) |> configure_redirects(options) end @@ -201,6 +204,10 @@ defmodule CurlReq.Curl do end end + defp add_insecure(request, options) do + CurlReq.Request.put_insecure(request, options[:insecure]) + end + defp configure_redirects(request, options) do CurlReq.Request.put_redirect(request, options[:location]) end @@ -310,11 +317,14 @@ defmodule CurlReq.Curl do _ -> [] end + insecure = if request.insecure, do: [insecure_flag(flag_style)], else: [] + url = [" ", to_string(request.url)] IO.iodata_to_binary([ "curl", compressed, + insecure, auth, headers, cookies, @@ -376,4 +386,7 @@ defmodule CurlReq.Curl do defp proxy_user_flag(:short, value), do: [" -U ", escape(value)] defp proxy_user_flag(:long, value), do: [" --proxy-user ", escape(value)] + + defp insecure_flag(:short), do: " -k" + defp insecure_flag(:long), do: " --insecure" end diff --git a/lib/curl_req/req.ex b/lib/curl_req/req.ex index 90c598c..415d1e0 100644 --- a/lib/curl_req/req.ex +++ b/lib/curl_req/req.ex @@ -37,6 +37,14 @@ defmodule CurlReq.Req do nil end + request = + with transport_opts <- Keyword.get(connect_options, :transport_opts, []), + :verify_none <- Keyword.get(transport_opts, :verify) do + CurlReq.Request.put_insecure(request, true) + else + _ -> request + end + case Keyword.get(connect_options, :proxy) do {scheme, host, port, _} -> CurlReq.Request.put_proxy(request, %URI{ @@ -146,31 +154,45 @@ defmodule CurlReq.Req do req end - req = + proxy = if request.proxy do %URI{scheme: scheme, host: host, port: port} = request.proxy_url - connect_options = + [ + proxy: {String.to_existing_atom(scheme), host, port, []} + ] + else + [] + end + + proxy_auth = + case request.proxy_auth do + {:basic, userinfo} -> [ - proxy: {String.to_existing_atom(scheme), host, port, []} + proxy_headers: [ + {"proxy-authorization", "Basic " <> Base.encode64(userinfo)} + ] ] - connect_options = - case request.proxy_auth do - :none -> - connect_options + _ -> + [] + end - {:basic, userinfo} -> - Keyword.merge(connect_options, - proxy_headers: [ - {"proxy-authorization", "Basic " <> Base.encode64(userinfo)} - ] - ) + transport_opts = + if request.insecure do + [transport_opts: [verify: :verify_none]] + else + [] + end - _ -> - connect_options - end + connect_options = + [] + |> Keyword.merge(proxy) + |> Keyword.merge(proxy_auth) + |> Keyword.merge(transport_opts) + req = + if connect_options != [] do req |> Req.Request.register_options([ :connect_options diff --git a/lib/curl_req/request.ex b/lib/curl_req/request.ex index 68b7e6b..57e3e96 100644 --- a/lib/curl_req/request.ex +++ b/lib/curl_req/request.ex @@ -23,7 +23,8 @@ defmodule CurlReq.Request do auth: auth(), encoding: encoding(), body: term(), - raw_body: term() + raw_body: term(), + insecure: boolean() } @type user_agent() :: :curl | :req | String.t() @@ -49,7 +50,8 @@ defmodule CurlReq.Request do auth: :none, encoding: :raw, body: nil, - raw_body: nil + raw_body: nil, + insecure: false @doc """ Puts the header into the CurlReq.Request struct. Special headers like encoding, authorization or user-agent are stored in their respective field in the #{__MODULE__} struct instead of a general header. @@ -369,6 +371,22 @@ defmodule CurlReq.Request do %{request | compression: type} end + @doc """ + Sets the insecure option in the Curl.Request struct + + ## Examples + + iex> request = %CurlReq.Request{} |> CurlReq.Request.put_insecure(true) + iex> request.insecure + true + """ + @spec put_insecure(__MODULE__.t(), boolean() | nil) :: __MODULE__.t() + def put_insecure(%__MODULE__{} = request, nil), do: request + + def put_insecure(%__MODULE__{} = request, insecure) when is_boolean(insecure) do + %{request | insecure: insecure} + end + @doc """ Sets the redirect option in the Curl.Request struct diff --git a/mix.exs b/mix.exs index a7db916..f00531e 100644 --- a/mix.exs +++ b/mix.exs @@ -11,7 +11,7 @@ defmodule CurlReq.MixProject do package: package(), source_url: "https://github.com/derekkraan/curl_req", start_permanent: Mix.env() == :prod, - version: "0.99.0" + version: "0.100.0" ] end diff --git a/test/curl_req_test.exs b/test/curl_req_test.exs index f2612f2..d281488 100644 --- a/test/curl_req_test.exs +++ b/test/curl_req_test.exs @@ -168,6 +168,35 @@ defmodule CurlReqTest do Req.new(url: "https://example.com", json: %{key: "val"}) |> CurlReq.to_curl(run_steps: [except: [:compressed, :encode_body]]) end + + test "insecure flag" do + assert ~s(curl -k -X GET http://example.com) == + %Req.Request{ + url: URI.parse("http://example.com"), + registered_options: MapSet.new([:connect_options]), + options: %{ + connect_options: [ + transport_opts: [verify: :verify_none] + ] + } + } + |> CurlReq.to_curl() + end + + test "insecure flag with proxy" do + assert ~s(curl -k -x "http://my.proxy.com:2233" -X GET http://example.com) == + %Req.Request{ + url: URI.parse("http://example.com"), + registered_options: MapSet.new([:connect_options]), + options: %{ + connect_options: [ + proxy: {:http, "my.proxy.com", 2233, []}, + transport_opts: [verify: :verify_none] + ] + } + } + |> CurlReq.to_curl() + end end describe "from_curl" do @@ -448,6 +477,44 @@ defmodule CurlReqTest do end ) end + + test "insecure flag" do + assert ~CURL(curl -k http://example.com) == + %Req.Request{ + url: URI.parse("http://example.com"), + registered_options: MapSet.new([:connect_options]), + options: %{ + connect_options: [ + transport_opts: [verify: :verify_none] + ] + } + } + + assert ~CURL(curl --insecure http://example.com) == + %Req.Request{ + url: URI.parse("http://example.com"), + registered_options: MapSet.new([:connect_options]), + options: %{ + connect_options: [ + transport_opts: [verify: :verify_none] + ] + } + } + end + + test "insecure flag with proxy" do + assert ~CURL(curl -k --proxy my.proxy.com:2233 http://example.com) == + %Req.Request{ + url: URI.parse("http://example.com"), + registered_options: MapSet.new([:connect_options]), + options: %{ + connect_options: [ + proxy: {:http, "my.proxy.com", 2233, []}, + transport_opts: [verify: :verify_none] + ] + } + } + end end describe "newlines" do