From 2be9ea60d7f171ee3375258b774191f4cf911752 Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Thu, 23 Feb 2023 01:28:29 +0900 Subject: Handle requests to both ICANN and OpenNIC hosts --- hybring.cr | 109 ------------------------------------------------------------- 1 file changed, 109 deletions(-) delete mode 100644 hybring.cr (limited to 'hybring.cr') diff --git a/hybring.cr b/hybring.cr deleted file mode 100644 index 13ba893..0000000 --- a/hybring.cr +++ /dev/null @@ -1,109 +0,0 @@ -# Hybrid web ring server -# Copyright (C) 2023 Nguyễn Gia Phong -# -# This file if part of hybring. -# -# Hybring is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Hybring is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with hybring. If not, see . - -require "http/server" -require "ini" -require "uri" - -require "./sqlite" -require "./xhtml" - -MAX_CONTENT_LENGTH = 4096 -OPENNIC_TLD = Set{".bbs", ".chan", ".cyb", ".dyn", ".epic", - ".geek", ".gopher", ".indy", ".libre", ".neo", - ".null", ".o", ".oss", ".oz", ".parody", ".pirate"} - -def http_error(context, status, message = nil) - context.response.respond_with_status status, message -end - -if ARGV.empty? - puts "usage: #{PROGRAM_NAME} config.ini" - exit 1 -end -cfg = INI.parse File.read ARGV[0] -db = Database.new cfg["path"]["db"] -members = db.members -page = Page.new cfg["url"]["static"], cfg["url"]["api"] -File.write Path[cfg["path"]["static"]] / "index.xhtml", page.build members - -server = HTTP::Server.new do |context| - # Manually crafted request - next http_error context, 405 if context.request.method != "POST" - content_length = context.request.content_length - next http_error context, 411 unless content_length - next http_error context, 413 if content_length > MAX_CONTENT_LENGTH - - body = context.request.body.try &.gets_to_end || "" - errors = {} of String => String - params = {} of String => String - invalid_param = false - URI::Params.parse body do |key, value| - params[key] = value - case key - when "nick" - if /^[0-9a-z]+$/ !~ value - next errors["nick"] = "Must be ASCII lowercase alphanumeric" - end - when "opennic" - uri = URI.parse value - next errors["opennic"] = "Must be absolute URL" unless uri.absolute? - if uri.scheme != "http" && uri.scheme != "https" - next errors["opennic"] = "Must be HTTP/S" - end - host = uri.host - unless OPENNIC_TLD.includes? Path[host].extension - next errors["opennic"] = "Must be under OpenNIC domain" - end if host - when "icann" - uri = URI.parse value - next errors["icann"] = "Must be absolute URL" unless uri.absolute? - next errors["icann"] = "Must be HTTPS" unless uri.scheme == "https" - host = uri.host # impractical to check for ICANN TLD - if OPENNIC_TLD.includes? Path[host].extension - next errors["icann"] = "Must not be under OpenNIC domain" - end if host - else - break invalid_param = true - end - end - - # Manually crafted request - next http_error context, 400, "Invalid Parameter" if invalid_param - next http_error context, 400, "Missing Parameter" unless params.size == 3 - - members.each do |nick, opennic, icann| - errors["nick"] = "Must be unique" if nick == params["nick"] - errors["opennic"] = "Must be unique" if opennic == params["opennic"] - errors["icann"] = "Must be unique" if icann == params["icann"] - end - - if errors.empty? - # TODO: write feed - else - context.response.status_code = 400 unless errors.empty? - end - context.response.content_type = "application/xhtml+xml" - context.response.print page.build members, errors, params - # TODO: schedule dynamic check -end - -# TODO: support Unix socket -address = server.bind_tcp cfg["listen"]["port"].to_i -puts "Listening on http://#{address}" -server.listen -- cgit 1.4.1