Packages
ace
0.15.5
0.19.0
0.18.10
0.18.9
0.18.8
0.18.7
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.1
0.17.0
0.16.8
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
retired
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
retired
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.0
0.3.0
0.2.0
HTTP web server and client, supports http1 and http2
Current section
Files
Jump to
Current section
Files
lib/ace/http/worker.ex
defmodule Ace.HTTP.Worker do
@moduledoc false
use GenServer
def child_spec({module, config}) do
# DEBT is module previously checked to implement Raxx.Application or Raxx.Server
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [{module, config}]},
type: :worker,
restart: :temporary,
shutdown: 500
}
end
# TODO decide whether a channel should be limited from startup to single channel (stream/pipeline)
def start_link({module, config}, channel \\ nil) do
GenServer.start_link(__MODULE__, {module, config, nil}, [])
end
## Server Callbacks
def handle_info({client, request = %Raxx.Request{}}, {mod, state, nil}) do
mod.handle_head(request, state)
|> normalise_reaction(state)
|> do_send({mod, state, client})
end
def handle_info({client, data = %Raxx.Data{}}, {mod, state, client}) do
mod.handle_data(data.data, state)
|> normalise_reaction(state)
|> do_send({mod, state, client})
end
def handle_info({client, tail = %Raxx.Tail{}}, {mod, state, client}) do
mod.handle_tail(tail.headers, state)
|> normalise_reaction(state)
|> do_send({mod, state, client})
end
def handle_info(other, {mod, state, client}) do
mod.handle_info(other, state)
|> normalise_reaction(state)
|> do_send({mod, state, client})
end
defp normalise_reaction(response = %Raxx.Response{}, state) do
case response.body do
false ->
{[response], state}
true ->
{[response], state}
_body ->
# {[%{response | body: true}, Raxx.data(response.body), Raxx.tail], state}
{[response], state}
end
end
defp normalise_reaction({parts, new_state}, _old_state) do
parts = Enum.map(parts, &fix_part/1)
{parts, new_state}
end
defp do_send({parts, new_state}, {mod, _old_state, client}) do
case parts do
[] ->
:ok
parts ->
case client do
ref = {:http1, pid, _count} ->
send(pid, {ref, parts})
stream = {:stream, _, _, _} ->
Enum.each(parts, fn part ->
Ace.HTTP2.send(stream, part)
end)
end
end
case List.last(parts) do
%{body: false} ->
{:stop, :normal, {mod, new_state, client}}
%Raxx.Tail{} ->
{:stop, :normal, {mod, new_state, client}}
%{body: body} when is_binary(body) ->
{:stop, :normal, {mod, new_state, client}}
_ ->
{:noreply, {mod, new_state, client}}
end
end
# TODO remove this special case
defp fix_part({:promise, request}) do
request =
request
|> Map.put(:scheme, request.scheme || :https)
{:promise, request}
end
defp fix_part(part) do
part
end
end