Skip to content

Updated the KeyExists from aws to keep the response metadata in the image resolver #317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
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
Original file line number Diff line number Diff line change
@@ -108,12 +108,13 @@ public async Task<IImageResolver> GetAsync(HttpContext context)
return null;
}

if (!await KeyExists(s3Client, bucketName, key))
KeyExistsResult keyExists = await KeyExists(s3Client, bucketName, key);
if (!keyExists.Exists)
{
return null;
}

return new AWSS3StorageImageResolver(s3Client, bucketName, key);
return new AWSS3StorageImageResolver(s3Client, bucketName, key, keyExists.Metadata);
}

private bool IsMatch(HttpContext context)
@@ -133,39 +134,40 @@ private bool IsMatch(HttpContext context)
}

// ref https://github.com/aws/aws-sdk-net/blob/master/sdk/src/Services/S3/Custom/_bcl/IO/S3FileInfo.cs#L118
private static async Task<bool> KeyExists(IAmazonS3 s3Client, string bucketName, string key)
private static async Task<KeyExistsResult> KeyExists(IAmazonS3 s3Client, string bucketName, string key)
{
try
{
GetObjectMetadataRequest request = new()
{
BucketName = bucketName,
Key = key
};
GetObjectMetadataRequest request = new() { BucketName = bucketName, Key = key };

// If the object doesn't exist then a "NotFound" will be thrown
await s3Client.GetObjectMetadataAsync(request);
return true;
GetObjectMetadataResponse metadata = await s3Client.GetObjectMetadataAsync(request);
return new KeyExistsResult(metadata);
}
catch (AmazonS3Exception e)
{
if (string.Equals(e.ErrorCode, "NoSuchBucket", StringComparison.Ordinal))
{
return false;
return default;
}

if (string.Equals(e.ErrorCode, "NotFound", StringComparison.Ordinal))
{
return false;
return default;
}

// If the object exists but the client is not authorized to access it, then a "Forbidden" will be thrown.
if (string.Equals(e.ErrorCode, "Forbidden", StringComparison.Ordinal))
{
return false;
return default;
}

throw;
}
}

private readonly record struct KeyExistsResult(GetObjectMetadataResponse Metadata)
{
public bool Exists => this.Metadata is not null;
}
}
Original file line number Diff line number Diff line change
@@ -16,24 +16,27 @@ public class AWSS3StorageImageResolver : IImageResolver
private readonly IAmazonS3 amazonS3;
private readonly string bucketName;
private readonly string imagePath;
private readonly GetObjectMetadataResponse metadataResponse;

/// <summary>
/// Initializes a new instance of the <see cref="AWSS3StorageImageResolver"/> class.
/// </summary>
/// <param name="amazonS3">The Amazon S3 Client</param>
/// <param name="bucketName">The bucket name.</param>
/// <param name="imagePath">The image path.</param>
public AWSS3StorageImageResolver(IAmazonS3 amazonS3, string bucketName, string imagePath)
/// <param name="metadataResponse">Optional metadata response.</param>
public AWSS3StorageImageResolver(IAmazonS3 amazonS3, string bucketName, string imagePath, GetObjectMetadataResponse metadataResponse = null)
{
this.amazonS3 = amazonS3;
this.bucketName = bucketName;
this.imagePath = imagePath;
this.metadataResponse = metadataResponse;
}

/// <inheritdoc />
public async Task<ImageMetadata> GetMetaDataAsync()
{
GetObjectMetadataResponse metadata = await this.amazonS3.GetObjectMetadataAsync(this.bucketName, this.imagePath);
GetObjectMetadataResponse metadata = this.metadataResponse ?? await this.amazonS3.GetObjectMetadataAsync(this.bucketName, this.imagePath);

// Try to parse the max age from the source. If it's not zero then we pass it along
// to set the cache control headers for the response.