Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Self Destructing S3 Content Link Generator

[![GoDoc](https://godoc.org/github.com/markhayden/s3querybuilder?status.png)](https://godoc.org/github.com/markhayden/s3querybuilder)

## License
Contributors: Mark Hayden
Tags: go, golang, s3, aws, amazon web services, s3querybuilder
Expand All @@ -8,8 +10,44 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html

## Overview

This is a simple package used for generating the full encoded url to allow a user download access for a single file in a AWS S3 bucket. Generated link includes a expiration setting to ensure bucket security. Expiration is set by the second.
This is a simple package used for generating the full encoded url to allow an anonymous user to access a single file in a AWS S3 bucket. Generated link includes a expiration setting to ensure bucket security. Expiration is set by the second.

You can specify an HTTP verb such as `PUT` to allow users to upload an specific file, if no verb is specified it defaults to `GET`, allowing the file to be downloaded.

`go get github.com/markhayden/s3querybuilder`

## Usage (Coming Soon)
## Usage

### Generate a URL which expires in 5 minutes to download a file from s3


```Go
q := s3querybuilder.Cfg{
File: "file.txt",
Bucket: "my-s3-bucket",
AccessKey: "<AWS_KEY>",
SecretKey: "<AWS_KEY_SECRET>",
Expire: 300,
}
fmt.Println(q.Link())
```

### Generate a URL to upload a file to s3

```Go
q := s3querybuilder.Cfg{
File: "file.txt",
Bucket: "my-s3-bucket",
AccessKey: "<AWS_KEY>",
SecretKey: "<AWS_KEY_SECRET>",
HTTPVerb: "PUT",
Expire: 300,
}
fmt.Println(q.Link())
```

This will output the URL, you can use it with curl for example:

```curl -v -X PUT --upload-file "file.txt" "<URL>"```

Notice that you must put the URL inside double quotes or curl will not send all the query parameters.
25 changes: 17 additions & 8 deletions s3querybuilder.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package s3querybuilder is used for generating the full encoded url to allow an anonymous user to access a single file in a AWS S3 bucket
package s3querybuilder

import (
Expand All @@ -11,26 +12,34 @@ import (

// Cfg containts the necessary params to generate a secure, self destructing s3 download url
type Cfg struct {
File string
Bucket string
AccessKey string
SecretKey string
Expire int
File string
Bucket string
AccessKey string
SecretKey string
HTTPVerb string // Defaults to GET if not specified
ContentMD5 string // Optional
ContentType string // Optional, S3 will default to octet/stream if not specified
Expire int // Seconds for the URL to expire
}

// Link creates the necessary headers / signatures for anonymous user to download assets from s3 bucket
// Link creates the necessary headers / signatures for anonymous user to download/upload assets from s3 bucket
func (d *Cfg) Link() string {
// convert date to string so it doesnt explode
expiration := time.Now().Unix() + int64(d.Expire)

// generate base url from the bucket name
s3BaseURL := "http://" + d.Bucket + ".s3.amazonaws.com"
s3BaseURL := "https://" + d.Bucket + ".s3.amazonaws.com"

// prepare the uri for the selected file
uri := "/" + d.Bucket + "/" + d.File

// defaults to GET to not break compatibility
if d.HTTPVerb == "" {
d.HTTPVerb = "GET"
}

// generate the aws message in preparation for signature generation
message := fmt.Sprintf("GET\n\n\n%d\n%s", expiration, uri)
message := fmt.Sprintf("%s\n%s\n%s\n%d\n%s", d.HTTPVerb, d.ContentMD5, d.ContentType, expiration, uri)

// generate a signature for aws handshake
sha256 := sha1.New
Expand Down