// // Copyright (c) Microsoft Corporation. All rights reserved. // namespace System.ServiceModel.Channels { using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Http; using System.Runtime; /// /// A static extension methods class for getting either an /// or instance from a instance. /// public static class MessageExtensionMethods { private const string MessageHeadersPropertyKey = "System.ServiceModel.Channels.MessageHeaders"; private const string ToHttpRequestMessageMethodName = "ToHttpRequestMessage()"; private const string ToHttpResponseMessageMethodName = "ToHttpResponseMessage()"; private static readonly string HttpRequestMessagePropertyTypeName = typeof(HttpRequestMessageProperty).Name; private static readonly string HttpResponseMessagePropertyTypeName = typeof(HttpResponseMessageProperty).Name; /// /// An extension method for getting a instance /// from an instance. /// /// The instance from which to /// get the instance. /// The instance. public static HttpRequestMessage ToHttpRequestMessage(this Message message) { if (message == null) { throw FxTrace.Exception.ArgumentNull("message"); } HttpRequestMessage httpRequestMessage = HttpRequestMessageProperty.GetHttpRequestMessageFromMessage(message); if (httpRequestMessage == null) { HttpRequestMessageProperty requestMessageProperty = message.Properties.GetValue(HttpRequestMessageProperty.Name); if (requestMessageProperty == null) { throw FxTrace.Exception.AsError( new InvalidOperationException( SR.MissingHttpMessageProperty( ToHttpRequestMessageMethodName, HttpRequestMessagePropertyTypeName))); } httpRequestMessage = CreateRequestMessage(message, requestMessageProperty); } return httpRequestMessage; } /// /// An extension method for getting a instance /// from an instance. /// /// The instance from which to /// get the instance. /// The instance. public static HttpResponseMessage ToHttpResponseMessage(this Message message) { if (message == null) { throw FxTrace.Exception.ArgumentNull("message"); } HttpResponseMessage httpResponseMessage = HttpResponseMessageProperty.GetHttpResponseMessageFromMessage(message); if (httpResponseMessage == null) { HttpResponseMessageProperty responseMessageProperty = message.Properties.GetValue(HttpResponseMessageProperty.Name); if (responseMessageProperty == null) { throw FxTrace.Exception.AsError( new InvalidOperationException( SR.MissingHttpMessageProperty( ToHttpResponseMessageMethodName, HttpResponseMessagePropertyTypeName))); } httpResponseMessage = CreateResponseMessage(message, responseMessageProperty); } return httpResponseMessage; } internal static void ConfigureAsHttpMessage(this Message message, HttpRequestMessage httpRequestMessage) { Fx.Assert(message != null, "The 'message' parameter should never be null."); Fx.Assert(httpRequestMessage != null, "The 'httpRequestMessage' parameter should never be null."); message.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty(httpRequestMessage)); CopyPropertiesToMessage(message, httpRequestMessage.Properties); } internal static void ConfigureAsHttpMessage(this Message message, HttpResponseMessage httpResponseMessage) { Fx.Assert(message != null, "The 'message' parameter should never be null."); Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null."); message.Properties.Add(HttpResponseMessageProperty.Name, new HttpResponseMessageProperty(httpResponseMessage)); HttpRequestMessage httpRequestMessage = httpResponseMessage.RequestMessage; if (httpRequestMessage != null) { CopyPropertiesToMessage(message, httpRequestMessage.Properties); } } private static void CopyPropertiesToMessage(Message message, IDictionary properties) { Fx.Assert(message != null, "The 'message' parameter should not be null."); Fx.Assert(properties != null, "The 'properties' parameter should not be null."); foreach (KeyValuePair property in properties) { MessageHeaders messageHeaders = property.Value as MessageHeaders; if (messageHeaders != null && messageHeaders.MessageVersion == MessageVersion.None && string.Equals(property.Key, MessageHeadersPropertyKey, StringComparison.Ordinal)) { foreach (MessageHeader header in messageHeaders) { message.Headers.Add(header); } } else { message.Properties.Add(property.Key, property.Value); } } } private static HttpRequestMessage CreateRequestMessage(Message message, HttpRequestMessageProperty requestMessageProperty) { Fx.Assert(message != null, "The 'message' parameter should not be null."); Fx.Assert(requestMessageProperty != null, "The 'requestMessageProperty' parameter should not be null."); HttpRequestMessage request = new HttpRequestMessage(); request.RequestUri = message.Properties.Via; Fx.Assert(requestMessageProperty.Method != null, "The HttpRequestMessageProperty class ensures the 'Method' property will never be null."); request.Method = new HttpMethod(requestMessageProperty.Method); request.Content = CreateMessageContent(message, requestMessageProperty.SuppressEntityBody); WebHeaderCollection headers = requestMessageProperty.Headers; foreach (string headerKey in headers.AllKeys) { request.AddHeader(headerKey, headers[headerKey]); } request.CopyPropertiesFromMessage(message); return request; } private static HttpResponseMessage CreateResponseMessage(Message message, HttpResponseMessageProperty responseMessageProperty) { Fx.Assert(message != null, "The 'message' parameter should not be null."); Fx.Assert(responseMessageProperty != null, "The 'responseMessageProperty' parameter should not be null."); HttpResponseMessage response = new HttpResponseMessage(); response.StatusCode = responseMessageProperty.HasStatusCodeBeenSet ? responseMessageProperty.StatusCode : message.IsFault ? HttpStatusCode.InternalServerError : HttpStatusCode.OK; string reasonPhrase = responseMessageProperty.StatusDescription; if (!string.IsNullOrEmpty(reasonPhrase)) { response.ReasonPhrase = reasonPhrase; } response.Content = CreateMessageContent(message, responseMessageProperty.SuppressEntityBody); WebHeaderCollection headers = responseMessageProperty.Headers; foreach (string headerKey in headers.AllKeys) { response.AddHeader(headerKey, headers[headerKey]); } return response; } private static HttpContent CreateMessageContent(Message message, bool suppressEntityBody) { Fx.Assert(message != null, "The 'message' parameter should not be null."); if (suppressEntityBody || message.IsEmpty) { return new ByteArrayContent(EmptyArray.Instance); } return new StreamContent(message.GetBody()); } } }