/// <summary> /// This method was copied from AmazonServiceClient and adapted for use with this Utility. /// TODO When the SDK supports arrays in request parameters use the new implementation and delete this method. /// </summary> /// <param name="iRequest"></param> /// <returns></returns> private static Uri ComposeUrl(IRequest iRequest) { Uri url = iRequest.Endpoint; var resourcePath = iRequest.ResourcePath; if (resourcePath == null) { resourcePath = string.Empty; } else { if (resourcePath.StartsWith("/", StringComparison.Ordinal)) { resourcePath = resourcePath.Substring(1); } } // Construct any sub resource/query parameter additions to append to the // resource path. Services like S3 which allow '?' and/or '&' in resource paths // should use SubResources instead of appending them to the resource path with // query string delimiters during request marshalling. var delim = "?"; var sb = new StringBuilder(); if (iRequest.SubResources.Count > 0) { foreach (var subResource in iRequest.SubResources) { sb.AppendFormat("{0}{1}", delim, subResource.Key); if (subResource.Value != null) { sb.AppendFormat("={0}", subResource.Value); } delim = "&"; } } if (iRequest.UseQueryString && iRequest.Parameters.Count > 0) { var queryString = SynthesizeSpeechPresignedUrlSigner.CanonicalizeQueryParametersForSynthesizeSpeech(iRequest.Parameters, true); sb.AppendFormat("{0}{1}", delim, queryString); } if (AWSSDKUtils.HasBidiControlCharacters(resourcePath)) { throw new AmazonClientException(string.Format(CultureInfo.InvariantCulture, "Target resource path [{0}] has bidirectional characters, which are not supported" + "by System.Uri and thus cannot be handled by the .NET SDK.", resourcePath)); } var parameterizedPath = string.Concat(AWSSDKUtils.UrlEncode(resourcePath, true), sb); var uri = new Uri(url.AbsoluteUri + parameterizedPath); DontUnescapePathDotsAndSlashes(uri); return(uri); }
/// <summary> /// Generate a presigned URL based on a <see cref="SynthesizeSpeechRequest"/>. /// </summary> /// <param name="credentials">The credentials to use in the presigned URL.</param> /// <param name="region">The region for the URL.</param> /// <param name="request">The request to base the presigned URL on.</param> /// <returns></returns> public static string GeneratePresignedUrl(AWSCredentials credentials, RegionEndpoint region, SynthesizeSpeechRequest request) { if (credentials == null) { throw new ArgumentNullException("credentials"); } if (region == null) { throw new ArgumentNullException("region"); } if (request == null) { throw new ArgumentNullException("request"); } // Marshall this request and prepare it to be signed var marshaller = new SynthesizeSpeechRequestMarshaller(); var iRequest = marshaller.Marshall(request); iRequest.UseQueryString = true; iRequest.HttpMethod = HTTPGet; iRequest.Endpoint = new UriBuilder(HTTPS, region.GetEndpointForService(PollyServiceName).Hostname).Uri; iRequest.Parameters[XAmzExpires] = ((int)FifteenMinutes.TotalSeconds).ToString(CultureInfo.InvariantCulture); if (request.IsSetLexiconNames()) { var sortedLexiconNames = new List <string>(request.LexiconNames); sortedLexiconNames.Sort(StringComparer.Ordinal); iRequest.Parameters[LexiconNamesParameter] = JsonMapper.ToJson(sortedLexiconNames); } if (request.IsSetOutputFormat()) { iRequest.Parameters["OutputFormat"] = request.OutputFormat.ToString(); } if (request.IsSetSampleRate()) { iRequest.Parameters["SampleRate"] = request.SampleRate.ToString(); } if (request.IsSetText()) { iRequest.Parameters["Text"] = request.Text; } if (request.IsSetTextType()) { iRequest.Parameters["TextType"] = request.TextType.ToString(); } if (request.IsSetVoiceId()) { iRequest.Parameters["VoiceId"] = request.VoiceId; } var immutableCredentials = credentials.GetCredentials(); if (immutableCredentials.UseToken) { // Don't use HeaderKeys.XAmzSecurityTokenHeader because Polly treats this as case-sensitive iRequest.Parameters["X-Amz-Security-Token"] = immutableCredentials.Token; } // Only the host header should be signed, and the signer adds that. // So clear out headers. iRequest.Headers.Clear(); // Create presigned URL and assign it var signingResult = SynthesizeSpeechPresignedUrlSigner.SignSynthesizeSpeechRequest(iRequest, new RequestMetrics(), immutableCredentials.AccessKey, immutableCredentials.SecretKey, PollyServiceName, region.SystemName); var authorization = "&" + signingResult.ForQueryParameters; return(ComposeUrl(iRequest).AbsoluteUri + authorization); }