HttpBindingBase.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. // <copyright>
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // </copyright>
  4. namespace System.ServiceModel
  5. {
  6. using System;
  7. using System.ComponentModel;
  8. using System.Diagnostics.CodeAnalysis;
  9. using System.Runtime;
  10. using System.ServiceModel.Channels;
  11. using System.ServiceModel.Configuration;
  12. using System.Text;
  13. using System.Xml;
  14. public abstract class HttpBindingBase : Binding, IBindingRuntimePreferences
  15. {
  16. // private BindingElements
  17. HttpTransportBindingElement httpTransport;
  18. HttpsTransportBindingElement httpsTransport;
  19. TextMessageEncodingBindingElement textEncoding;
  20. MtomMessageEncodingBindingElement mtomEncoding;
  21. internal HttpBindingBase()
  22. {
  23. this.httpTransport = new HttpTransportBindingElement();
  24. this.httpsTransport = new HttpsTransportBindingElement();
  25. this.textEncoding = new TextMessageEncodingBindingElement();
  26. this.textEncoding.MessageVersion = MessageVersion.Soap11;
  27. this.mtomEncoding = new MtomMessageEncodingBindingElement();
  28. this.mtomEncoding.MessageVersion = MessageVersion.Soap11;
  29. this.httpsTransport.WebSocketSettings = this.httpTransport.WebSocketSettings;
  30. }
  31. [DefaultValue(HttpTransportDefaults.AllowCookies)]
  32. public bool AllowCookies
  33. {
  34. get
  35. {
  36. return this.httpTransport.AllowCookies;
  37. }
  38. set
  39. {
  40. this.httpTransport.AllowCookies = value;
  41. this.httpsTransport.AllowCookies = value;
  42. }
  43. }
  44. [DefaultValue(HttpTransportDefaults.BypassProxyOnLocal)]
  45. public bool BypassProxyOnLocal
  46. {
  47. get
  48. {
  49. return this.httpTransport.BypassProxyOnLocal;
  50. }
  51. set
  52. {
  53. this.httpTransport.BypassProxyOnLocal = value;
  54. this.httpsTransport.BypassProxyOnLocal = value;
  55. }
  56. }
  57. [DefaultValue(HttpTransportDefaults.HostNameComparisonMode)]
  58. public HostNameComparisonMode HostNameComparisonMode
  59. {
  60. get
  61. {
  62. return this.httpTransport.HostNameComparisonMode;
  63. }
  64. set
  65. {
  66. this.httpTransport.HostNameComparisonMode = value;
  67. this.httpsTransport.HostNameComparisonMode = value;
  68. }
  69. }
  70. [DefaultValue(TransportDefaults.MaxBufferSize)]
  71. public int MaxBufferSize
  72. {
  73. get
  74. {
  75. return this.httpTransport.MaxBufferSize;
  76. }
  77. set
  78. {
  79. this.httpTransport.MaxBufferSize = value;
  80. this.httpsTransport.MaxBufferSize = value;
  81. this.mtomEncoding.MaxBufferSize = value;
  82. }
  83. }
  84. [DefaultValue(TransportDefaults.MaxBufferPoolSize)]
  85. public long MaxBufferPoolSize
  86. {
  87. get
  88. {
  89. return this.httpTransport.MaxBufferPoolSize;
  90. }
  91. set
  92. {
  93. this.httpTransport.MaxBufferPoolSize = value;
  94. this.httpsTransport.MaxBufferPoolSize = value;
  95. }
  96. }
  97. [DefaultValue(TransportDefaults.MaxReceivedMessageSize)]
  98. public long MaxReceivedMessageSize
  99. {
  100. get
  101. {
  102. return this.httpTransport.MaxReceivedMessageSize;
  103. }
  104. set
  105. {
  106. this.httpTransport.MaxReceivedMessageSize = value;
  107. this.httpsTransport.MaxReceivedMessageSize = value;
  108. }
  109. }
  110. [DefaultValue(HttpTransportDefaults.ProxyAddress)]
  111. [TypeConverter(typeof(UriTypeConverter))]
  112. public Uri ProxyAddress
  113. {
  114. get
  115. {
  116. return this.httpTransport.ProxyAddress;
  117. }
  118. set
  119. {
  120. this.httpTransport.ProxyAddress = value;
  121. this.httpsTransport.ProxyAddress = value;
  122. }
  123. }
  124. public XmlDictionaryReaderQuotas ReaderQuotas
  125. {
  126. get
  127. {
  128. return this.textEncoding.ReaderQuotas;
  129. }
  130. set
  131. {
  132. if (value == null)
  133. {
  134. throw FxTrace.Exception.ArgumentNull("value");
  135. }
  136. value.CopyTo(this.textEncoding.ReaderQuotas);
  137. value.CopyTo(this.mtomEncoding.ReaderQuotas);
  138. this.SetReaderQuotas(value);
  139. }
  140. }
  141. public override string Scheme
  142. {
  143. get
  144. {
  145. return this.GetTransport().Scheme;
  146. }
  147. }
  148. public EnvelopeVersion EnvelopeVersion
  149. {
  150. get { return this.GetEnvelopeVersion(); }
  151. }
  152. [TypeConverter(typeof(EncodingConverter))]
  153. public Encoding TextEncoding
  154. {
  155. get
  156. {
  157. return this.textEncoding.WriteEncoding;
  158. }
  159. set
  160. {
  161. this.textEncoding.WriteEncoding = value;
  162. this.mtomEncoding.WriteEncoding = value;
  163. }
  164. }
  165. [DefaultValue(HttpTransportDefaults.TransferMode)]
  166. public TransferMode TransferMode
  167. {
  168. get
  169. {
  170. return this.httpTransport.TransferMode;
  171. }
  172. set
  173. {
  174. this.httpTransport.TransferMode = value;
  175. this.httpsTransport.TransferMode = value;
  176. }
  177. }
  178. [DefaultValue(HttpTransportDefaults.UseDefaultWebProxy)]
  179. public bool UseDefaultWebProxy
  180. {
  181. get
  182. {
  183. return this.httpTransport.UseDefaultWebProxy;
  184. }
  185. set
  186. {
  187. this.httpTransport.UseDefaultWebProxy = value;
  188. this.httpsTransport.UseDefaultWebProxy = value;
  189. }
  190. }
  191. bool IBindingRuntimePreferences.ReceiveSynchronously
  192. {
  193. get { return false; }
  194. }
  195. internal TextMessageEncodingBindingElement TextMessageEncodingBindingElement
  196. {
  197. get
  198. {
  199. return this.textEncoding;
  200. }
  201. }
  202. internal MtomMessageEncodingBindingElement MtomMessageEncodingBindingElement
  203. {
  204. get
  205. {
  206. return this.mtomEncoding;
  207. }
  208. }
  209. internal abstract BasicHttpSecurity BasicHttpSecurity
  210. {
  211. get;
  212. }
  213. internal WebSocketTransportSettings InternalWebSocketSettings
  214. {
  215. get
  216. {
  217. return this.httpTransport.WebSocketSettings;
  218. }
  219. }
  220. [EditorBrowsable(EditorBrowsableState.Never)]
  221. public bool ShouldSerializeReaderQuotas()
  222. {
  223. return !EncoderDefaults.IsDefaultReaderQuotas(this.ReaderQuotas);
  224. }
  225. [EditorBrowsable(EditorBrowsableState.Never)]
  226. public bool ShouldSerializeTextEncoding()
  227. {
  228. return !this.TextEncoding.Equals(BasicHttpBindingDefaults.TextEncoding);
  229. }
  230. internal static bool GetSecurityModeFromTransport(HttpTransportBindingElement http, HttpTransportSecurity transportSecurity, out UnifiedSecurityMode mode)
  231. {
  232. mode = UnifiedSecurityMode.None;
  233. if (http == null)
  234. {
  235. return false;
  236. }
  237. Fx.Assert(http.AuthenticationScheme.IsSingleton(), "authenticationScheme used in an Http(s)ChannelFactory must be a singleton value.");
  238. if (http is HttpsTransportBindingElement)
  239. {
  240. mode = UnifiedSecurityMode.Transport | UnifiedSecurityMode.TransportWithMessageCredential;
  241. BasicHttpSecurity.EnableTransportSecurity((HttpsTransportBindingElement)http, transportSecurity);
  242. }
  243. else if (HttpTransportSecurity.IsDisabledTransportAuthentication(http))
  244. {
  245. mode = UnifiedSecurityMode.Message | UnifiedSecurityMode.None;
  246. }
  247. else if (!BasicHttpSecurity.IsEnabledTransportAuthentication(http, transportSecurity))
  248. {
  249. return false;
  250. }
  251. else
  252. {
  253. mode = UnifiedSecurityMode.TransportCredentialOnly;
  254. }
  255. return true;
  256. }
  257. internal static bool TryCreateSecurity(SecurityBindingElement securityElement, UnifiedSecurityMode mode, HttpTransportSecurity transportSecurity, out BasicHttpSecurity security)
  258. {
  259. return BasicHttpSecurity.TryCreate(securityElement, mode, transportSecurity, out security);
  260. }
  261. internal TransportBindingElement GetTransport()
  262. {
  263. Fx.Assert(this.BasicHttpSecurity != null, "this.BasicHttpSecurity should not return null from a derived class.");
  264. BasicHttpSecurity basicHttpSecurity = this.BasicHttpSecurity;
  265. if (basicHttpSecurity.Mode == BasicHttpSecurityMode.Transport || basicHttpSecurity.Mode == BasicHttpSecurityMode.TransportWithMessageCredential)
  266. {
  267. basicHttpSecurity.EnableTransportSecurity(this.httpsTransport);
  268. return this.httpsTransport;
  269. }
  270. else if (basicHttpSecurity.Mode == BasicHttpSecurityMode.TransportCredentialOnly)
  271. {
  272. basicHttpSecurity.EnableTransportAuthentication(this.httpTransport);
  273. return this.httpTransport;
  274. }
  275. else
  276. {
  277. // ensure that there is no transport security
  278. basicHttpSecurity.DisableTransportAuthentication(this.httpTransport);
  279. return this.httpTransport;
  280. }
  281. }
  282. internal abstract EnvelopeVersion GetEnvelopeVersion();
  283. internal virtual void SetReaderQuotas(XmlDictionaryReaderQuotas readerQuotas)
  284. {
  285. }
  286. internal virtual void InitializeFrom(HttpTransportBindingElement transport, MessageEncodingBindingElement encoding)
  287. {
  288. this.BypassProxyOnLocal = transport.BypassProxyOnLocal;
  289. this.HostNameComparisonMode = transport.HostNameComparisonMode;
  290. this.MaxBufferPoolSize = transport.MaxBufferPoolSize;
  291. this.MaxBufferSize = transport.MaxBufferSize;
  292. this.MaxReceivedMessageSize = transport.MaxReceivedMessageSize;
  293. this.ProxyAddress = transport.ProxyAddress;
  294. this.TransferMode = transport.TransferMode;
  295. this.UseDefaultWebProxy = transport.UseDefaultWebProxy;
  296. this.httpTransport.WebSocketSettings = transport.WebSocketSettings;
  297. this.httpsTransport.WebSocketSettings = transport.WebSocketSettings;
  298. if (encoding is TextMessageEncodingBindingElement)
  299. {
  300. TextMessageEncodingBindingElement text = (TextMessageEncodingBindingElement)encoding;
  301. this.TextEncoding = text.WriteEncoding;
  302. this.ReaderQuotas = text.ReaderQuotas;
  303. }
  304. else if (encoding is MtomMessageEncodingBindingElement)
  305. {
  306. MtomMessageEncodingBindingElement mtom = (MtomMessageEncodingBindingElement)encoding;
  307. this.TextEncoding = mtom.WriteEncoding;
  308. this.ReaderQuotas = mtom.ReaderQuotas;
  309. }
  310. this.BasicHttpSecurity.Transport.ExtendedProtectionPolicy = transport.ExtendedProtectionPolicy;
  311. }
  312. // In the Win8 profile, some settings for the binding security are not supported.
  313. internal virtual void CheckSettings()
  314. {
  315. if (!UnsafeNativeMethods.IsTailoredApplication.Value)
  316. {
  317. return;
  318. }
  319. BasicHttpSecurity security = this.BasicHttpSecurity;
  320. if (security == null)
  321. {
  322. return;
  323. }
  324. BasicHttpSecurityMode mode = security.Mode;
  325. if (mode == BasicHttpSecurityMode.None)
  326. {
  327. return;
  328. }
  329. else if (mode == BasicHttpSecurityMode.Message)
  330. {
  331. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedSecuritySetting, "Mode", mode)));
  332. }
  333. // Message.ClientCredentialType = Certificate is not supported.
  334. if (mode == BasicHttpSecurityMode.TransportWithMessageCredential)
  335. {
  336. BasicHttpMessageSecurity message = security.Message;
  337. if ((message != null) && (message.ClientCredentialType == BasicHttpMessageCredentialType.Certificate))
  338. {
  339. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedSecuritySetting, "Message.ClientCredentialType", message.ClientCredentialType)));
  340. }
  341. }
  342. // Transport.ClientCredentialType = Certificate or InheritedFromHost are not supported.
  343. Fx.Assert(
  344. (mode == BasicHttpSecurityMode.Transport) || (mode == BasicHttpSecurityMode.TransportCredentialOnly) || (mode == BasicHttpSecurityMode.TransportWithMessageCredential),
  345. "Unexpected BasicHttpSecurityMode value: " + mode);
  346. HttpTransportSecurity transport = security.Transport;
  347. if ((transport != null) && ((transport.ClientCredentialType == HttpClientCredentialType.Certificate) || (transport.ClientCredentialType == HttpClientCredentialType.InheritedFromHost)))
  348. {
  349. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedSecuritySetting, "Transport.ClientCredentialType", transport.ClientCredentialType)));
  350. }
  351. }
  352. }
  353. }