// redirect to strip off any index.html
n := len(name) - len(indexPage);
if n >= 0 && name[n:len(name)] == indexPage {
- http.Redirect(c, name[0:n+1]);
+ http.Redirect(c, name[0:n+1], StatusMovedPermanently);
return;
}
url := r.Url.Path;
if d.IsDirectory() {
if url[len(url)-1] != '/' {
- http.Redirect(c, url + "/");
+ http.Redirect(c, url + "/", StatusMovedPermanently);
return;
}
} else {
if url[len(url)-1] == '/' {
- http.Redirect(c, url[0:len(url)-1]);
+ http.Redirect(c, url[0:len(url)-1], StatusMovedPermanently);
return;
}
}
// Redirect replies to the request with a redirect to url,
// which may be a path relative to the request path.
-func Redirect(c *Conn, url string) {
+func Redirect(c *Conn, url string, code int) {
+ // RFC2616 recommends that a short note "SHOULD" be included in the
+ // response because older user agents may not understand 301/307.
+ note := "<a href=\"%v\">" + statusText[code] + "</a>.\n";
+ if c.Req.Method == "POST" {
+ note = "";
+ }
+
u, err := ParseURL(url);
if err != nil {
- // TODO report internal error instead?
- c.SetHeader("Location", url);
- c.WriteHeader(StatusMovedPermanently);
+ goto finish
}
// If url was relative, make absolute by
}
}
+finish:
c.SetHeader("Location", url);
- c.WriteHeader(StatusMovedPermanently);
+ c.WriteHeader(code);
+ fmt.Fprintf(c, note, url);
}
// Redirect to a fixed URL
-type redirectHandler string
-func (url redirectHandler) ServeHTTP(c *Conn, req *Request) {
- Redirect(c, string(url));
+type redirectHandler struct {
+ url string;
+ code int;
+}
+func (rh *redirectHandler) ServeHTTP(c *Conn, req *Request) {
+ Redirect(c, rh.url, rh.code);
}
// RedirectHandler returns a request handler that redirects
-// each request it receives to the given url.
-func RedirectHandler(url string) Handler {
- return redirectHandler(url);
+// each request it receives to the given url using the given
+// status code.
+func RedirectHandler(url string, code int) Handler {
+ return &redirectHandler{ url, code }
}
// ServeMux is an HTTP request multiplexer.
mux.m[pattern] = handler;
// Helpful behavior:
- // If pattern is /tree/, insert redirect for /tree.
+ // If pattern is /tree/, insert permanent redirect for /tree.
n := len(pattern);
if n > 0 && pattern[n-1] == '/' {
- mux.m[pattern[0:n-1]] = RedirectHandler(pattern);
+ mux.m[pattern[0:n-1]] = RedirectHandler(pattern, StatusMovedPermanently);
}
}