Current section
Files
Jump to
Current section
Files
lib/elasticsearch/api/http.ex
defmodule Elasticsearch.API.HTTP do
@moduledoc """
A "real" HTTP implementation of `Elasticsearch.API`.
"""
@behaviour Elasticsearch.API
@impl true
def request(config, method, url, data, opts) do
method
|> HTTPoison.request(
process_url(url, config),
process_request_body(data, config),
headers(config),
opts ++ Map.get(config, :default_options, [])
)
|> process_response(config)
end
# Respect absolute URLs if passed
defp process_url("http" <> _rest = url, _config) do
url
end
# On relative urls, prepend the configured base URL
defp process_url(url, config) do
Path.join(config.url, url)
end
# Converts the request body into JSON, unless it has already
# been converted. If the data is empty, sends ""
defp process_request_body(data, _config) when is_binary(data) do
data
end
defp process_request_body(data, config) when is_map(data) and data != %{} do
json_library(config).encode!(data)
end
defp process_request_body(_data, _config) do
""
end
# Converts the response body string from JSON into a map, if it looks like it
# is actually JSON
defp process_response({:ok, %{body: body} = response}, config) do
body =
cond do
json?(body) -> json_library(config).decode!(body)
true -> body
end
{:ok, %{response | body: body}}
end
defp process_response(response, _config) do
response
end
defp json?(str) when is_binary(str) do
str =~ ~r/^\{/ || str =~ ~r/^\[/
end
# Produces request headers for the request, based on the configuration
defp headers(config) do
headers = [{"Content-Type", "application/json"}] ++ Map.get(config, :default_headers, [])
credentials = http_basic_credentials(config)
if credentials do
[{"Authorization", "Basic #{credentials}"} | headers]
else
headers
end
end
defp http_basic_credentials(%{username: username, password: password}) do
Base.encode64("#{username}:#{password}")
end
defp http_basic_credentials(_config) do
nil
end
defp json_library(%{json_library: json_library}) do
json_library
end
defp json_library(_config) do
Poison
end
end