/* * Copyright 2010-2018 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 System; using System.Collections.Generic; using System.Text; using System.Net; using System.Xml; using System.IO; using Amazon.Util; using Amazon.Runtime.Internal.Util; using System.Globalization; namespace Amazon.Runtime.Internal.Transform { /// /// Abstract class for unmarshalling service responses. /// public abstract class ResponseUnmarshaller : IResponseUnmarshaller { public virtual UnmarshallerContext CreateContext(IWebResponseData response, bool readEntireResponse, Stream stream, RequestMetrics metrics) { if (response == null) { throw new AmazonServiceException("The Web Response for a successful request is null!"); } UnmarshallerContext context = ConstructUnmarshallerContext(stream, ShouldReadEntireResponse(response,readEntireResponse), response); return context; } public virtual bool HasStreamingProperty { get { return false; } } #region IResponseUnmarshaller Members public virtual AmazonServiceException UnmarshallException(UnmarshallerContext input, Exception innerException, HttpStatusCode statusCode) { throw new NotImplementedException(); } #endregion public AmazonWebServiceResponse UnmarshallResponse(UnmarshallerContext context) { var response = this.Unmarshall(context); response.ContentLength = context.ResponseData.ContentLength; response.HttpStatusCode = context.ResponseData.StatusCode; return response; } #region IUnmarshaller Members public abstract AmazonWebServiceResponse Unmarshall(UnmarshallerContext input); #endregion public static string GetDefaultErrorMessage() where T : Exception { return string.Format(CultureInfo.InvariantCulture, "An exception of type {0}, please check the error log for mode details.", typeof(T).Name); } protected abstract UnmarshallerContext ConstructUnmarshallerContext( Stream responseStream, bool maintainResponseBody, IWebResponseData response); protected virtual bool ShouldReadEntireResponse(IWebResponseData response, bool readEntireResponse) { return readEntireResponse; } } /// /// Class for unmarshalling XML service responses. /// public abstract class XmlResponseUnmarshaller : ResponseUnmarshaller { public override AmazonWebServiceResponse Unmarshall(UnmarshallerContext input) { XmlUnmarshallerContext context = input as XmlUnmarshallerContext; if (context == null) throw new InvalidOperationException("Unsupported UnmarshallerContext"); AmazonWebServiceResponse response = this.Unmarshall(context); if (context.ResponseData.IsHeaderPresent(HeaderKeys.RequestIdHeader) && !string.IsNullOrEmpty(context.ResponseData.GetHeaderValue(HeaderKeys.RequestIdHeader))) { if (response.ResponseMetadata == null) response.ResponseMetadata = new ResponseMetadata(); response.ResponseMetadata.RequestId = context.ResponseData.GetHeaderValue(HeaderKeys.RequestIdHeader); } else if (context.ResponseData.IsHeaderPresent(HeaderKeys.XAmzRequestIdHeader) && !string.IsNullOrEmpty(context.ResponseData.GetHeaderValue(HeaderKeys.XAmzRequestIdHeader))) { if (response.ResponseMetadata == null) response.ResponseMetadata = new ResponseMetadata(); response.ResponseMetadata.RequestId = context.ResponseData.GetHeaderValue(HeaderKeys.XAmzRequestIdHeader); } return response; } public override AmazonServiceException UnmarshallException(UnmarshallerContext input, Exception innerException, HttpStatusCode statusCode) { XmlUnmarshallerContext context = input as XmlUnmarshallerContext; if (context == null) throw new InvalidOperationException("Unsupported UnmarshallerContext"); return this.UnmarshallException(context, innerException, statusCode); } public abstract AmazonWebServiceResponse Unmarshall(XmlUnmarshallerContext input); public abstract AmazonServiceException UnmarshallException(XmlUnmarshallerContext input, Exception innerException, HttpStatusCode statusCode); protected override UnmarshallerContext ConstructUnmarshallerContext(Stream responseStream, bool maintainResponseBody, IWebResponseData response) { return new XmlUnmarshallerContext(responseStream, maintainResponseBody, response); } } /// /// Class for unmarshalling EC2 service responses. /// public abstract class EC2ResponseUnmarshaller : XmlResponseUnmarshaller { public override AmazonWebServiceResponse Unmarshall(UnmarshallerContext input) { // Unmarshall response var response = base.Unmarshall(input); // Make sure ResponseMetadata is set if (response.ResponseMetadata == null) response.ResponseMetadata = new ResponseMetadata(); // Populate RequestId var ec2UnmarshallerContext = input as EC2UnmarshallerContext; if (ec2UnmarshallerContext != null && !string.IsNullOrEmpty(ec2UnmarshallerContext.RequestId)) { response.ResponseMetadata.RequestId = ec2UnmarshallerContext.RequestId; } return response; } protected override UnmarshallerContext ConstructUnmarshallerContext(Stream responseStream, bool maintainResponseBody, IWebResponseData response) { return new EC2UnmarshallerContext(responseStream, maintainResponseBody, response); } } /// /// Class for unmarshalling JSON service responses. /// public abstract class JsonResponseUnmarshaller : ResponseUnmarshaller { public override AmazonWebServiceResponse Unmarshall(UnmarshallerContext input) { JsonUnmarshallerContext context = input as JsonUnmarshallerContext; if (context == null) throw new InvalidOperationException("Unsupported UnmarshallerContext"); string requestId = context.ResponseData.GetHeaderValue(HeaderKeys.RequestIdHeader); try { var response = this.Unmarshall(context); response.ResponseMetadata = new ResponseMetadata(); response.ResponseMetadata.RequestId = requestId; return response; } catch (Exception e) { throw new AmazonUnmarshallingException(requestId, context.CurrentPath, e, context.ResponseData.StatusCode); } } public override AmazonServiceException UnmarshallException(UnmarshallerContext input, Exception innerException, HttpStatusCode statusCode) { JsonUnmarshallerContext context = input as JsonUnmarshallerContext; if (context == null) throw new InvalidOperationException("Unsupported UnmarshallerContext"); var responseException = this.UnmarshallException(context, innerException, statusCode); responseException.RequestId = context.ResponseData.GetHeaderValue(HeaderKeys.RequestIdHeader); return responseException; } public abstract AmazonWebServiceResponse Unmarshall(JsonUnmarshallerContext input); public abstract AmazonServiceException UnmarshallException(JsonUnmarshallerContext input, Exception innerException, HttpStatusCode statusCode); protected override UnmarshallerContext ConstructUnmarshallerContext(Stream responseStream, bool maintainResponseBody, IWebResponseData response) { return new JsonUnmarshallerContext(responseStream, maintainResponseBody, response); } protected override bool ShouldReadEntireResponse(IWebResponseData response, bool readEntireResponse) { return readEntireResponse && response.ContentType != "application/octet-stream"; } } }