(defpackage :fwoar.websocket-acceptor (:use :cl ) (:export #:websocket-acceptor #:find-websocket-resource)) (in-package :fwoar.websocket-acceptor) (defclass websocket-acceptor (hunchensocket:websocket-acceptor) ()) (defgeneric find-websocket-resource (acceptor request)) (defmethod hunchentoot:acceptor-dispatch-request ((acceptor websocket-acceptor) (request hunchensocket::websocket-request)) "Attempt WebSocket connection, else fall back to HTTP. Override version in hunchensocket to provide a better route-finding experience" (cond ((and (member "upgrade" (cl-ppcre:split "\\s*,\\s*" (hunchentoot:header-in* :connection)) :test #'string-equal) (string= "websocket" (string-downcase (hunchentoot:header-in* :upgrade)))) (cond ((setf (hunchensocket:websocket-resource hunchentoot:*request*) (find-websocket-resource acceptor hunchentoot:*request*)) (hunchensocket::handle-handshake acceptor hunchentoot:*request* hunchentoot:*reply*) (values "" nil nil)) (t ;; Didn't find the websocket-specific resource, return 404. (setf (hunchentoot:return-code hunchentoot:*reply*) hunchentoot:+http-not-found+) (values nil nil nil)))) (t (call-next-method))))