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