I have the following code:
client := &http.Client{}
/* Authenticate */
req, err := http.NewRequest("GET", "http://164.99.113.32/Authenticate", nil)
req.SetBasicAuth("<username>","<password>")
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Error : %s", err)
}
/* Get Details */
req.URL, _ = url.Parse("http://164.99.113.32/Details")
resp, err = client.Do(req)
if err != nil {
fmt.Printf("Error : %s", err)
}
Now, the second http call is failing with a 401 access-denied error. A different REST client (a firefox plugin) correctly gets the details from the server, so I know that nothing is wrong on the server side. Do I need to pass some kind of session string or something that we got in the previous request ?
Okay. I have resolved this. I just needed to create a cookie jar.
I am surprised that this is not handled by default by the golang http
req/client class.
The code that I had to use was:
type myjar struct {
jar map[string] []*http.Cookie
}
func (p* myjar) SetCookies(u *url.URL, cookies []*http.Cookie) {
fmt.Printf("The URL is : %s\n", u.String())
fmt.Printf("The cookie being set is : %s\n", cookies)
p.jar [u.Host] = cookies
}
func (p *myjar) Cookies(u *url.URL) []*http.Cookie {
fmt.Printf("The URL is : %s\n", u.String())
fmt.Printf("Cookie being returned is : %s\n", p.jar[u.Host])
return p.jar[u.Host]
}
and then in main:
jar := &myjar{}
jar.jar = make(map[string] []*http.Cookie)
client.Jar = jar
Works.
With HTTP Basic Authentication, the credentials are required for every request. Try copying the
req.SetBasicAuth("<username>", "<password>")
line before the second client.Do(req).
The reason the Firefox plugin gets the details is that the browser will cache HTTP Basic
Authentication tokens for subsequent use.
There is a new official library, maybe this is helpful.
http://golang.org/pkg/net/http/cookiejar/
example:
Golang: how to follow location with cookie