#lang racket (require net/url xml web-server/web-server web-server/servlet-dispatch web-server/dispatch (prefix-in files: web-server/dispatchers/dispatch-files) (prefix-in filter: web-server/dispatchers/dispatch-filter) (prefix-in sequencer: web-server/dispatchers/dispatch-sequencer) web-server/dispatchers/filesystem-map web-server/http) (define (html-response content) (response/full 200 #"OK" (current-seconds) TEXT/HTML-MIME-TYPE '() (list content))) (define (xexpr-file->xml file) (string->bytes/utf-8 (xexpr->string (read (open-input-file file))))) ;;; httpx ;; sends only the requested resource (define (about request) (html-response (xexpr-file->xml "source/about.txt"))) (define (home request) (html-response (xexpr-file->xml "source/index.txt"))) (define (404- request) (html-response (xexpr-file->xml "source/not-found.txt"))) (define (structures request structure-id) (html-response (xexpr-file->xml "source/not-found.txt"))) (define (index-structures request) (html-response (xexpr-file->xml "source/not-found.txt"))) (define (unstructures request structure-id) (html-response (xexpr-file->xml "source/not-found.txt"))) (define (index-unstructures request) (html-response (xexpr-file->xml "source/not-found.txt"))) (define-values (httpx-app reverse-httpx-uri) (dispatch-rules [("hx" "about") about] [("hx" "home") home] [("hx" "structures" (integer-arg)) structures] [("hx" "structures") index-structures] [("hx" "unstructures" (integer-arg)) unstructures] [("hx" "unstructures") index-unstructures] [else 404-])) ;;; page-app ;; constructs entire page for each response (define (make-page resource) (string->bytes/utf-8 (xexpr->string `(html ((lang "en")) ,(read (open-input-file "source/head.txt")) (body ,(read (open-input-file "source/header.txt")) ,(read (open-input-file resource))))))) (define (homepage request) (html-response (make-page "source/index.txt"))) (define (about-page request) (html-response (make-page "source/about.txt"))) (define-values (page-app reverse-page-uri) (dispatch-rules [("") homepage] [("about") about-page])) ;;; from /static (define url->path/static (make-url->path "static")) (define static-dispatcher (files:make #:url->path (lambda (u) (url->path/static (struct-copy url u [path (cdr (url-path u))]))))) ;;; 404 (define (not-found request) (html-response (make-page "source/not-found.txt"))) ;;; server (define stop (serve #:dispatch (sequencer:make (filter:make #rx"^/static/" static-dispatcher) (dispatch/servlet #:regexp #rx"^/hx/" httpx-app) (dispatch/servlet page-app) (dispatch/servlet not-found) ) #:listen-ip "127.0.0.1" #:port 8000)) (with-handlers ([exn:break? (lambda (e) (stop))]) (sync/enable-break never-evt))