1
0
mirror of https://github.com/golang/go synced 2024-11-20 07:44:41 -07:00

http: fix text displayed in Redirect

In the case where r.Method == "POST", was
calling Printf with an argument but "" format string,
causing a spurious %!EXTRA(...) message.

Also escape string properly in HTML generation.

R=r
CC=golang-dev
https://golang.org/cl/3923043
This commit is contained in:
Russ Cox 2011-01-11 17:15:28 -05:00
parent 3a43ff1a77
commit cc928b7b6e

View File

@ -452,58 +452,63 @@ func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
// 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(w ResponseWriter, r *Request, url string, code int) { func Redirect(w ResponseWriter, r *Request, url string, code int) {
if u, err := ParseURL(url); err == nil {
// If url was relative, make absolute by
// combining with request path.
// The browser would probably do this for us,
// but doing it ourselves is more reliable.
// NOTE(rsc): RFC 2616 says that the Location
// line must be an absolute URI, like
// "http://www.google.com/redirect/",
// not a path like "/redirect/".
// Unfortunately, we don't know what to
// put in the host name section to get the
// client to connect to us again, so we can't
// know the right absolute URI to send back.
// Because of this problem, no one pays attention
// to the RFC; they all send back just a new path.
// So do we.
oldpath := r.URL.Path
if oldpath == "" { // should not happen, but avoid a crash if it does
oldpath = "/"
}
if u.Scheme == "" {
// no leading http://server
if url == "" || url[0] != '/' {
// make relative path absolute
olddir, _ := path.Split(oldpath)
url = olddir + url
}
// clean up but preserve trailing slash
trailing := url[len(url)-1] == '/'
url = path.Clean(url)
if trailing && url[len(url)-1] != '/' {
url += "/"
}
}
}
w.SetHeader("Location", url)
w.WriteHeader(code)
// RFC2616 recommends that a short note "SHOULD" be included in the // RFC2616 recommends that a short note "SHOULD" be included in the
// response because older user agents may not understand 301/307. // response because older user agents may not understand 301/307.
note := "<a href=\"%v\">" + statusText[code] + "</a>.\n" note := "<a href=\"" + htmlEscape(url) + "\">" + statusText[code] + "</a>.\n"
if r.Method == "POST" { if r.Method == "POST" {
note = "" note = ""
} }
fmt.Fprintln(w, note)
}
u, err := ParseURL(url) func htmlEscape(s string) string {
if err != nil { s = strings.Replace(s, "&", "&amp;", -1)
goto finish s = strings.Replace(s, "<", "&lt;", -1)
} s = strings.Replace(s, ">", "&gt;", -1)
s = strings.Replace(s, "\"", "&quot;", -1)
// If url was relative, make absolute by s = strings.Replace(s, "'", "&apos;", -1)
// combining with request path. return s
// The browser would probably do this for us,
// but doing it ourselves is more reliable.
// NOTE(rsc): RFC 2616 says that the Location
// line must be an absolute URI, like
// "http://www.google.com/redirect/",
// not a path like "/redirect/".
// Unfortunately, we don't know what to
// put in the host name section to get the
// client to connect to us again, so we can't
// know the right absolute URI to send back.
// Because of this problem, no one pays attention
// to the RFC; they all send back just a new path.
// So do we.
oldpath := r.URL.Path
if oldpath == "" { // should not happen, but avoid a crash if it does
oldpath = "/"
}
if u.Scheme == "" {
// no leading http://server
if url == "" || url[0] != '/' {
// make relative path absolute
olddir, _ := path.Split(oldpath)
url = olddir + url
}
// clean up but preserve trailing slash
trailing := url[len(url)-1] == '/'
url = path.Clean(url)
if trailing && url[len(url)-1] != '/' {
url += "/"
}
}
finish:
w.SetHeader("Location", url)
w.WriteHeader(code)
fmt.Fprintf(w, note, url)
} }
// Redirect to a fixed URL // Redirect to a fixed URL