From c4352d64a25d2c5d297d433320df05a5181fee2e Mon Sep 17 00:00:00 2001 From: Colin Okay Date: Fri, 4 Feb 2022 14:56:48 -0600 Subject: initial work developing hunchentoot backend --- lazybones-hunchentoot.lisp | 105 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) (limited to 'lazybones-hunchentoot.lisp') diff --git a/lazybones-hunchentoot.lisp b/lazybones-hunchentoot.lisp index f9c0af6..9d91b54 100644 --- a/lazybones-hunchentoot.lisp +++ b/lazybones-hunchentoot.lisp @@ -1,2 +1,107 @@ ;;;; lazybones-hunchentoot.lisp -- hunchentoot backend for lazybones +(defpackage #:lazybones.backend/hunchentoot + (:use #:cl #:lazybones.backend) + (:local-nicknames (#:h #:hunchentoot ))) + +(in-package :lazybones.backend/hunchentoot) + +(defun request-path (request) + "Returns the PATH part of the REQUEST URL. + +See Also: https://en.wikipedia.org/wiki/URL#Syntax." + (h:script-name request)) + +(defun request-host (request) + "Returns the HOST part of the REQUEST URL. + +See Also: https://en.wikipedia.org/wiki/URL#Syntax" + (h:host request)) + +(defun request-url (request) + "Returns the full url of REQUST" + (h:request-uri* request)) + +(defun request-port (request) + "The port associated with REQUEST." + (h:local-port* request)) + +(defun request-query-string (request) + "Returns the full query string of the URL associated with REQUEST + +See Also: https://en.wikipedia.org/wiki/URL#Syntax" + (h:query-string request)) + +(defun request-parameter (name request) + "Returns the the value of the query parameter named NAME, or NIL + if there there is none." + (h:get-parameter name request)) + +(defun request-parameters (request) + "Returns an alist of parameters associated with REQUEST. Each +member of the list looks like (NAME . VALUE) where both are strings." + (h:get-parameters request)) + +(defun request-headers (request) + "Returns an alist of headers associated with REQUEST. Each member of +the list looks like (HEADER-NAME . VALUE) where HEADER-NAME is a +keyword or a string and VALUE is a string." + (h:headers-in request)) + +(defun request-header (header-name request) + "Returns the string value of the REQUEST header named HEADER-NAME. +HEADER-NAME can be a keyword or a string." + (h:header-in header-name request)) + +(defun request-method (request) + "Returns a keyword representing the http method of the request." + (h:request-method request)) + +(defparameter +hunchentoot-pre-decoded-content-types+ + '("multipart/form-data" "application/x-www-form-urlencoded")) + +(defun pre-decoded-body-p (request) + (member (request-header :content-type request) + +hunchentoot-pre-decoded-content-types+ + :test #'string-equal)) + +(defparameter +hunchentoot-methods-with-body+ + '(:post :put :patch)) + +(defun request-body (request &key (want-stream-p nil)) + "Returns the decoded request body. The value returned depends upon +the value of the Content-Type request header." + (when (member (request-method request) +hunchentoot-methods-with-body+) + (let ((pre-decoded-body-p + (pre-decoded-body-p request)) + (content-type + (request-header :content-type request))) + (cond + ;; try to get a stream on request + (want-stream-p + ;; can't do it if the body is already decoded - return nil so + ;; that request-body can be called again + (unless pre-decoded-body-p + (h:raw-post-data :request request :want-stream t))) + + (pre-decoded-body-p + (format-as-lazybones-document + (h:post-parameters request))) + + ((string-equal "application/json" content-type) + (jonathan:parse + (h:raw-post-data :request request :external-format :utf8 ))) ; TODO don't hardcode the format + + (t + ;; default case is to return a bytevector + (h:raw-post-data :request request :force-binary t)))))) + +(defun format-as-lazybones-document (post-parameters) + "internal function. Formats all the post parmaeters (see docstring + on hunchentoot:post-parameters) into a plist with keyword keys, as + is the convention for lazybones." + (loop for (k . value) in post-parameters + collect (alexandria:make-keyword k) + collect value)) + + -- cgit v1.2.3