WEB: Implemented terrible routing control.

This commit is contained in:
Able 2025-02-18 09:21:58 -06:00
commit 07d553ab92
11 changed files with 300 additions and 0 deletions

4
.formatter.exs Normal file
View file

@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]

26
.gitignore vendored Normal file
View file

@ -0,0 +1,26 @@
# The directory Mix will write compiled artifacts to.
/_build/
# If you run "mix test --cover", coverage assets end up here.
/cover/
# The directory Mix downloads your dependencies sources to.
/deps/
# Where third-party dependencies like ExDoc output generated docs.
/doc/
# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch
# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump
# Also ignore archive artifacts (built via "mix archive.build").
*.ez
# Ignore package tarball (built via "mix hex.build").
rl_repo-*.tar
# Temporary files, for example, from tests.
/tmp/

36
README.md Normal file
View file

@ -0,0 +1,36 @@
# RlRepo
## API Usage
/<repo_name>/<?sub_repo_name>/<pkg_name>/download
### Repo management
/repo/<action>
#### Repo Creation
/repo/create
#### Repo deletion
/repo/delete
### Sub-repo management
/<repo_name>/create
/<repo_name>/delete
### Package management
/<repo_name>/<action>
#### Create
/<repo_name>/create
#### Delete
/<repo_name>/delete
### Package Info
/<repo_name>/<pkg_name>/<action>

89
lib/client_handler.ex Normal file
View file

@ -0,0 +1,89 @@
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, "/");
# Ignore the first slash.
[_ | rest ] = split_path
split_path_length = length(rest)
Logger.info split_path_length
ret = case split_path_length do
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)
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

8
lib/json.ex Normal file
View file

@ -0,0 +1,8 @@
defmodule RlRepo.Json do
require Logger
@moduledoc """
"""
def fmt_json(a) do
"{\"pkg_names\": 10}"
end
end

31
lib/rl_repo.ex Normal file
View file

@ -0,0 +1,31 @@
defmodule RlRepo do
require Logger
@moduledoc """
"""
@doc """
"""
def start(port) do
{:ok, listener_socket} = :gen_tcp.listen(port, [:binary, packet: :raw, active: false, reuseaddr: true])
Logger.info("Listening on port #{port}")
loop_acceptor(listener_socket)
end
def loop_acceptor(listener_socket) do
Logger.debug "Waiting for connection."
{:ok, client_socket} = :gen_tcp.accept(listener_socket)
Logger.info "Client Connected."
process_pid = spawn(fn -> RlRepo.ClientHandler.process_request(client_socket) end)
Logger.info "Handling client connection at PID #{inspect(process_pid)}"
Logger.info "Handing over socket control."
:ok = :gen_tcp.controlling_process(client_socket, process_pid)
loop_acceptor(listener_socket)
end
end

View file

@ -0,0 +1,23 @@
defmodule RlRepo.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
@impl true
def start(_type, _args) do
port = String.to_integer(System.get_env("PORT") || "10002")
children = [
# Starts a worker by calling: RlRepo.Worker.start_link(arg)
# {RlRepo.Worker, arg}
Supervisor.child_spec({Task, fn -> RlRepo.start(port) end}, restart: :permanent)
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: RlRepo.Supervisor]
Supervisor.start_link(children, opts)
end
end

45
lib/routing.ex Normal file
View file

@ -0,0 +1,45 @@
defmodule RlRepo.Router do
require Logger
@moduledoc """
"""
def route_3( path, request_type) do
Logger.info "#{request_type}"
{repo_name, pkg_name, action} = path
if action == "info" do
Logger.info "fetching json"
end
{200, "application/json", "{\"pkg_name\": \"#{pkg_name}\"}"}
end
def route_4(path, request_type) do
Logger.info "#{request_type}"
{repo_name, sub_repo_name, pkg_name, action} = path
{200, "text/html", "<p>Hi</p>"}
end
def parse_3_segment_path(path) do
[repo_name | rest ] = path
[pkg_name | rest] = rest
[action | _ ] = rest
Logger.info "REPO #{repo_name} PKG #{pkg_name} ACTION #{action}"
{repo_name, pkg_name, action}
end
def parse_4_segment_path(path) do
[repo_name | rest ] = path
[sub_repo_name | rest] = rest
[pkg_name | rest] = rest
[action | _ ] = rest
Logger.info "REPO #{repo_name} SUB_REPO #{sub_repo_name} PKG #{pkg_name} ACTION #{action}"
{repo_name, sub_repo_name, pkg_name, action}
end
end

29
mix.exs Normal file
View file

@ -0,0 +1,29 @@
defmodule RlRepo.MixProject do
use Mix.Project
def project do
[
app: :rl_repo,
version: "0.1.0",
elixir: "~> 1.12",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger],
mod: {RlRepo.Application, []}
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
end
end

8
test/rl_repo_test.exs Normal file
View file

@ -0,0 +1,8 @@
defmodule RlRepoTest do
use ExUnit.Case
doctest RlRepo
test "greets the world" do
# assert RlRepo.hello() == :world
end
end

1
test/test_helper.exs Normal file
View file

@ -0,0 +1 @@
ExUnit.start()