Created
January 25, 2023 00:35
-
-
Save manilz/99b1a1d5a93594301d37f806427aaab7 to your computer and use it in GitHub Desktop.
Golang POST request with multipart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"fmt" | |
"io" | |
"mime/multipart" | |
"net/http" | |
"net/http/httptest" | |
"net/http/httputil" | |
"os" | |
"strings" | |
) | |
func main() { | |
var client *http.Client | |
var remoteURL string | |
{ | |
//setup a mocked http client. | |
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
b, err := httputil.DumpRequest(r, true) | |
if err != nil { | |
panic(err) | |
} | |
fmt.Printf("%s", b) | |
})) | |
defer ts.Close() | |
client = ts.Client() | |
remoteURL = ts.URL | |
} | |
//prepare the reader instances to encode | |
values := map[string]io.Reader{ | |
"file": mustOpen("main.go"), // lets assume its this file | |
"other": strings.NewReader("hello world!"), | |
} | |
err := Upload(client, remoteURL, values) | |
if err != nil { | |
panic(err) | |
} | |
} | |
func Upload(client *http.Client, url string, values map[string]io.Reader) (err error) { | |
// Prepare a form that you will submit to that URL. | |
var b bytes.Buffer | |
w := multipart.NewWriter(&b) | |
for key, r := range values { | |
var fw io.Writer | |
if x, ok := r.(io.Closer); ok { | |
defer x.Close() | |
} | |
// Add an image file | |
if x, ok := r.(*os.File); ok { | |
if fw, err = w.CreateFormFile(key, x.Name()); err != nil { | |
return | |
} | |
} else { | |
// Add other fields | |
if fw, err = w.CreateFormField(key); err != nil { | |
return | |
} | |
} | |
if _, err = io.Copy(fw, r); err != nil { | |
return err | |
} | |
} | |
// Don't forget to close the multipart writer. | |
// If you don't close it, your request will be missing the terminating boundary. | |
w.Close() | |
// Now that you have a form, you can submit it to your handler. | |
req, err := http.NewRequest("POST", url, &b) | |
if err != nil { | |
return | |
} | |
// Don't forget to set the content type, this will contain the boundary. | |
req.Header.Set("Content-Type", w.FormDataContentType()) | |
// Submit the request | |
res, err := client.Do(req) | |
if err != nil { | |
return | |
} | |
// Check the response | |
if res.StatusCode != http.StatusOK { | |
err = fmt.Errorf("bad status: %s", res.Status) | |
} | |
return | |
} | |
func mustOpen(f string) *os.File { | |
r, err := os.Open(f) | |
if err != nil { | |
panic(err) | |
} | |
return r | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment