Sending POST request in Golang with header

I create my form like this:

form := url.Values{}
form.Add("region", "San Francisco")
if len(params) > 0 { 
    for i := 0; i < len(params); i += 2 { 
        form.Add(params[i], params[i+1])
    testLog.Infof("form %v", form)

Now if I use

resp, err = http.PostForm(address+r.Path, form)

then everything works fine, I get back a response with an expected cookie.

However, I would like to to add a header in which case I can’t use PostForm hence I created my POST request manually like:

req, err := http.NewRequest("POST", address+r.Path, strings.NewReader(form.Encode()))

Then I add stuff to the header and send the request

req.Header.Add("region", "San Francisco") 
resp, err = http.DefaultClient.Do(req)

But the form is not received and my response does not contain any cookie.

When I print the req , it looks like the form is nil :

&{POST http://localhost:8081/login HTTP/1.1 1 1 map[Region:[San Francisco]] {0xc420553600} 78

You need to add a content type to your request.

You said http.PostForm worked so let's look at the source of that:

func PostForm(url string, data url.Values) (resp *Response, err error) {
    return DefaultClient.PostForm(url, data)

OK so it's just a wrapper around the PostForm method on the default client. Let's look at that:

func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
    return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))

OK it's calling the Post method and passing in "application/x-www-form-urlencoded" for bodyType and doing the same thing for the body that you're doing. Let's look at the Post method

func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
    req, err := NewRequest("POST", url, body)
    if err != nil {
        return nil, err
    req.Header.Set("Content-Type", bodyType)
    return c.doFollowingRedirects(req, shouldRedirectPost)

So the solution to your problem is to add

req.Header.Set("Content-Type", "application/x-www-form-urlencoded")