92 lines
2.1 KiB
Elixir
92 lines
2.1 KiB
Elixir
defmodule RlRepo.ClientHandler do
|
|
require Logger
|
|
@moduledoc """
|
|
"""
|
|
|
|
def process_request(client_socket) do
|
|
Logger.info("Processing client request.")
|
|
|
|
client_socket
|
|
|> read_request
|
|
|> create_response()
|
|
|> create_response_header()
|
|
|> write_response(client_socket)
|
|
|
|
end
|
|
|
|
def read_request(client_socket) do
|
|
Logger.info("Reading request.")
|
|
{:ok, request} = :gen_tcp.recv(client_socket, 0)
|
|
Logger.info("Request recieved.")
|
|
request
|
|
end
|
|
|
|
def create_response(request) do
|
|
Logger.info("Building body.")
|
|
|
|
# NOTE: Reliability testing.
|
|
if String.match?(request, ~r{GET /error}) do
|
|
raise(request)
|
|
end
|
|
|
|
# TODO: Handle routing here.
|
|
a = String.split(request, "\n\r");
|
|
# Logger.info a
|
|
[get_line | rest] = a
|
|
|
|
b = String.split(get_line, " ");
|
|
[request_type | rest] = b
|
|
[path | rest] = rest
|
|
Logger.info "#{request_type} #{path}"
|
|
|
|
# Parse path
|
|
split_path = String.split(path, "/", trim: true);
|
|
# Ignore the first slash.
|
|
# [_ | rest ] = split_path
|
|
|
|
split_path_length = length(split_path)
|
|
|
|
ret = case split_path_length do
|
|
1 -> RlRepo.Router.parse_1_segment_path(rest)
|
|
|> RlRepo.Router.route_1(request_type)
|
|
3 ->
|
|
RlRepo.Router.parse_3_segment_path(rest)
|
|
|> RlRepo.Router.route_3(request_type)
|
|
4 ->
|
|
RlRepo.Router.parse_4_segment_path(rest)
|
|
|> RlRepo.Router.route_4(request_type)
|
|
# Note: Error handling.
|
|
_ -> RlRepo.Router.status_404()
|
|
end
|
|
end
|
|
|
|
|
|
def create_return_code_string(return_code) do
|
|
case return_code do
|
|
200 -> "200 OK"
|
|
404 -> "404 Not Found"
|
|
end
|
|
end
|
|
|
|
def create_response_header(body) do
|
|
{return_code, content_type, body} = body
|
|
|
|
"""
|
|
HTTP/1.1 #{create_return_code_string(return_code)}\r
|
|
Content-Type: #{content_type}\r
|
|
Content-Length: #{byte_size(body)}\r
|
|
\r
|
|
#{body}
|
|
"""
|
|
end
|
|
|
|
|
|
def write_response(response, client_socket) do
|
|
:ok = :gen_tcp.send(client_socket, response)
|
|
|
|
# Logger.info("Response:\n\n#{response}")
|
|
|
|
:gen_tcp.close(client_socket)
|
|
end
|
|
end
|