1//go:build example && go1.7
2// +build example,go1.7
3
4package main
5
6import (
7	"context"
8	"flag"
9	"fmt"
10	"os"
11	"time"
12
13	"github.com/aws/aws-sdk-go/aws"
14	"github.com/aws/aws-sdk-go/aws/awserr"
15	"github.com/aws/aws-sdk-go/aws/request"
16	"github.com/aws/aws-sdk-go/aws/session"
17	"github.com/aws/aws-sdk-go/service/s3"
18)
19
20// Uploads a file to S3 given a bucket and object key. Also takes a duration
21// value to terminate the update if it doesn't complete within that time.
22//
23// The AWS Region needs to be provided in the AWS shared config or on the
24// environment variable as `AWS_REGION`. Credentials also must be provided
25// Will default to shared config file, but can load from environment if provided.
26//
27// Usage:
28//   # Upload myfile.txt to myBucket/myKey. Must complete within 10 minutes or will fail
29//   go run withContext.go -b mybucket -k myKey -d 10m < myfile.txt
30func main() {
31	var bucket, key string
32	var timeout time.Duration
33
34	flag.StringVar(&bucket, "b", "", "Bucket name.")
35	flag.StringVar(&key, "k", "", "Object key name.")
36	flag.DurationVar(&timeout, "d", 0, "Upload timeout.")
37	flag.Parse()
38
39	sess := session.Must(session.NewSession())
40	svc := s3.New(sess)
41
42	// Create a context with a timeout that will abort the upload if it takes
43	// more than the passed in timeout.
44	ctx := context.Background()
45	var cancelFn func()
46	if timeout > 0 {
47		ctx, cancelFn = context.WithTimeout(ctx, timeout)
48	}
49	// Ensure the context is canceled to prevent leaking.
50	// See context package for more information, https://golang.org/pkg/context/
51	defer cancelFn()
52
53	// Uploads the object to S3. The Context will interrupt the request if the
54	// timeout expires.
55	_, err := svc.PutObjectWithContext(ctx, &s3.PutObjectInput{
56		Bucket: aws.String(bucket),
57		Key:    aws.String(key),
58		Body:   os.Stdin,
59	})
60	if err != nil {
61		if aerr, ok := err.(awserr.Error); ok && aerr.Code() == request.CanceledErrorCode {
62			// If the SDK can determine the request or retry delay was canceled
63			// by a context the CanceledErrorCode error code will be returned.
64			fmt.Fprintf(os.Stderr, "upload canceled due to timeout, %v\n", err)
65		} else {
66			fmt.Fprintf(os.Stderr, "failed to upload object, %v\n", err)
67		}
68		os.Exit(1)
69	}
70
71	fmt.Printf("successfully uploaded file to %s/%s\n", bucket, key)
72}
73