HttpResponseMessageExtensionMethods.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // <copyright>
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // </copyright>
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Net.Http;
  9. using System.Net.Http.Headers;
  10. using System.Runtime;
  11. internal static class HttpResponseMessageExtensionMethods
  12. {
  13. internal static void AddHeader(this HttpResponseMessage httpResponseMessage, string header, string value)
  14. {
  15. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  16. Fx.Assert(!string.IsNullOrWhiteSpace(header), "The 'header' parameter should never be null or whitespace.");
  17. HttpHeaderInfo headerInfo = HttpHeaderInfo.Create(header);
  18. EnsureNotRequestHeader(headerInfo);
  19. AddHeader(httpResponseMessage, headerInfo, value);
  20. }
  21. internal static void SetHeader(this HttpResponseMessage httpResponseMessage, string header, string value)
  22. {
  23. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  24. Fx.Assert(!string.IsNullOrWhiteSpace(header), "The 'header' parameter should never be null or whitespace.");
  25. HttpHeaderInfo headerInfo = HttpHeaderInfo.Create(header);
  26. EnsureNotRequestHeader(headerInfo);
  27. RemoveHeader(httpResponseMessage, headerInfo);
  28. AddHeader(httpResponseMessage, headerInfo, value);
  29. }
  30. internal static IEnumerable<string> GetHeader(this HttpResponseMessage httpResponseMessage, string header)
  31. {
  32. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  33. Fx.Assert(!string.IsNullOrWhiteSpace(header), "The 'header' parameter should never be null or whitespace.");
  34. HttpHeaderInfo headerInfo = HttpHeaderInfo.Create(header);
  35. EnsureNotRequestHeader(headerInfo);
  36. return GetHeader(httpResponseMessage, headerInfo);
  37. }
  38. internal static void RemoveHeader(this HttpResponseMessage httpResponseMessage, string header)
  39. {
  40. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  41. Fx.Assert(!string.IsNullOrWhiteSpace(header), "The 'header' parameter should never be null or whitespace.");
  42. HttpHeaderInfo headerInfo = HttpHeaderInfo.Create(header);
  43. EnsureNotRequestHeader(headerInfo);
  44. RemoveHeader(httpResponseMessage, headerInfo);
  45. }
  46. internal static HttpResponseMessage CreateBufferedCopy(this HttpResponseMessage httpResponseMessage)
  47. {
  48. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  49. HttpResponseMessage bufferedHttpResponseMessage = new HttpResponseMessage();
  50. bufferedHttpResponseMessage.ReasonPhrase = httpResponseMessage.ReasonPhrase;
  51. bufferedHttpResponseMessage.StatusCode = httpResponseMessage.StatusCode;
  52. bufferedHttpResponseMessage.Version = (Version)(httpResponseMessage.Version != null ? httpResponseMessage.Version.Clone() : null);
  53. if (httpResponseMessage.RequestMessage != null)
  54. {
  55. bufferedHttpResponseMessage.RequestMessage = httpResponseMessage.RequestMessage.CreateBufferedCopy();
  56. }
  57. foreach (KeyValuePair<string, IEnumerable<string>> header in httpResponseMessage.Headers)
  58. {
  59. bufferedHttpResponseMessage.Headers.AddHeaderWithoutValidation(header);
  60. }
  61. bufferedHttpResponseMessage.Content = HttpRequestMessageExtensionMethods.CreateBufferedCopyOfContent(httpResponseMessage.Content);
  62. return bufferedHttpResponseMessage;
  63. }
  64. internal static void CopyPropertiesFromMessage(this HttpResponseMessage httpResponseMessage, Message message)
  65. {
  66. Fx.Assert(httpResponseMessage != null, "The 'httpRequestMessage' parameter should not be null.");
  67. Fx.Assert(message != null, "The 'message' parameter should not be null.");
  68. HttpRequestMessage request = httpResponseMessage.RequestMessage;
  69. if (request != null)
  70. {
  71. request.CopyPropertiesFromMessage(message);
  72. }
  73. }
  74. private static void EnsureNotRequestHeader(HttpHeaderInfo headerInfo)
  75. {
  76. if (!headerInfo.IsResponseHeader && !headerInfo.IsContentHeader && headerInfo.IsResponseHeader)
  77. {
  78. throw FxTrace.Exception.AsError(
  79. new InvalidOperationException(
  80. SR.GetString(SR.RequestHeaderWithResponseHeadersCollection, headerInfo.Name)));
  81. }
  82. }
  83. private static IEnumerable<string> GetHeader(HttpResponseMessage httpResponseMessage, HttpHeaderInfo headerInfo)
  84. {
  85. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  86. Fx.Assert(headerInfo != null, "The 'headerInfo' parameter should never be null.");
  87. Fx.Assert(headerInfo.IsResponseHeader || headerInfo.IsContentHeader, "The 'headerInfo' parameter should be either a response or content header.");
  88. IEnumerable<string> values = null;
  89. if (headerInfo.IsResponseHeader)
  90. {
  91. values = headerInfo.TryGetHeader(httpResponseMessage.Headers);
  92. }
  93. if (values == null &&
  94. headerInfo.IsContentHeader &&
  95. httpResponseMessage.Content != null)
  96. {
  97. values = headerInfo.TryGetHeader(httpResponseMessage.Content.Headers);
  98. }
  99. return values;
  100. }
  101. private static void RemoveHeader(HttpResponseMessage httpResponseMessage, HttpHeaderInfo headerInfo)
  102. {
  103. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  104. Fx.Assert(headerInfo != null, "The 'headerInfo' parameter should never be null.");
  105. Fx.Assert(headerInfo.IsResponseHeader || headerInfo.IsContentHeader, "The 'headerInfo' parameter should be either a response or content header.");
  106. if (headerInfo.IsResponseHeader)
  107. {
  108. headerInfo.TryRemoveHeader(httpResponseMessage.Headers);
  109. }
  110. if (headerInfo.IsContentHeader && httpResponseMessage.Content != null)
  111. {
  112. headerInfo.TryRemoveHeader(httpResponseMessage.Content.Headers);
  113. }
  114. }
  115. private static void AddHeader(HttpResponseMessage httpResponseMessage, HttpHeaderInfo headerInfo, string value)
  116. {
  117. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  118. Fx.Assert(headerInfo != null, "The 'headerInfo' parameter should never be null.");
  119. Fx.Assert(headerInfo.IsResponseHeader || headerInfo.IsContentHeader, "The 'headerInfo' parameter should be either a response or content header.");
  120. if (headerInfo.IsResponseHeader)
  121. {
  122. if (headerInfo.TryAddHeader(httpResponseMessage.Headers, value))
  123. {
  124. return;
  125. }
  126. }
  127. if (headerInfo.IsContentHeader)
  128. {
  129. CreateContentIfNull(httpResponseMessage);
  130. headerInfo.TryAddHeader(httpResponseMessage.Content.Headers, value);
  131. }
  132. }
  133. private static bool CreateContentIfNull(HttpResponseMessage httpResponseMessage)
  134. {
  135. Fx.Assert(httpResponseMessage != null, "The 'httpResponseMessage' parameter should never be null.");
  136. if (httpResponseMessage.Content == null)
  137. {
  138. httpResponseMessage.Content = new ByteArrayContent(EmptyArray<byte>.Instance);
  139. return true;
  140. }
  141. return false;
  142. }
  143. }
  144. }