In my Go application I use a Web API, which accepts a POST request and returns a token if it is successful.
The URL is the following: "https://accounts.zoho.com/apiauthtoken/nb/create?SCOPE=xxxx&EMAIL_ID=xxxx&PASSWORD=xxxx"
If I send this in Postman or any other tool, I get the status code 200 with the expected body, but in my go code the same request returns error code 400.
url := "https://accounts.zoho.com/apiauthtoken/nb/create?SCOPE=xxxx&EMAIL_ID=xxxx&PASSWORD=xxxx"
req, err := http.NewRequest("POST", url, nil)
log.Println(err)
res, err := client.Do(req)
log.Println(err)
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
log.Println(err)
fmt.Println(res)
fmt.Println(string(body))
All errors are nil, but the res struct contains 400 Bad Request and the last output (of the body) is empty.
&{400 Bad Request 400 HTTP/1.1 1 1 map[Date:[Sat, 03 Mar 2018 16:48:35 GMT] Connection:[keep-alive] Set-Cookie:[a8c61fa0dc=5f224f2ab9d067cfce10fd0b7fae48bf; Path=/; Secure; HttpOnly] Server:[ZGS]] 0xc04225a080 -1 [chunked] false false map[] 0xc042034a00 0xc0421bc370}
I would appreciate any help, because I don't know where this problem comes from.
Url-encoded parameters should be provided in body parameter not as query string. So this can be a problem too. Set your paramters in body implementing io.Reader
.
func NewRequest(method, url string, body io.Reader) (*Request, error)
Set the header Content-Type in your request before sending it using Client.Do
.
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
Since postman is smart enough to set the headers for you. Thats why no error. The whole code becomes
package main
import (
"log"
"net/http"
"net/url"
"io/ioutil"
"strings"
)
func main(){
url := "https://accounts.zoho.com/apiauthtoken/nb/create"
var data url.Values{}
data.Set("SCOPE","xxxx")
data.Add("EMAIL","xxxx")
data.Add("PASSWORD","xxxx")
req, err := http.NewRequest("POST", url, strings.NewReader(data.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
log.Println(err)
res, err := client.Do(req)
log.Println(err)
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
log.Println(err)
fmt.Println(res)
fmt.Println(string(body))
}