mholt / curl-to-go Goto Github PK
View Code? Open in Web Editor NEWConvert curl commands to Go code in your browser
Home Page: https://mholt.github.io/curl-to-go
License: MIT License
Convert curl commands to Go code in your browser
Home Page: https://mholt.github.io/curl-to-go
License: MIT License
Hi,
Your latest update has a bug where new lines (using ) are not working. Even some of your examples don't work anymore.
--data-binary
(HTTP) This posts data exactly as specified with no extra processing whatsoever.
If you start the data with the letter @, the rest should be a filename. Data is posted in a similar manner as -d, --data does, except that newlines and carriage returns are preserved and conversions are never done.
If this option is used several times, the ones following the first will append data as described in -d, --data.
I'm currently using etcd which brings me to use your awesome curl-to-go converter. However when trying a basic command like putting a value:
curl -L -X PUT http://127.0.0.1:2379/v2/keys/message -d value="Hello"
This generate this:
// Generated by curl-to-Go: https://mholt.github.io/curl-to-go
body := strings.NewReader(`value=Hello`)
req, err := http.NewRequest("PUT", "http://127.0.0.1:2379/v2/keys/message", body)
if err != nil {
// handle err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
// handle err
}
defer resp.Body.Close()
The Curl command works but this code doesn't. The reason is one of the Curl default header is not set:
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
This should be the generated code that actually works with my code:
// Generated by curl-to-Go: https://mholt.github.io/curl-to-go
body := strings.NewReader(`value=Hello`)
req, err := http.NewRequest("PUT", "http://127.0.0.1:2379/v2/keys/message", body)
if err != nil {
// handle err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := http.DefaultClient.Do(req)
if err != nil {
// handle err
}
defer resp.Body.Close()
curl --location --request POST 'https://test.test/pest' \
--header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0' \
--data-urlencode 'test=1' \
--data-urlencode 'lang=ru_RU'```
go generated code :
```go
req, err := http.NewRequest("POST", "https://test.test/pest", nil)
if err != nil {
// handle err
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0")
resp, err := http.DefaultClient.Do(req)
if err != nil {
// handle err
}
defer resp.Body.Close()
I think it is better to add in the generated sample code a check (even if commented) for HTTP status code (just as a hint). example:
if resp.StatusCode != http.StatusOK {
// handle status code not 200
}
BTW, I spent long time not sure what is the error until I realized at the end that, the status code check is not there 😄
As of now, I cannot convert --data-urlencode
. Is this doable? If not, can you pls take it as a feature request? This is my curl command.
$ curl --user 'admin:password' -X POST "https://my-url" -d token=XXXX-XXX \
--data-urlencode json='{"parameter": [{"name":"ACCOUNT", "value":"111111"}]}'
Thanks.
PS: This is duplicate of sethgrid/gencurl#3
It would be nice to explode the URL into a native net/url structure too.
Are you requesting support for a new curl flag? If so, what is the flag and the equivalent Go code?
The code is wrong
#curl --resolve www.aqzt.com:80:127.0.0.1 http://www.aqzt.com
// Generated by curl-to-Go: https://mholt.github.io/curl-to-go
resp, err := http.Get("http://www.aqzt.com")
if err != nil {
// handle err
}
defer resp.Body.Close()
curl -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Token ${PIVOTAL_NETWORK_TOKEN}" -X GET https://network.pivotal.io/api/v2/products
would use https://golang.org/pkg/os/#ExpandEnv to become:
// Generated by curl-to-Go: https://mholt.github.io/curl-to-go
req, err := http.NewRequest("GET", "https://network.pivotal.io/api/v2/products", nil)
if err != nil {
// handle err
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", os.ExpandEnv("Token ${PIVOTAL_NETWORK_TOKEN}"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
// handle err
}
defer resp.Body.Close()
Perhaps the algorithm would detect $
in any string and wrap the string in os.ExpandEnv(...)
?
Are you requesting support for a new curl flag? If so, what is the flag and the equivalent Go code?
# curl -v -u admin:admin123 -X POST 'http://localhost:8081/service/rest/v1/components?repository=maven-releases' -F maven2.groupId=com.google.guava -F maven2.artifactId=guava -F maven2.version=24.0-jre -F [email protected] -F maven2.asset1.extension=jar -F [email protected] -F maven2.asset2.classifier=sources -F maven2.asset2.extension=jar
From Curl manual pages -
curl also supports the more capable
multipart/form-data type. This latter type supports things like file upload.
-F accepts parameters like -F "name=contents". If you want the contents to
be read from a file, use <@filename> as contents. When specifying a file,
you can also specify the file content type by appending ';type='
to the file name. You can also post the contents of several files in one
field. For example, the field name 'coolfiles' is used to send three files,
with different content types using the following syntax:
curl -F "[email protected];type=image/gif,fil2.txt,fil3.html" \
http://www.post.com/postit.cgi
If the content-type is not specified, curl will try to guess from the file
extension (it only knows a few), or use the previously specified type (from
an earlier file if several files are specified in a list) or else it will
use the default type 'application/octet-stream'.
Emulate a fill-in form with -F. Let's say you fill in three fields in a
form. One field is a file name which to post, one field is your name and one
field is a file description. We want to post the file we have written named
"cooltext.txt". To let curl do the posting of this data instead of your
favourite browser, you have to read the HTML source of the form page and
find the names of the input fields. In our example, the input field names
are 'file', 'yourname' and 'filedescription'.
curl -F "[email protected]" -F "yourname=Daniel" \
-F "filedescription=Cool text file with cool text inside" \
http://www.post.com/postit.cgi
// (put Go code here
hi,
thanks for your work!
when I try this I need curl one self-signed https web, my curl command need -k to ignore security check , after some digging,I add some code , then golang code works, kindly consider this.
same discussion on https://stackoverflow.com/questions/12122159/golang-how-to-do-a-https-request-with-bad-certificate
code like
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
_, err := client.Get("https://golang.org/")
regards, hua
Just want to say thanks man! You saved me couple of hours. God bless you
Hi, I just getting blank header when I use proposed os.ExpandEnv("$Cookie"), if I try without it (ie just setting req.Header.Set("Cookie","cookies;values;")
the request does not work, while curl works.
Hi Thanks for this great software.
Would you please enhance the generated go code to be almost ready-to-run ?
Goal is to have user modify variable part(actual site url and login account/password).
This project looks really useful! Seems that sometimes using net/http
package can be prone to subtle bugs when closing the response body so thought that maybe it would be useful to generate snippets of code which prevent this.
Currently output displayed is like...
// Generated by curl-to-Go: https://mholt.github.io/curl-to-go
resp, err := http.Get("http://www.google.com")
if err != nil {
// handle err
}
defer resp.Body.Close()
But considering that on redirection failure both variables will be non-nil
so there can be a leak
How about maybe changing output to something like below?
// Generated by curl-to-Go: https://mholt.github.io/curl-to-go
resp, err := http.Get("http://www.google.com")
if resp != nil {
defer resp.Body.Close()
}
if err != nil {
// handle err
}
Thanks!
Are you requesting support for a new curl flag? If so, what is the flag and the equivalent Go code?
curl -G https://curl-to-go.com \
-d "id=8a829417567d952801568d9d9e3c0b84" \
-H "Authorization: Bearer OGE4Mjk0MTc1NjdkOTUyODAxNTY4ZDlkOWU5ZjBiODh8amF5MjdhdDVzMg=="
params := url.Values{
"id": {"8a829417567d952801568d9d9e3c0b84"},
}
reqUrl := "https://curl-to-go.com?" + params.Encode()
req, err := http.NewRequest(http.MethodGet, reqUrl, nil)
if err != nil {
// handle err
}
req.Header.Set("Authorization", "Bearer OGFjN2E0Yzc4MTZmYjJmNjAxODE2ZmRmMmFjMzAwYTJ8NVF4ZmtDcWZqSA==")
resp, err := http.DefaultClient.Do(req)
if err != nil {
// handle err
}
defer resp.Body.Close()
Consider the following example:
curl -H "X-Access-Key: dgfh464f45v66773454vv666" https://domain.com --resolve 4e45-9996-65d7f49e46f2.another-domain.com:12345:145.23.143.248
After some minutes of fight, I saw that if in a curl like:
(Purge for Varnish stuff)
curl -v -X PURGE -H "Host: www.xxxx.com" ....
from: *request.go
// For server requests Host specifies the host on which the
// URL is sought. Per RFC 2616, this is either the value of
// the "Host" header or the host name given in the URL itself.
// It may be of the form "host:port". For international domain
// names, Host may be in Punycode or Unicode form. Use
// golang.org/x/net/idna to convert it to either format if
// needed.
//
// For client requests Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.
Bad -> req.Header.Set("Host", "www.xxxx.com")
Good -> req.Host = "www.xxxx.com"
At least in: go version go1.8.1 linux/amd64
Are you requesting support for a new curl flag? If so, what is the flag and the equivalent Go code?
curl --user "{PUBLIC-KEY}:{PRIVATE-KEY}" --digest \
--header "Accept: application/json" \
--include \
--request GET "https://{OPSMANAGER-HOST}:{PORT}/api/public/v1.0/groups/{PROJECT-ID}/hosts?pretty=true"
import (
"bytes"
"crypto/md5"
"crypto/rand"
"crypto/sha256"
"errors"
"fmt"
"hash"
"io"
"io/ioutil"
"net/http"
"strings"
)
const (
MsgAuth string = "auth"
AlgMD5 string = "MD5"
AlgSha256 string = "SHA-256"
)
var (
ErrNilTransport = errors.New("transport is nil")
ErrBadChallenge = errors.New("challenge is bad")
ErrAlgNotImplemented = errors.New("alg not implemented")
)
func DoRequest() (err error) {
body := bytes.NewBufferString(data)
req, err := http.NewRequest("GET","https://{OPSMANAGER-HOST}:{PORT}/api/public/v1.0/groups/{PROJECT-ID}/hosts?pretty=true",nil)
if err != nil {
return err
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
client, err := NewTransport("{PUBLIC-KEY}","{PRIVATE-KEY}").Client()
if err != nil {
return err
}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
bytesResp, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
fmt.Println(string(bytesResp))
return
}
// Transport is an implementation of http.RoundTripper that takes care of http
// digest authentication.
type Transport struct {
Username string
Password string
Transport http.RoundTripper
}
// NewTransport creates a new digest transport using the http.DefaultTransport.
func NewTransport(username, password string) *Transport {
t := &Transport{
Username: username,
Password: password,
}
t.Transport = http.DefaultTransport
return t
}
type challenge struct {
Realm string
Domain string
Nonce string
Opaque string
Stale string
Algorithm string
Qop string
}
func parseChallenge(input string) (*challenge, error) {
const ws = " \n\r\t"
const qs = `"`
s := strings.Trim(input, ws)
if !strings.HasPrefix(s, "Digest ") {
return nil, ErrBadChallenge
}
s = strings.Trim(s[7:], ws)
sl := strings.Split(s, ", ")
c := &challenge{
Algorithm: AlgMD5,
}
var r []string
for i := range sl {
r = strings.SplitN(sl[i], "=", 2)
switch r[0] {
case "realm":
c.Realm = strings.Trim(r[1], qs)
case "domain":
c.Domain = strings.Trim(r[1], qs)
case "nonce":
c.Nonce = strings.Trim(r[1], qs)
case "opaque":
c.Opaque = strings.Trim(r[1], qs)
case "stale":
c.Stale = strings.Trim(r[1], qs)
case "algorithm":
c.Algorithm = strings.Trim(r[1], qs)
case "qop":
c.Qop = strings.Trim(r[1], qs)
default:
return nil, ErrBadChallenge
}
}
return c, nil
}
type credentials struct {
Username string
Realm string
Nonce string
DigestURI string
Algorithm string
Cnonce string
Opaque string
MessageQop string
NonceCount int
method string
password string
impl hashingFunc
}
type hashingFunc func() hash.Hash
func h(data string, f hashingFunc) (string, error) {
hf := f()
if _, err := io.WriteString(hf, data); err != nil {
return "", err
}
return fmt.Sprintf("%x", hf.Sum(nil)), nil
}
func kd(secret, data string, f hashingFunc) (string, error) {
return h(fmt.Sprintf("%s:%s", secret, data), f)
}
func (c *credentials) ha1() (string, error) {
return h(fmt.Sprintf("%s:%s:%s", c.Username, c.Realm, c.password), c.impl)
}
func (c *credentials) ha2() (string, error) {
return h(fmt.Sprintf("%s:%s", c.method, c.DigestURI), c.impl)
}
func (c *credentials) resp(cnonce string) (resp string, err error) {
var ha1 string
var ha2 string
c.NonceCount++
if c.MessageQop == MsgAuth {
if cnonce != "" {
c.Cnonce = cnonce
} else {
b := make([]byte, 8)
_, err = io.ReadFull(rand.Reader, b)
if err != nil {
return "", err
}
c.Cnonce = fmt.Sprintf("%x", b)[:16]
}
if ha1, err = c.ha1(); err != nil {
return "", err
}
if ha2, err = c.ha2(); err != nil {
return "", err
}
return kd(ha1, fmt.Sprintf("%s:%08x:%s:%s:%s", c.Nonce, c.NonceCount, c.Cnonce, c.MessageQop, ha2), c.impl)
} else if c.MessageQop == "" {
if ha1, err = c.ha1(); err != nil {
return "", err
}
if ha2, err = c.ha2(); err != nil {
return "", err
}
return kd(ha1, fmt.Sprintf("%s:%s", c.Nonce, ha2), c.impl)
}
return "", ErrAlgNotImplemented
}
func (c *credentials) authorize() (string, error) {
// Note that this is only implemented for MD5 and NOT MD5-sess.
// MD5-sess is rarely supported and those that do are a big mess.
if c.Algorithm != AlgMD5 && c.Algorithm != AlgSha256 {
return "", ErrAlgNotImplemented
}
// Note that this is NOT implemented for "qop=auth-int". Similarly the
// auth-int server side implementations that do exist are a mess.
if c.MessageQop != MsgAuth && c.MessageQop != "" {
return "", ErrAlgNotImplemented
}
resp, err := c.resp("")
if err != nil {
return "", ErrAlgNotImplemented
}
sl := []string{fmt.Sprintf(`username="%s"`, c.Username)}
sl = append(sl, fmt.Sprintf(`realm="%s"`, c.Realm),
fmt.Sprintf(`nonce="%s"`, c.Nonce),
fmt.Sprintf(`uri="%s"`, c.DigestURI),
fmt.Sprintf(`response="%s"`, resp))
if c.Algorithm != "" {
sl = append(sl, fmt.Sprintf(`algorithm="%s"`, c.Algorithm))
}
if c.Opaque != "" {
sl = append(sl, fmt.Sprintf(`opaque="%s"`, c.Opaque))
}
if c.MessageQop != "" {
sl = append(sl, fmt.Sprintf("qop=%s", c.MessageQop),
fmt.Sprintf("nc=%08x", c.NonceCount),
fmt.Sprintf(`cnonce="%s"`, c.Cnonce))
}
return fmt.Sprintf("Digest %s", strings.Join(sl, ", ")), nil
}
func (t *Transport) newCredentials(req *http.Request, c *challenge) (*credentials, error) {
cred := &credentials{
Username: t.Username,
Realm: c.Realm,
Nonce: c.Nonce,
DigestURI: req.URL.RequestURI(),
Algorithm: c.Algorithm,
Opaque: c.Opaque,
MessageQop: c.Qop, // "auth" must be a single value
NonceCount: 0,
method: req.Method,
password: t.Password,
}
switch c.Algorithm {
case AlgMD5:
cred.impl = md5.New
case AlgSha256:
cred.impl = sha256.New
default:
return nil, ErrAlgNotImplemented
}
return cred, nil
}
// RoundTrip makes a request expecting a 401 response that will require digest
// authentication. It creates the credentials it needs and makes a follow-up
// request.
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
if t.Transport == nil {
return nil, ErrNilTransport
}
// Copy the request so we don't modify the input.
origReq := new(http.Request)
*origReq = *req
origReq.Header = make(http.Header, len(req.Header))
for k, s := range req.Header {
origReq.Header[k] = s
}
// We'll need the request body twice. In some cases we can use GetBody
// to obtain a fresh reader for the second request, which we do right
// before the RoundTrip(origReq) call. If GetBody is unavailable, read
// the body into a memory buffer and use it for both requests.
if req.Body != nil && req.GetBody == nil {
body, err := ioutil.ReadAll(req.Body)
if err != nil {
return nil, err
}
req.Body = ioutil.NopCloser(bytes.NewBuffer(body))
origReq.Body = ioutil.NopCloser(bytes.NewBuffer(body))
}
// Make a request to get the 401 that contains the challenge.
challenge, resp, err := t.fetchChallenge(req)
if challenge == "" || err != nil {
return resp, err
}
c, err := parseChallenge(challenge)
if err != nil {
return nil, err
}
// Form credentials based on the challenge.
cr, err := t.newCredentials(origReq, c)
if err != nil {
return nil, err
}
auth, err := cr.authorize()
if err != nil {
return nil, err
}
// Obtain a fresh body.
if req.Body != nil && req.GetBody != nil {
origReq.Body, err = req.GetBody()
if err != nil {
return nil, err
}
}
// Make authenticated request.
origReq.Header.Set("Authorization", auth)
return t.Transport.RoundTrip(origReq)
}
func (t *Transport) fetchChallenge(req *http.Request) (string, *http.Response, error) {
resp, err := t.Transport.RoundTrip(req)
if err != nil {
return "", resp, err
}
if resp.StatusCode != http.StatusUnauthorized {
return "", resp, nil
}
// We'll no longer use the initial response, so close it
defer func() {
// Ensure the response body is fully read and closed
// before we reconnect, so that we reuse the same TCP connection.
// Close the previous response's body. But read at least some of
// the body so if it's small the underlying TCP connection will be
// re-used. No need to check for errors: if it fails, the Transport
// won't reuse it anyway.
const maxBodySlurpSize = 2 << 10
if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize {
_, _ = io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize)
}
resp.Body.Close()
}()
return resp.Header.Get("WWW-Authenticate"), resp, nil
}
// Client returns an HTTP client that uses the digest transport.
func (t *Transport) Client() (*http.Client, error) {
if t.Transport == nil {
return nil, ErrNilTransport
}
return &http.Client{Transport: t}, nil
}
when porting stuff with curl-to-to, it would be useful to see a list of options it ignored, then it would be much easier to spot options that needs to be ported manually
curl --socks5 127.0.0.1:1080 http://xyz.com
proxyUrl, err := url.Parse("socks5://127.0.0.1:1080")
httpClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}
u := "http://xyz.com"
req, err := http.NewRequest("GET", u, nil)
if err != nil {
panic(err)
}
resp, err := httpClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
log.Println(string(body))
Whenever doing a call, request timeout should be done. Typically, this would be around 15,000ms
Maybe, use goreq
instead? https://github.com/franela/goreq#user-content-setting-timeouts
Other timeout durations:
http://stackoverflow.com/questions/13582409/http-client-timeout-and-server-timeout
curl
timeout:
http://unix.stackexchange.com/questions/94604/does-curl-have-a-timeout/94612
Looking for a command line version that I can use -- is that possible?
While obvious to a lot of developers, it doesn't mention it requires "net/http".
Not sure if that's best in the generated Gocode or up in the description, but I think it's worth having somewhere on the page.
Are you requesting support for a new curl flag? If so, what is the flag and the equivalent Go code?
# (curl –X POST https://ssomesite.com/convert \
-F “media[file_data]=@/tmp/Example.wav;type=audio/x-wav” \
-F “account_did=5555555555” \
-F “api_key=a28f48da8da33402daef356abc567abfedc” \
-F “media[external_id]=123456789” \
-F “media[sender_id]=444-555-6666” \
-F “media[sender_name]=Mark Smith” \
-F “media[receiver_id]=333-555-1212” \
-F “media[receiver_name]=James Jones” \
-F “media[external_id]=4aef5432” \
-F “media[external_data]=Free-form text relative to your use case.”
// (no idea
I am looking at trying to make a complex request (like the above), and with the curl request (see above), code it up using the Go's net/http package.
Now, my main concern is that I am relatively new to the net/http package. It looks and feels pretty powerful, so I suspect this could be done. Your little curl-to-go program, and the example code have fired the imagination. I think I might be able to supply a -F option to code, but I need a nudge in the right direction.
If you were to code up (in go) the conversion, how would you (from a high-level perspective) do it? A little point in the right direction can get me started pretty quickly.
The curl above results in this sequence: (trace from curl):
== Info: About to connect() to eps-4voice.nuancemobility.net port 443 (#0)
== Info: Trying 8.39.192.14... == Info: connected
== Info: Connected to eps-4voice.nuancemobility.net (8.39.192.14) port 443 (#0)
== Info: Initializing NSS with certpath: sql:/etc/pki/nssdb
== Info: warning: ignoring value of ssl.verifyhost
== Info: skipping SSL peer certificate verification
== Info: NSS: client certificate not found (nickname not specified)
== Info: SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
== Info: Server certificate:
== Info: subject: CN=*.nuancemobility.net,OU=BOS,O=Nuance Communications Inc.,L=Burlington,ST=Massachusetts,C=US
== Info: start date: Jul 10 00:00:00 2020 GMT
== Info: expire date: Jul 11 12:00:00 2022 GMT
== Info: common name: *.nuancemobility.net
== Info: issuer: CN=DigiCert Global CA G2,O=DigiCert Inc,C=US
=> Send header, 344 bytes (0x158)
0000: POST /conversions/4voice-us-voicemail HTTP/1.1
0030: User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7
0070: NSS/3.44 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
00a0: Host: eps-4voice.nuancemobility.net
00c5: Accept: /
00d2: Content-Length: 202234
00ea: Expect: 100-continue
0100: Content-Type: multipart/form-data; boundary=--------------------
0140: --------744dab5b632c
0156:
<= Recv header, 23 bytes (0x17)
0000: HTTP/1.1 100 Continue
=> Send data, 187 bytes (0xbb)
0000: ------------------------------744dab5b632c
002c: Content-Disposition: form-data; name="media[file_data]"; filenam
006c: e="Example.wav"
009e: Content-Type: audio/x-wav
00b9:
=> Send data, 16383 bytes (0x3fff)
0000: RIFF$...WAVEfmt ........@....>......data.............. .........
0040: ............. .......(.........................................
0080: ................................................................
00c0: ................................................................
0100: ......0............. ............. .......0.....................
... (15 16k blocks of info snipped out...)
1080: ....D...............T...................t.............$.........
10c0: ............|$|.|,|&..............D.....D.<.............D...D.d.
1100: ..............<.......$.4...............
=> Send data, 1043 bytes (0x413)
0000:
0002: ------------------------------744dab5b632c
002e: Content-Disposition: form-data; name="account_did"
0062:
0064: 5555555555
0070: ------------------------------744dab5b632c
009c: Content-Disposition: form-data; name="api_key"
00cc:
00ce: a28f48da8da33402daef356abc567abfedc
00f8: ------------------------------744dab5b632c
0124: Content-Disposition: form-data; name="media[sender_id]"
015d:
015f: 444-555-6666
0164: ------------------------------744dab5b632c
0190: Content-Disposition: form-data; name="media[sender_name]"
01cb:
01cd: Mark Smith
01dc: ------------------------------744dab5b632c
0208: Content-Disposition: form-data; name="media[receiver_id]"
0243:
0245: 333-555-1212
025b: ------------------------------744dab5b632c
0287: Content-Disposition: form-data; name="media[receiver_name]"
02c4:
02c6: James Jones
02d9: ------------------------------744dab5b632c
0305: Content-Disposition: form-data; name="media[external_id]"
0340:
0342: 4aef5432
0362: ------------------------------744dab5b632c
038e: Content-Disposition: form-data; name="media[external_data]"
03cb:
03cd: Free-form text relative to your use case.
03e5: ------------------------------744dab5b632c--
Got any words of wisdom?
Hi the file.io has curl like this
curl -F "[email protected]" https://file.io
It doesn't seems like converts correctly by curl-to-go....
Hi,
The use of the default http client (resp, err := http.DefaultClient.Do(req)
causes a bug: when the response returns a redirection, go's default http client follows that redirection by default, while curl does not.
The client in use here should be changed from the default client to this:
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
This will fix this incolcnsistany with curl.
Cheers
That would be fairly awesome!
Given
curl -d "" google.com
the program generates:
body := strings.NewReader(`google.com`)
req, err := http.NewRequest("GET", "", body)
if err != nil {
// handle err
}
client := http.Client{}
resp, err := client.Do(req)
if err != nil {
// handle err
}
defer resp.Body.Close()
but curl
will perform a POST request, not GET
For GET, POST and HEAD http.Get()
, http.Post()
, http.Head()
methods are used respectively here which internally use http.DefaultClient
. I guess this is more of a suggestion, but why not use http.DefaultClient
to do requests made with http.NewRequest
also?
So instead of:
return 'req, err := http.NewRequest("'+method+'", "'+url+'", nil)\n'+err+'client := http.Client{}\nresp, err := client.Do(req)\n'+err+deferClose;
do
return 'req, err := http.NewRequest("'+method+'", "'+url+'", nil)\n'+err+'resp, err := http.DefaultClient.Do(req)\n'+err+deferClose;
and instead of:
// create the client and execute request
go += "\nclient := http.Client{}\nresp, err := client.Do(req)\n";
do
// create the client and execute request
go += "\nresp, err := http.DefaultClient.Do(req)\n";
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.