使用Go 1.5.1。
当我尝试向使用Basic Auth自动重定向到HTTPS的网站发出请求时,我希望获得301重定向响应,而不是我得到401。
this.get('settings').crud.read.defaults(); // "blah.blah"
请注意,curl返回301:
package main
import "net/http"
import "log"
func main() {
url := "http://aerolith.org/files"
username := "cesar"
password := "password"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Println("error", err)
}
if username != "" || password != "" {
req.SetBasicAuth(username, password)
log.Println("[DEBUG] Set basic auth to", username, password)
}
cli := &http.Client{
}
resp, err := cli.Do(req)
if err != nil {
log.Println("Do error", err)
}
log.Println("[DEBUG] resp.Header", resp.Header)
log.Println("[DEBUG] req.Header", req.Header)
log.Println("[DEBUG] code", resp.StatusCode)
}
知道可能出现什么问题吗?
答案 0 :(得分:5)
http://aerolith.org/files
重定向到https://aerolith.org/files
的请求(请注意从http更改为https)。请求https://aerolith.org/files
重定向到https://aerolith.org/files/
(请注意添加尾随/)。
Curl不遵循重定向。 Curl将重定向的301状态从http://aerolith.org/files
打印到https://aerolith.org/files/
。
Go客户端遵循两个重定向到https://aerolith.org/files/
。对https://aerolith.org/files/
的请求返回状态为401,因为Go客户端不会通过重定向传播授权标头。
来自Go客户端的https://aerolith.org/files/
请求和Curl返回状态200.
如果您想成功遵循重定向和身份验证,请在CheckRedirect函数中设置auth标头:
cli := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
req.SetBasicAuth(username, password)
return nil
}}
resp, err := cli.Do(req)
如果您想匹配Curl的作用,请直接使用transport。传输不遵循重定向。
resp, err := http.DefaultTransport.RoundTrip(req)
应用程序还可以使用客户端CheckRedirect函数和区分错误来防止重定向,如How Can I Make the Go HTTP Client NOT Follow Redirects Automatically?的答案所示。这种技术似乎有点流行,但比直接使用传输更复杂。
redirectAttemptedError := errors.New("redirect")
cli := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return redirectAttemptedError
}}
resp, err := cli.Do(req)
if urlError, ok := err.(*url.Error); ok && urlError.Err == redirectAttemptedError {
// ignore error from check redirect
err = nil
}
if err != nil {
log.Println("Do error", err)
}