;; Simplified guile web server outlined in ;; https://spritely.institute/files/docs/guile-hoot/0.2.0/Tutorial.html (use-modules (ice-9 binary-ports) (ice-9 format) (ice-9 match) (web server) (web request) (web response) (web uri) (haunt html)) (define (extension file) (match (string-split file #\.) (() #f) ((_ ... ext) ext))) (define (mime-type file-name) (or (assoc-ref '(("js" . application/javascript) ("css" . text/css) ("html" . text/html) ("scm" . text/stml) ("wasm" . application/wasm)) (extension file-name)) 'text/plain)) (define (render-file file-name) (let ((type (mime-type file-name))) (if (eq? type 'text/stml) (values '((content-type . (text/html))) (sxml->html-string (load file-name))) (values `((content-type . (,type))) (call-with-input-file file-name get-bytevector-all))))) (define (not-found path) (values (build-response #:code 404) (string-append "Not found: " path))) (define (directory? file-name) (eq? (stat:type (stat file-name)) 'directory)) (define (serve-file path) (define %prefix `(,(getcwd) "public")) (define (prepend-prefix path) (string-join (append %prefix `(,path)) file-name-separator-string)) (let ((f (prepend-prefix (uri-decode path)))) (cond ((and (file-exists? f) (not (directory? f))) (render-file f)) ((equal? "/" path) (render-file (prepend-prefix "index.scm"))) (else (not-found path))))) (define (handle-request request body) (let ((method (request-method request)) (path (uri-path (request-uri request)))) (format #t "~a ~a\n" method path) (serve-file path))) (run-server handle-request 'http '(#:port 8080))