Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Enforcing content addressed storage on S3 with signed URLs and sha256 hashes
package main
import (
"crypto/sha256"
"encoding/hex"
"flag"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
func main() {
bucket := "tmp.myriabit.eu"
flag.StringVar(&bucket, "bucket", bucket, "Bucket to use")
flag.Parse()
if len(flag.Args()) != 1 {
fmt.Println("Expect a filename")
os.Exit(1)
}
filename := flag.Args()[0]
fileReader, err := os.Open(filename)
if err != nil {
fmt.Println("Cannot open file:", err)
os.Exit(1)
}
defer fileReader.Close()
hf := sha256.New()
if _, err := io.Copy(hf, fileReader); err != nil {
fmt.Println("%v", err)
os.Exit(1)
}
if _, err := fileReader.Seek(0, 0); err != nil {
fmt.Println("%v", err)
os.Exit(1)
}
h := hex.EncodeToString(hf.Sum(nil))
fmt.Printf("sha256 hash is %s\n", h)
url, err := vURL(bucket, h)
if err != nil {
fmt.Println("%v", err)
os.Exit(1)
}
fmt.Println("URL", url)
st, err := fileReader.Stat()
if err != nil {
fmt.Println("Cannot stat file:", err)
os.Exit(1)
}
req, err := http.NewRequest("PUT", url, fileReader)
if err != nil {
fmt.Println("error creating request", url)
os.Exit(1)
}
req.ContentLength = st.Size()
req.Header.Add("x-amz-content-sha256", h)
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("failed making request")
os.Exit(1)
}
defer resp.Body.Close()
if resp.StatusCode > 299 {
fmt.Printf("Bad response code: %d\n", resp.StatusCode)
io.Copy(os.Stdout, resp.Body)
os.Exit(1)
}
fmt.Printf("%s\n", resp.Status)
}
func vURL(bucket, h string) (string, error) {
svc := s3.New(session.New())
r, _ := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(h),
})
r.HTTPRequest.Header.Set("x-amz-content-sha256", h)
url, err := r.Presign(15 * time.Minute)
if err != nil {
fmt.Println("error presigning request", err)
return "", err
}
return url, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.