=== 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(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;