Current section
Files
Jump to
Current section
Files
lib/servo/parser.ex
defmodule Servo.Parser do
@moduledoc """
Example HTTP Request:
"""
alias Servo.Request
@doc """
Convert HTTP Request string to a Request struct
Returns: `%Request{}`
"""
def parse(request) do
# Separate request body from headers
[head, body] = String.split(request, "\r\n\r\n")
# Separate request headers from request method line
[request_line | header_lines] = String.split(head, "\r\n")
[method, path, _] = String.split(request_line, " ")
headers = parse_headers(header_lines)
params = parse_params(headers["Content-Type"], body)
%Request{
method: method,
path: path,
params: params,
headers: headers
}
end
@doc """
Converts HTTP header lines to a Map
## Examples
iex> header_lines = ["Host: example.com", "User-Agent: ExampleBrowser/1.0"]
iex> Servo.Parser.parse_headers(header_lines)
%{ "Host" => "example.com", "User-Agent" => "ExampleBrowser/1.0" }
"""
def parse_headers(header_lines) do
Enum.reduce(header_lines, %{}, fn(line, headers) ->
[key, value] = String.split(line, ": ")
Map.put(headers, key, String.trim(value))
end)
end
@doc """
Parses a param string of the form `key1=value1&key2=value2`
into a map with corresponding keys and values.
## Examples
iex> params_string = "name=C3PO&color=gold"
iex> Servo.Parser.parse_params("application/x-www-form-urlencoded", params_string)
%{ "name" => "C3PO", "color" => "gold" }
iex> Servo.Parser.parse_params("multipart/form-data", params_string)
%{}
iex> params_string = ~s({"name": "C3PO", "color": "gold"})
iex> Servo.Parser.parse_params("application/json", params_string)
%{ "name" => "C3PO", "color" => "gold" }
"""
def parse_params("application/x-www-form-urlencoded", params_string) do
params_string |> String.trim |> URI.decode_query
end
def parse_params("application/json", params_string) do
Poison.Parser.parse!(params_string)
end
def parse_params(_, _), do: %{}
end