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