/* * MinIO .NET Library for Amazon S3 Compatible Cloud Storage, (C) 2017 MinIO, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System.Collections.Concurrent; using System.Net; using System.Xml.Linq; using Minio.Helper; namespace Minio; /// /// A singleton bucket/region cache map. /// public sealed class BucketRegionCache { private static readonly Lazy lazy = new(() => new BucketRegionCache()); private readonly ConcurrentDictionary regionMap; private BucketRegionCache() { regionMap = new ConcurrentDictionary(StringComparer.Ordinal); } public static BucketRegionCache Instance => lazy.Value; /// /// Returns AWS region for given bucket name. /// /// /// public string Region(string bucketName) { _ = regionMap.TryGetValue(bucketName, out var value); return value ?? "us-east-1"; } /// /// Adds bucket name and its region to BucketRegionCache. /// /// /// public void Add(string bucketName, string region) { _ = regionMap.TryAdd(bucketName, region); } /// /// Removes region cache of the bucket if any. /// /// public void Remove(string bucketName) { _ = regionMap.TryRemove(bucketName, out _); } /// /// Returns true if given bucket name is in the map else false. /// /// /// public bool Exists(string bucketName) { _ = regionMap.TryGetValue(bucketName, out var value); return !string.Equals(value, null, StringComparison.OrdinalIgnoreCase); } /// /// Updates Region cache for given bucket. /// /// /// internal static async Task Update(IMinioClient client, string bucketName) { string region = null; if (!string.Equals(bucketName, null, StringComparison.OrdinalIgnoreCase) && client.Config.AccessKey is not null && client.Config.SecretKey is not null && !Instance.Exists(bucketName)) { string location = null; var path = Utils.UrlEncode(bucketName); // Initialize client var requestUrl = RequestUtil.MakeTargetURL(client.Config.BaseUrl, client.Config.Secure); var requestBuilder = new HttpRequestMessageBuilder(HttpMethod.Get, requestUrl, path); requestBuilder.AddQueryParameter("location", ""); using var response = await client.ExecuteTaskAsync(client.ResponseErrorHandlers, requestBuilder).ConfigureAwait(false); if (response is not null && HttpStatusCode.OK.Equals(response.StatusCode)) { var root = XDocument.Parse(response.Content); location = root.Root.Value; } if (string.IsNullOrEmpty(location)) { region = "us-east-1"; } else { // eu-west-1 can be sometimes 'EU'. if (string.Equals(location, "EU", StringComparison.OrdinalIgnoreCase)) region = "eu-west-1"; else region = location; } // Add the new location. Instance.Add(bucketName, region); } return region; } }