1package s3crypto 2 3import ( 4 "errors" 5 "io" 6 "io/ioutil" 7 "os" 8 9 "github.com/aws/aws-sdk-go/aws/request" 10) 11 12func getWriterStore(req *request.Request, path string, useTempFile bool) (io.ReadWriteSeeker, error) { 13 if !useTempFile { 14 return &bytesReadWriteSeeker{}, nil 15 } 16 // Create temp file to be used later for calculating the SHA256 header 17 f, err := ioutil.TempFile(path, "") 18 if err != nil { 19 return nil, err 20 } 21 22 req.Handlers.Complete.PushBack(func(r *request.Request) { 23 // Close the temp file and cleanup 24 f.Close() 25 os.Remove(f.Name()) 26 }) 27 return f, nil 28} 29 30type bytesReadWriteSeeker struct { 31 buf []byte 32 i int64 33} 34 35// Copied from Go stdlib bytes.Reader 36func (ws *bytesReadWriteSeeker) Read(b []byte) (int, error) { 37 if ws.i >= int64(len(ws.buf)) { 38 return 0, io.EOF 39 } 40 n := copy(b, ws.buf[ws.i:]) 41 ws.i += int64(n) 42 return n, nil 43} 44 45func (ws *bytesReadWriteSeeker) Write(b []byte) (int, error) { 46 ws.buf = append(ws.buf, b...) 47 return len(b), nil 48} 49 50// Copied from Go stdlib bytes.Reader 51func (ws *bytesReadWriteSeeker) Seek(offset int64, whence int) (int64, error) { 52 var abs int64 53 switch whence { 54 case 0: 55 abs = offset 56 case 1: 57 abs = int64(ws.i) + offset 58 case 2: 59 abs = int64(len(ws.buf)) + offset 60 default: 61 return 0, errors.New("bytes.Reader.Seek: invalid whence") 62 } 63 if abs < 0 { 64 return 0, errors.New("bytes.Reader.Seek: negative position") 65 } 66 ws.i = abs 67 return abs, nil 68} 69