golang 上传图片到aws s3 bucket

  • Post author:
  • Post category:golang




一、创建aws账户,以及s3 bucket

首先,创建一个aws账户,可以在

这里

创建。

创建账户后,进入控制台,在storage分类中选择s3 服务。

在s3控制台,创建一个新的bucket,命名友好一些,因为bucket命名将会成为url的一部分。

bucket创建完以后,可以用来存储文件,此处即用来存储图片。



二、上传图片编码

开始之前,我们需要先从github上安装aws sdk,可以通过下边代码在终端上执行来完成。

$ go get github.com/aws/aws-sdk-go/...

下边是server代码,用一个handler来处理文件上传到路由/的请求。

package main

import (
	"net/http"
	"log"
	"fmt"
	"mime/multipart"
	"bytes"
	"path/filepath"
	
	"github.com/globalsign/mgo/bson"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
)

// UploadFileToS3 上传文件到aws bucket,并且返回文件url以及可能出现的错误
func UploadFileToS3(s *session.Session, file multipart.File, fileHeader *multipart.FileHeader) (string, error) {
  // get the file size and read
  // the file content into a buffer
  size := fileHeader.Size
  buffer := make([]byte, size)
  file.Read(buffer)

  // create a unique file name for the file
  // 此处文件名称即为上传到aws bucket的名称,也是文件url路径的一部分。也可以在此处拼接url全路径,把域名部分拼接在前边即可。
  tempFileName := "pictures/" + bson.NewObjectId().Hex()  +  filepath.Ext(fileHeader.Filename)
	
  // config settings: this is where you choose the bucket,
  // filename, content-type and storage class of the file
  // you're uploading
  _, err := s3.New(s).PutObject(&s3.PutObjectInput{
     Bucket:               aws.String("test-bucket"),  // bucket名称,把自己创建的bucket名称替换到此处即可
     Key:                  aws.String(tempFileName),
     ACL:                  aws.String("public-read"),// could be private if you want it to be access by only authorized users
     Body:                 bytes.NewReader(buffer),
     ContentLength:        aws.Int64(int64(size)),
     ContentType:        aws.String(http.DetectContentType(buffer)),
     ContentDisposition:   aws.String("attachment"),
     ServerSideEncryption: aws.String("AES256"),
     StorageClass:         aws.String("INTELLIGENT_TIERING"),
  })
  if err != nil {
     return "", err
  }

  return tempFileName, err
}

// handler 处理上传图片请求
func handler(w http.ResponseWriter, r *http.Request) {
	maxSize := int64(1024000) // allow only 1MB of file size

	err := r.ParseMultipartForm(maxSize)
	if err != nil {
	   log.Println(err)
	   fmt.Fprintf(w, "Image too large. Max Size: %v", maxSize)
	   return
	}

   // 文件上传为post请求, formdata file格式
	file, fileHeader, err := r.FormFile("profile_picture")
	if err != nil {
		log.Println(err)
		fmt.Fprintf(w, "Could not get uploaded file")
		return
	}
	defer file.Close()

	// create an AWS session which can be
	// reused if we're uploading many files
	s, err := session.NewSession(&aws.Config{
		Region: aws.String("us-east-2"),  // 替换自己账户的region
		Credentials: credentials.NewStaticCredentials(
			"secret-id", // 替换成自己账户的secret-id
			"secret-key",   // 替换成自己账户的secret-key
			""),  // token can be left blank for now
	})
	if err != nil {
		fmt.Fprintf(w, "Could not upload file")
	}

	fileName, err := UploadFileToS3(s, file, fileHeader)
	if err != nil {
		fmt.Fprintf(w, "Could not upload file")
	}

	fmt.Fprintf(w, "Image uploaded successfully: %v", fileName)
}

func main() {
	http.HandleFunc("/", handler)
	log.Println("Upload server started")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

备注:


ACL

:文件授权类型,可以是public-read、private或者是其他

此处

列表里的内容。


Session

:上传文件到aws时需要创建一个session,每次请求可以复用。创建session需要 bucket region、secret i、secret_key这几个参数,这些参数可以用IAM 控制台获取,不知道怎么获取的可以点击

此处

参考资料:


Upload images to AWS S3 bucket in a golang web application