public AmazonS3Uri(Uri uri)
{
if (uri == null)
throw new ArgumentNullException("uri");
if (string.IsNullOrEmpty(uri.Host))
throw new ArgumentException("Invalid URI - no hostname present");
var match = new Regex(EndpointPattern).Match(uri.Host);
if (!match.Success)
throw new ArgumentException("Invalid S3 URI - hostname does not appear to be a valid S3 endpoint");
// for host style urls:
// group 0 is bucketname plus 's3' prefix and possible region code
// group 1 is bucket name
// group 2 will be region or 'amazonaws' if US Classic region
// for path style urls:
// group 0 will be s3 prefix plus possible region code
// group 1 will be empty
// group 2 will be region or 'amazonaws' if US Classic region
var bucketNameGroup = match.Groups[1];
if (string.IsNullOrEmpty(bucketNameGroup.Value))
{
// no bucket name in the authority, parse it from the path
this.IsPathStyle = true;
// grab the encoded path so we don't run afoul of '/'s in the bucket name
var path = uri.AbsolutePath;
if (path.Equals("/"))
{
this.Bucket = null;
this.Key = null;
}
else
{
var index = path.IndexOf('/', 1);
if (index == -1)
{
// https://s3.amazonaws.com/bucket
this.Bucket = Decode(path.Substring(1));
this.Key = null;
}
else if (index == (path.Length - 1))
{
// https://s3.amazonaws.com/bucket/
this.Bucket = Decode(path.Substring(1, index)).TrimEnd('/');
this.Key = null;
}
else
{
// https://s3.amazonaws.com/bucket/key
this.Bucket = Decode(path.Substring(1, index)).TrimEnd('/');
this.Key = Decode(path.Substring(index + 1));
}
}
}
else
{
// bucket name in the host, path is the object key
this.IsPathStyle = false;
// remove any trailing '.' from the prefix to get the bucket name
this.Bucket = bucketNameGroup.Value.TrimEnd('.');
this.Key = uri.AbsolutePath.Equals("/") ? null : uri.AbsolutePath.Substring(1);
}
if (match.Groups.Count > 2)
{
// US 'classic' urls will not have a region code in the endpoint
var regionGroupValue = match.Groups[2].Value;
if (regionGroupValue.Equals("amazonaws", StringComparison.Ordinal)
|| regionGroupValue.Equals("external-1", StringComparison.Ordinal))
this.Region = RegionEndpoint.USEast1;
else
{
try
{
this.Region = RegionEndpoint.GetBySystemName(regionGroupValue);
}
catch (Amazon.Runtime.AmazonClientException)
{
// in cases where endpoints such as "s3-accelerate" matches,
// just set the region to null and move on.
this.Region = null;
}
}
}
}