51 lines
1.1 KiB
Crystal
51 lines
1.1 KiB
Crystal
require "socket"
|
|
require "log"
|
|
require "./request"
|
|
require "./response"
|
|
|
|
class Gemini::Server
|
|
getter server : TCPServer
|
|
getter port : Int32
|
|
getter pwd : Path
|
|
|
|
def initialize(@port : Int32 = 1965)
|
|
@server = TCPServer.new(@port)
|
|
@pwd = Path[Dir.current]
|
|
|
|
Log.info { "Gemini server started at port #{@port}" }
|
|
end
|
|
|
|
# Runs the server and starts waiting for connections
|
|
def start : Nil
|
|
while connection = @server.accept?
|
|
begin
|
|
uri = connection.gets
|
|
|
|
# Client must send URI first
|
|
unless uri.nil? || uri.blank?
|
|
request = Request.new(self, connection, uri)
|
|
response = Response.new(self, connection, request)
|
|
|
|
request.validate!
|
|
|
|
response.send
|
|
else
|
|
raise Error.new("URI is empty")
|
|
end
|
|
rescue ex
|
|
puts connection, "40 Error"
|
|
Log.error(exception: ex) { "Gemini::Error" }
|
|
end
|
|
|
|
# Always close the connection
|
|
connection.close
|
|
end
|
|
end
|
|
|
|
# Sends a message through the connection
|
|
def puts(connection : IO, message : String) : Nil
|
|
connection.puts message
|
|
connection.puts "\r\n"
|
|
end
|
|
end
|