[hunchentoot-devel] header(s)-out

Robert J. Macomber tbnl at rojoma.com
Thu Nov 9 21:55:58 UTC 2006


[oops, originally sent this to tbnl at ... hope that's not a different
list or person.  Hasn't bounced in any case.]

There seems to be some small bugs involving header-out.  The accessor
is documented to take both keywords and strings, but neither works
reliably because:
  The reader will use string-equal if given a string and eq if given a
  symbol, because of the assoc shadowing in the hunchentoot package.
  This will find what it's looking for if it's given a string or if
  it's given a keyword _and_ the header entry was originally created
  with a keyword.

  The writer will do the same, so it's possible to have two different
  entries for any given header in the headers-out list, one for a
  string entry and one for a symbol.  (The code _looks_ like it does
  the right thing, but if "name" is a symbol, it calls the
  symbol-specialized version of assoc which ignores its test
  argument).

Finally, if a header-out entry is created with a symbol, response
generation fails because it uses write-string (or write-line with
mod-lisp) to output the header name, and they don't take string
designators.

Here's a patch which normalizes things so the keys of this alist are
always strings and the lookup is always done with strings.  It uses
string-capitalize to convert keywords when storing in order to make
them have conventional HTTP header capitalization.

--- hunchentoot-0.4.8.orig/reply.lisp	2006-11-05 15:55:06.000000000 -0700
+++ hunchentoot-0.4.8/reply.lisp	2006-11-08 15:40:15.000000000 -0700
@@ -115,7 +115,7 @@
 (defun header-out (name &optional (reply *reply*))
   "Returns the current value of the outgoing http header named NAME.
 NAME should be a keyword or a string."
-  (cdr (assoc name (headers-out reply))))
+  (cdr (assoc (string name) (headers-out reply))))
 
 (defun cookie-out (name &optional (reply *reply*))
   "Returns the current value of the outgoing cookie named
@@ -129,7 +129,8 @@
 created."
   (with-rebinding (name reply)
     (with-unique-names (place)
-      `(let ((,place (assoc ,name (headers-out ,reply) :test #'string-equal)))
+      `(let* ((,name (if (stringp ,name) ,name (string-capitalize ,name)))
+              (,place (assoc ,name (headers-out ,reply))))
          (cond
            (,place
             (setf (cdr ,place) ,new-value))

-- 
Robert Macomber
tbnl at rojoma.com



More information about the Tbnl-devel mailing list