=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2010-11-18 08:01:53 +0000
+++ src/cf.data.pre	2010-11-19 14:08:43 +0000
@@ -5921,8 +5921,10 @@
 	by specifying TCP_RESET.
 
 	Or you can specify an error URL or URL pattern. The browsers will
-	get redirected (302) to the specified URL after formatting tags have
-	been replaced.
+	get redirected to the specified URL after formatting tags have
+	been replaced. Redirect will be done with 302 or 307 according to
+	HTTP/1.1 specs. A different 3xx code may be specified by prefixing
+	the URL. e.g. 303:http://example.com/
 
 	URL FORMAT TAGS:
 		%a	- username (if available. Password NOT included)

=== modified file 'src/errorpage.cc'
--- src/errorpage.cc	2010-11-01 05:44:28 +0000
+++ src/errorpage.cc	2010-11-19 14:03:37 +0000
@@ -76,6 +76,7 @@
 typedef struct {
     int id;
     char *page_name;
+    http_status page_redirect;
 } ErrorDynamicPageInfo;
 
 /* local constant and vars */
@@ -325,6 +326,9 @@
     ErrorDynamicPageInfo *info = new ErrorDynamicPageInfo;
     info->id = id;
     info->page_name = xstrdup(page_name);
+    info->page_redirect = static_cast<http_status>(atoi(page_name));
+    if (info->page_redirect < 300 || info->page_redirect > 399)
+        info->page_redirect = HTTP_STATUS_NONE;
     return info;
 }
 
@@ -894,6 +898,9 @@
     char const *p = m;
     char const *t;
 
+    if (m[0] == '3')
+        m += 4; // skip "3xx:"
+
     while ((p = strchr(m, '%'))) {
         result.append(m, p - m);       /* copy */
         t = Convert(*++p, true);       /* convert */
@@ -916,7 +923,19 @@
 
     if (strchr(name, ':')) {
         /* Redirection */
-        rep->setHeaders(HTTP_MOVED_TEMPORARILY, NULL, "text/html", 0, 0, -1);
+        http_status status;
+        // Use configured 3xx reply status if set.
+        if (name[0] == '3')
+            status = ErrorDynamicPages.items[page_id - ERR_MAX]->page_redirect;
+        else {
+            // Use 307 for HTTP/1.1 non-GET/HEAD requests.
+            if (request->method != METHOD_GET && request->method != METHOD_HEAD && request->http_ver >= HttpVersion(1,1))
+                status = HTTP_TEMPORARY_REDIRECT;
+            else
+                status = HTTP_MOVED_TEMPORARILY;
+        }
+
+        rep->setHeaders(status, NULL, "text/html", 0, 0, -1);
 
         if (request) {
             MemBuf redirect_location;

