From 4ba0d882b96212e079552db8ccc9a506edcad842 Mon Sep 17 00:00:00 2001 From: Christopher Brannon Date: Thu, 25 Mar 2021 14:50:35 -0700 Subject: [PATCH] Support name-based virtual hosting. Instead of putting content directly under server-root, it now should go under server-root/HOSTNAME. E.G., /srv/gemini/the-brannons.com/ for my public capsule. --- rags.scm | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/rags.scm b/rags.scm index ef4726f..8fb1bd9 100644 --- a/rags.scm +++ b/rags.scm @@ -8,6 +8,7 @@ ;; See the readme for details. (import (chicken io) + (chicken irregex) (chicken port) (chicken file) (chicken string) @@ -21,7 +22,7 @@ uri-common tcp6 openssl) (define-record config - root-dir host port certfile keyfile uid gid) + root-dir port certfile keyfile uid gid) (define file-types '(("gmi" "text/gemini" "charset=utf-8") @@ -43,7 +44,9 @@ (fail-permanent "Unsupported scheme.")) ((not (uri-host uri)) (fail-permanent "URL lacks host name.")) - ((not (equal? (uri-host uri) (config-host config))) + ((not (valid-hostname (uri-host uri))) + (fail-permanent "Invalid host name.")) + ((not (existing-host config uri)) (fail-permanent "Proxy requests forbidden.")) ((uri-path-relative? uri) (fail-permanent "Path must be absolute.")) @@ -72,6 +75,16 @@ (define (uri-with-trailing-slash uri) (update-uri uri path: (append (uri-path uri) '("")))) +(define (valid-hostname name) + (let* + ((host-label-part '(+ (or alphanumeric #\- #\_))) + (domain-part `(: #\. ,host-label-part)) + (hostname-regex `(: ,host-label-part (+ ,domain-part)))) + (irregex-match? hostname-regex name))) + +(define (existing-host config uri) + (directory-exists? (make-pathname (config-root-dir config) (uri-host uri)))) + (define (document-available? config uri) (file-exists? (document-path config uri))) @@ -85,7 +98,8 @@ (directory-exists? (document-path-raw config uri))) (define (document-path-raw config uri) - (let* ((crumbs (reverse (cons (config-root-dir config) (cdr (uri-path uri)))))) + (let* ((crumbs (reverse (cons (config-root-dir config) + (cons (uri-host uri) (cdr (uri-path uri))))))) (make-pathname (reverse (cdr crumbs)) (car crumbs)))) (define (document-path config uri) @@ -186,7 +200,7 @@ private-key: (config-keyfile config) protocol: 'tlsv12)) - (print "Host: '" (config-host config) "'\n" + (print "Port: '" (config-port config) "'\n" "Root directory: '" (config-root-dir config) "'\n" "Cert file: '" (config-certfile config) "'\n" @@ -230,11 +244,11 @@ (print "Usage:\n" progname " [-h/--help]\n" progname " [-p/--port PORT] [-u/--user UID] [-g/--group GID]\n" - indent-str " server-root-dir hostname certfile keyfile"))) + indent-str " server-root-dir certfile keyfile"))) (define (main) (let* ((progname (pathname-file (car (argv)))) - (config (make-config #f #f 1965 #f #f #f #f))) + (config (make-config #f 1965 #f #f #f #f))) (if (null? (command-line-arguments)) (print-usage progname) (let loop ((args (command-line-arguments))) @@ -260,9 +274,8 @@ (else (print-usage progname))) (match args - ((root-dir host certfile keyfile) + ((root-dir certfile keyfile) (config-root-dir-set! config root-dir) - (config-host-set! config host) (config-certfile-set! config certfile) (config-keyfile-set! config keyfile) (run-server config)) -- 2.20.1