/// <summary>
/// Determines whether an S3 bucket exists or not.
/// This is done by:
/// 1. Creating a PreSigned Url for the bucket. To work with Signature V4 only regions, as
/// well as Signature V4-optional regions, we keep the expiry to within the maximum for V4
/// (which is one week).
/// 2. Making a HEAD request to the Url
/// </summary>
/// <param name="bucketName">The name of the bucket to check.</param>
/// <param name="s3Client">The Amazon S3 Client to use for S3 specific operations.</param>
/// <returns></returns>
public static bool DoesS3BucketExist(IAmazonS3 s3Client, string bucketName)
{
if (s3Client == null)
{
throw new ArgumentNullException("s3Client", "The s3Client cannot be null!");
}
if (String.IsNullOrEmpty(bucketName))
{
throw new ArgumentNullException("bucketName", "The bucketName cannot be null or the empty string!");
}
var request = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Expires = DateTime.Now.AddDays(1),
Verb = HttpVerb.HEAD,
Protocol = Protocol.HTTP
};
var url = s3Client.GetPreSignedURL(request);
var uri = new Uri(url);
var config = s3Client.Config;
var response = AmazonS3HttpUtil.GetHead(s3Client, config, url, HeaderKeys.XAmzBucketRegion);
if (response.StatusCode == null)
{
// there was a problem with the request and we weren't able
// conclusively determine if the bucket exists
return(false);
}
else
{
AmazonS3Uri s3Uri;
var mismatchDetected = AmazonS3Uri.TryParseAmazonS3Uri(uri, out s3Uri) &&
BucketRegionDetector.GetCorrectRegion(s3Uri, response.StatusCode.Value, response.HeaderValue) != null;
var statusCodeAcceptable = response.StatusCode != HttpStatusCode.NotFound && response.StatusCode != HttpStatusCode.BadRequest;
return(statusCodeAcceptable || mismatchDetected);
}
}