I am new to Golang and come from a python background and i am having some issues managing form requests.
I am trying to send data in form format with Go in order to mimic this curl call:
curl -X POST -k --cacert mycert --key mykey --cert cert "https://api/v1/house?action=paint&room=hall" -F "houses=street123"
This is what i see in the API server (runs on Flask) getting the call made with curl checking headers and form information from the request.
HEADERS
Host: localhost
Connection: close
Content-Length: 152
User-Agent: curl/7.29.0
Accept: */*
Content-Type: multipart/form-data; boundary=----------------------------991133af3afb
FORM
ImmutableMultiDict([('houses', 'street123')])
When i do it using my GO code i get the following:
HEADERS
Host: localhost
Connection: close
Content-Length: 18
User-Agent: Go-http-client/1.1
Accept-Encoding: */*
Content-Type: multipart/form-data
FORM
ImmutableMultiDict([])
What I am doing:
1- I am generating a client in Generate_client for authentication with mutual tls
2- I am making my call to the API using a map[string][]string as payload and printing it before the call to ensure it has been properly constructed.
- I return the body and print it when calling the function.
This is my result:
Doing Form call
Params after maping:map[houses:[street123]]
FULL-URL:https://api/v1/house?action=paint&room=hall
Params encoded:&{houses=street123 0 -1}
This is my code
func Generate_client() *http.Client {
caCert, err := ioutil.ReadFile(cacert)
checkForErrors(err)
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Create key pair for certificate
cert, err := tls.LoadX509KeyPair(cert, key)
checkForErrors(err)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: caCertPool,
Certificates: []tls.Certificate{cert},
},
},
}
return client
}
func CallFormUrl(endpoint string, method string, dataPayload []string) string {
fmt.Println("Doing Form call")
FormMap := ConvertPayloadToMap(dataPayload)
params := url.Values{}
for key, value:= range FormMap{
params.Add(key,value)
}
fmt.Println("Params after maping:"+params)
client := Generate_client()
fullUrl := controllerUrl+endpoint
fmt.Println("FULL-URL:"+fullUrl)
var ContentType string = "multipart/form-data"
var err error
var req *http.Request
fmt.Println("Params encoded:"+strings.NewReader(params.Encode()))
switch method {
case "POST":
req, err = http.NewRequest(http.MethodPost, fullUrl, strings.NewReader(params.Encode()))
case "PUT":
req, err = http.NewRequest(http.MethodPut, fullUrl, strings.NewReader(params.Encode()))
case "GET":
req, err = http.NewRequest(http.MethodGet, fullUrl, strings.NewReader(params.Encode()))
case "DELETE":
req, err = http.NewRequest(http.MethodDelete, fullUrl, strings.NewReader(params.Encode()))
}
req.Header.Set("Content-type", ContentType)
checkForErrors(err)
resp, err:= client.Do(req)
checkForErrors(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
return string(body)
}
Why the form data is not been sent?