redirect - 使用基本身份验证返回 401 而不是 301 重定向的 HTTP 请求

标签 redirect curl go

使用 Go 1.5.1。

当我尝试向使用 Basic Auth 自动重定向到 HTTPS 的站点发出请求时,我希望得到 301 重定向响应,但我得到的是 401。

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)

}

请注意,curl 返回 301:

curl -vvv http://aerolith.org/files --user cesar:password

知道可能出了什么问题吗?

最佳答案

http://aerolith.org/files 的请求重定向到 https://aerolith.org/files(注意从 http 更改为 https)。对 https://aerolith.org/files 的请求重定向到 https://aerolith.org/files/(注意尾随/的添加)。

Curl 不遵循重定向。 Curl 打印从 http://aerolith.org/fileshttps://aerolith.org/files/ 的重定向的 301 状态。

Go 客户端遵循这两个重定向到 https://aerolith.org/files/。对 https://aerolith.org/files/ 的请求返回状态 401,因为 Go 客户端不会通过重定向传播授权 header 。

从 Go 客户端向 https://aerolith.org/files/ 发出请求,Curl 返回状态 200。

如果你想跟随重定向并成功认证,在 CheckRedirect 中设置 auth header功能:

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)
}

关于redirect - 使用基本身份验证返回 401 而不是 301 重定向的 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32751065/

相关文章:

将 CloudFlare 上的子域重定向到 Google 日历

apache - 将 URL 重定向到另一个 URL

go - 如何将curl通过管道传输到Go程序中?

json - 我可以从 http.ResponseWriter 获得 io.Writer 吗?

go - 如何通过reflect.TypeOf(interface{})从struct迭代*T funcs?

go - 仅从 YAML 配置文件加载一个部分

javascript - 如何从 JSON 响应重定向?

apache - htaccess 一个 RewriteCond 用于多个 RewriteRules?

bash - CURL 转义单引号

python - 使用 curl 将文件上传到 python flask 服务器