Edited at

golang リダイレクトでハマった

More than 5 years have passed since last update.

ごっそり書き直しました


問題

net/httpのDo,Get,Post,PostFormは301,302とかが帰ってくると自動的にリダイレクトしてくれるんだけど

Set-Cookieを読み捨ててしまう


再現


server.go

package main

import (
"fmt"
"net/http"
"time"
)

func redirectHandler(w http.ResponseWriter, r *http.Request){
name := r.PostFormValue("name")

if name == "" {
fmt.Fprint(w, "nameが設定されていません")
} else {
cookie := http.Cookie {
Name : "name",
Value : name,
Expires : time.Now().AddDate(0, 0, 1),
}

http.SetCookie(w, &cookie)
http.Redirect(w, r, "/home", http.StatusFound)
}
}

func homeHandler(w http.ResponseWriter, r *http.Request){
cookie, err := r.Cookie("name")

name := "unknown"
if err == nil {
name = cookie.Value
}

fmt.Fprintf(w, "Hello %s", name)
}

func main() {
http.HandleFunc("/home", homeHandler)
http.HandleFunc("/redirect", redirectHandler)
http.ListenAndServe(":8080", nil)
}



post.go

package main

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

func main(){
res, _ := http.PostForm("http://localhost:8080/redirect",
url.Values{
"name" : {"hogeeeeeeeee"},
},
)

defer res.Body.Close()

body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}



サーバを起動して

$ go run server.go


post.goを実行

$ go run post.go

Hello unknown
$


解決策

cookiejarを使いましょう


post2.go

package main

import (
"fmt"
"net/http"
"io/ioutil"
"net/url"
"net/http/cookiejar"
)

func main(){
jar, _ := cookiejar.New(nil)
client := http.Client{Jar: jar}

res, _ := client.PostForm("http://localhost:8080/redirect",
url.Values{
"name" : {"hogeeeeeeeee"},
},
)

defer res.Body.Close()

body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}


$ go run post2.go

Hello hogeeeeeeeee
$


参考

http://stackoverflow.com/questions/18414212/golang-how-to-follow-location-with-cookie