< Summary

Class:Azure.Storage.Files.Shares.ShareUriBuilder
Assembly:Azure.Storage.Files.Shares
File(s):C:\Git\azure-sdk-for-net\sdk\storage\Azure.Storage.Files.Shares\src\ShareUriBuilder.cs
Covered lines:81
Uncovered lines:2
Coverable lines:83
Total lines:322
Line coverage:97.5% (81 of 83)
Covered branches:35
Total branches:36
Branch coverage:97.2% (35 of 36)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
get_Scheme()-100%100%
set_Scheme(...)-100%100%
get_Host()-100%100%
set_Host(...)-100%100%
get_Port()-100%100%
set_Port(...)-100%100%
get_AccountName()-100%100%
set_AccountName(...)-100%100%
get_ShareName()-100%100%
set_ShareName(...)-100%100%
get_DirectoryOrFilePath()-100%100%
set_DirectoryOrFilePath(...)-100%100%
get_Snapshot()-100%100%
set_Snapshot(...)-100%100%
get_Sas()-100%100%
set_Sas(...)-100%100%
get_LastDirectoryOrFileName()-100%100%
get_Query()-100%100%
set_Query(...)-100%100%
.ctor(...)-100%100%
ToUri()-100%100%
ToString()-0%100%
ResetUri()-100%100%
BuildUri()-95.65%95%

File(s)

