From e6964e661af83363ac5e0e7b98e49e5036b460ca Mon Sep 17 00:00:00 2001 From: Cory O'Daniel Date: Wed, 3 Jul 2019 10:48:49 -0700 Subject: [PATCH] added method as arg to HTTPProvider.headers/2 --- CHANGELOG.md | 1 + lib/k8s/client/behaviour.ex | 2 +- lib/k8s/client/dynamic_http_provider.ex | 2 +- lib/k8s/client/http_provider.ex | 38 ++++++++++++++---------- lib/k8s/client/runner/base.ex | 2 +- lib/k8s/cluster/discovery/http_driver.ex | 2 +- test/k8s/client/http_provider_test.exs | 4 +++ test/k8s/client_test.exs | 2 -- 8 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 test/k8s/client/http_provider_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a9c084c..c6355652 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refactored tests on DynamicHTTPProvider - Refactored discovery to use `K8s.Cluster.Discovery` +- Set correct content-type for patch operations (https://github.com/coryodaniel/k8s/issues/32) ## [0.2.13] - 2019-06-27 diff --git a/lib/k8s/client/behaviour.ex b/lib/k8s/client/behaviour.ex index 3f77a999..e773727e 100644 --- a/lib/k8s/client/behaviour.ex +++ b/lib/k8s/client/behaviour.ex @@ -2,7 +2,7 @@ defmodule K8s.Client.Behaviour do @moduledoc "HTTP Request / Response provider behaviour" @doc "Generate headers for HTTP Requests" - @callback headers(K8s.Conf.RequestOptions.t()) :: list({binary, binary}) + @callback headers(atom(), K8s.Conf.RequestOptions.t()) :: list({binary, binary}) @doc "Perform HTTP Requests" @callback request(atom, binary, binary, keyword, keyword) :: diff --git a/lib/k8s/client/dynamic_http_provider.ex b/lib/k8s/client/dynamic_http_provider.ex index 5f113450..d2b23b9d 100644 --- a/lib/k8s/client/dynamic_http_provider.ex +++ b/lib/k8s/client/dynamic_http_provider.ex @@ -8,7 +8,7 @@ defmodule K8s.Client.DynamicHTTPProvider do @behaviour K8s.Client.Behaviour @impl true - defdelegate headers(request_options), to: K8s.Client.HTTPProvider + defdelegate headers(method, request_options), to: K8s.Client.HTTPProvider @impl true defdelegate handle_response(resp), to: K8s.Client.HTTPProvider diff --git a/lib/k8s/client/http_provider.ex b/lib/k8s/client/http_provider.ex index da355fe3..dafb58b5 100644 --- a/lib/k8s/client/http_provider.ex +++ b/lib/k8s/client/http_provider.ex @@ -7,8 +7,6 @@ defmodule K8s.Client.HTTPProvider do @impl true def request(method, url, body, headers, opts) do - content_type = content_type_header(method) - headers = [content_type | headers] {duration, response} = :timer.tc(HTTPoison, :request, [method, url, body, headers, opts]) measurements = %{duration: duration} metadata = %{method: method} @@ -24,15 +22,6 @@ defmodule K8s.Client.HTTPProvider do end end - @spec content_type_header(atom()) :: {binary(), binary()} - defp content_type_header(:patch) do - {"Content-Type", "application/merge-patch+json"} - end - - defp content_type_header(_http_method) do - {"Content-Type", "application/json"} - end - @doc """ Handle HTTPoison responses and errors @@ -90,15 +79,34 @@ defmodule K8s.Client.HTTPProvider do @doc """ Generates HTTP headers from `K8s.Conf.RequestOptions` + + * Adds `{"Accept", "application/json"}` to all requests. + * Adds `Content-Type` base on HTTP method. + ## Example + Sets `Content-Type` to `application/merge-patch+json` for PATCH operations + iex> opts = %K8s.Conf.RequestOptions{headers: [{"Authorization", "Basic AF"}]} + ...> K8s.Client.HTTPProvider.headers(:patch, opts) + [{"Accept", "application/json"}, {"Content-Type", "application/merge-patch+json"}, {"Authorization", "Basic AF"}] + Sets `Content-Type` to `application/json` for all other operations iex> opts = %K8s.Conf.RequestOptions{headers: [{"Authorization", "Basic AF"}]} - ...> K8s.Client.HTTPProvider.headers(opts) - [{"Accept", "application/json"}, {"Authorization", "Basic AF"}] + ...> K8s.Client.HTTPProvider.headers(:get, opts) + [{"Accept", "application/json"}, {"Content-Type", "application/json"}, {"Authorization", "Basic AF"}] """ @impl true - def headers(%RequestOptions{} = opts) do - [{"Accept", "application/json"} | opts.headers] + def headers(method, %RequestOptions{} = opts) do + defaults = [{"Accept", "application/json"}, content_type_header(method)] + defaults ++ opts.headers + end + + @spec content_type_header(atom()) :: {binary(), binary()} + defp content_type_header(:patch) do + {"Content-Type", "application/merge-patch+json"} + end + + defp content_type_header(_http_method) do + {"Content-Type", "application/json"} end @spec decode(binary()) :: list | map | nil diff --git a/lib/k8s/client/runner/base.ex b/lib/k8s/client/runner/base.ex index ccefa467..600773f3 100644 --- a/lib/k8s/client/runner/base.ex +++ b/lib/k8s/client/runner/base.ex @@ -90,7 +90,7 @@ defmodule K8s.Client.Runner.Base do {:ok, conf} <- Cluster.conf(cluster_name), {:ok, request_options} <- RequestOptions.generate(conf), {:ok, http_body} <- encode(body, operation.method) do - http_headers = K8s.http_provider().headers(request_options) + http_headers = K8s.http_provider().headers(operation.method, request_options) http_opts = Keyword.merge([ssl: request_options.ssl_options], opts) K8s.http_provider().request( diff --git a/lib/k8s/cluster/discovery/http_driver.ex b/lib/k8s/cluster/discovery/http_driver.ex index 10ff917b..f18781ef 100644 --- a/lib/k8s/cluster/discovery/http_driver.ex +++ b/lib/k8s/cluster/discovery/http_driver.ex @@ -66,7 +66,7 @@ defmodule K8s.Cluster.Discovery.HTTPDriver do defp get(url, conf, opts) do case RequestOptions.generate(conf) do {:ok, request_options} -> - headers = K8s.http_provider().headers(request_options) + headers = K8s.http_provider().headers(:get, request_options) opts = Keyword.merge([ssl: request_options.ssl_options], opts) K8s.http_provider().request(:get, url, "", headers, opts) diff --git a/test/k8s/client/http_provider_test.exs b/test/k8s/client/http_provider_test.exs new file mode 100644 index 00000000..5b939afe --- /dev/null +++ b/test/k8s/client/http_provider_test.exs @@ -0,0 +1,4 @@ +defmodule K8s.Client.HTTPProviderTest do + use ExUnit.Case, async: true + doctest K8s.Client.HTTPProvider +end diff --git a/test/k8s/client_test.exs b/test/k8s/client_test.exs index 90293997..86a857f7 100644 --- a/test/k8s/client_test.exs +++ b/test/k8s/client_test.exs @@ -1,6 +1,4 @@ defmodule K8s.ClientTest do use ExUnit.Case, async: true doctest K8s.Client - - doctest K8s.Client.HTTPProvider end