diff -rN -u old-hunchentoot/doc/index.html new-hunchentoot/doc/index.html
--- old-hunchentoot/doc/index.html	2008-03-11 12:04:50.000000000 +0100
+++ new-hunchentoot/doc/index.html	2008-03-11 12:04:50.000000000 +0100
@@ -2127,7 +2127,7 @@
 which is active during the lifetime of a <a
 href='#handlers'>handler</a>. The handler can at any time <a
 href='http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_t.htm#throw'><em>throw</em></a>
-the outgoing content body (or <code>NIL</code>) to this catch to immediately abort handling the request. See the source code of <a href="#redirect"><code>REDIRECT</code></a> for an example.
+the outgoing content body (or <code>NIL</code>) to this catch to immediately abort handling the request. See the source code of <a href="#redirect*"><code>REDIRECT*</code></a> for an example.
 </blockquote>
 
 <p><br>[Function]
@@ -2196,6 +2196,32 @@
 </blockquote>
 
 <p><br>[Function]
+<br><a class=none name="redirect*"><b>redirect*</b> <i>target</i> <tt>&amp;key</tt> <i>host port protocol add-session-id code</i> =&gt; |</a>
+
+<blockquote><br> Sends back appropriate headers to redirect the client
+to <code><i>target</i></code> (a string).
+
+If <code><i>target</i></code> is a full URL starting with a scheme, <code><i>host</i></code>, <code><i>port</i></code>, and <code><i>protocol</i></code>
+are ignored.  Otherwise, <code><i>target</i></code> should denote the path part of a
+URL, <code><i>protocol</i></code> must be one of the keywords <code>:HTTP</code> or <code>:HTTPS</code>, and
+the URL to redirect to will be constructed from <code><i>host</i></code>, <code><i>port</i></code>, <code><i>protocol</i></code>,
+and <code><i>target</i></code>.
+<p>
+If <code><i>code</i></code> is a 3xx&nbsp;redirection code, it will be sent
+as status code.  In case of <code>NIL</code>, a 302&nbsp;status code
+will be sent to the client.
+If <code><i>host</i></code>
+is not provided, the current host (see <a
+href="#host"><code>HOST</code></a>) will be
+used. If <code><i>protocol</i></code> is the
+keyword <code>:HTTPS</code>, the client will be redirected to a https
+URL, if it's <code>:HTTP</code> it'll be sent to a http URL.  If
+both <code><i>host</i></code> and <code><i>protocol</i></code> aren't
+provided, then the value of <code><i>protocol</i></code> will
+match the current request.
+</blockquote>
+
+<p><br>[Function]
 <br><a class=none name="require-authorization"><b>require-authorization</b> <tt>&amp;optional</tt> <i>realm</i> =&gt; |</a>
 
 <blockquote><br> 
diff -rN -u old-hunchentoot/misc.lisp new-hunchentoot/misc.lisp
--- old-hunchentoot/misc.lisp	2008-03-11 12:04:50.000000000 +0100
+++ new-hunchentoot/misc.lisp	2008-03-11 12:04:50.000000000 +0100
@@ -232,13 +232,12 @@
         (t #-:hunchentoot-no-ssl (server-ssl-certificate-file *server*)
            #+:hunchentoot-no-ssl nil)))
 
-(defun redirect (target &key (host (host *request*) host-provided-p)
-                             port
-                             (protocol (if (ssl-p) :https :http))
-                             (add-session-id (not (or host-provided-p
-                                                      (starts-with-scheme-p target)
-                                                      (cookie-in *session-cookie-name*))))
-                             permanently)
+(defun redirect (target &rest args
+                 &key (host nil host-provided-p)
+                      (port nil port-provided-p)
+                      (protocol nil protocol-provided-p)
+                      (add-session-id nil add-session-id-provided-p)
+                      permanently)
   "Redirects the browser to TARGET which should be a string.  If
 TARGET is a full URL starting with a scheme, HOST, PORT and PROTOCOL
 are ignored.  Otherwise, TARGET should denote the path part of a URL,
@@ -246,6 +245,39 @@
 redirect to will be constructed from HOST, PORT, PROTOCOL, and TARGET.
 Adds a session ID if ADD-SESSION-ID is true.  If PERMANENTLY is true,
 a 301 request is sent to the browser, otherwise a 302."
+  (declare (ignore host port protocol add-session-id))
+  (setf args (remove-from-plist args :permanently
+                                (unless host-provided-p
+                                  :host)
+                                (unless port-provided-p
+                                  :port)
+                                (unless protocol-provided-p
+                                  :protocol)
+                                (unless add-session-id-provided-p
+                                  :add-session-id)))
+  (apply #'redirect* target
+         :code (if permanently
+                   +http-moved-permanently+
+                   +http-moved-temporarily+)
+         args))
+  
+(defun redirect* (target &key (host (host *request*) host-provided-p)
+                              port
+                              (protocol (if (ssl-p) :https :http))
+                              (add-session-id (not (or host-provided-p
+                                                       (starts-with-scheme-p target)
+                                                       (cookie-in *session-cookie-name*))))
+                              code)
+  "Redirects the browser to TARGET which should be a string.  If
+TARGET is a full URL starting with a scheme, HOST, PORT and PROTOCOL
+are ignored.  Otherwise, TARGET should denote the path part of a URL,
+PROTOCOL must be one of the keywords :HTTP or :HTTPS, and the URL to
+redirect to will be constructed from HOST, PORT, PROTOCOL, and TARGET.
+Adds a session ID if ADD-SESSION-ID is true.  If CODE is a 3xx
+redirection code, it will be sent as status code.  In case of NIL, a 
+302 status code will be sent to the client."
+  (setf code (or code +http-moved-temporarily+))
+  (check-type code (integer 300 399))
   (let ((url (if (starts-with-scheme-p target)
                target
                (format nil "~A://~A~@[:~A~]~A"
@@ -258,12 +290,8 @@
                        port target))))
     (when add-session-id
       (setq url (add-cookie-value-to-url url :replace-ampersands-p nil)))
-    (setf (header-out :location)
-            url
-          (return-code *reply*)
-            (if permanently
-              +http-moved-permanently+
-              +http-moved-temporarily+))
+    (setf (header-out :location) url
+          (return-code *reply*) code)
     (throw 'handler-done nil)))
 
 (defun require-authorization (&optional (realm "Hunchentoot"))
diff -rN -u old-hunchentoot/packages.lisp new-hunchentoot/packages.lisp
--- old-hunchentoot/packages.lisp	2008-03-11 12:04:50.000000000 +0100
+++ new-hunchentoot/packages.lisp	2008-03-11 12:04:50.000000000 +0100
@@ -187,6 +187,7 @@
            :reason-phrase
            :recompute-request-parameters
            :redirect
+           :redirect*
            :referer
            :remote-addr
            :remote-port
diff -rN -u old-hunchentoot/util.lisp new-hunchentoot/util.lisp
--- old-hunchentoot/util.lisp	2008-03-11 12:04:50.000000000 +0100
+++ new-hunchentoot/util.lisp	2008-03-11 12:04:50.000000000 +0100
@@ -29,6 +29,13 @@
 
 (in-package :hunchentoot)
 
+
+(defun remove-from-plist (plist &rest keys)
+  "Removes KEYS (including their values) from PLIST."
+  (loop for (key val) on plist by #'cddr
+        unless (member key keys)
+        collect key and collect val))
+
 #-:lispworks
 (defmacro when-let ((var form) &body body)
   "Evaluates FORM and binds VAR to the result, then executes BODY

