public string GetSignedUrl(SigningOption options)
        {
            ValidateOptions(options);

            var signingPayloadAsString = string.Join("\n", BuildSigningPayload(options));
            var encryptedBase64String  = EncryptPayload(signingPayloadAsString);

            return(PrepareSignedUrl(options, encryptedBase64String));
        }
        private string PrepareSignedUrl(SigningOption options, string signature)
        {
            var uri = new UriBuilder();

            uri.Scheme = "https";
            uri.Host   = $"{_firebaseConfiguration.StorageBaseAuthority.TrimSlashes().Replace("https://", "")}/{_credentials.GetDefaultBucket().TrimSlashes()}";
            uri.Path   = options.Path.Trim().TrimSlashes();
            uri.Query  = string.Format("GoogleAccessId={0}&Expires={1}&Signature={2}", _credentials.GetServiceAccountEmail(),
                                       BuildExpiration(options.ExpireDate), WebUtility.UrlEncode(signature));
            return(uri.Uri.AbsoluteUri);
        }
        private IList <string> BuildSigningPayload(SigningOption options)
        {
            var payload = new List <string>()
            {
                BuildActionMethod(options.Action),
                BuildContentMD5(options.ContentMD5),
                BuildContentType(options.ContentType),
                BuildExpiration(options.ExpireDate),
                BuilCanonicalizedResource(options.Path)
            };

            return(payload);
        }
 private void ValidateOptions(SigningOption options)
 {
     if (options == null)
     {
         throw new ArgumentNullException(nameof(options));
     }
     if (options.ExpireDate.ToUnixSeconds() == 0)
     {
         throw new ArgumentOutOfRangeException(nameof(options.ExpireDate), "ExpireDate should be reasonable value");
     }
     if (String.IsNullOrWhiteSpace(options.Path))
     {
         throw new ArgumentNullException(nameof(options.Path));
     }
 }