GoLang send file via POST request

20,612

Solution 1

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)

}

Solution 2

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.

Share:
20,612
vladimir
Author by

vladimir

Updated on August 31, 2021

Comments

  • vladimir
    vladimir over 2 years

    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?