C:\Git\azure-sdk-for-net\sdk\storage\Azure.Storage.Files.Shares\src\ShareUriBuilder.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Linq;
 6using System.Net;
 7using System.Text;
 8using Azure.Core;
 9using Azure.Storage.Sas;
 10using Azure.Storage.Shared;
 11
 12namespace Azure.Storage.Files.Shares
 13{
 14    /// <summary>
 15    /// The <see cref="ShareUriBuilder"/> class provides a convenient way to
 16    /// modify the contents of a <see cref="System.Uri"/> instance to point to
 17    /// different Azure Storage resources like an account, share, or file.
 18    ///
 19    /// For more information, see
 20    /// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-shares--directories-
 21    /// Naming and Referencing Shares, Directories, Files, and Metadata</see>.
 22    /// </summary>
 23    public class ShareUriBuilder
 24    {
 25        /// <summary>
 26        /// The Uri instance constructed by this builder.  It will be reset to
 27        /// null when changes are made and reconstructed when <see cref="System.Uri"/>
 28        /// is accessed.
 29        /// </summary>
 30        private Uri _uri;
 31
 32        /// <summary>
 33        /// Whether the Uri is an IP Uri as determined by
 34        /// <see cref="UriExtensions.IsHostIPEndPointStyle"/>.
 35        /// </summary>
 36        private readonly bool _isIPStyleUri;
 37
 38        /// <summary>
 39        /// Gets or sets the scheme name of the URI.
 40        /// Example: "https"
 41        /// </summary>
 42        public string Scheme
 43        {
 93944            get => _scheme;
 350145            set { ResetUri(); _scheme = value; }
 46        }
 47        private string _scheme;
 48
 49        /// <summary>
 50        /// Gets or sets the Domain Name System (DNS) host name or IP address
 51        /// of a server.
 52        ///
 53        /// Example: "account.file.core.windows.net"
 54        /// </summary>
 55        public string Host
 56        {
 93957            get => _host;
 350158            set { ResetUri(); _host = value; }
 59        }
 60        private string _host;
 61
 62        /// <summary>
 63        /// Gets or sets the port number of the URI.
 64        /// </summary>
 65        public int Port
 66        {
 93967            get => _port;
 350168            set { ResetUri(); _port = value; }
 69        }
 70        private int _port;
 71
 72        /// <summary>
 73        /// Gets or sets the Azure Storage account name.
 74        /// </summary>
 75        public string AccountName
 76        {
 20877            get => _accountName;
 700278            set { ResetUri(); _accountName = value; }
 79        }
 80        private string _accountName;
 81
 82        /// <summary>
 83        /// Gets or sets the name of a file storage share.  The value defaults
 84        /// to <see cref="string.Empty"/> if not present in the
 85        /// <see cref="System.Uri"/>.
 86        ///
 87        /// </summary>
 88        public string ShareName
 89        {
 204090            get => _shareName;
 715891            set { ResetUri(); _shareName = value; }
 92        }
 93        private string _shareName;
 94
 95        /// <summary>
 96        /// Gets or sets the path of the directory or file.  The value defaults
 97        /// to <see cref="string.Empty"/> if not present in the
 98        /// <see cref="System.Uri"/>.
 99        /// Example: "mydirectory/myfile"
 100        /// </summary>
 101        public string DirectoryOrFilePath
 102        {
 722103            get => _directoryOrFilePath;
 104            set
 105            {
 2522106                ResetUri();
 2522107                _directoryOrFilePath = value;
 2522108            }
 109        }
 110        private string _directoryOrFilePath;
 111
 112        /// <summary>
 113        /// Gets or sets the name of a file snapshot.  The value defaults to
 114        /// <see cref="string.Empty"/> if not present in the <see cref="System.Uri"/>.
 115        /// </summary>
 116        public string Snapshot
 117        {
 985118            get => _snapshot;
 3639119            set { ResetUri(); _snapshot = value; }
 120        }
 121        private string _snapshot;
 122
 123        /// <summary>
 124        /// Gets or sets the Shared Access Signature query parameters, or null
 125        /// if not present in the <see cref="System.Uri"/>.
 126        /// </summary>
 127        public SasQueryParameters Sas
 128        {
 959129            get => _sas;
 3741130            set { ResetUri(); _sas = value; }
 131        }
 132        private SasQueryParameters _sas;
 133
 134        /// <summary>
 135        /// Get the last directory or file name from the <see cref="DirectoryOrFilePath"/>, or null if
 136        /// not present in the <see cref="Uri"/>.
 137        /// </summary>
 138        internal string LastDirectoryOrFileName =>
 184139            DirectoryOrFilePath.TrimEnd('/').Split('/').LastOrDefault();
 140
 141        /// <summary>
 142        /// Gets or sets any query information included in the URI that's not
 143        /// relevant to addressing Azure storage resources.
 144        /// </summary>
 145        public string Query
 146        {
 939147            get => _query;
 3501148            set { ResetUri(); _query = value; }
 149        }
 150        private string _query;
 151
 152        /// <summary>
 153        /// Initializes a new instance of the <see cref="ShareUriBuilder"/>
 154        /// class with the specified <see cref="System.Uri"/>.
 155        /// </summary>
 156        /// <param name="uri">
 157        /// The <see cref="System.Uri"/> to a storage resource.
 158        /// </param>
 1167159        public ShareUriBuilder(Uri uri)
 160        {
 1167161            Scheme = uri.Scheme;
 1167162            Host = uri.Host;
 1167163            Port = uri.Port;
 1167164            AccountName = "";
 165
 1167166            ShareName = "";
 1167167            DirectoryOrFilePath = "";
 168
 1167169            Snapshot = "";
 1167170            Sas = null;
 171
 172            // Find the share & directory/file path (if any)
 1167173            if (!string.IsNullOrEmpty(uri.AbsolutePath))
 174            {
 175                // If path starts with a slash, remove it
 176
 1167177                var path = uri.GetPath();
 178
 1167179                var startIndex = 0;
 180
 1167181                if (uri.IsHostIPEndPointStyle())
 182                {
 6183                    _isIPStyleUri = true;
 6184                    var accountEndIndex = path.IndexOf("/", StringComparison.InvariantCulture);
 185
 186                    // Slash not found; path has account name & no share name
 6187                    if (accountEndIndex == -1)
 188                    {
 4189                        AccountName = path;
 4190                        startIndex = path.Length;
 191                    }
 192                    else
 193                    {
 2194                        AccountName = path.Substring(0, accountEndIndex);
 2195                        startIndex = accountEndIndex + 1;
 196                    }
 197                }
 198                else
 199                {
 1161200                    AccountName = uri.GetAccountNameFromDomain(Constants.File.UriSubDomain) ?? string.Empty;
 201                }
 202
 203                // Find the next slash (if it exists)
 204
 1167205                var shareEndIndex = path.IndexOf("/", startIndex, StringComparison.InvariantCulture);
 1167206                if (shareEndIndex == -1)
 207                {
 208                    // Slash not found; path has share name & no directory/file path
 653209                    ShareName = path.Substring(startIndex);
 210                }
 211                else
 212                {
 213                    // The share name is the part between the slashes
 514214                    ShareName = path.Substring(startIndex, shareEndIndex - startIndex);
 215
 216                    // The directory/file path name is after the share slash
 514217                    DirectoryOrFilePath = path.Substring(shareEndIndex + 1).Trim('/').UnescapePath();
 218                }
 219            }
 220
 221            // Convert the query parameters to a case-sensitive map & trim whitespace
 222
 1167223            var paramsMap = new UriQueryParamsCollection(uri.Query);
 224
 1167225            if (paramsMap.TryGetValue(Constants.File.SnapshotParameterName, out var snapshotTime))
 226            {
 22227                Snapshot = snapshotTime;
 228
 229                // If we recognized the query parameter, remove it from the map
 22230                paramsMap.Remove(Constants.File.SnapshotParameterName);
 231            }
 232
 1167233            if (paramsMap.ContainsKey(Constants.Sas.Parameters.Version))
 234            {
 74235                Sas = SasQueryParametersInternals.Create(paramsMap);
 236            }
 237
 1167238            Query = paramsMap.ToString();
 1167239        }
 240
 241        /// <summary>
 242        /// Returns the <see cref="System.Uri"/> constructed from the
 243        /// <see cref="ShareUriBuilder"/>'s fields. The <see cref="Uri.Query"/>
 244        /// property contains the SAS and additional query parameters.
 245        /// </summary>
 246        public Uri ToUri()
 247        {
 929248            if (_uri == null)
 249            {
 929250                _uri = BuildUri().ToUri();
 251            }
 929252            return _uri;
 253        }
 254
 255        /// <summary>
 256        /// Returns the display string for the specified
 257        /// <see cref="ShareUriBuilder"/> instance.
 258        /// </summary>
 259        /// <returns>
 260        /// The display string for the specified <see cref="ShareUriBuilder"/>
 261        /// instance.
 262        /// </returns>
 263        public override string ToString() =>
 0264            BuildUri().ToString();
 265
 266        /// <summary>
 267        /// Reset our cached URI.
 268        /// </summary>
 269        private void ResetUri() =>
 14370270            _uri = null;
 271
 272        /// <summary>
 273        /// Construct a <see cref="RequestUriBuilder"/> representing the
 274        /// <see cref="ShareUriBuilder"/>'s fields. The <see cref="Uri.Query"/>
 275        /// property contains the SAS, snapshot, and additional query parameters.
 276        /// </summary>
 277        /// <returns>The constructed <see cref="RequestUriBuilder"/>.</returns>
 278        private RequestUriBuilder BuildUri()
 279        {
 280            // Concatenate account, share & directory/file path (if they exist)
 929281            var path = new StringBuilder("");
 282            // only append the account name to the path for Ip style Uri.
 283            // regular style Uri will already have account name in domain
 929284            if (_isIPStyleUri && !string.IsNullOrWhiteSpace(AccountName))
 285            {
 2286                path.Append("/").Append(AccountName);
 287            }
 929288            if (!string.IsNullOrWhiteSpace(ShareName))
 289            {
 915290                path.Append("/").Append(ShareName);
 915291                if (!string.IsNullOrWhiteSpace(_directoryOrFilePath))
 292                {
 817293                    path.Append("/").Append(_directoryOrFilePath.EscapePath());
 294                }
 295            }
 296
 297            // Concatenate query parameters
 929298            var query = new StringBuilder(Query);
 929299            if (!string.IsNullOrWhiteSpace(Snapshot))
 300            {
 0301                if (query.Length > 0) { query.Append("&"); }
 34302                query.Append(Constants.File.SnapshotParameterName).Append("=").Append(Snapshot);
 303            }
 929304            var sas = Sas?.ToString();
 929305            if (!string.IsNullOrWhiteSpace(sas))
 306            {
 82307                if (query.Length > 0) { query.Append("&"); }
 80308                query.Append(sas);
 309            }
 310
 311            // Use RequestUriBuilder, which has slightly nicer formatting
 929312            return new RequestUriBuilder
 929313            {
 929314                Scheme = Scheme,
 929315                Host = Host,
 929316                Port = Port,
 929317                Path = path.ToString(),
 929318                Query = query.Length > 0 ? "?" + query.ToString() : null
 929319            };
 320        }
 321    }
 322}