Spaces:
Sleeping
Sleeping
File size: 2,791 Bytes
2e92879 a8d7371 2e92879 b2ff4b5 2e92879 a8d7371 0b53aa4 a8d7371 0b53aa4 abcde98 a8d7371 abcde98 0b53aa4 a8d7371 8f1b0f2 a8d7371 0b53aa4 2e92879 b2ff4b5 2e92879 0b53aa4 b2ff4b5 2e92879 8f1b0f2 a8d7371 2e92879 0b53aa4 2e92879 b2ff4b5 abcde98 b2ff4b5 76486d3 0b53aa4 2e92879 0b53aa4 b2ff4b5 0b53aa4 2e92879 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
defmodule Srh.Http.BaseRouter do
use Plug.Router
alias Srh.Http.RequestValidator
alias Srh.Http.CommandHandler
alias Srh.Http.ResultEncoder
plug(:match)
plug(Plug.Parsers, parsers: [:json], pass: ["application/json"], json_decoder: Jason)
plug(:dispatch)
get "/" do
handle_response({:ok, "Welcome to Serverless Redis HTTP!"}, conn)
end
post "/" do
do_command_request(conn, &CommandHandler.handle_command(&1, &2))
end
post "/pipeline" do
do_command_request(conn, &CommandHandler.handle_command_array(&1, &2))
end
post "/multi-exec" do
do_command_request(conn, &CommandHandler.handle_command_transaction_array(&1, &2))
end
match _ do
send_resp(conn, 404, "Endpoint not found")
end
defp do_command_request(conn, success_lambda) do
encoding_enabled = handle_extract_encoding?(conn)
conn
|> handle_extract_auth(&success_lambda.(conn, &1))
|> handle_encoding_step(encoding_enabled)
|> handle_response(conn)
end
defp handle_extract_auth(conn, success_lambda) do
case conn
|> get_req_header("authorization")
|> RequestValidator.validate_bearer_header() do
{:ok, token} ->
success_lambda.(token)
{:error, _} ->
{:malformed_data, "Missing/Invalid authorization header"}
end
end
defp handle_extract_encoding?(conn) do
case conn
|> get_req_header("upstash-encoding")
|> RequestValidator.validate_encoding_header() do
{:ok, _encoding_enabled} -> true
{:error, _} -> false # it's not required to be present
end
end
defp handle_encoding_step(response, encoding_enabled) do
case encoding_enabled do
true ->
# We need to use the encoder to
ResultEncoder.encode_response(response)
false -> response
end
end
defp handle_response(response, conn) do
%{code: code, message: message, json: json} =
case response do
{:ok, data} ->
%{code: 200, message: Jason.encode!(data), json: true}
{:not_found, message} ->
%{code: 404, message: message, json: false}
{:malformed_data, message} ->
%{code: 400, message: message, json: false}
{:redis_error, data} ->
%{code: 400, message: Jason.encode!(data), json: true}
{:not_authorized, message} ->
%{code: 401, message: message, json: false}
{:server_error, _} ->
%{code: 500, message: "An error occurred internally", json: false}
_ ->
%{code: 500, message: "An error occurred internally", json: false}
end
case json do
true ->
conn
|> put_resp_header("content-type", "application/json")
false ->
conn
end
|> send_resp(code, message)
end
end
|