68 lines
1.8 KiB
Elixir
68 lines
1.8 KiB
Elixir
defmodule ChronoscopeWeb.API.V1.Gemini.ConnectionController do
|
|
use ChronoscopeWeb, :controller
|
|
|
|
require Logger
|
|
|
|
alias Chronoscope.Gemini
|
|
|
|
@default_port 1965
|
|
@default_path "/"
|
|
@max_host_length 255
|
|
@gemini Application.compile_env(:chronoscope, :gemini, Gemini)
|
|
|
|
def get(conn, %{"host" => host, "port" => port, "path" => path}) do
|
|
try do
|
|
handle_get(conn, %{host: host, port: String.to_integer(port), path: path})
|
|
rescue
|
|
ArgumentError -> bad_request_response(conn, "invalid port")
|
|
end
|
|
end
|
|
|
|
def get(conn, %{"host" => host, "path" => path}) do
|
|
handle_get(conn, %{host: host, port: @default_port, path: path})
|
|
end
|
|
|
|
def get(conn, %{"host" => host, "port" => port}) do
|
|
handle_get(conn, %{host: host, port: port, path: @default_path})
|
|
end
|
|
|
|
def get(conn, %{"host" => host}) do
|
|
handle_get(conn, %{host: host, port: @default_port, path: @default_path})
|
|
end
|
|
|
|
def get(conn, _params) do
|
|
bad_request_response(conn, "missing host")
|
|
end
|
|
|
|
defp handle_get(conn, %{host: host, port: port, path: path}) when port > 0 and port < 65536 do
|
|
case connect(host, port, path) do
|
|
{:ok, response} ->
|
|
json(conn, %{status: :ok, response: format_response(response)})
|
|
|
|
{:error, error} ->
|
|
json(conn, %{status: :error, reason: to_string(error)})
|
|
end
|
|
end
|
|
|
|
defp handle_get(conn, _params) do
|
|
bad_request_response(conn, "port out of range")
|
|
end
|
|
|
|
defp connect(host, port, path) do
|
|
# TODO - max path length
|
|
host
|
|
|> String.slice(0, @max_host_length)
|
|
|> @gemini.connect(port, path)
|
|
end
|
|
|
|
defp format_response(response) do
|
|
Map.take(response, [:status, :mime_type, :body])
|
|
end
|
|
|
|
defp bad_request_response(conn, message) do
|
|
conn
|
|
|> put_status(:bad_request)
|
|
|> json(%{error: message})
|
|
end
|
|
end
|