5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005-2006 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections.Generic;
31 using System.Net.Security;
32 using System.ServiceModel.Channels;
33 using System.ServiceModel.Description;
36 using System.ServiceModel.Configuration;
38 namespace System.ServiceModel
40 public class BasicHttpBinding : Binding,
41 IBindingRuntimePreferences
43 bool allow_cookies, bypass_proxy_on_local;
44 HostNameComparisonMode host_name_comparison_mode
45 = HostNameComparisonMode.StrongWildcard;
46 long max_buffer_pool_size = 0x80000;
47 int max_buffer_size = 0x10000;
48 long max_recv_message_size = 0x10000;
49 WSMessageEncoding message_encoding
50 = WSMessageEncoding.Text;
52 XmlDictionaryReaderQuotas reader_quotas
53 = new XmlDictionaryReaderQuotas ();
54 EnvelopeVersion env_version = EnvelopeVersion.Soap11;
55 Encoding text_encoding = new UTF8Encoding ();
56 TransferMode transfer_mode
57 = TransferMode.Buffered;
58 bool use_default_web_proxy = true;
59 BasicHttpSecurity security;
61 public BasicHttpBinding ()
62 : this (BasicHttpSecurityMode.None)
67 public BasicHttpBinding (string configurationName)
70 BindingsSection bindingsSection = ConfigUtil.BindingsSection;
71 BasicHttpBindingElement el =
72 bindingsSection.BasicHttpBinding.Bindings [configurationName];
74 el.ApplyConfiguration (this);
78 public BasicHttpBinding (
79 BasicHttpSecurityMode securityMode)
81 security = new BasicHttpSecurity (securityMode);
84 public bool AllowCookies {
85 get { return allow_cookies; }
86 set { allow_cookies = value; }
89 public bool BypassProxyOnLocal {
90 get { return bypass_proxy_on_local; }
91 set { bypass_proxy_on_local = value; }
95 public bool EnableHttpCookieContainer { get; set; }
98 public HostNameComparisonMode HostNameComparisonMode {
99 get { return host_name_comparison_mode; }
100 set { host_name_comparison_mode = value; }
103 public long MaxBufferPoolSize {
104 get { return max_buffer_pool_size; }
107 throw new ArgumentOutOfRangeException ();
108 max_buffer_pool_size = value;
112 public int MaxBufferSize {
113 get { return max_buffer_size; }
116 throw new ArgumentOutOfRangeException ();
117 max_buffer_size = value;
121 public long MaxReceivedMessageSize {
122 get { return max_recv_message_size; }
125 throw new ArgumentOutOfRangeException ();
126 max_recv_message_size = value;
130 public WSMessageEncoding MessageEncoding {
131 get { return message_encoding; }
132 set { message_encoding = value; }
135 public Uri ProxyAddress {
136 get { return proxy_address; }
137 set { proxy_address = value; }
140 public XmlDictionaryReaderQuotas ReaderQuotas {
141 get { return reader_quotas; }
142 set { reader_quotas = value; }
145 public override string Scheme {
147 switch (Security.Mode) {
148 case BasicHttpSecurityMode.Transport:
149 case BasicHttpSecurityMode.TransportWithMessageCredential:
150 return Uri.UriSchemeHttps;
152 return Uri.UriSchemeHttp;
157 public BasicHttpSecurity Security {
158 get { return security; }
161 public EnvelopeVersion EnvelopeVersion {
162 get { return env_version; }
165 public Encoding TextEncoding {
166 get { return text_encoding; }
167 set { text_encoding = value; }
170 public TransferMode TransferMode {
171 get { return transfer_mode; }
172 set { transfer_mode = value; }
175 public bool UseDefaultWebProxy {
176 get { return use_default_web_proxy; }
177 set { use_default_web_proxy = value; }
180 public override BindingElementCollection
181 CreateBindingElements ()
183 var list = new List<BindingElement> ();
185 var security = CreateSecurityBindingElement ();
186 if (security != null)
190 if (EnableHttpCookieContainer)
191 list.Add (new HttpCookieContainerBindingElement ());
194 list.Add (BuildMessageEncodingBindingElement ());
195 list.Add (GetTransport ());
197 return new BindingElementCollection (list.ToArray ());
200 SecurityBindingElement CreateSecurityBindingElement ()
202 SecurityBindingElement element;
203 switch (Security.Mode) {
205 case BasicHttpSecurityMode.Message:
206 if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate)
207 throw new InvalidOperationException ("When Message security is enabled in a BasicHttpBinding, the message security credential type must be BasicHttpMessageCredentialType.Certificate.");
208 element = SecurityBindingElement.CreateMutualCertificateBindingElement (
209 MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
212 case BasicHttpSecurityMode.TransportWithMessageCredential:
213 if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate)
214 // FIXME: pass proper security token parameters.
215 element = SecurityBindingElement.CreateCertificateOverTransportBindingElement ();
217 element = new AsymmetricSecurityBindingElement ();
225 element.SetKeyDerivation (false);
226 element.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
231 MessageEncodingBindingElement BuildMessageEncodingBindingElement ()
233 if (MessageEncoding == WSMessageEncoding.Text) {
234 TextMessageEncodingBindingElement tm = new TextMessageEncodingBindingElement (
235 MessageVersion.CreateVersion (EnvelopeVersion, AddressingVersion.None), TextEncoding);
237 ReaderQuotas.CopyTo (tm.ReaderQuotas);
243 throw new SystemException ("INTERNAL ERROR: should not happen");
245 return new MtomMessageEncodingBindingElement (
246 MessageVersion.CreateVersion (EnvelopeVersion, AddressingVersion.None), TextEncoding);
250 TransportBindingElement GetTransport ()
252 HttpTransportBindingElement h;
253 switch (Security.Mode) {
254 case BasicHttpSecurityMode.Transport:
255 case BasicHttpSecurityMode.TransportWithMessageCredential:
256 h = new HttpsTransportBindingElement ();
259 h = new HttpTransportBindingElement ();
263 h.AllowCookies = AllowCookies;
264 h.BypassProxyOnLocal = BypassProxyOnLocal;
265 h.HostNameComparisonMode = HostNameComparisonMode;
266 h.MaxBufferPoolSize = MaxBufferPoolSize;
267 h.MaxBufferSize = MaxBufferSize;
268 h.MaxReceivedMessageSize = MaxReceivedMessageSize;
269 h.ProxyAddress = ProxyAddress;
270 h.UseDefaultWebProxy = UseDefaultWebProxy;
271 h.TransferMode = TransferMode;
273 h.ExtendedProtectionPolicy = Security.Transport.ExtendedProtectionPolicy;
277 switch (Security.Mode) {
278 case BasicHttpSecurityMode.Transport:
279 switch (Security.Transport.ClientCredentialType) {
280 case HttpClientCredentialType.Basic:
281 h.AuthenticationScheme = AuthenticationSchemes.Basic;
283 case HttpClientCredentialType.Ntlm:
284 h.AuthenticationScheme = AuthenticationSchemes.Ntlm;
286 case HttpClientCredentialType.Windows:
287 h.AuthenticationScheme = AuthenticationSchemes.Negotiate;
289 case HttpClientCredentialType.Digest:
290 h.AuthenticationScheme = AuthenticationSchemes.Digest;
292 case HttpClientCredentialType.Certificate:
293 var https = (HttpsTransportBindingElement) h;
294 https.RequireClientCertificate = true;
298 case BasicHttpSecurityMode.TransportCredentialOnly:
299 switch (Security.Transport.ClientCredentialType) {
300 case HttpClientCredentialType.Basic:
301 h.AuthenticationScheme = AuthenticationSchemes.Basic;
303 case HttpClientCredentialType.Ntlm:
304 h.AuthenticationScheme = AuthenticationSchemes.Ntlm;
306 case HttpClientCredentialType.Windows:
307 h.AuthenticationScheme = AuthenticationSchemes.Negotiate;
309 case HttpClientCredentialType.Digest:
310 h.AuthenticationScheme = AuthenticationSchemes.Digest;
312 case HttpClientCredentialType.Certificate:
313 throw new InvalidOperationException ("Certificate-based client authentication is not supported by 'TransportCredentialOnly' mode.");
322 // explicit interface implementations
324 bool IBindingRuntimePreferences.ReceiveSynchronously {
325 get { return false; }