/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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 Amazon.Polly.Model; using Amazon.Polly.Model.Internal.MarshallTransformations; using Amazon.Runtime; using Amazon.Runtime.Internal.Auth; using Amazon.Runtime.Internal.Util; using System; using System.Globalization; using Amazon.Internal; namespace Amazon.Polly { /// /// Utility methods for synthesizing speech. /// public static class SynthesizeSpeechUtil { private const string HTTPS = "https"; private const string HTTPGet = "GET"; private const string XAmzExpires = "X-Amz-Expires"; private const string PollyServiceName = "polly"; private static readonly TimeSpan FifteenMinutes = TimeSpan.FromMinutes(15); /// /// Generate a presigned URL based on a /// using the default configured credentials. /// /// The region for the URL. /// The request to base the presigned URL on. /// public static string GeneratePresignedUrl(RegionEndpoint region, SynthesizeSpeechRequest request) { AWSCredentials credentials = FallbackCredentialsFactory.GetCredentials(); return GeneratePresignedUrl(credentials, region, request); } /// /// Generate a presigned URL based on a . /// /// The credentials to use in the presigned URL. /// The region for the URL. /// The request to base the presigned URL on. public static string GeneratePresignedUrl(AWSCredentials credentials, RegionEndpoint region, SynthesizeSpeechRequest request) { var options = new PreSignerOptions(); if (region.SystemName.Contains("fips-") || region.SystemName.Contains("-fips") || region.OriginalSystemName.Contains("fips-") || region.OriginalSystemName.Contains("-fips")) { region = RegionEndpoint.GetBySystemName(region.SystemName.Replace("fips-", "").Replace("-fips", "")); options.FIPS = true; } return GeneratePresignedUrl(credentials, region, request, options); } /// /// Generate a presigned URL based on a . /// /// The credentials to use in the presigned URL. /// The region for the URL. /// The request to base the presigned URL on. /// Options to configure how the presigner will calculate the service url. /// This is the preferred method for generating a presigned url for a FIPS endpoint. /// public static string GeneratePresignedUrl(AWSCredentials credentials, RegionEndpoint region, SynthesizeSpeechRequest request, PreSignerOptions signerOptions) { 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, signerOptions.ToGetEndpointForServiceOptions()).Hostname).Uri; iRequest.Parameters[XAmzExpires] = ((int)FifteenMinutes.TotalSeconds).ToString(CultureInfo.InvariantCulture); if (request.IsSetLexiconNames()) iRequest.ParameterCollection.Add("LexiconNames", request.LexiconNames); 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; if (request.IsSetSpeechMarkTypes()) iRequest.ParameterCollection.Add("SpeechMarkTypes", request.SpeechMarkTypes); if (request.IsSetLanguageCode()) iRequest.ParameterCollection.Add("LanguageCode", request.LanguageCode); 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 = AWS4PreSignedUrlSigner.SignRequest(iRequest, null, new RequestMetrics(), immutableCredentials.AccessKey, immutableCredentials.SecretKey, PollyServiceName, region.SystemName); var authorization = "&" + signingResult.ForQueryParameters; return AmazonServiceClient.ComposeUrl(iRequest).AbsoluteUri + authorization; } } /// /// Customizations for /// public class PreSignerOptions { /// /// If true a dualstack endpoint is returned. It is the user's responsibility to verify that the given service /// supports a dualstack endpoint for the region. /// public bool DualStack { get; set; } /// /// If true an endpoint that supports FIPS is returned. It is the user's responsibility to verify that the given service /// supports a FIPS endpoint for the region. For background, see https://aws.amazon.com/compliance/fips/ /// public bool FIPS { get; set; } internal GetEndpointForServiceOptions ToGetEndpointForServiceOptions() { return new GetEndpointForServiceOptions { DualStack = DualStack, FIPS = FIPS }; } } }