Mercurial > core / lisp/lib/net/srv.lisp
changeset 698: |
96958d3eb5b0 |
parent: |
7a5d6e45de7a
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; net/srv.lisp --- Lisp Web Services 3 ;; This library contains provides a Web Server abstraction a la Hunchentoot or 8 ;; The code in this file is meant to be small. We want to leverage the core 9 ;; ecosystem and internal NET/* packages to build high-level abstractions that 10 ;; are still useful with minimal boilerplate. 12 ;; In other words we want to support both these use-cases in the least amount 15 (srv:start (srv:file-server)) ;; start a simple HTTP file server in current 16 ;; directory with all default values 18 (srv:define-service my-homepage (:port 8080 19 :auth (auth settings ...) 22 (with-ws (ws 'my-homepage) 26 ;; not considering SSL currently - not a core object type but perhaps subclass 28 ;; mostly following the implementation of hunchentoot with attempts at 38 (defvar-unbound *request*) 39 (defvar-unbound *response*) 40 (defvar *global-session-db* nil) 41 (defvar *global-session-db-lock* (make-mutex :name "global-session-db")) 42 (defvar *default-connection-timeout* 20) 43 (defvar *default-service-port* 8000) 44 #+ssl (defvar *default-ssl-service-port* 8000) 45 (defvar *default-session-timeout* #.(* 30 60)) ;; 30m 46 (defvar *default-content-type* "text/html") 49 (define-condition srv-condition (condition) ()) 50 (deferror srv-error (srv-condition error) () ()) 51 (deferror srv-simple-error (srv-error simple-condition) () (:auto t)) 53 (define-condition srv-warning (srv-condition warning) ()) 54 (define-condition srv-simple-warning (srv-warning simple-condition) ()) 56 (deferror bad-request (srv-error) ()) 59 (eval-when (:load-toplevel :compile-toplevel :execute) 60 (defun default-web-directory (&optional sub-directory) 61 (let ((source-directory #.(or *compile-file-truename* *load-truename*))) 62 (merge-pathnames (make-pathname :directory (append (pathname-directory source-directory) 65 (list sub-directory))) 68 :defaults source-directory))))) 71 (defgeneric start-service (self) 72 (:documentation "Start a service.")) 74 (defgeneric stop-service (self) 75 (:documentation "Stop a service.")) 77 (defgeneric restart-service (self) 78 (:documentation "Restart a service.") 81 (start-service self))) 83 (defgeneric add-route (self uri handler &key &allow-other-keys)) 84 (defgeneric delete-route (self uri &key &allow-other-keys)) 85 (defgeneric handle-request (self request)) 86 (defgeneric service-name (self) 91 (defclass service-response () ()) 92 (defclass http-service-response (service-response) ((response :type http-response))) 95 (defclass service-request () 96 ((origin :initarg :origin 97 :reader request-origin) 98 (session :initform nil 101 (defclass http-service-request (service-request) 102 ((request :type http-request))) 106 ;; HACK 2024-07-18: currently not storing the SESSION-STRING directly in this 107 ;; class as a slot. may need to change but I would rather have the string 108 ;; cached/displaced to some other location.. depends how often we need that 110 (defclass session (obj/id:id) 117 (max-time :type fixnum)) 119 :session-start (get-universal-time) 120 :last-click (get-universal-time) 121 :max-time *default-session-timeout*)) 126 (defclass router () ()) 129 ;; Multithreaded runtime for services 130 (define-task-kernel service-task-kernel () () 131 "Default task kernel for service-based tasks.") 133 (defclass service-engine () 134 ((task-pool :type task-pool))) 136 ;; supervisor, worker, task, kernel 138 (defclass service (obj/id:id) 141 ;; HACK 2024-07-18: will this only accept class names? are structures classes? (http-request, http-response) 142 (request-class :type symbol) 143 (response-class :type symbol) 144 (engine :type service-engine) 145 (read-timeout :type fixnum) 146 (write-timeout :type fixnum) 147 (connection-max :type fixnum) 148 ;; RESEARCH 2024-07-18: 149 ;; may need to start dealing with this 150 ;; https://datatracker.ietf.org/doc/html/rfc2616#section-3.6.1 151 (chunk-output-p :type boolean) 152 (chunk-input-p :type boolean) 153 (socket :type socket) 154 (request-count :type integer) 155 (shutdown-lock :type mutex) 156 (shutdown-queue :type waitqueue)) 158 :id (symbol-name (gensym "srv")) 159 :port *default-service-port* 161 :request-class 'service-request 162 :response-class 'service-response 165 :read-timeout *default-connection-timeout* 166 :write-timeout *default-connection-timeout* 168 :shutdown-lock (sb-thread:make-mutex :name "shutdown-lock") 169 :shutdown-queue (sb-thread:make-waitqueue :name "shutdown-queue")) 170 (:documentation "The service class is designed primarily for webservers and functionally 171 similar to HUNCHENTOOT:ACCEPTOR.")) 174 (defclass ssl-service (service) 175 ((certificate-file :initarg :certificate-file 176 :reader service-certificate-file) 177 (privatekey-file :initarg :privatekey-file 178 :reader service-privatekey-file) 179 (privatekey-password :initarg :privatekey-password 180 :reader service-privatekey-password)) 186 (defmacro define-service (name &rest initargs) 187 "Define a subclass of NET/SRV:SERVICE." 188 `(defclass ,name ,@initargs))