Storing Files in S3 with Go

Storing Files in S3 with Go

This Go program uploads a file to an S3 bucket and then downloads and reads that same file from S3.

It's surprisingly difficult to find a straightforward tutorial on how to write to and read from S3. I need this in almost every language I utilize and in every language it has its own intricacies!

package main

import (
    "bytes"
    "fmt"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
    "io"
    "net/http"
)

const S3_REGION = "us-west-2"
const S3_BUCKET = "your-bucket-here"

type S3Handler struct {
    Session *session.Session
    Bucket  string
}

func main() {
    sess, err := session.NewSession(&aws.Config{Region: aws.String(S3_REGION)})
    if err != nil {
        // Handle error
    }

    handler := S3Handler{
        Session: sess,
        Bucket:  S3_BUCKET,
    }

    err = handler.UploadFile("test-file", "This is a test file")
    if err != nil {
        // Handle error
    }

    contents, err := handler.ReadFile("test-file")
    if err != nil {
        // Handle error
    }

    fmt.Println(contents) // "This is a test file"
}

func (h S3Handler) UploadFile(key string, body string) error {
    buffer := []byte(body)

    _, err := s3.New(h.Session).PutObject(&s3.PutObjectInput{
        Bucket:               aws.String(h.Bucket),
        Key:                  aws.String(key),
        ACL:                  aws.String("private"),
        Body:                 bytes.NewReader(buffer),
        ContentLength:        aws.Int64(int64(len(buffer))),
        ContentType:          aws.String(http.DetectContentType(buffer)),
        ContentDisposition:   aws.String("attachment"),
        ServerSideEncryption: aws.String("AES256"),
    })

    return err
}

func (h S3Handler) ReadFile(key string) (string, error) {
    results, err := s3.New(h.Session).GetObject(&s3.GetObjectInput{
        Bucket: aws.String(h.Bucket),
        Key:    aws.String(key),
    })
    if err != nil {
        return "", err
    }
    defer results.Body.Close()

    buf := bytes.NewBuffer(nil)
    if _, err := io.Copy(buf, results.Body); err != nil {
        return "", err
    }
    return string(buf.Bytes()), nil
}

Gotchas

Be sure to either use the aws configure command via the AWS CLI or set the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY before running your go application.

Also - Make sure to set the S3_BUCKET constant to a bucket you have created and have permission to write to and read from.

Using Github OAuth2 with Go

Using Github OAuth2 with Go

Extending a Struct in Go

Extending a Struct in Go