gemini/src/gemini/request.cr
2022-01-05 17:02:05 -03:00

49 lines
1.1 KiB
Crystal

require "uri"
# Processes a Gemini request
class Gemini::Request
getter server : Server
getter connection : IO
getter uri : URI
getter path : Path
getter host : Path
def initialize(@server, @connection, uri : String)
@uri = URI.parse uri
if @uri.host.nil? || @uri.host.try(&.blank?)
raise Error.new("Host can't be empty")
end
@host = @server.pwd / Path[@uri.host || "doesnt_exist"]
@path = process_path
end
# Validates the request by raising exceptions
def validate!
unless host_exist?
raise Error.new("Missing host directory #{@uri.host} at #{Dir.current}, you may need to create and populate it")
end
if malicious_path?
raise Error.new("#{path} is outside served directory #{@host}")
end
end
def host_exist? : Bool
File.directory? @host
end
# Path must be inside served directory
def malicious_path? : Bool
!path.to_s.starts_with?(@host.to_s)
end
private def process_path : Path
path = (@host / Path[@uri.path]).normalize
path = path / Path["index.gmi"] if File.directory? path
path
end
end