Request/response class skeletons

This commit is contained in:
Yessiest 2023-09-01 00:15:03 +04:00
parent 3af7a372da
commit 9d483aa163
1 changed files with 76 additions and 10 deletions

View File

@ -1,21 +1,87 @@
# frozen_string_literal: true
require 'uri'
module Hyde
# Request wrapper for Rack protocol
class Request
# @param env [Array]
def initialize(env)
@env = env
@method = env["REQUEST_METHOD"]
@path = env["PATH_INFO"]
# Should not be used under regular circumstances or depended upon.
@_original_env = env
# Rack environment variable bindings. Should be public.
@request_method = env["REQUEST_METHOD"]
@script_name = env["SCRIPT_NAME"]
@query_string = env["QUERY_STRING"]
@host = env["SERVER_NAME"]
@port = env["SERVER_PORT"]
@virtual_host = env["HTTP_HOST"]
@headers = env.filter { |k, _| k.start_with? "HTTP_" }
@path_info = env["PATH_INFO"]
@server_name = env["SERVER_NAME"]
@server_port = env["SERVER_PORT"]
@server_protocol = env["SERVER_PROTOCOL"]
@headers = init_headers(env)
# Encapsulates all rack variables. Should not be public.
@rack = init_rack_vars(env)
end
attr_reader @host
attr_reader @port
# Returns request body (if POST data exists)
def body
@rack.input&.gets
end
attr_reader :request_method, :script_name, :path_info, :server_name, :server_port, :server_protocol, :headers
private
# Initialize rack parameters struct
# @param env [Hash]
# @return Object
def init_rack_vars(env)
rack_vars = env.filter_map do |k|
k.delete_prefix "rack." if k.start_with? "rack."
end
rack_vars["multipart"] = init_multipart_vars
rack_keys = rack_vars.keys.map(&:to_sym)
Struct.new(*rack_keys)
.new(*rack_vars.values_at(rack_keys))
.freeze
end
# Initialize multipart parameters struct
# @param env [Hash]
# @return Object
def init_multipart_vars
multipart_vars = env.filter_map do |k|
k.delete_prefix "rack.multipart." if k.start_with? "rack.multipart"
end
multipart_keys = multipart_vars.keys.map(&:to_sym)
Struct.new(*multipart_keys)
.new(*multipart_vars.values_at(multipart_keys))
.freeze
end
# Iniitalize headers hash
# @param env [Hash]
# @return Hash
def init_headers(env)
headers = env.filter_map do |name, value|
[name.delete_prefix("HTTP_"), value] if name.start_with?("HTTP_")
end.to_h
headers.merge!({ "CONTENT_TYPE" => env["CONTENT_TYPE"],
"CONTENT_LENGTH" => env["CONTENT_LENGTH"] })
headers.freeze
end
end
# Rack protocol response wrapper.
class Response
def initialize
@status = 404
@headers = {}
@body = []
end
# Finish constructing Rack protocol response.
# @return [Array(Integer,Hash,Array)]
def finalize
[@status, @headers, @body]
end
end
end