[hunchentoot-devel] hunchentoot-cgi and the new hunchentoot regime
Cyrus Harmon
ch-tbnl at bobobeach.com
Sat Jul 19 20:40:20 UTC 2008
So... any input/suggestions on how to hack start-output to deal with
CGI-style content?
thanks,
Cyrus
On Jul 11, 2008, at 12:20 AM, Cyrus Harmon wrote:
> So... I'm trying to convert my hunchentoot-cgi over to the new
> hunchentoot and running into some problems. My old approach was to do:
>
> (progn
> (let* ((return-code (tbnl::return-code))
> (reason-phrase (reason-phrase return-code))
> (first-line
> (format nil "HTTP/1.1 ~D ~A" return-code reason-
> phrase)))
> (write-sequence (map 'list #'char-code first-line) out)
> (write-sequence tbnl::+crlf+ out)
> (tbnl::maybe-write-to-header-stream first-line))
> (setf tbnl::*headers-sent* t)
> (setf (tbnl::content-type) nil)
> (sb-ext::run-program path nil :output out :environment env)
> nil)
>
>
> but this doesn't seem to work anymore. My new approach is to try to
> use send-headers, but with some hackery to make it optionally more
> cgi-friendly:
> Index: headers.lisp
> ===================================================================
> --- headers.lisp (revision 3423)
> +++ headers.lisp (working copy)
> @@ -70,6 +70,8 @@
> (:method (key value)
> (write-header-line key (princ-to-string value))))
> +(defparameter *cgi-hack* nil)
> +
> (defun start-output (&key (content nil content-provided-p)
> (request *request*))
> "Sends all headers and maybe the content body to
> @@ -84,7 +86,8 @@
> ;; Read post data to clear stream - Force binary mode to avoid
> OCTETS-TO-STRING overhead.
> (raw-post-data :force-binary t)
> (let* ((return-code (return-code))
> - (chunkedp (and (server-output-chunking-p *server*)
> + (chunkedp (and (not *cgi-hack*)
> + (server-output-chunking-p *server*)
> (eq (server-protocol request) :http/1.1)
> ;; only turn chunking on if the content
> ;; length is unknown at this point...
> @@ -196,12 +199,14 @@
> ;; write all headers from the REPLY object
> (loop for (key . value) in (headers-out)
> when value
> - do (write-header-line (as-capitalized-string key) value))
> + do (unless (and *cgi-hack* (equal key :content-type))
> + (write-header-line (as-capitalized-string key) value)))
> ;; now the cookies
> (loop for (nil . cookie) in (cookies-out)
> do (write-header-line "Set-Cookie" (stringify-cookie cookie)))
> ;; all headers sent
> - (write-sequence +crlf+ *hunchentoot-stream*)
> + (unless *cgi-hack*
> + (write-sequence +crlf+ *hunchentoot-stream*))
> (maybe-write-to-header-stream "")
> ;; access log message
> (when-let (access-logger (server-access-logger *server*))
>
>
>
> The motivation for this hack being that the CGI script wants to send
> the content-type header, so we can't finish the headers here when
> running a CGI script.
>
> Then I can do:
>
> (let* ((tbnl::*cgi-hack* t) (stream (flexi-
> streams:make-flexi-stream
> (tbnl:send-headers)
> :external-format tbnl::+latin-1+)))
> (sb-ext::run-program path nil :output stream :environment env))
>
>
> and this sort of works, but, 1) it's kind of a hack and 2) it either
> exacerbates the timeout situation or there's some other problem
> where the first request is handled promptly, but subsequent requests
> to 10 seconds or so while something times out. Not sure why this
> would be.
>
> any thoughts on a good way to handle this?
>
> thanks,
>
> Cyrus
>
> _______________________________________________
> tbnl-devel site list
> tbnl-devel at common-lisp.net
> http://common-lisp.net/mailman/listinfo/tbnl-devel
More information about the Tbnl-devel
mailing list