awful-sse/awful-sse.scm

72 lines
3 KiB
Scheme
Raw Normal View History

2014-07-08 02:13:58 +00:00
;; Copyright (c) 2010-2014, Arthur Maciel
2014-07-08 02:01:53 +00:00
;; All rights reserved.
;;
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following conditions
;; are met:
;; 1. Redistributions of source code must retain the above copyright
;; notice, this list of conditions and the following disclaimer.
;; 2. Redistributions in binary form must reproduce the above copyright
;; notice, this list of conditions and the following disclaimer in the
;; documentation and/or other materials provided with the distribution.
;; 3. The name of the authors may not be used to endorse or promote products
;; derived from this software without specific prior written permission.
;;
;; THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
;; IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
;; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(module awful-sse
(define-page/sse send-sse-data send-sse-retry)
(import scheme chicken data-structures extras posix)
(use awful spiffy intarweb)
2014-07-08 02:37:35 +00:00
(define (add-sse-resource! sse-path sse-proc vhost-root-path client-path)
(add-resource! sse-path
2014-07-08 02:01:53 +00:00
(or vhost-root-path (root-path))
(lambda (#!optional given-path)
(let ((accept (header-values 'accept
(request-headers (current-request)))))
2014-07-08 02:37:35 +00:00
;; If client 'EventSource' JS code requested SSE page...
2014-07-08 02:01:53 +00:00
(if (memq 'text/event-stream accept)
2014-07-08 02:37:35 +00:00
;; ...complete handshake and keep connection alive with 'sse-proc'.
(lambda ()
2014-07-08 02:01:53 +00:00
(with-headers '((content-type text/event-stream)
(cache-control no-cache)
(connection keep-alive))
(lambda ()
(write-logged-response)
2014-07-08 02:37:35 +00:00
(sse-proc))))
(redirect-to client-path))))
2014-07-08 02:01:53 +00:00
'GET))
2014-07-08 02:37:35 +00:00
(define (define-page/sse path contents sse-path sse-proc #!rest rest)
(apply define-page (append (list path contents) rest))
(add-sse-resource! sse-path sse-proc (get-keyword vhost-root-path: rest) path))
2014-07-08 02:01:53 +00:00
(define (write-body data)
(display data (response-port (current-response)))
(finish-response-body (current-response)))
(define (send-sse-data data #!key event id)
(let ((msg (conc (if id (conc "id: " id "\n") "")
2014-07-08 02:37:35 +00:00
(if event (conc "event: " event "\n") "")
"data: " data "\n\n")))
2014-07-08 02:01:53 +00:00
(write-body msg)))
(define (send-sse-retry retry)
(write-body (conc "retry: " retry "\n\n")))
) ; End of module