Go-HTTP-RedirectHandler

u013344915 · · 1619 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Keywords: HandlerFunc, RedirectHandler, Redirect

前言

Go-http-HandlerFunc()函数中,详细介绍了HandlerFunc,所以本文换个方式来讲:从外往里一层层剥离,即先讲用户层面的API或使用方法,然后再介绍涉及的内部实现细节。

RedirectHandler实现代码

func Redirect(w ResponseWriter, r *Request, urlStr string, code int) {
    // Skipped now ...
}

// Redirect to a fixed URL
type redirectHandler struct {
    url  string
    code int
}

func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
    Redirect(w, r, rh.url, rh.code)
}

// RedirectHandler returns a request handler that redirects
// each request it receives to the given url using the given
// status code.
//
// The provided code should be in the 3xx range and is usually
// StatusMovedPermanently, StatusFound or StatusSeeOther.
func RedirectHandler(url string, code int) Handler {
    return &redirectHandler{url, code}
}

惯用法

用户可以看到的接口就是:

func RedirectHandler(url string, code int) Handler

示例

TODO 待补充

type redirectHandler

上面的源代码中,给出了type redirectHandler的定义。——redirectHandler也是Handler接口的一个实现。

Redirect()

redirectHandler具体类用到了Redirect()函数,源代码如下:

// Redirect replies to the request with a redirect to url,
// which may be a path relative to the request path.
//
// The provided code should be in the 3xx range and is usually
// StatusMovedPermanently, StatusFound or StatusSeeOther.
func Redirect(w ResponseWriter, r *Request, urlStr string, code int) {
    if u, err := url.Parse(urlStr); 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.
        if u.Scheme == "" && u.Host == "" {
            oldpath := r.URL.Path
            if oldpath == "" { // should not happen, but avoid a crash if it does
                oldpath = "/"
            }

            // no leading http://server
            if urlStr == "" || urlStr[0] != '/' {
                // make relative path absolute
                olddir, _ := path.Split(oldpath)
                urlStr = olddir + urlStr
            }

            var query string
            if i := strings.Index(urlStr, "?"); i != -1 {
                urlStr, query = urlStr[:i], urlStr[i:]
            }

            // clean up but preserve trailing slash
            trailing := strings.HasSuffix(urlStr, "/")
            urlStr = path.Clean(urlStr)
            if trailing && !strings.HasSuffix(urlStr, "/") {
                urlStr += "/"
            }
            urlStr += query
        }
    }

    w.Header().Set("Location", urlStr)
    w.WriteHeader(code)

    // RFC 2616 recommends that a short note "SHOULD" be included in the
    // response because older user agents may not understand 301/307.
    // Shouldn't send the response for POST or HEAD; that leaves GET.
    if r.Method == "GET" {
        note := "<a href=\"" + htmlEscape(urlStr) + "\">" + statusText[code] + "</a>.\n"
        fmt.Fprintln(w, note)
    }
}

var htmlReplacer = strings.NewReplacer(
    "&", "&amp;",
    "<", "&lt;",
    ">", "&gt;",
    // "&#34;" is shorter than "&quot;".
    `"`, "&#34;",
    // "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
    "'", "&#39;",
)

func htmlEscape(s string) string {
    return htmlReplacer.Replace(s)
}

待详细解释


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:u013344915

查看原文:Go-HTTP-RedirectHandler

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1619 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传