dongmeng2509 2019-07-18 14:01
浏览 20

为什么去http发布会获得与curl发布不同的结果?

I'm trying to implement a Rest API login process. I have verified the process with curl.

With curl, the following command will do the login:

$ curl -i -X POST  https://the-service.mycompany.com/login -d username=<my username> -d password=<mypassword>
HTTP/1.1 200 Connection established

HTTP/1.1 302
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT, PATCH
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: x-requested-with, content-type, authorization, X-RateLimit-App, X-Spinnaker-Priority
Access-Control-Expose-Headers: X-AUTH-REDIRECT-URL
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: SESSION=ODdmNGZjZmEtY2EwOC00YzA4LWFmMmYtMjAwNDI1ODM2NjI3; Path=/; HttpOnly; SameSite=Lax
Location: http://the-service.mycompany.com
Content-Length: 0
Date: Thu, 18 Jul 2019 14:38:40 GMT

This command will successfully and returns a cookie in response.

But when I tried to use Go code:

http := http.Client{
}

const body = "username=myuser&password=mypass"
req, err := http.NewRequest("POST", "https://the-service.mycompany.com/login", strings.NewReader(body))
req.Header.Add("Accept", "*/*")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Del("Accept-Encoding")
dump, err := httputil.DumpRequestOut(req, true)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("%q
", dump)

resp, err := client.Do(req)

dump, err = httputil.DumpRequestOut(resp.Request, true)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("%q
", dump)

fmt.Println("Dump response ==================")
fmt.Println(resp.Status)
for k, v := range resp.Header {
    fmt.Printf("%s: %s
", k, v)
}

It returned a different response than curl gets, meaning that both response header and body are totally different.

I noticed that, curl returns two status code, 200 and 302. But the go code's resp.Status is 200.

The go code output is:

"POST /login HTTP/1.1
Host: the-service.mycompany.com
User-Agent: Go-http-client/1.1
Content-Length: 36
Accept: */*
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

username=myuser&password=mypass"
"GET /login HTTP/1.1
Host: the-service.mycompany.com
User- Agent: Go-http-client/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
Referer: http://the-service.mycompany.com/login
Accept-Encoding: gzip

"
Dump response ==================
200 
Access-Control-Allow-Origin: [*]
Access-Control-Max-Age: [3600]
Cache-Control: [no-cache, no-store, max-age=0, must-revalidate]
Date: [Thu, 18 Jul 2019 14:53:07 GMT]
Access-Control-Allow-Credentials: [true]
Content-Type: [text/html;charset=UTF-8]
X-Xss-Protection: [1; mode=block]
Pragma: [no-cache]
X-Frame-Options: [DENY]
X-Content-Type-Options: [nosniff]
Access-Control-Allow-Headers: [x-requested-with, content-type, authorization, X-RateLimit-App, X-Spinnaker-Priority]
Access-Control-Expose-Headers: [X-AUTH-REDIRECT-URL]
Expires: [0]
Content-Length: [1324]
Access-Control-Allow-Methods: [POST, GET, OPTIONS, DELETE, PUT, PATCH]

From the output, before do post, the request is a POST, but in when I dump resp.Request, it becomes to a GET, why?

  • 写回答

1条回答 默认 最新

  • dongwei1855 2019-07-18 23:08
    关注

    Finally I figured out the problem. Let me do a self answer, hopefully it helps future people if they hit similar issue.

    Actually, in my case, curl didn't auto redirect, because I didn't use -L option with curl. But the go POST did auto redirect.

    So I added a CheckRedirect function to block redirecting:

    func check(req *http.Request, via []*http.Request) error {
        return http.ErrUseLastResponse
    }
    
    ... in main() ...
    
        client := http.Client {
            CheckRedirect: check,
        }
    

    Then client.PostForm returns same 302 result as what curl gets.

    评论

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100