defmodule ExCurl.Response do
@moduledoc """
A valid response returned by ExCurl.
## Metrics
When the `metrics_returned` field is set to `true`, the following metrics will be included:
* `total_time` - corresponds to the [CURLINFO_TOTAL_TIME_T option](https://curl.se/libcurl/c/CURLINFO_TOTAL_TIME_T.html).
* `namelookup_time` - corresponds to the [CURLINFO_NAMELOOKUP_TIME_T option](https://curl.se/libcurl/c/CURLINFO_NAMELOOKUP_TIME_T.html).
* `connect_time` - corresponds to the [CURLINFO_CONNECT_TIME_T option](https://curl.se/libcurl/c/CURLINFO_CONNECT_TIME_T.html).
* `appconnect_time` - corresponds to the [CURLINFO_APPCONNECT_TIME_T option](https://curl.se/libcurl/c/CURLINFO_APPCONNECT_TIME_T.html).
* `pretransfer_time` - corresponds to the [CURLINFO_PRETRANSFER_TIME_T option](https://curl.se/libcurl/c/CURLINFO_PRETRANSFER_TIME_T.html).
* `starttransfer_time` - corresponds to the [CURLINFO_STARTTRANSFER_TIME_T option](https://curl.se/libcurl/c/CURLINFO_STARTTRANSFER_TIME_T.html).
"""
defstruct body: "",
headers: %{},
status_code: 200,
total_time: 0,
namelookup_time: 0,
connect_time: 0,
appconnect_time: 0,
pretransfer_time: 0,
starttransfer_time: 0,
metrics_returned: false
@type t :: %__MODULE__{
body: nil | String.t(),
headers: map(),
status_code: integer(),
total_time: float(),
namelookup_time: float(),
connect_time: float(),
appconnect_time: float(),
pretransfer_time: float(),
starttransfer_time: float(),
metrics_returned: bool()
}
@doc false
def from_keyword_list_response(list) do
response = struct(__MODULE__, list)
%__MODULE__{
response
| headers: header_string_to_map(response.headers)
}
end
defp header_string_to_map(headers) do
headers
|> String.split("\r\n")
|> Stream.filter(&String.contains?(&1, ":"))
|> Stream.map(&String.split(&1, ": "))
|> Stream.map(fn [head | rest] -> [head, Enum.join(rest, ": ")] end)
|> Stream.map(fn [key, value] -> {key, value} end)
|> Enum.into(%{})
end
end