Could someone explains what's happening here?
package main
import (
"fmt"
"net/http"
"strings"
)
func Verify(req http.Request) string {
return req.FormValue("g-recaptcha-response")
}
func main() {
req, _ := http.NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not",
strings.NewReader("z=post&both=y&prio=2&empty="))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
Verify(*req)
fmt.Println(req.FormValue("z"))
}
(https://play.golang.org/p/ve4Cc_JTzr)
This will produce an empty output. Now if I access the value "z" before passing the request as value, it works!
package main
import (
"fmt"
"net/http"
"strings"
)
func Verify(req http.Request) string {
return req.FormValue("g-recaptcha-response")
}
func main() {
req, _ := http.NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not",
strings.NewReader("z=post&both=y&prio=2&empty="))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
Verify(*req)
fmt.Println(req.FormValue("z"))
}
(https://play.golang.org/p/5ALnt-pHTl)
I have tried with several versions of go from 1.5 to 1.7, with the same odd result. If the request is passed by reference, it's working as expected.
It's because Request's body is io.Reader
, and you can read from io.Reader
only once, when you try to read content second time, there is no more data to read.
Method FormValue
calls ParseForm
, and it reads all data from the reader.