feat: configuration system
This commit is contained in:
parent
e6f616148a
commit
399e5a6461
34
config.json
34
config.json
|
|
@ -1,18 +1,22 @@
|
||||||
{
|
{
|
||||||
"notaname.home": {
|
"hostname": "192.168.50.50",
|
||||||
"handler": "static_serve",
|
"port": 80,
|
||||||
|
|
||||||
"document_root": "/var/www/notaname/home"
|
"vhosts": [
|
||||||
},
|
{
|
||||||
|
"server_name": "notaname.home",
|
||||||
"compteur.notaname.home": {
|
"handler": "static_serve",
|
||||||
"handler": "internal.compter"
|
"document_root": "/var/www/notaname/home"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
"compteur.cheat.notaname.home": {
|
"server_name": "compteur.notaname.home",
|
||||||
"handler": "proxy_pass",
|
"handler": "internal.compter"
|
||||||
|
},
|
||||||
"host": "127.0.0.1",
|
{
|
||||||
"port": 8080
|
"server_name": "compteur.cheat.notaname.home",
|
||||||
}
|
"handler": "proxy_pass",
|
||||||
|
"hostname": "127.0.0.1",
|
||||||
|
"port": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
require "json"
|
||||||
|
|
||||||
|
class Configuration
|
||||||
|
include JSON::Serializable
|
||||||
|
|
||||||
|
property hostname : String
|
||||||
|
property port : UInt32
|
||||||
|
|
||||||
|
property vhosts : Array(VHost)
|
||||||
|
end
|
||||||
|
|
||||||
|
class VHost
|
||||||
|
include JSON::Serializable
|
||||||
|
|
||||||
|
property handler : String
|
||||||
|
|
||||||
|
property server_name : String?
|
||||||
|
|
||||||
|
property hostname : String?
|
||||||
|
property port : UInt32?
|
||||||
|
|
||||||
|
property document_root : String?
|
||||||
|
end
|
||||||
|
|
@ -2,8 +2,5 @@ require "json"
|
||||||
require "../request"
|
require "../request"
|
||||||
|
|
||||||
abstract class Handler
|
abstract class Handler
|
||||||
def initialize(@configuration : JSON::Any)
|
|
||||||
end
|
|
||||||
|
|
||||||
abstract def handle(request : Request) : Response
|
abstract def handle(request : Request) : Response
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@ require "./handler"
|
||||||
require "../response"
|
require "../response"
|
||||||
|
|
||||||
class ProxyHandler < Handler
|
class ProxyHandler < Handler
|
||||||
def handle(request : Request) : Response
|
|
||||||
puts "ping"
|
|
||||||
host = @configuration["host"].to_s
|
|
||||||
port = @configuration["port"].to_s.to_i
|
|
||||||
|
|
||||||
return TCPSocket.open host, port do |tcp_socket|
|
def initialize (@host : String, @port : UInt32); end
|
||||||
|
|
||||||
|
def handle(request : Request) : Response
|
||||||
|
return TCPSocket.open @host, @port do |tcp_socket|
|
||||||
tcp_socket << request.to_s
|
tcp_socket << request.to_s
|
||||||
return Response.new tcp_socket.receive[0]
|
return Response.new tcp_socket.receive[0]
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
require "./handler"
|
require "./handler"
|
||||||
|
require "../../configuration"
|
||||||
|
|
||||||
class StaticHandler < Handler
|
class StaticHandler < Handler
|
||||||
|
|
||||||
|
def initialize (@document_root : String); end
|
||||||
|
|
||||||
def handle(request : Request) : Response
|
def handle(request : Request) : Response
|
||||||
file = @configuration["document_root"].to_s + request.uri
|
file = @document_root + request.uri
|
||||||
|
|
||||||
if request.uri.ends_with? "/"
|
if request.uri.ends_with? "/"
|
||||||
file = @configuration["document_root"].to_s + request.uri + "index.html"
|
file = @document_root + request.uri + "index.html"
|
||||||
end
|
end
|
||||||
|
|
||||||
if !File.exists?(file)
|
if !File.exists?(file)
|
||||||
|
|
|
||||||
60
src/main.cr
60
src/main.cr
|
|
@ -1,35 +1,36 @@
|
||||||
require "socket"
|
|
||||||
require "option_parser"
|
|
||||||
require "env"
|
|
||||||
require "json"
|
require "json"
|
||||||
|
require "socket"
|
||||||
|
|
||||||
|
require "./configuration"
|
||||||
require "./http/request"
|
require "./http/request"
|
||||||
require "./http/response"
|
require "./http/response"
|
||||||
require "./http/handler/static_handler"
|
require "./http/handler/static_handler"
|
||||||
require "./http/handler/proxy_handler"
|
require "./http/handler/proxy_handler"
|
||||||
require "./http/handler/compter_handler"
|
require "./http/handler/compter_handler"
|
||||||
|
|
||||||
|
def handle_request(client, vhosts)
|
||||||
def handle_request(client)
|
|
||||||
request = Request.new(client)
|
request = Request.new(client)
|
||||||
puts request
|
|
||||||
configuration_file = File.open("/home/kooka/config.json") do |file|
|
|
||||||
file.gets_to_end
|
|
||||||
end
|
|
||||||
|
|
||||||
configuration = Hash(String, JSON::Any).from_json configuration_file
|
vhosts.each do |vhost|
|
||||||
configuration.each do |key, value|
|
if request.header("Host") != vhost.server_name
|
||||||
if request.header("Host") != key
|
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
case value["handler"]
|
case vhost.handler
|
||||||
when "proxy_pass"
|
when "proxy_pass"
|
||||||
handler = ProxyHandler.new value
|
if (hostname = vhost.hostname).nil? || (port = vhost.port).nil?
|
||||||
|
raise "hostname or port key should not be null"
|
||||||
|
end
|
||||||
|
|
||||||
|
handler = ProxyHandler.new hostname, port
|
||||||
when "static_serve"
|
when "static_serve"
|
||||||
handler = StaticHandler.new value
|
if (document_root = vhost.document_root).nil?
|
||||||
|
raise "document_root key should not be null"
|
||||||
|
end
|
||||||
|
|
||||||
|
handler = StaticHandler.new document_root
|
||||||
when "internal.compter"
|
when "internal.compter"
|
||||||
handler = CompterHandler.new value
|
handler = CompterHandler.new
|
||||||
else
|
else
|
||||||
client << Response.new "HTTP", "1.0", HTTPStatus::BAD_GATEWAY
|
client << Response.new "HTTP", "1.0", HTTPStatus::BAD_GATEWAY
|
||||||
break
|
break
|
||||||
|
|
@ -40,30 +41,11 @@ def handle_request(client)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
tcp_port = 8090
|
configuration_file = File.read("./config.json")
|
||||||
hostname = "127.0.0.1"
|
configuration = Configuration.from_json configuration_file
|
||||||
|
|
||||||
OptionParser.parse do |parser|
|
server = TCPServer.new(configuration.hostname, configuration.port)
|
||||||
parser.banner = "Usage: webcrystal [arguments]"
|
|
||||||
parser.on("-p PORT", "--port=PORT", "Specify the port to listen, default to 8000") do |port|
|
|
||||||
tcp_port = port.to_u32
|
|
||||||
end
|
|
||||||
parser.on("-n NAME", "--name NAME", "Hostname to listen, default to 127.0.0.1") do |name|
|
|
||||||
hostname = name
|
|
||||||
end
|
|
||||||
parser.on("-h", "--help", "Show this help") do
|
|
||||||
puts parser
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
parser.invalid_option do |flag|
|
|
||||||
STDERR.puts "ERROR: #{flag} is not a valid option."
|
|
||||||
STDERR.puts parser
|
|
||||||
exit(1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
server = TCPServer.new(hostname, tcp_port)
|
|
||||||
|
|
||||||
while client = server.accept?
|
while client = server.accept?
|
||||||
spawn handle_request(client)
|
spawn handle_request(client, configuration.vhosts)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue