Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http client POST/GET.. will not save cookie before do redirect request #27596

Closed
qianguozheng opened this issue Sep 10, 2018 · 7 comments
Closed

Comments

@qianguozheng
Copy link

qianguozheng commented Sep 10, 2018

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.10.3 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/weeds/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/weeds/magicwifi/golang"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build307535869=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Simply do http POST request, I want to login with http client to the server https://github.com/qianguozheng/goadmin.git, but it not work out.

If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

func httpPost() {
	resp, err := http.Post("http://127.0.0.1:8081/login",
		"application/x-www-form-urlencoded",
		strings.NewReader("username=admin&password=pass"))
	if err != nil {
		fmt.Println(err)
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
	}
	for k, v := range resp.Header {
		fmt.Println(k, v)
	}
	fmt.Println(string(body))
	fmt.Println("Done")
}

func main() {
	httpPost()
}

What did you expect to see?

the cookie in response

What did you see instead?

no cookie in response

@qianguozheng
Copy link
Author

I think this is the bug of http client Do method, when it do redirect in client, it should put the cookie get from response to the request to do next request.
But, in my opinion, this looks not fix the problem I encounter, my client still can't get cookie, so I think, maybe we should remove the redirect, or and a switch to open or close it.

@agnivade
Copy link
Contributor

You have mentioned about a redirect request in the title. However, I do not see any redirects here. You are just doing a POST request and printing the response headers. Can you clarify that ? Also, please post an output of curl -v -d 'username=admin&password=pass' http://localhost:8081/login so that we can understand what is going on.

Also, please see this - https://golang.org/pkg/net/http/#Client

When following redirects, the Client will forward all headers set on the initial Request except:

• when forwarding sensitive headers like "Authorization", "WWW-Authenticate", and "Cookie" to untrusted targets. These headers will be ignored when following a redirect to a domain that is not a subdomain match or exact match of the initial domain. For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com" will forward the sensitive headers, but a redirect to "bar.com" will not.

• when forwarding the "Cookie" header with a non-nil cookie Jar. Since each redirect may mutate the state of the cookie jar, a redirect may possibly alter a cookie set in the initial request. When forwarding the "Cookie" header, any mutated cookies will be omitted, with the expectation that the Jar will insert those mutated cookies with the updated values (assuming the origin matches). If Jar is nil, the initial cookies are forwarded without change.

Maybe relevant to your case.

@qianguozheng
Copy link
Author

qianguozheng commented Sep 11, 2018

You can see that I only do the POST /login and the later is execute by http client implementation.

From my point of view, I think the GET /home.html request should add the cookie from last response, but it didn't, since you don't do that, why don't just return the response to me instead of doing useless request cause we go the login page.

POST /login HTTP/1.1
Host: 127.0.0.1:8081
User-Agent: Go-http-client/1.1
Content-Length: 28
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

username=admin&password=testHTTP/1.1 302 Found
Location: /home.html
Set-Cookie: user=MTUzNjY1NjA2MXxEdi1CQkFFQ180SUFBUkFCRUFBQUpfLUNBQUVHYzNSeWFXNW5EQW9BQ0hWelpYSnVZVzFsQm5OMGNtbHVad3dIQUFWaFpHMXBiZz09fKI-QQWYHP_ZywpgkIoDmTzL1eJhd7pk-i9FSUgwI89E; Path=/; HttpOnly
Date: Tue, 11 Sep 2018 08:54:21 GMT
Content-Length: 0

GET /home.html HTTP/1.1
Host: 127.0.0.1:8081
User-Agent: Go-http-client/1.1
Content-Type: application/x-www-form-urlencoded
Referer: http://127.0.0.1:8081/login
Accept-Encoding: gzip

HTTP/1.1 302 Found
Location: /login.html
Date: Tue, 11 Sep 2018 08:54:21 GMT
Content-Length: 0

GET /login.html HTTP/1.1
Host: 127.0.0.1:8081
User-Agent: Go-http-client/1.1
Content-Type: application/x-www-form-urlencoded
Referer: http://127.0.0.1:8081/home.html
Accept-Encoding: gzip

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Date: Tue, 11 Sep 2018 08:54:21 GMT
Transfer-Encoding: chunked

f15
<!DOCTYPE html>
<html>


