Packages

High performance multiple backend web server

Current section

Files

Jump to
ringbahn lib serializer.ex
Raw

lib/serializer.ex

defmodule Ringbahn.Serializer do
@moduledoc """
Provides serialization interface like mongrel2 for zmq.
Includes serialization strategy for data dispatch to sockets.
"""
def serialize(conn, req_body, route_data, conn_id \\ Integer.to_string(Enum.random(1..1_000))) do
args = [
route_data.recv_ident, # SENDER
conn_id, # IDENT
conn.request_path, # PATH
request_headers(conn), # REQUEST HEADERS as Netstring
request_body(req_body), # REQUEST BODY as Netstring
]
Enum.join(args, " ")
end
# Serialize request body as netstring
defp request_body(req_body) do
req_body |> Netstrings.encode
end
# Get request header serialized as netstring
def request_headers(conn) do
(builtin_headers(conn) ++ conn.req_headers)
|> create_kv_pair_string
|> create_request_header_string
|> Netstrings.encode
end
defp builtin_headers(conn) do
{_, req} = conn.adapter
[
{"METHOD", conn.method},
{"VERSION", version(req)},
{"URI", uri(conn, req)},
{"PATH", path(req)},
{"QUERY", conn.query_string},
{"PATTERN", conn.request_path <> "/"},
{"URL_SCHEME", Atom.to_string(conn.scheme)},
{"REMOTE_ADDR", conn.remote_ip |> Tuple.to_list |> Enum.join(".")}
]
end
# Header assembly for serialization
defp create_kv_pair_string(headers) do
Enum.map headers, fn (kv_pair) ->
"\"#{elem(kv_pair, 0)}\":\"#{elem(kv_pair, 1)}\""
end
end
# Serializes array of KV-pair strings
defp create_request_header_string(kv_pair_array) do
generated_headers = Enum.join(kv_pair_array, ",")
"{#{generated_headers}}"
end
# Option fetchers
defp path(req) do
{path, _} = :cowboy_req.path(req)
path
end
defp uri(conn, req) do
{full_path, _} = :cowboy_req.url(req)
full_path |> String.replace(conn.host <> ":" <> Integer.to_string(conn.port), "") |> String.replace(Atom.to_string(conn.scheme) <> "://", "")
end
defp version(req) do
{version, _} = :cowboy_req.version(req)
Atom.to_string(version)
end
end