using System; using System.IO; using System.Net; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; using Amazon; using Amazon.S3; using Amazon.S3.Model; using Amazon.S3.Util; using Amazon.Runtime; using AWSSDK_DotNet.IntegrationTests.Utils; using Amazon.Util; using System.Globalization; using System.Threading; using System.Collections.Generic; namespace AWSSDK_DotNet.IntegrationTests.Tests.S3 { [TestClass] public class RegionsTest { [TestMethod] [TestCategory("S3")] public void TestLocation() { // Disable EUW2 for now until we figure out why we are hitting the bucket number limit. foreach (var location in new S3Region[] { S3Region.USW1, S3Region.EUC1, S3Region.EUW1/*, S3Region.EUW2*/}) { string bucketName = null; var region = RegionEndpoint.GetBySystemName(location.Value); using (var client = new AmazonS3Client(region)) { try { bucketName = S3TestUtils.CreateBucketWithWait(client); var returnedLocation = client.GetBucketLocation(new GetBucketLocationRequest { BucketName = bucketName }).Location; //Map S3Region.EUW1 to S3Region.EU //S3 considers this as the same region. if (location == S3Region.EUW1) { Assert.AreEqual(S3Region.EU, returnedLocation); } else { Assert.AreEqual(location, returnedLocation); } } finally { if (bucketName != null) AmazonS3Util.DeleteS3BucketWithObjects(client, bucketName); } } } } [TestMethod] [TestCategory("S3")] public void TestPostUpload() { var region = RegionEndpoint.USWest1; using (var client = new AmazonS3Client(region)) { var bucketName = S3TestUtils.CreateBucketWithWait(client, true); client.PutACL(new PutACLRequest { BucketName = bucketName, CannedACL = S3CannedACL.BucketOwnerFullControl }); var credentials = GetCredentials(client); try { var response = testPost("foo/bar/content.txt", bucketName, testContentStream("Line one\nLine two\nLine three\n"), "", credentials, region); Assert.IsNotNull(response.RequestId); Assert.IsNotNull(response.HostId); Assert.AreEqual(HttpStatusCode.NoContent, response.StatusCode); } finally { AmazonS3Util.DeleteS3BucketWithObjects(client, bucketName); } } } /// /// Tests that, prior to DNS propagation, the SDK correctly follows a /// 307 temporary redirect response to a bucket located in a region /// requiring AWS4 signing when using a client initially configured /// to us-east-1. /// [TestMethod] [TestCategory("S3")] public void TestAWS2ToAWS4RedirectBeforeDNSPropagation() { var useast1Client = new AmazonS3Client(RegionEndpoint.USEast1); var eucentral1Client = new AmazonS3Client(RegionEndpoint.EUCentral1); var bucketName = S3TestUtils.CreateBucketWithWait(eucentral1Client); try { var response = useast1Client.PutObject(new PutObjectRequest { BucketName = bucketName, Key = "test.txt", ContentBody = "some stuff" }); Assert.IsNotNull(response); Assert.AreEqual(HttpStatusCode.OK, response.HttpStatusCode); } finally { AmazonS3Util.DeleteS3BucketWithObjects(eucentral1Client, bucketName); } } /// /// Tests that the SDK handling for 400/307 responses when trying to access /// buckets in AWS4 regions does not affect the exception thrown when a 301 /// is issued. This can happen if you use a non-US East 1-client to access /// a bucket in a region such as us-west-2. /// [TestMethod] [TestCategory("S3")] [ExpectedException(typeof(AmazonS3Exception), "The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.")] public void Test301RedirectTriggersException() { var uswest2Client = new AmazonS3Client(RegionEndpoint.USWest2); var eucentral1Client = new AmazonS3Client(RegionEndpoint.EUCentral1); // there is no distinction given for buckets that have not had DNS // propagated yet so a new bucket will suffice var bucketName = S3TestUtils.CreateBucketWithWait(eucentral1Client); try { var response = uswest2Client.PutObject(new PutObjectRequest { BucketName = bucketName, Key = "test.txt", ContentBody = "some stuff" }); } finally { AmazonS3Util.DeleteS3BucketWithObjects(eucentral1Client, bucketName); } } private static AWSCredentials GetCredentials(AmazonServiceClient client) { var type = client.GetType(); var property = type.GetProperty("Credentials", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); var credentials = property.GetValue(client, null) as AWSCredentials; return credentials; } static string policy_tmpl = @"{ ""expiration"": ""EXPIRATIONDATE"", ""conditions"": [{ ""bucket"": ""BUCKETNAME"" }, { ""acl"": ""public-read"" }, [""eq"", ""$Content-Type"", ""text/plain""], [""starts-with"", ""$key"", ""foo/bar/""]MOARCONDITIONS]}"; private S3PostUploadResponse testPost(string key, string bucketName, Stream contentStream, string extraConditions, AWSCredentials credentials, RegionEndpoint region) { var expDate = DateTime.UtcNow.AddMinutes(5).ToString(AWSSDKUtils.ISO8601DateFormat, CultureInfo.InvariantCulture); var policy = policy_tmpl.Replace("EXPIRATIONDATE", expDate) .Replace("BUCKETNAME", bucketName) .Replace("MOARCONDITIONS", extraConditions); var signedPolicy = S3PostUploadSignedPolicy.GetSignedPolicy(policy, credentials); var req = new S3PostUploadRequest { Key = key, Bucket = bucketName, CannedACL = S3CannedACL.PublicRead, InputStream = contentStream, SignedPolicy = signedPolicy, Region = region }; return AmazonS3Util.PostUpload(req); } private Stream testContentStream(string content) { return new MemoryStream(Encoding.UTF8.GetBytes(content), false); } } }