with golang application app go multipartform-data httpserver

application - ¿Cómo puedo recibir un archivo cargado utilizando un servidor Golang net/http?



web application golang (3)

Aquí hay un ejemplo rápido

func ReceiveFile(w http.ResponseWriter, r *http.Request) { var Buf bytes.Buffer // in your case file would be fileupload file, header, err := r.FormFile("file") if err != nil { panic(err) } defer file.Close() name := strings.Split(header.Filename, ".") fmt.Printf("File name %s/n", name[0]) // Copy the file data to my buffer io.Copy(&Buf, file) // do something with the contents... // I normally have a struct defined and unmarshal into a struct, but this will // work as an example contents := Buf.String() fmt.Println(contents) // I reset the buffer in case I want to use it again // reduces memory allocations in more intense projects Buf.Reset() // do something else // etc write header return }

Estoy jugando con Mux y net/http . Últimamente, estoy tratando de obtener un servidor simple con un punto final para aceptar la carga de un archivo.

Aquí está el código que tengo hasta ahora:

server.go

package main import ( "fmt" "github.com/gorilla/mux" "log" "net/http" ) func main() { router := mux.NewRouter() router. Path("/upload"). Methods("POST"). HandlerFunc(UploadCsv) fmt.Println("Starting") log.Fatal(http.ListenAndServe(":8080", router)) }

endpoint.go

package main import ( "fmt" "net/http" ) func UploadFile(w http.ResponseWriter, r *http.Request) { err := r.ParseMultipartForm(5 * 1024 * 1024) if err != nil { panic(err) } fmt.Println(r.FormValue("fileupload")) }

Creo que he reducido el problema para recuperar realmente el cuerpo de la solicitud dentro de UploadFile . Cuando ejecuto este comando cURL:

curl http://localhost:8080/upload -F "[email protected]" -vvv

Recibo una respuesta en blanco (como se esperaba, no estoy imprimiendo en el ResponseWriter ), pero solo imprimo una nueva línea (vacía) en el indicador donde ejecuto el servidor, en lugar del cuerpo de la solicitud.

Estoy enviando el archivo como multiparte (AFAIK, implícito mediante el uso de -F lugar de -d en cURL), y la salida detallada de cURL muestra 502 bytes enviados:

$ curl http://localhost:8080/upload -F "[email protected]" -vvv * Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > POST /upload HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.51.0 > Accept: */* > Content-Length: 520 > Expect: 100-continue > Content-Type: multipart/form-data; boundary=------------------------b578878d86779dc5 > < HTTP/1.1 100 Continue < HTTP/1.1 200 OK < Date: Fri, 18 Nov 2016 19:01:50 GMT < Content-Length: 0 < Content-Type: text/plain; charset=utf-8 < * Curl_http_done: called premature == 0 * Connection #0 to host localhost left intact

¿Cuál es la forma correcta de recibir archivos cargados como datos de formulario de varias partes utilizando un servidor net/http en Go?


Aquí hay una función que escribí para ayudarme a subir mis archivos. Puede consultar la versión completa aquí. Cómo subir archivos en golang

package helpers import ( "net/http" "os" "io" ) func FileUpload(r *http.Request) (string, error) { //this function returns the filename(to save in database) of the saved file or an error if it occurs r.ParseMultipartForm(32 << 20) //ParseMultipartForm parses a request body as multipart/form-data var file_name string var errors error file, handler, err := r.FormFile("file")//retrieve the file from form data defer file.Close() //close the file when we finish if err != nil { errors = err } //this is path which we want to store the file f, err := os.OpenFile("./images/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { errors = err } file_name = handler.Filename defer f.Close() io.Copy(f, file) //here we save our file to our path return file_name, errors }


Debe usar FormFile lugar de FormValue :

file, handler, err := r.FormFile("fileupload") defer file.Close() // copy example f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) defer f.Close() io.Copy(f, file)