Current section
Files
Jump to
Current section
Files
lib/http-message.ex
defmodule HTTPMessage do
import String
defstruct method: "GET", version: "HTTP/1.1", url: "/", fields: [], body: ""
def parse(source) do
# Parse message sections:
{header, body} =
case split(source, ["\r\n\r\n", "\n\n"], parts: 2) do
[header, body] -> {header, body}
[header] -> {header, ""}
[] -> {"", ""}
end
# Parse message header:
[leader, fields] = header |> split(["\r\n", "\n"], parts: 2)
[method, url, version] = leader |> split(" ", parts: 3)
fields = if fields, do: parse_fields fields
# Create struct:
%HTTPMessage{
url: url,
body: body,
method: method,
version: version,
fields: fields
}
end
defp parse_fields(fields) do
fields
|> split(["\r\n", "\n"])
|> Enum.map(fn (field) ->
case split(field, ":", parts: 2) do
[name, value] -> {name, trim value}
other -> other
end
end)
end
def create(message) do
%HTTPMessage{
method: method,
url: url,
version: version,
fields: fields,
body: body
} = message
# Convert struct values to string (if not already):
method = to_string method
url = to_string url
version = to_string version
body = to_string body
fields = to_string create_fields fields
# Create HTTP message from the struct values:
method <> " " <> url <> " " <> version <> "\r\n" <>
fields <> "\r\n\r\n" <>
body
end
defp create_fields(fields) do
fields
|> Enum.map(fn (field) ->
elem(field, 0) <> ": " <> to_string(elem(field, 1))
end)
|> Enum.join("\r\n")
end
end