Permalink
Browse files

allows Clack.Handler.Fcgi to handle delayed body. this feature is

required for streaming.
  • Loading branch information...
fukamachi committed Mar 18, 2012
1 parent a436708 commit 92b83d7a572df1a0fb5c4e3f9bb484348566a48b
Showing with 21 additions and 11 deletions.
  1. +21 −11 src/core/handler/fcgi.lisp
View
@@ -42,24 +42,25 @@
(lambda ()
(cl-fastcgi::server-on-fd
#'(lambda (req)
- (let ((env (request->plist req)))
- (handle-response
- req
- (if debug (call app env)
- (aif (handler-case (call app env)
- (condition (error)
- @ignore error
- nil))
- it
- '(500 nil nil))))))
+ (let* ((env (request->plist req))
+ (res (if debug (call app env)
+ (aif (handler-case (call app env)
+ (condition (error)
+ @ignore error
+ nil))
+ it
+ '(500 nil nil)))))
+ (etypecase res
+ (list (handle-response req res))
+ (function (funcall res (lambda (res) (handle-response req res)))))))
(cl-fastcgi::usocket-to-fd sock)))))))
@export
(defun stop (acceptor)
(usocket:socket-close acceptor))
(defun handle-response (req res)
- (destructuring-bind (status headers body) res
+ (destructuring-bind (status headers &optional body) res
(fcgx-puts req (format nil "Status: ~D ~A~%" status (gethash status *http-status*)))
(loop for (k v) on headers by #'cddr
with hash = (make-hash-table :test #'eq)
@@ -74,6 +75,15 @@
do (fcgx-puts req (format nil "~:(~A~): ~A~%" k v))))
(fcgx-puts req #.(format nil "~%"))
(etypecase body
+ (null
+ ;; TODO: This should return a object which can write & close.
+ ;; Currently returns a function only for writing.
+ (lambda (body)
+ (fcgx-puts req body)
+ ;; XXX: cl-fastcgi doesn't provide `fcgx-flush' now.
+ (cffi:foreign-funcall "FCGX_FFlush"
+ :pointer (cffi:foreign-slot-value req 'cl-fastcgi::fcgx-request 'cl-fastcgi::out)
+ :int)))
(pathname
(with-open-file (in body
:direction :input

0 comments on commit 92b83d7

Please sign in to comment.