festlegen Ich habe eine Funktion zum Downloaden einer Datei von S3. Es funktioniert, erkennt die Option IfModifiedSince jedoch nicht. Die folgende Funktion sucht lokal nach der gleichen benannten Datei und setzt, falls vorhanden, ein time.Time-Objekt auf das Änderungsdatum und die Änderungszeit. Dies wird dann in der Anforderung an S3 verwendet, die Datei nur herunterzuladen, wenn sie seither modifiziert wurde.Wie If-Modified-Since-Header in AWS S3 mithilfe von Go
func DownloadS3Media(filename string, mediaDirectory string, bucket string, c *configuration.Configuration) (dest string, bytes int64, err error) {
os.Setenv("AWS_ACCESS_KEY_ID", c.AWS_ACCESS_KEY_ID)
os.Setenv("AWS_SECRET_ACCESS_KEY", c.AWS_SECRET_ACCESS_KEY)
// Create the directories in the path
finalFilePath := filepath.Join(mediaDirectory, filename)
if err1 := os.MkdirAll(filepath.Dir(finalFilePath), 0775); err1 != nil {
return "", 0, err1
}
//Create the blank file to push the data into
var t *time.Time
if fi, err2 := os.Stat(finalFilePath); err2 == nil {
t1 := fi.ModTime()
t = &t1
}
tempFilePath := filepath.Join(mediaDirectory, filename + ".tmp")
tempFile, err3 := os.Create(tempFilePath)
if err3 != nil {
log.Println("Failed to create file", err3)
return finalFilePath, 0, err3
}
defer tempFile.Close()
logLevel := aws.LogDebug
downloader := s3manager.NewDownloader(session.New(&aws.Config{Region: aws.String("us-east-1"), LogLevel:&logLevel}))
params := &s3.GetObjectInput{Bucket: aws.String(bucket),
Key: aws.String(filename),
IfModifiedSince: t}
numBytes, err4 := downloader.Download(tempFile, params)
if err4 != nil {
log.Println("Failed to download file", err4)
return finalFilePath, 0, err4
}
//if downloader pulled down the file, rename the tmp file to original.
if _, err5 := os.Stat(tempFilePath); err5 == nil {
os.Rename(tempFilePath, finalFilePath)
log.Println("Renamed ", tempFilePath, "to", finalFilePath)
}
log.Println("Downloaded file", filename, "to", finalFilePath, numBytes, "bytes")
return finalFilePath, numBytes, nil
}
Beim Debuggen, sehe ich den richtigen Wert für & t, die so etwas wie sec: 63606119179
ist. Zu dem Zeitpunkt, zu dem AWS die Anforderung sendet, ist der Header vorhanden, wird jedoch auf 1/1/0001 festgelegt.
---[ REQUEST POST-SIGN ]-----------------------------
GET http://*****.s3.amazonaws.com/domenic-test.png HTTP/1.1
Host: *****.s3.amazonaws.com
User-Agent: aws-sdk-go/1.3.1 (go1.6.3; darwin; amd64) S3Manager
Authorization: AWS4-HMAC-SHA256 Credential= *****/20160806/us-east-1/s3/aws4_request, SignedHeaders=host;if-modified-since;range;x-amz-content-sha256;x-amz-date, Signature= *****
If-Modified-Since: Mon, 1 Jan 0001 00:00:00 GMT
Range: bytes=0-5242879
X-Amz-Content-Sha256: *****
X-Amz-Date: 20160806T223302Z
Dies endete als ein Fehler im Amazon-Code, der seitdem korrigiert und veröffentlicht wurde. –