file-upload curl go multipart

file upload - datos POST de golang utilizando el contenido de tipo multipart/form-data



file-upload curl (3)

Aquí hay un código de muestra.

En resumen, deberá usar el paquete mime/multipart para compilar el formulario.

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 }

Estoy intentando subir imágenes de mi computadora a un sitio web usando ir. Por lo general, utilizo un script bash que envía una clave al servidor:

curl -F "image"=@"IMAGEFILE" -F "key"="KEY" URL

funciona bien, pero estoy tratando de convertir esta solicitud en mi programa de golang.

http://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/

Intenté este enlace y muchos otros. Pero para cada código que intento, la respuesta para el servidor es "sin imagen enviada". Y no tengo idea de por qué. Si alguien sabe lo que pasó con el ejemplo anterior.

Gracias


Con respecto a la publicación de attila-o, el encabezado de la solicitud no tiene el límite ya que el escritor está cerrado.

// after the close, the bounday will be nil. w.Close() ... req.Header.Set("Content-Type", w.FormDataContentType())

Entonces, debería cerrarse después del set, creo.

req.Header.Set("Content-Type", w.FormDataContentType()) w.Close()


He encontrado este tutorial muy útil para aclarar mis confusiones sobre la carga de archivos en Go.

Básicamente, cargue el archivo a través de ajax usando form-data en un cliente y use el siguiente pequeño fragmento de código Go en el servidor:

file, handler, err := r.FormFile("img") // img is the key of the form-data if err != nil { fmt.Println(err) return } defer file.Close() fmt.Println("File is good") fmt.Println(handler.Filename) fmt.Println() fmt.Println(handler.Header) f, err := os.OpenFile(handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { fmt.Println(err) return } defer f.Close() io.Copy(f, file)

Aquí está r *http.Request . PD esto solo almacena el archivo en la misma carpeta y no realiza ninguna comprobación de seguridad.