在 Go 中有选择地遵循重定向

Selectively Follow Redirects in Go

我正在尝试编写一个 Twitter 阅读器来解决 link 缩短器等的最终 URLs,但在途中给了我一个 URL 手动列表定义的主机模式。这样做的原因是我不想以付费专区结束URL,而是之前的那个。

据我所知,这样做的方法是基于默认值 RoundTripper 编写我自己的客户端,因为从自定义 CheckRedirect 函数返回错误会中止客户端而不产生响应。

有没有办法使用默认 client 并通过自定义 checkRedirect 函数记录 URLs/specific URL 的列表?

如果您的自定义 CheckResponse 产生错误(如前所述在评论中)。

http://golang.org/pkg/net/http/#Client

If CheckRedirect returns an error, the Client's Get method returns both the previous Response and CheckRedirect's error (wrapped in a url.Error) instead of issuing the Request req.

如果您维护 "known" 付费专区 url 列表,您可以使用自定义 error 类型(PaywalledCheckResponse 中中止付费专区重定向下面的例子)。 您的错误处理代码稍后必须将该错误类型视为特殊(非错误)情况。

示例:

package main

import (
    "errors"
    "fmt"
    "net/http"
    "net/url"
)

var Paywalled = errors.New("next redirect would hit a paywall")

var badHosts = map[string]error{
    "registration.ft.com": Paywalled,
}

var client = &http.Client{
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
        // N.B.: when used in production, also check for redirect loops
        return badHosts[req.URL.Host]
    },
}

func main() {
    resp, err := client.Get("http://on.ft.com/14pQBYE")
    // ignore non-nil err if it's a `Paywalled` wrapped in url.Error
    if e, ok := err.(*url.Error); (ok && e.Err != Paywalled) || (!ok && err != nil) {
        fmt.Println("error: ", err)
        return
    }   
    resp.Body.Close()
    fmt.Println(resp.Request.URL)
}