1
0
mirror of https://github.com/golang/go synced 2024-11-26 00:48:01 -07:00

Allow http.Redirect to do both temporary (307) and permanent (301) redirects.

This also adds a missing 'return' when a malformed URL is passed to it.

R=rsc
APPROVED=rsc
DELTA=30  (13 added, 2 deleted, 15 changed)
OCL=28598
CL=28710
This commit is contained in:
David Symonds 2009-05-12 15:41:19 -07:00
parent a8f6e38bce
commit 6c384d2268
3 changed files with 28 additions and 17 deletions

View File

@ -78,7 +78,7 @@ func serveFileInternal(c *Conn, r *Request, name string, redirect bool) {
// redirect to strip off any index.html // redirect to strip off any index.html
n := len(name) - len(indexPage); n := len(name) - len(indexPage);
if n >= 0 && name[n:len(name)] == 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; return;
} }
@ -103,12 +103,12 @@ func serveFileInternal(c *Conn, r *Request, name string, redirect bool) {
url := r.Url.Path; url := r.Url.Path;
if d.IsDirectory() { if d.IsDirectory() {
if url[len(url)-1] != '/' { if url[len(url)-1] != '/' {
http.Redirect(c, url + "/"); http.Redirect(c, url + "/", StatusMovedPermanently);
return; return;
} }
} else { } else {
if url[len(url)-1] == '/' { if url[len(url)-1] == '/' {
http.Redirect(c, url[0:len(url)-1]); http.Redirect(c, url[0:len(url)-1], StatusMovedPermanently);
return; return;
} }
} }

View File

@ -278,12 +278,17 @@ func NotFoundHandler() Handler {
// Redirect replies to the request with a redirect to url, // Redirect replies to the request with a redirect to url,
// which may be a path relative to the request path. // 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); u, err := ParseURL(url);
if err != nil { if err != nil {
// TODO report internal error instead? goto finish
c.SetHeader("Location", url);
c.WriteHeader(StatusMovedPermanently);
} }
// If url was relative, make absolute by // If url was relative, make absolute by
@ -322,20 +327,26 @@ func Redirect(c *Conn, url string) {
} }
} }
finish:
c.SetHeader("Location", url); c.SetHeader("Location", url);
c.WriteHeader(StatusMovedPermanently); c.WriteHeader(code);
fmt.Fprintf(c, note, url);
} }
// Redirect to a fixed URL // Redirect to a fixed URL
type redirectHandler string type redirectHandler struct {
func (url redirectHandler) ServeHTTP(c *Conn, req *Request) { url string;
Redirect(c, string(url)); code int;
}
func (rh *redirectHandler) ServeHTTP(c *Conn, req *Request) {
Redirect(c, rh.url, rh.code);
} }
// RedirectHandler returns a request handler that redirects // RedirectHandler returns a request handler that redirects
// each request it receives to the given url. // each request it receives to the given url using the given
func RedirectHandler(url string) Handler { // status code.
return redirectHandler(url); func RedirectHandler(url string, code int) Handler {
return &redirectHandler{ url, code }
} }
// ServeMux is an HTTP request multiplexer. // ServeMux is an HTTP request multiplexer.
@ -441,10 +452,10 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
mux.m[pattern] = handler; mux.m[pattern] = handler;
// Helpful behavior: // Helpful behavior:
// If pattern is /tree/, insert redirect for /tree. // If pattern is /tree/, insert permanent redirect for /tree.
n := len(pattern); n := len(pattern);
if n > 0 && pattern[n-1] == '/' { if n > 0 && pattern[n-1] == '/' {
mux.m[pattern[0:n-1]] = RedirectHandler(pattern); mux.m[pattern[0:n-1]] = RedirectHandler(pattern, StatusMovedPermanently);
} }
} }

View File

@ -585,7 +585,7 @@ func servePkg(c *http.Conn, r *http.Request) {
/* /*
// TODO do we still need this? // TODO do we still need this?
if r.Url.Path != Pkg + info.Path { if r.Url.Path != Pkg + info.Path {
http.Redirect(c, info.Path); http.Redirect(c, info.Path, http.StatusMovedPermanently);
return; return;
} }
*/ */