1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
// <copyright>
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
namespace System.ServiceModel.Channels
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Runtime;
/// <summary>
/// A static extension methods class for getting either an <see cref="HttpRequestMessage"/>
/// or <see cref="HttpResponseMessage"/> instance from a <see cref="Message"/> instance.
/// </summary>
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;
/// <summary>
/// An extension method for getting a <see cref="HttpRequestMessage"/> instance
/// from an <see cref="Message"/> instance.
/// </summary>
/// <param name="message">The <see cref="Message"/> instance from which to
/// get the <see cref="HttpRequestMessage"/> instance.</param>
/// <returns>The <see cref="HttpRequestMessage"/> instance.</returns>
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>(HttpRequestMessageProperty.Name);
if (requestMessageProperty == null)
{
throw FxTrace.Exception.AsError(
new InvalidOperationException(
SR.MissingHttpMessageProperty(
ToHttpRequestMessageMethodName,
HttpRequestMessagePropertyTypeName)));
}
httpRequestMessage = CreateRequestMessage(message, requestMessageProperty);
}
return httpRequestMessage;
}
/// <summary>
/// An extension method for getting a <see cref="HttpResponseMessage"/> instance
/// from an <see cref="Message"/> instance.
/// </summary>
/// <param name="message">The <see cref="Message"/> instance from which to
/// get the <see cref="HttpResponseMessage"/> instance.</param>
/// <returns>The <see cref="HttpResponseMessage"/> instance.</returns>
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>(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<string, object> 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<string, object> 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<byte>.Instance);
}
return new StreamContent(message.GetBody<Stream>());
}
}
}
|