Go Http Post request with basic auth and formvalue - http

I am writing a wrapper for an API in go. The api uses basic auth and then POST request requires PostForm value. I'm doing something like this:
func NewFoo(name string) string {
client := &http.Client{}
URL := HOST + "foo/"
req, err := http.NewRequest("POST", URL, nil)
v := url.Values{}
v.Set("name", name)
req.Form = v
req.SetBasicAuth(EMAIL, PASSWORD)
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
bodyText, err := ioutil.ReadAll(resp.Body)
s := string(bodyText)
return s
}
I had a similar, GET request without the form value and it works. When I run it, it tells me that the "name" value is required. (so it's not getting it)
Is there any reason this does not work?

From http://golang.org/pkg/net/http/#Request
// Form contains the parsed form data, including both the URL
// field's query parameters and the POST or PUT form data.
// This field is only available after ParseForm is called.
// The HTTP client ignores Form and uses Body instead.
Form url.Values
You have to pass your url.Values to the request's body instead.
func NewFoo(name string) string {
client := &http.Client{}
URL := HOST + "foo/"
v := url.Values{}
v.Set("name", name)
//pass the values to the request's body
req, err := http.NewRequest("POST", URL, strings.NewReader(v.Encode()))
req.SetBasicAuth(EMAIL, PASSWORD)
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
bodyText, err := ioutil.ReadAll(resp.Body)
s := string(bodyText)
return s
}

Related

Sending form-data in a POST request in golang

I'm trying to send form-data by making a post request. The api works fine (I've tested on postman), but I'm not sure why I'm having trouble to do it in golang. The form-data contains a task field and a file field. But if I do the following I get Bad Request. Any ideas why I might be getting this? Thanks in advance.
// Create new buffer and writer
buf := new(bytes.Buffer)
w := multipart.NewWriter(buf)
// read data from file
var fdata []byte
if fd, e := os.Open(pdf); e != nil {
log.Fatal(e)
} else {
fd.Read(fdata)
}
// create file field and write
part, err := w.CreateFormFile("file", pdf)
if err != nil {
log.Fatal(err)
}
part.Write(fdata)
// create the task field and write
part, err = w.CreateFormField("task")
if err != nil {
log.Fatal(err)
}
part.Write([]byte(os.Getenv("task")))
w.Close()
// Create a new request
req, err := http.NewRequest("POST", fmt.Sprintf("https://%v/v1/upload",os.Getenv("server")), buf)
// Set content type header
req.Header.Add("Content-Type", "multipart/form-data")
// Send the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// other stuff

Convert string from args/flags to json then send to post http request as body

I'm trying to pass the values ​​I get in the arg / flag --BODY="{user: root}" as the body of the post request I'm trying to do, I've already used json.Marshal and even so I wasn't successful, thanks for the help !
Code below:
func Custom(method string, url string, token string, data string) {
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
req.Header.Add("Authorization", FormatBearerToken(token))
// req.Header.Set("Content-Type", "application/json")
if err != nil {
log.Println("Request failed, ", err)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Println(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
log.Println("response Body:", string(body))
}

How to send post form data through a http client?

I have a problem with post request, needed to send simple form data through http client.
http.PostForm() is not ok because I need to set my own user agent and other headers.
Here is the sample
func main() {
formData := url.Values{
"form1": {"value1"},
"form2": {"value2"},
}
client := &http.Client{}
//Not working, the post data is not a form
req, err := http.NewRequest("POST", "http://test.local/api.php", strings.NewReader(formData.Encode()))
if err != nil {
log.Fatalln(err)
}
req.Header.Set("User-Agent", "Golang_Super_Bot/0.1")
resp, err := client.Do(req)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Println(string(body))
}
You also need to set the content type to application/x-www-form-urlencoded which corresponds to the encoding used by Value.Encode().
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
This is mentioned as one of the things done by Client.PostForm.

How to properly set path params in url using golang http client?

I'm using net/http package and i would like to set dynamic values to an POST url:
http://myhost.com/v1/sellers/{id}/whatever
How can i set id values in this path parameter?
You can use path.Join to build the url. You may also need to pathEscape the path-params received externally so that they can be safely placed within the path.
url1 := path.Join("http://myhost.com/v1/sellers", url.PathEscape(id), "whatever")
req, err := http.NewRequest(http.MethodPost, url1, body)
if err != nil {
return err
}
If you are trying to add params to a URL before you make a server request you can do something like this.
const (
sellersURL = "http://myhost.com/v1/sellers"
)
q := url.Values{}
q.Add("id", "1")
req, err := http.NewRequest("POST", sellersURL, strings.NewReader(q.Encode()))
if err != nil {
return err
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Close = true
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}

How to set headers in http get request?

I'm doing a simple http GET in Go:
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
res, _ := client.Do(req)
But I can't found a way to customize the request header in the doc, thanks
The Header field of the Request is public. You may do this :
req.Header.Set("name", "value")
Pay attention that in http.Request header "Host" can not be set via Set method
req.Header.Set("Host", "domain.tld")
but can be set directly:
req.Host = "domain.tld":
req, err := http.NewRequest("GET", "http://10.0.0.1/", nil)
if err != nil {
...
}
req.Host = "domain.tld"
client := &http.Client{}
resp, err := client.Do(req)
If you want to set more than one header, this can be handy rather than writing set statements.
client := http.Client{}
req , err := http.NewRequest("GET", url, nil)
if err != nil {
//Handle Error
}
req.Header = http.Header{
"Host": {"www.host.com"},
"Content-Type": {"application/json"},
"Authorization": {"Bearer Token"},
}
res , err := client.Do(req)
if err != nil {
//Handle Error
}
Go's net/http package has many functions that deal with headers. Among them are Add, Del, Get and Set methods. The way to use Set is:
func yourHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("header_name", "header_value")
}

Resources