Multiple File Upload Handling in Golang to Amazon S3

Estimated read time 3 min read

Handling multiple file uploads to Amazon S3 in a Golang web application involves a combination of client-side HTML, server-side Golang code, and integration with the AWS SDK for Go (AWS SDK).

1. Server-Side Handling with Gin and AWS SDK:

1.1 Install Required Packages:

Ensure you have the necessary packages installed for Gin and the AWS SDK.

go get -u github.com/gin-gonic/gin
go get -u github.com/aws/aws-sdk-go/aws
go get -u github.com/aws/aws-sdk-go/aws/session
go get -u github.com/aws/aws-sdk-go/service/s3

1.2 Set Up Your Golang Web Server:

package main

import (
    "fmt"
    "log"
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

const (
    awsRegion      = "your-aws-region"
    awsBucketName  = "your-s3-bucket-name"
    awsAccessKey   = "your-aws-access-key"
    awsSecretKey   = "your-aws-secret-key"
    uploadsFolder  = "uploads/"
    maxUploadSize  = 10 << 20 // 10 MB
    formFieldName  = "files"
)

func main() {
    router := gin.Default()

    router.Static("/uploads", "./uploads")

    router.POST("/upload", uploadHandler)

    router.Run(":8080")
}

1.3 Handle File Uploads and Send to Amazon S3:

func uploadHandler(c *gin.Context) {
    err := c.Request.ParseMultipartForm(maxUploadSize)
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "File size limit exceeded"})
        return
    }

    form, err := c.MultipartForm()
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Error parsing form"})
        return
    }

    sess, err := session.NewSession(&aws.Config{
        Region:      aws.String(awsRegion),
        Credentials: credentials.NewStaticCredentials(awsAccessKey, awsSecretKey, ""),
    })
    if err != nil {
        log.Fatal(err)
    }

    svc := s3.New(sess)
    for _, files := range form.File {
        for _, file := range files {
            f, err := file.Open()
            if err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{"error": "Error opening file"})
                return
            }
            defer f.Close()

            fileBytes, err := ioutil.ReadAll(f)
            if err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{"error": "Error reading file"})
                return
            }

            fileType := http.DetectContentType(fileBytes)
            fileName := filepath.Base(file.Filename)

            params := &s3.PutObjectInput{
                Bucket:        aws.String(awsBucketName),
                Key:           aws.String(uploadsFolder + fileName),
                Body:          bytes.NewReader(fileBytes),
                ContentLength: aws.Int64(file.Size),
                ContentType:   aws.String(fileType),
            }

            _, err = svc.PutObject(params)
            if err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{"error": "Error uploading file to S3"})
                return
            }
        }
    }

    c.JSON(http.StatusOK, gin.H{"message": "Files uploaded successfully"})
}

2. Client-Side HTML Form:

Create an HTML form to allow users to select and upload multiple files.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Multiple File Upload to Amazon S3</title>
</head>
<body>
    <form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
        <label for="files">Select multiple files:</label>
        <input type="file" id="files" name="files" multiple>
        <button type="submit">Upload to S3</button>
    </form>
</body>
</html>

3. Testing the Setup:

  1. Ensure your Golang server is running.
  2. Open the HTML form in a browser.
  3. Select multiple files.
  4. Submit the form to trigger the file upload to Amazon S3.

Conclusion:

Integrating multiple file uploads in a Golang web application with Amazon S3 requires combining server-side Golang code with client-side HTML. Utilizing the AWS SDK for Go simplifies the process of sending files to an S3 bucket. Adjust the AWS configuration, folder paths, and other parameters based on your project’s requirements. This example provides a solid foundation for efficiently handling multiple file uploads to Amazon S3 in a Golang web application. Happy coding!

Related Articles