I want to send a GET request with login data and save cookie data to txt file.
I had a curl data
curl -c cookies.txt 'http://localhost:8080/api/v2/auth/login' \
-H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98"' \
-H 'sec-ch-ua-mobile: ?1' \
-H 'User-Agent: Mozilla/5.0 (Linux; Android 9; BND-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.106 Mobile Safari/537.36' \
-H 'Content-type: application/x-www-form-urlencoded; charset=UTF-8' \
-H 'Accept: text/javascript, text/html, application/xml, text/xml, */*' \
-H 'Referer: http://localhost:8080/' \
-H 'X-Requested-With: XMLHttpRequest' \
-H 'sec-ch-ua-platform: "Android"' \
--data-raw 'username=admin&password=pasxxord7' \
--compressed
I need to convert this curl to Go; I have tried online converter, it's giving error and I don't think they have any capability to store cookies to txt file.
I had a sample Go file which doesn't have a capability to send username and password, but I think it does saves cookies.txt file:
My main.go contents:
package main
import "net/http/cookiejar"
import "net/http"
import "encoding/json"
import "io/ioutil"
import "fmt"
func main(){
cookies := make(map[string][]*http.Cookie)
jar, _ := cookiejar.New(nil)
client := http.Client{Jar: jar}
r, err := client.Get("http://localhost:8080/api/v2/auth/login")
if err != nil {
fmt.Println(err)
return
}
siteCookies := jar.Cookies(r.Request.URL)
cookies[r.Request.URL.String()] = siteCookies
data, _ := json.Marshal(cookies)
ioutil.WriteFile("cookies.txt", data, 0644)
}
I need to mainly convert and add this curl flag and data --data-raw 'username=admin&password=pasxxord7'
to Go.
CodePudding user response:
When you use the curl flag --data-raw
is sends a POST
request. You can verify this by using the verbose output flag -v
, for example:
$ curl -c cookies.txt 'http://requestbin.net/r/40vmgerp' \
-H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98"' \
-H 'sec-ch-ua-mobile: ?1' \
-H 'User-Agent: Mozilla/5.0 (Linux; Android 9; BND-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.106 Mobile Safari/537.36' \
-H 'Content-type: application/x-www-form-urlencoded; charset=UTF-8' \
-H 'Accept: text/javascript, text/html, application/xml, text/xml, */*' \
-H 'Referer: http://localhost:8080/' \
-H 'X-Requested-With: XMLHttpRequest' \
-H 'sec-ch-ua-platform: "Android"' \
--data-raw 'username=admin&password=pasxxord7' \
--compressed -v
* Connected to requestbin.net (172.67.190.62) port 80 (#0)
> POST /r/40vmgerp HTTP/1.1 <--------------------
> Host: requestbin.net
> Accept-Encoding: deflate, gzip
> sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98"
> sec-ch-ua-mobile: ?1
...
Generally GET requests are not used for transmitting data in the body so using a POST
as curl does automatically when data-raw
is given is correct.
Based on your example headers and data for data-raw
it appears you are using form values which can also be specified as:
curl localhost -F 'username=admin' -F 'password=pasxxord7'
This would add the content-type multipart/form-data header and send as POST automatically. This has the advantage of doing any necessary escaping as well.
To recreate your curl request in Go would be as follows:
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"strings"
)
func main() {
data := url.Values{}
data.Set("username", "admin")
data.Set("password", "pasxxord7")
body := strings.NewReader(data.Encode())
req, err := http.NewRequest(http.MethodPost, "https://requestbin.net/r/40vmgerp", body)
if err != nil {
panic(err)
}
// Omitted other headers for brevity.
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Set("Accept", "text/javascript, text/html, application/xml, text/xml, */*")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
cookies := resp.Cookies()
if len(cookies) > 0 {
cookieFile, err := os.Create("cookies.txt")
if err != nil {
panic(err)
}
defer cookieFile.Close()
encoder := json.NewEncoder(cookieFile)
for _, cookie := range cookies {
// fmt.Fprintln(cookieFile, cookie.String()) // write plain text to file
if err := encoder.Encode(cookie); err != nil {
panic(err)
}
}
} else {
fmt.Println("No cookies found.")
}
}
Note the example above uses RequestBin rather than localhost but should otherwise be complete if you add your other headers.
You don't need to use a Cookie Jar because that is used to store and send cookies with an outgoing request. It appears you are only interested in storing the cookies sent back from the server and so you need to call the .Cookies()
method on the response and use what is returned.