Merged into single file, added assertions
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / HttpTransportBindingElement.cs
1 //
2 // HttpTransportBindingElement.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005-2010 Novell, Inc.  http://www.novell.com
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.ComponentModel;
31 using System.Net;
32 using System.Net.Security;
33 #if NET_4_0
34 using System.Security.Authentication.ExtendedProtection;
35 #endif
36 using System.ServiceModel.Channels;
37 #if !NET_2_1
38 using System.ServiceModel.Channels.Http;
39 #endif
40 using System.ServiceModel.Description;
41 using System.Xml;
42
43 namespace System.ServiceModel.Channels
44 {
45         public class HttpTransportBindingElement : TransportBindingElement,
46                 IPolicyExportExtension, IWsdlExportExtension
47         {
48                 bool allow_cookies, bypass_proxy_on_local,
49                         unsafe_ntlm_auth;
50                 bool use_default_proxy = true, keep_alive_enabled = true;
51                 int max_buffer_size = 0x10000;
52                 HostNameComparisonMode host_cmp_mode;
53                 Uri proxy_address;
54                 string realm = String.Empty;
55                 TransferMode transfer_mode;
56                 IDefaultCommunicationTimeouts timeouts;
57 #if !MOONLIGHT
58                 AuthenticationSchemes auth_scheme =
59                         AuthenticationSchemes.Anonymous;
60                 AuthenticationSchemes proxy_auth_scheme =
61                         AuthenticationSchemes.Anonymous;
62 #endif
63                 // If you add fields, do not forget them in copy constructor.
64
65                 public HttpTransportBindingElement ()
66                 {
67                 }
68
69                 protected HttpTransportBindingElement (
70                         HttpTransportBindingElement other)
71                         : base (other)
72                 {
73                         allow_cookies = other.allow_cookies;
74                         bypass_proxy_on_local = other.bypass_proxy_on_local;
75                         unsafe_ntlm_auth = other.unsafe_ntlm_auth;
76                         use_default_proxy = other.use_default_proxy;
77                         keep_alive_enabled = other.keep_alive_enabled;
78                         max_buffer_size = other.max_buffer_size;
79                         host_cmp_mode = other.host_cmp_mode;
80                         proxy_address = other.proxy_address;
81                         realm = other.realm;
82                         transfer_mode = other.transfer_mode;
83                         // FIXME: it does not look safe
84                         timeouts = other.timeouts;
85 #if !MOONLIGHT
86                         auth_scheme = other.auth_scheme;
87                         proxy_auth_scheme = other.proxy_auth_scheme;
88 #endif
89
90 #if NET_4_0
91                         DecompressionEnabled = other.DecompressionEnabled;
92                         LegacyExtendedProtectionPolicy = other.LegacyExtendedProtectionPolicy;
93                         ExtendedProtectionPolicy = other.ExtendedProtectionPolicy;
94 #endif
95                 }
96
97 #if !MOONLIGHT
98 #if NET_4_0
99                 [DefaultValue (AuthenticationSchemes.Anonymous)]
100 #endif
101                 public AuthenticationSchemes AuthenticationScheme {
102                         get { return auth_scheme; }
103                         set { auth_scheme = value; }
104                 }
105
106 #if NET_4_0
107                 [DefaultValue (AuthenticationSchemes.Anonymous)]
108 #endif
109                 public AuthenticationSchemes ProxyAuthenticationScheme {
110                         get { return proxy_auth_scheme; }
111                         set { proxy_auth_scheme = value; }
112                 }
113 #endif
114
115 #if NET_4_0
116                 [DefaultValue (false)]
117 #endif
118                 public bool AllowCookies {
119                         get { return allow_cookies; }
120                         set { allow_cookies = value; }
121                 }
122
123 #if NET_4_0
124                 [DefaultValue (false)]
125 #endif
126                 public bool BypassProxyOnLocal {
127                         get { return bypass_proxy_on_local; }
128                         set { bypass_proxy_on_local = value; }
129                 }
130
131 #if NET_4_0
132                 [DefaultValue (false)]
133                 [MonoTODO]
134                 public bool DecompressionEnabled { get; set; }
135 #endif
136
137 #if NET_4_0
138                 [DefaultValue (HostNameComparisonMode.StrongWildcard)]
139 #endif
140                 public HostNameComparisonMode HostNameComparisonMode {
141                         get { return host_cmp_mode; }
142                         set { host_cmp_mode = value; }
143                 }
144
145 #if NET_4_0
146                 [DefaultValue (true)]
147 #endif
148                 public bool KeepAliveEnabled {
149                         get { return keep_alive_enabled; }
150                         set { keep_alive_enabled = value; }
151                 }
152
153 #if NET_4_0
154                 [DefaultValue (0x10000)]
155 #endif
156                 public int MaxBufferSize {
157                         get { return max_buffer_size; }
158                         set { max_buffer_size = value; }
159                 }
160
161 #if NET_4_0
162                 [DefaultValue (null)]
163                 [TypeConverter (typeof (UriTypeConverter))]
164 #endif
165                 public Uri ProxyAddress {
166                         get { return proxy_address; }
167                         set { proxy_address = value; }
168                 }
169
170 #if NET_4_0
171                 [DefaultValue ("")]
172 #endif
173                 public string Realm {
174                         get { return realm; }
175                         set { realm = value; }
176                 }
177
178                 public override string Scheme {
179                         get { return Uri.UriSchemeHttp; }
180                 }
181
182 #if NET_4_0
183                 [DefaultValue (TransferMode.Buffered)]
184 #endif
185                 public TransferMode TransferMode {
186                         get { return transfer_mode; }
187                         set { transfer_mode = value; }
188                 }
189
190 #if NET_4_0
191                 [DefaultValue (false)]
192 #endif
193                 public bool UnsafeConnectionNtlmAuthentication {
194                         get { return unsafe_ntlm_auth; }
195                         set { unsafe_ntlm_auth = value; }
196                 }
197
198 #if NET_4_0
199                 [DefaultValue (true)]
200 #endif
201                 public bool UseDefaultWebProxy {
202                         get { return use_default_proxy; }
203                         set { use_default_proxy = value; }
204                 }
205
206 #if NET_4_0
207                 [Obsolete ("Use ExtendedProtectionPolicy")]
208                 [MonoTODO]
209                 public object LegacyExtendedProtectionPolicy { get; set; }
210
211                 [MonoTODO]
212                 public ExtendedProtectionPolicy ExtendedProtectionPolicy { get; set; }
213 #endif
214
215                 public override bool CanBuildChannelFactory<TChannel> (
216                         BindingContext context)
217                 {
218                         return typeof (TChannel) == typeof (IRequestChannel);
219                 }
220
221 #if !NET_2_1
222                 public override bool CanBuildChannelListener<TChannel> (
223                         BindingContext context)
224                 {
225                         return typeof (TChannel) == typeof (IReplyChannel);
226                 }
227 #endif
228
229                 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
230                         BindingContext context)
231                 {
232                         // remaining contexts are ignored ... e.g. such binding
233                         // element that always causes an error is ignored.
234                         return new HttpChannelFactory<TChannel> (this, context);
235                 }
236
237 #if !NET_2_1
238                 internal static object ListenerBuildLock = new object ();
239
240                 public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
241                         BindingContext context)
242                 {
243                         // remaining contexts are ignored ... e.g. such binding
244                         // element that always causes an error is ignored.
245                         return new HttpChannelListener<TChannel> (this, context);
246                 }
247 #endif
248
249                 public override BindingElement Clone ()
250                 {
251                         return new HttpTransportBindingElement (this);
252                 }
253
254                 public override T GetProperty<T> (BindingContext context)
255                 {
256                         // http://blogs.msdn.com/drnick/archive/2007/04/10/interfaces-for-getproperty-part-1.aspx
257 #if !NET_2_1
258                         if (typeof (T) == typeof (ISecurityCapabilities))
259                                 return (T) (object) new HttpBindingProperties (this);
260                         if (typeof (T) == typeof (IBindingDeliveryCapabilities))
261                                 return (T) (object) new HttpBindingProperties (this);
262 #endif
263                         if (typeof (T) == typeof (TransferMode))
264                                 return (T) (object) TransferMode;
265                         return base.GetProperty<T> (context);
266                 }
267
268 #if !NET_2_1
269                 void IPolicyExportExtension.ExportPolicy (
270                         MetadataExporter exporter,
271                         PolicyConversionContext context)
272                 {
273                         if (exporter == null)
274                                 throw new ArgumentNullException ("exporter");
275                         if (context == null)
276                                 throw new ArgumentNullException ("context");
277
278                         PolicyAssertionCollection assertions = context.GetBindingAssertions ();
279                         XmlDocument doc = new XmlDocument ();
280
281                         assertions.Add (doc.CreateElement ("wsaw", "UsingAddressing", "http://www.w3.org/2006/05/addressing/wsdl"));
282
283                         switch (auth_scheme) {
284                                 case AuthenticationSchemes.Basic:
285                                 case AuthenticationSchemes.Digest:
286                                 case AuthenticationSchemes.Negotiate:
287                                 case AuthenticationSchemes.Ntlm:
288                                         assertions.Add (doc.CreateElement ("http", 
289                                                 auth_scheme.ToString () + "Authentication", 
290                                                 "http://schemas.microsoft.com/ws/06/2004/policy/http"));
291                                         break;
292                         }
293                 }
294
295                 [MonoTODO]
296                 void IWsdlExportExtension.ExportContract (WsdlExporter exporter,
297                         WsdlContractConversionContext context)
298                 {
299                         throw new NotImplementedException ();
300                 }
301
302                 [MonoTODO]
303                 void IWsdlExportExtension.ExportEndpoint (WsdlExporter exporter,
304                         WsdlEndpointConversionContext context)
305                 {
306                         throw new NotImplementedException ();
307                 }
308 #endif
309         }
310
311 #if !NET_2_1
312         class HttpBindingProperties : ISecurityCapabilities, IBindingDeliveryCapabilities
313         {
314                 HttpTransportBindingElement source;
315
316                 public HttpBindingProperties (HttpTransportBindingElement source)
317                 {
318                         this.source = source;
319                 }
320
321                 public bool AssuresOrderedDelivery {
322                         get { return false; }
323                 }
324
325                 public bool QueuedDelivery {
326                         get { return false; }
327                 }
328
329                 public virtual ProtectionLevel SupportedRequestProtectionLevel {
330                         get { return ProtectionLevel.None; }
331                 }
332
333                 public virtual ProtectionLevel SupportedResponseProtectionLevel {
334                         get { return ProtectionLevel.None; }
335                 }
336
337                 public virtual bool SupportsClientAuthentication {
338                         get { return source.AuthenticationScheme != AuthenticationSchemes.Anonymous; }
339                 }
340
341                 public virtual bool SupportsServerAuthentication {
342                         get {
343                                 switch (source.AuthenticationScheme) {
344                                 case AuthenticationSchemes.Negotiate:
345                                         return true;
346                                 default:
347                                         return false;
348                                 }
349                         }
350                 }
351
352                 public virtual bool SupportsClientWindowsIdentity {
353                         get {
354                                 switch (source.AuthenticationScheme) {
355                                 case AuthenticationSchemes.Basic:
356                                 case AuthenticationSchemes.Digest: // hmm... why? but they return true on .NET
357                                 case AuthenticationSchemes.Negotiate:
358                                 case AuthenticationSchemes.Ntlm:
359                                         return true;
360                                 default:
361                                         return false;
362                                 }
363                         }
364                 }
365         }
366 #endif
367 }