guile-docs/guile-docs/server/webserver.scm

56 lines
1.7 KiB
Scheme

;; Simplified guile web server outlined in
;; https://spritely.institute/files/docs/guile-hoot/0.2.0/Tutorial.html
(define-module (guile-docs server webserver)
#:use-module (guile-docs html templates)
#:use-module (ice-9 binary-ports)
#:use-module (ice-9 format)
#:use-module (ice-9 match)
#:use-module (web server)
#:use-module (web request)
#:use-module (web response)
#:use-module (web uri)
#:use-module (haunt html)
#:export (handle-request))
(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-html sxml)
(values '((content-type . (text/html)))
(sxml->html-string sxml)))
(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-html index-page))
(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)))