<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>............ Admin | ......</title>
    <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
    <link rel="shortcut icon" href="/assets/magicwifi-admin/core/img/favicon.ico">
    <link rel="stylesheet" href="/assets/vender/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/assets/vender/font-awesome/css/font-awesome.min.css">
    <link rel="stylesheet" href="/assets/vender/ionicons/css/ionicons.min.css">
    <link rel="stylesheet" href="/assets/vender/adminlte2/css/AdminLTE.min.css">
    <link rel="stylesheet" href="/assets/vender/adminlte2/plugins/iCheck/square/blue.css">
    
</head>
<body class="hold-transition login-page">
<div class="login-box">
    <div class="login-logo">
        <img src="assets/magicwifi-admin/core/img/logo.png" height="44px"><br/>
        <a href="http://richard.qian:ubuntu123@magicwifi.com.cn/"><b>Magic</b>WiFi</a>
    </div>
    
    <div class="login-box-body">
        <p class="login-box-msg">......</p>
        <form id="loginForm" action="/login" method="post">
            <div class="form-group has-feedback">
                <input type="text" class="form-control required" placeholder=".................." id="username" name="username" oninput="removePsw();">
                <span class="glyphicon glyphicon-user form-control-feedback"></span>
            </div>
            <div class="form-group has-feedback">
                <input type="password" class="form-control required" placeholder="..............." id="password" name="password">
                <span class="glyphicon glyphicon-lock form-control-feedback"></span>
            </div>
            <div class="row">
                
                    
                        
                            
                        
                    
                
                <div class="col-xs-12">
                    <button type="submit" class="btn btn-primary btn-block btn-flat">......</button>
                </div>
            </div>
        </form>
        <div class="social-auth-links text-right">
            <a href="reset.html">...............</a>
        </div>
        <div class="social-auth-links text-center">
            <p>- OR -</p>
            <p><a href="https://open.weixin.qq.com/connect/qrconnect?appid=wxf7a07021f679b466&amp;redirect_uri=http://magicwifi.com.cn/v3/core/callbackByWechat&amp;response_type=code&amp;scope=snsapi_login&amp;state=login15320666316191513574#wechat_redirect"><i class="fa fa-wechat"></i> ..................</a></p>
        </div>
        <div class="social-auth-links text-center">
            <img src="assets/magicwifi-admin/wechat/img/qrcode_for_gz.jpg" height="150px;">
            <p>.....................</p>
        </div>
    </div>
    
    <div class="lockscreen-footer text-center">
        Copyright &copy; 2016 <b><a href="http://www.magicwifi.com.cn/" class="text-black">magicwifi.com.cn</a></b>
    </div>
</div>


<script src="/assets/vender/adminlte2/plugins/jQuery/jQuery-2.1.4.min.js"></script>
<script src="/assets/vender/bootstrap/js/bootstrap.min.js"></script>
<script src="/assets/vender/adminlte2/plugins/iCheck/icheck.min.js"></script>
<script src="/assets/vender/adminlte2/plugins/validation/jquery.validate.min.js"></script>
<script>
    $(function () {
        $("#loginForm").validate();
        $("#username").focus();
        $('input').iCheck({
            checkboxClass: 'icheckbox_square-blue',
            radioClass: 'iradio_square-blue',
            increaseArea: '20%' 
        });
    });
    function removePsw(){
    	$("#password").val("");
    }
</script>
</body>


</html>
0


@qianguozheng
Copy link
Author

Code I am use to testing

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

func httpPost() {
	resp, err := http.Post("http://127.0.0.1:8081/login",
		"application/x-www-form-urlencoded",
		strings.NewReader("username=admin&password=test"))
	if err != nil {
		fmt.Println(err)
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
	}
	for k, v := range resp.Header {
		fmt.Println(k, v)
	}
	fmt.Println(string(body))
	fmt.Println("Done")
}

func main() {
	httpPost()
}

@agnivade
Copy link
Contributor

This maybe just a hunch, but looks like you need to have a non-nil jar for it to copy cookies from the response.

// If Jar is nil, cookies are only sent if they are explicitly
// set on the Request.

@meirf

@mvdan
Copy link
Member

mvdan commented Sep 11, 2018

@qianguozheng have you tried asking on an online forum like golang-nuts? Those are better places to ask questions and giving your code for others to debug, as we use the issue tracker for bugs and proposals. See https://github.com/golang/go/wiki/Questions.

@agnivade
Copy link
Contributor

As pointed out by @vdobler in the golang-nuts thread, you need to have a non-nil cookie jar implementation for it to capture and set the cookies in the outgoing request.

I am closing this now. Please feel free to continue the discussion in the golang-nuts thread.

@golang golang locked and limited conversation to collaborators Sep 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants