Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GoLang send file via POST request

I am new in GoLang language, and I want to create REST API WebServer for file uploading...

So I am stuck in main function (file uploading) via POST request to my server...

I have this line for calling upload function

router.POST("/upload", UploadFile)

and this is my upload function:

func UploadFile( w http.ResponseWriter, r *http.Request, _ httprouter.Params ) {
    io.WriteString(w, "Upload files\n")
    postFile( r.Form.Get("file"), "/uploads" )
}

func postFile(filename string, targetUrl string) error {
    bodyBuf := &bytes.Buffer{}
    bodyWriter := multipart.NewWriter(bodyBuf)

    // this step is very important
    fileWriter, err := bodyWriter.CreateFormFile("file", filename)
    if err != nil {
        fmt.Println("error writing to buffer")
        return err
    }

    // open file handle
    fh, err := os.Open(filename)
    if err != nil {
        fmt.Println("error opening file")
        return err
    }

    //iocopy
    _, err = io.Copy(fileWriter, fh)
    if err != nil {
        panic(err)
    }

    bodyWriter.FormDataContentType()
    bodyWriter.Close()

    return err

}

but I can't see any uploaded files in my /upload/ directory...

So what am I doing wrong?

P.S I am getting second error => error opening file, so I think something wrong in file uploading or getting file from UploadFile function, am I right? If yes, than how I can teancfer or get file from this function to postFile function?

like image 616
vladimir Avatar asked Aug 07 '17 07:08

vladimir


People also ask

What is the difference between get and post in Golang?

The HTTP GET method requests a representation of the specified resource. Requests using GET should only retrieve data. The HTTP POST method sends data to the server. It is often used when uploading a file or when submitting a completed web form. In Go, we use the http package to create GET and POST requests.

What is the HTTP package in Golang?

Golang http package offers convenient functions like Get, Post, Head for common http requests. In addition, the http package provides HTTP client and server implementations. Let’s see the following example. In this example, we’re calling http.Get, which gives us a response and error value.

How do I create a get and POST request in go?

In Go, we use the http package to create GET and POST requests. The package provides HTTP client and server implementations. The following example creates a simple GET request in Go. We create a GET request to the webcode.me webpage.

What is file uploading in Golang?

Golang file uploading File uploading is an essential part of many great applications of our time but can be challenging to implement in our own applications. In this article, you will build a simple file uploading HTTP server in Golang that allows you to upload files to the server running the application.


2 Answers

The multipart.Writer generates multipart messages, this is not something you want to use for receiving a file from a client and saving it to disk.

Assuming you're uploading the file from a client, e.g. a browser, with Content-Type: application/x-www-form-urlencoded you should use FormFile instead of r.Form.Get which returns a *multipart.File value that contains the content of the file the client sent and which you can use to write that content to disk with io.Copy or what not.

like image 92
mkopriva Avatar answered Sep 30 '22 15:09

mkopriva


os.Open will open a file, since the file doesn't exist you will get an error. Use os.Create instead it will create a new file and open it. (ref: https://golang.org/pkg/os/#Open)

func Open

func Open(name string) (*File, error)

Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY. If there is an error, it will be of type *PathError.

func Create

func Create(name string) (*File, error)

Create creates the named file with mode 0666 (before umask), truncating it if it already exists. If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR. If there is an error, it will be of type *PathError.

EDIT

Made a new handler as an example: And also using OpenFile as mentioned by: GoLang send file via POST request

func Upload(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Upload files\n")

    file, handler, err := r.FormFile("file")
    if err != nil {
        panic(err) //dont do this
    }
    defer file.Close()

    // copy example
    f, err := os.OpenFile(handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
    if err != nil {
        panic(err) //please dont
    }
    defer f.Close()
    io.Copy(f, file)

}
like image 45
Fredrik Mårlind Avatar answered Sep 30 '22 15:09

Fredrik Mårlind