Skip to content

Commit

Permalink
A collection of general API improvements
Browse files Browse the repository at this point in the history
- Working with Conn APIs requires calling new/0 or new/1 first
  old APIs are deprecated
- new/1 parses the provided string with URI.parse/1 and sets the Conn
  struct fields accordingly (so you can pass full or partial url
  fragments and get what you would expect, including those containing
  query strings)
- All headers are normalized to lower-case on put/get, and internally
  headers are a simple key/value map instead of the previous key =>
  key/value map, which was unnecessary.
- Implemented get_req_headers/1, deprecated get_req_header/1
- Implemented put_req_headers/2, deprecated put_req_header/2
- get_req_header/2 returns String.t instead of {String.t, String.t}
- get_req_headers/1 returns %{String.t => String.t} instead of
  %{String.t => %{String.t => String.t}}
- Added a number of typespecs, and fixed invalid ones
- Some small style fixes, documentation updates
- Fixed a bug with the Header middleware which was not overriding
  headers in the connection if already set. This one may be up for
  discussion if what's really desired.
- Added HeaderCase middleware for enforcing header casing
  • Loading branch information
bitwalker committed Jan 16, 2017
1 parent d6a3be5 commit 1924595
Show file tree
Hide file tree
Showing 21 changed files with 561 additions and 420 deletions.
9 changes: 3 additions & 6 deletions lib/maxwell/adapter/hackney.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ if Code.ensure_loaded?(:hackney) do
end

defp format_response({:ok, status, headers, body}, conn) when is_binary(body) do
headers = for {key, value} <- headers, into: %{} do
down_key = key |> to_string |> String.downcase
{down_key, {key, to_string(value)}}
end
headers = Enum.reduce(headers, %{}, fn {k, v}, acc ->
Map.put(acc, String.downcase(to_string(k)), to_string(v))
end)
%{conn | status: status,
resp_headers: headers,
req_body: nil,
Expand All @@ -57,8 +56,6 @@ if Code.ensure_loaded?(:hackney) do
defp format_response({:error, reason}, conn) do
{:error, reason, %{conn | state: :error}}
end

end

end

11 changes: 4 additions & 7 deletions lib/maxwell/adapter/httpc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ defmodule Maxwell.Adapter.Httpc do

defp header_serialize(headers) do
{content_type, headers} = Map.pop(headers, "content-type")
headers = Enum.map(headers, fn({_, {key, value}}) -> {to_char_list(key), to_char_list(value)} end)
headers = Enum.map(headers, fn {key, value} -> {to_char_list(key), to_char_list(value)} end)
case content_type do
nil -> {nil, headers}
{_, type} -> {to_char_list(type), headers}
nil -> {nil, headers}
type -> {to_char_list(type), headers}
end
end

Expand All @@ -80,9 +80,7 @@ defmodule Maxwell.Adapter.Httpc do
defp format_response({:ok, {status_line, headers, body}}, conn) do
{_http_version, status, _reason_phrase} = status_line
headers = for {key, value} <- headers, into: %{} do
key = key |> to_string
down_key = key |> String.downcase
{down_key, {key, to_string(value)}}
{String.downcase(to_string(key)), to_string(value)}
end
%{conn | status: status,
resp_headers: headers,
Expand All @@ -107,6 +105,5 @@ defmodule Maxwell.Adapter.Httpc do
defp format_response({:error, reason}, conn) do
{:error, reason, %{conn | state: :error}}
end

end

9 changes: 3 additions & 6 deletions lib/maxwell/adapter/ibrowse.ex
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ if Code.ensure_loaded?(:ibrowse) do

defp format_response({:ok, status, headers, body}, conn) do
{status, _} = status |> to_string |> Integer.parse
headers = for {key, value} <- headers, into: %{} do
down_key = key |> to_string |> String.downcase
{down_key, {key, to_string(value)}}
end
headers = Enum.reduce(headers, %{}, fn {k, v}, acc ->
Map.put(acc, String.downcase(to_string(k)), to_string(v))
end)
%{conn | status: status,
resp_headers: headers,
resp_body: body,
Expand All @@ -77,8 +76,6 @@ if Code.ensure_loaded?(:ibrowse) do
defp format_response({:error, reason}, conn) do
{:error, reason, %{conn | state: :error}}
end

end

end

25 changes: 11 additions & 14 deletions lib/maxwell/adapter/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,17 @@ defmodule Maxwell.Adapter.Util do
end

@doc """
Make headers to key word list.
Converts the headers map to a list of tuples.
* `headers` - `Map.t`, for example: `%{"content-type" => {"Content-Type", "application/json"}}`
* `headers` - `Map.t`, for example: `%{"content-type" => "application/json"}`
### Examples
#[{"Content-Type", "application/json"}]
iex> headers_serialize(%{"content-type" => {"Content-Type", "application/json"}})
iex> headers_serialize(%{"content-type" => "application/json"})
[{"content-type", "application/json"}]
"""

def header_serialize(headers) do
headers |> Map.values
Enum.into(headers, [])
end

@doc """
Expand Down Expand Up @@ -83,9 +81,8 @@ defmodule Maxwell.Adapter.Util do
"""
def chunked?(conn) do
case Conn.get_req_header(conn, "transfer-encoding") do
{_, "chunked"} -> true
{_, type} -> "chunked" == String.downcase(type)
nil -> false
nil -> false
type -> "chunked" == String.downcase(type)
end
end

Expand Down Expand Up @@ -122,15 +119,15 @@ defmodule Maxwell.Adapter.Util do
case next_stream_fun.({:cont, nil}) do
{:suspended, item, next_stream_fun} -> {:ok, item, next_stream_fun}
{:halted, _} -> :eof
{:done, _} -> :eof
{:done, _} -> :eof
end
end
def stream_iterate(stream) do
case Enumerable.reduce(stream, {:cont, nil}, fn(item, nil)-> {:suspend, item} end) do
case Enumerable.reduce(stream, {:cont, nil}, fn(item, nil)-> {:suspend, item} end) do
{:suspended, item, next_stream} -> {:ok, item, next_stream}
{:done, _} -> :eof
{:done, _} -> :eof
{:halted, _} -> :eof
end
end
end

defp multipart_body({:start, boundary, multiparts}) do
Expand Down
Loading

0 comments on commit 1924595

Please sign in to comment.