Convert cURL to Go (net/http)
Paste a curl command to get the same request as a Go program using only the standard library. Below the converter, each flag is shown with the exact lines it adds, and the client settings that reproduce curl's redirect, TLS and timeout behavior are spelled out.
What each curl flag becomes in Go net/http
Each example below is the converter's real output, generated when this page was built, from the same code the box above runs. Only the lines a flag adds are shown, compared with converting a bare curl URL, so you can see exactly where each piece of the command lands in Go.
-H · Request headers
curl
curl https://api.example.com/items -H "Accept: application/json" -H "X-Request-Id: 42"
Lines it adds to the Go net/http code
req.Header.Set("Accept", "application/json")
req.Header.Set("X-Request-Id", "42")
--json · A JSON body
--json is curl shorthand for a body plus both Content-Type: application/json and Accept: application/json, so both headers appear.
curl
curl https://api.example.com/items --json '{"name":"widget","qty":2}'
Lines it adds to the Go net/http code
"bytes"
…
method := "POST"
payload := bytes.NewBufferString("{\"name\":\"widget\",\"qty\":2}")
…
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
-d · A form body
Two -d flags join with &, any -d makes the request a POST, and curl labels the body application/x-www-form-urlencoded unless you set a Content-Type yourself.
curl
curl https://api.example.com/login -d "user=ada" -d "remember=1"
Lines it adds to the Go net/http code
"bytes"
…
method := "POST"
payload := bytes.NewBufferString("user=ada&remember=1")
…
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-G · Data sent as query parameters
-G moves the data into the URL and sends a GET with no body and no Content-Type, which is what curl puts on the wire.
curl
curl -G https://api.example.com/search --data-urlencode "q=café au lait"
Lines it adds to the Go net/http code
url := "https://api.example.com/search?q=caf%C3%A9+au+lait"
-u · Basic authentication
-u becomes an Authorization: Basic header with the base64 of user:password. If the command also sets its own Authorization header, that header wins, as it does in curl.
curl
curl -u ada:s3cret https://api.example.com/me
Lines it adds to the Go net/http code
req.Header.Set("Authorization", "Basic YWRhOnMzY3JldA==")
-b · Cookies
curl
curl -b "session=abc123; theme=dark" https://api.example.com/me
Lines it adds to the Go net/http code
req.Header.Set("Cookie", "session=abc123; theme=dark")
-F · A multipart upload
curl
curl https://api.example.com/upload -F "title=Q3 report" -F "file=@report.pdf"
Lines it adds to the Go net/http code
"bytes"
…
"mime/multipart"
…
"os"
…
method := "POST"
buf := &bytes.Buffer{}
w := multipart.NewWriter(buf)
if err := w.WriteField("title", "Q3 report"); err != nil { panic(err) }
f0, err := os.Open("report.pdf")
if err != nil { panic(err) }
defer f0.Close()
part0, err := w.CreateFormFile("file", "report.pdf")
if err != nil { panic(err) }
if _, err = io.Copy(part0, f0); err != nil { panic(err) }
if err := w.Close(); err != nil { panic(err) }
var payload io.Reader = buf
…
req.Header.Set("Content-Type", w.FormDataContentType())
The converter also notes: a -F upload needs Content-Type: multipart/form-data with a boundary generated per request, so the target language sets that header itself.
-X · A different method
curl
curl -X DELETE https://api.example.com/items/7
Lines it adds to the Go net/http code
method := "DELETE"
-I · A HEAD request
curl
curl -I https://api.example.com/health
Lines it adds to the Go net/http code
method := "HEAD"
What the generated code does not carry over
Some curl flags change how the transfer behaves rather than what the request is, and the converter leaves them out. For each flag below, this build checked that adding it leaves the Go net/http output unchanged, then noted what net/http does by default and how to match curl:
-L: Nothing to add:http.DefaultClientfollows up to 10 redirects. A command without-Lstops at the 3xx; to reproduce that, use a client whoseCheckRedirectreturnshttp.ErrUseLastResponse.--compressed: Nothing to add: the default transport asks for gzip and decompresses the body transparently, as long as you do not setAccept-Encodingyourself.-k: Use a client with&http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}. That disables certificate checking, so keep it to a test server.-m 10: Swap the generatedcontext.WithCancelforcontext.WithTimeout(context.Background(), 10*time.Second). The default client has no timeout.
More from cURLParse
Guides
Frequently Asked Questions
Why does the generated Go code use a context?
So the request can be cancelled and given a deadline. The default client has no timeout of its own, so without one a request to an unresponsive server waits indefinitely. To match curl -m 10, replace context.WithCancel with context.WithTimeout(context.Background(), 10*time.Second).
Do I need to handle gzip in Go when the curl command has --compressed?
No. Go's default transport asks for gzip and decompresses the response transparently, as long as you do not set an Accept-Encoding header yourself. That is why the converter leaves --compressed out.