From d78aa174040694fb3eaa887c7c4a93fe450dae48 Mon Sep 17 00:00:00 2001 From: sorrel Date: Wed, 17 Jan 2024 21:01:09 -0500 Subject: [PATCH] implement static cache --- .dev-log | 11 +- .gitignore | 1 + oxaliq.net.rkt | 207 +++++++++++++++++++--------- static/fragment/root/not-found.html | 1 - static/page/root/index.html | 53 ------- static/page/root/not-found.html | 48 ------- 6 files changed, 155 insertions(+), 166 deletions(-) delete mode 100644 static/fragment/root/not-found.html delete mode 100644 static/page/root/index.html delete mode 100644 static/page/root/not-found.html diff --git a/.dev-log b/.dev-log index eb100f2..e37f544 100644 --- a/.dev-log +++ b/.dev-log @@ -1,6 +1,15 @@ +2024/01/15 +- cache static logic +- START HERE: + - test caching everywhere + - add content in atom + 2024/01/14 - fix stylesheets -- +- update all url references +- START HERE: + - add content in atom + - cache static logic 2024/01/13 - update atom-table-writing diff --git a/.gitignore b/.gitignore index e166de0..2e0f065 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ sorrel/** deploy-dir/** tool/** +static/** publish-test/** todo.txt diff --git a/oxaliq.net.rkt b/oxaliq.net.rkt index 843f615..bbeecfa 100644 --- a/oxaliq.net.rkt +++ b/oxaliq.net.rkt @@ -31,98 +31,180 @@ '() (list content))) +;; bound path builders +;; extension is always #".txt" because source files are not well-formed racket, +;; but must be read and evaluated in this namespace +(define (make-path-no-param root-folder extension) + (lambda (t) + (path-add-extension + (if (and (non-empty-string? t) (not (eq? t "root"))) + (build-path root-folder t "index") + (build-path root-folder "index")) + extension))) + +(define (make-path-id-param root-folder extension) + (lambda (t id) + (path-add-extension + (build-path root-folder + (if (eq? t "root") + (if (eq? id "") + ;; if "root/" something weird has happened + "index" + ;; allows for loading "/about" and other root resources + (~a id)) + (if + ;; if url has trailing backslash, id will be an empty string + ;; and should return index for that type + (or (not (string? id)) + (non-empty-string? id)) + (build-path t (~a id)) + (build-path t "index")))) + extension))) + +(define (make-source-path-no-param t) + ((make-path-no-param "source" #".txt") t)) + +(define (make-source-path-id-param t id) + ((make-path-id-param "source" #".txt") t id)) + +(define (make-static-path-no-param api-type t) + (let ([root-folder + (cond + [(eq? api-type 'httpx) "static/fragment"] + [(eq? api-type 'page) "static/page"] + [else (error "api-type ~a not recognized" api-type)])]) + ((make-path-no-param root-folder #".html") t))) + +(define (make-static-path-id-param api-type t id) + (let ([root-folder + (cond + [(eq? api-type 'httpx) "static/fragment"] + [(eq? api-type 'page) "static/page"] + [else (error "api-type ~a not recognized" api-type)])]) + ((make-path-id-param root-folder #".html") t id))) + + + +(define (static-file-res static-path) + (string->bytes/utf-8 (file->string static-path))) + +;; wrapper for resource-processor +(define (wrapper-for-resource-processor static-path res-processor) + (if (not (file-exists? static-path)) + (html-response (static-file-res static-path)) + (res-processor))) + +;; write static-file +;; return data that was written +(define (write-static-file static-path) + (lambda (data) + (let ([out-port (open-output-file static-path #:exists 'error)]) + (if (port-try-file-lock? out-port 'exclusive) + (begin + (display data out-port) + (port-file-unlock out-port) + (close-output-port out-port) + data) + (error "couldn't obtain file lock on ~a" out-port))))) + + +(define (404-handler api-type) + (cond + [(eq? api-type 'httpx) (404-hx)] + [(eq? api-type 'page) (404-page)] + [else (error "api-type ~a not recognized" api-type)])) + ;; takes a resource-type (corresponds to the REST resource and the system path or ;; an index resource in the source path) ;; and a resource-processor (-> file-handle . http-response) ;; and returns a valid html-response irrespective of hx/ type fragment of html or full page (define respond-resource-with-processor - (lambda (type resource-processor) - ;; bound path builders - ;; extension is always #".txt" because source files are not well-formed racket, - ;; but must be read and evaluated in this namespace - (define (make-res-path-no-param t) - (path-add-extension - (if (and (non-empty-string? t) (not (eq? t "root"))) - (build-path "source" t "index") - (build-path "source" "index" )) - #".txt")) - - (define (make-res-path-id-param t id) - (path-add-extension - (build-path "source" (if (eq? t "root") - (if (eq? id "") - ;; if "root/" something weird has happened - "index" - ;; allows for loading "/this" and other root resources - (~a id)) - (if - ;; if url has trailing backslash, id will be an empty string - ;; and should return index for that type - (or (not (string? id)) - (non-empty-string? id)) - (build-path t (~a id)) - (build-path t "index")))) - #".txt")) + (lambda (api-type res-type resource-processor) ;; this lambda will be called by dispatch-rules ;; (req) is the request object (case-lambda - [(req) (let ([res-path (make-res-path-no-param type)]) + [(req) + (let ([static-path (make-static-path-no-param api-type res-type)]) + (if (file-exists? static-path) + (html-response (static-file-res static-path)) + (let ([res-path (make-source-path-no-param res-type)]) (if (file-exists? res-path) - (html-response (resource-processor res-path)) - (html-response (resource-processor "source/not-found.txt"))))] + (html-response + (resource-processor res-path (write-static-file static-path))) + (404-handler api-type)))))] ;; (req id) is (request object . url parameter) - [(req id) (let ([res-path (make-res-path-id-param type id)]) - (if (file-exists? res-path) - (html-response (resource-processor res-path)) - (html-response (resource-processor "source/not-found.txt"))))]))) - + [(req id) + (let ([static-path (make-static-path-id-param api-type res-type id)]) + (if (file-exists? static-path) + (html-response (static-file-res static-path)) + (let ([res-path (make-source-path-id-param res-type id)]) + (if (file-exists? res-path) + (html-response (resource-processor res-path (write-static-file static-path))) + (404-handler api-type)))))]))) ;;; httpx ;; sends only the requested resource -(define (xexpr-file->xml file) +(define (xexpr-file->res file static-write) (string->bytes/utf-8 - (xexpr->string (read (open-input-file file))))) + (static-write (xexpr-file->xml file)))) +(define (xexpr-file->xml file) + (xexpr->string (read (open-input-file file)))) -(define (404-hx request) - (html-response (xexpr-file->xml "source/not-found.txt"))) +(define (404-hx) + (let ([static-path "static/fragment/not-found.html"]) + (html-response + (if (file-exists? static-path) + (static-file-res static-path) + (xexpr-file->res "source/not-found.txt" (write-static-file static-path)))))) (define-values (httpx-app reverse-httpx-uri) (dispatch-rules - [("hx" "home") (respond-resource-with-processor "root" xexpr-file->xml)] - [("hx" "settled") (respond-resource-with-processor "settled" xexpr-file->xml)] - [("hx" "settled" (integer-arg)) (respond-resource-with-processor "settled" xexpr-file->xml)] - [("hx" "unsettled") (respond-resource-with-processor "unsettled" xexpr-file->xml)] - [("hx" "unsettled" (integer-arg)) (respond-resource-with-processor "unsettled" xexpr-file->xml)] - [("hx" "tagged") (respond-resource-with-processor "tagged" xexpr-file->xml)] - [("hx" "tagged" (string-arg)) (respond-resource-with-processor "tagged" xexpr-file->xml)] - [("hx" (string-arg)) (respond-resource-with-processor "root" xexpr-file->xml)] - [else 404-hx])) + [("hx" "home") (respond-resource-with-processor 'httpx "root" xexpr-file->res)] + [("hx" "settled") (respond-resource-with-processor 'httpx "settled" xexpr-file->res)] + [("hx" "settled" (integer-arg)) (respond-resource-with-processor 'httpx "settled" xexpr-file->res)] + [("hx" "unsettled") (respond-resource-with-processor 'httpx "unsettled" xexpr-file->res)] + [("hx" "unsettled" (integer-arg)) (respond-resource-with-processor 'httpx "unsettled" xexpr-file->res)] + [("hx" "tagged") (respond-resource-with-processor 'httpx "tagged" xexpr-file->res)] + [("hx" "tagged" (string-arg)) (respond-resource-with-processor 'httpx "tagged" xexpr-file->res)] + [("hx" (string-arg)) (respond-resource-with-processor 'httpx "root" xexpr-file->res)] + [else (lambda (req) (404-hx))])) ;;; page-app ;; constructs entire page for each response -(define (make-page resource) +(define (make-page resource static-write) (string->bytes/utf-8 - (xexpr->string + (static-write + (fragment->page resource)))) + +(define (fragment->page resource) + (xexpr->string `(html ((lang "en")) ,(read (open-input-file "source/head.txt")) (body ,(read (open-input-file "source/header.txt")) - (main ,(read (open-input-file resource)))))))) + (main ,(read (open-input-file resource))))))) + +(define (404-page) + (let ([static-path "static/page/not-found.html"]) + (html-response + (if (file-exists? static-path) + (static-file-res static-path) + (make-page "source/not-found.txt" (write-static-file static-path)))))) (define-values (page-app reverse-page-uri) (dispatch-rules - [("") (respond-resource-with-processor "" make-page)] - [("home") (respond-resource-with-processor "" make-page)] - [("settled") (respond-resource-with-processor "settled" make-page)] - [("settled" (integer-arg)) (respond-resource-with-processor "settled" make-page)] - [("unsettled") (respond-resource-with-processor "unsettled" make-page)] - [("unsettled" (integer-arg)) (respond-resource-with-processor "unsettled" make-page)] - [("tagged") (respond-resource-with-processor "tagged" make-page)] - [("tagged" (string-arg)) (respond-resource-with-processor "tagged" make-page)] - [((string-arg)) (respond-resource-with-processor "root" make-page)] - [else not-found])) + [("") (respond-resource-with-processor 'page "" make-page)] + [("home") (respond-resource-with-processor 'page "" make-page)] + [("settled") (respond-resource-with-processor 'page "settled" make-page)] + [("settled" (integer-arg)) (respond-resource-with-processor 'page "settled" make-page)] + [("unsettled") (respond-resource-with-processor 'page "unsettled" make-page)] + [("unsettled" (integer-arg)) (respond-resource-with-processor 'page "unsettled" make-page)] + [("tagged") (respond-resource-with-processor 'page "tagged" make-page)] + [("tagged" (string-arg)) (respond-resource-with-processor 'page "tagged" make-page)] + [((string-arg)) (respond-resource-with-processor 'page "root" make-page)] + [else (lambda (req) (404-page))])) @@ -152,8 +234,7 @@ ;;; 404 (define (not-found request) - (html-response (make-page "source/not-found.txt"))) - + (lambda (req) ((404-page)))) ;;; server (define stop diff --git a/static/fragment/root/not-found.html b/static/fragment/root/not-found.html deleted file mode 100644 index 2d60e1a..0000000 --- a/static/fragment/root/not-found.html +++ /dev/null @@ -1 +0,0 @@ -

404

hey, i couldn't find that. could ya try something else maybe?

\ No newline at end of file diff --git a/static/page/root/index.html b/static/page/root/index.html deleted file mode 100644 index 3cb93d1..0000000 --- a/static/page/root/index.html +++ /dev/null @@ -1,53 +0,0 @@ -learning and making things

hey! i'm sorrel.

(called like the plant up there)

this is my new-fangled website computer page on the world wide web. i had - a nice time building this little thing (how i build this little page.)

i hope you have a nice time looking at things here.

︿︿ - 〰

\ No newline at end of file diff --git a/static/page/root/not-found.html b/static/page/root/not-found.html deleted file mode 100644 index d79988f..0000000 --- a/static/page/root/not-found.html +++ /dev/null @@ -1,48 +0,0 @@ -learning and making things

404

hey, i couldn't find that. could ya try something else maybe?

\ No newline at end of file