File: MessageExtensionMethods.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (201 lines) | stat: -rw-r--r-- 9,271 bytes parent folder | download | duplicates (7)
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>());
        }
    }
}