Open wnortje opened 8 years ago
You're right. I will do this at the earliest.
Thank you.
Wimpie Nortje Strongroom - Encrypted Photo Backup https://strongroom.me[1] Selective Share - Encryption-as-a-Service https://www.selectiveshare.com[2]
On Fri, Jan 29, 2016, at 01:30, Fernando Borretti wrote:
You're right. I will do this at the earliest.
— Reply to this email directly or view it on GitHub[3].
Links:
@wnortje (CC: @eudoxia0)
The response is taken by Lucerne which in turn sends the response to Clack. Clack then adapts the response headers/etc to send them to the particular server, for example Huntchentoot.
If you want to send additional information on the headers, here is where you need to put them: https://github.com/eudoxia0/lucerne/blob/master/src/http.lisp Line 19
(defun respond (body &key (type "text/html;charset=utf-8") (status 200))
"Construct a response from a @cl:param(body), content @cl:param(type) and
@cl:param(status) code."
(list status
(list :content-type type)
(typecase body
(string (list body))
(otherwise body))))
Of course, then modify the calls to respond() : For example you can pass more arguments to respond() in render-template by modifying: line 52 of the same file:
(defmacro render-template ((template) &rest args)
"Render a Djula template @cl:param(template-name) passing arguments
@cl:param(args)."
`(respond (djula:render-template* ,template
nil
,@args)))
The list where there is only one :content-type keyword-value pair, is a property list (plist) and can have more information that will be then sent on the header. For example :location, :content-length, :set-cookie. Now, this will be then sent to Clack and Clack will then adapt the header key-values to what the actual server used (i.e. Huntchentoot) will use.
For example, for huntchentoot: https://github.com/fukamachi/clack/blob/master/src/handler/hunchentoot.lisp Line 135-146:
(defun handle-response (res)
"Convert Response from Clack application into a string
before passing to Hunchentoot."
(let ((no-body '#:no-body))
(flet ((handle-normal-response (res)
(destructuring-bind (status headers &optional (body no-body)) res
(setf (return-code*) status)
(loop for (k v) on headers by #'cddr
if (eq k :set-cookie)
do (rplacd (last (headers-out*))
(list (cons k v)))
else if (eq k :content-type) do
(setf (content-type*) v)
else if (eq k :content-length) do
(setf (content-length*) v)
else if (header-out k) do
(setf (header-out k)
(format nil "~A, ~A" (header-out k) v))
else
do (setf (header-out k) v))
As you can see, other http header keywords should be accepted. In theory, any keyword. Huntchentoot docummentation:
http://weitz.de/hunchentoot/ HEADER-OUT returns the outgoing http header named by the keyword name if there is one, otherwise NIL. SETF of HEADER-OUT changes the current value of the header named name. If no header named name exists, it is created. .
Regards, Flavio.
It will be useful if
respond
can be used to set custom HTTP headers. At the moment I have to use a custom respond-like function everywhere I need to return custom headers.This will also address my original question in #13.