Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Channels / TransportBindingElement.cs
1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4
5 namespace System.ServiceModel.Channels
6 {
7     using System.Collections.Generic;
8     using System.ServiceModel.Description;
9     using System.Runtime.Serialization;
10     using System.ServiceModel.Security;
11     using System.ServiceModel;
12     using System.Xml;
13     using WsdlNS = System.Web.Services.Description;
14     using System.Collections.ObjectModel;
15     using System.ComponentModel;
16
17     public abstract class TransportBindingElement
18         : BindingElement
19     {
20         bool manualAddressing;
21         long maxBufferPoolSize;
22         long maxReceivedMessageSize;
23
24         protected TransportBindingElement()
25         {
26             this.manualAddressing = TransportDefaults.ManualAddressing;
27             this.maxBufferPoolSize = TransportDefaults.MaxBufferPoolSize;
28             this.maxReceivedMessageSize = TransportDefaults.MaxReceivedMessageSize;
29         }
30
31         protected TransportBindingElement(TransportBindingElement elementToBeCloned)
32             : base(elementToBeCloned)
33         {
34             this.manualAddressing = elementToBeCloned.manualAddressing;
35             this.maxBufferPoolSize = elementToBeCloned.maxBufferPoolSize;
36             this.maxReceivedMessageSize = elementToBeCloned.maxReceivedMessageSize;
37         }
38
39         [DefaultValue(TransportDefaults.ManualAddressing)]
40         public virtual bool ManualAddressing
41         {
42             get
43             {
44                 return this.manualAddressing;
45             }
46
47             set
48             {
49                 this.manualAddressing = value;
50             }
51         }
52
53         [DefaultValue(TransportDefaults.MaxBufferPoolSize)]
54         public virtual long MaxBufferPoolSize
55         {
56             get
57             {
58                 return this.maxBufferPoolSize;
59             }
60             set
61             {
62                 if (value < 0)
63                 {
64                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value,
65                         SR.GetString(SR.ValueMustBeNonNegative)));
66                 }
67                 this.maxBufferPoolSize = value;
68             }
69         }
70
71         [DefaultValue(TransportDefaults.MaxReceivedMessageSize)]
72         public virtual long MaxReceivedMessageSize
73         {
74             get
75             {
76                 return this.maxReceivedMessageSize;
77             }
78             set
79             {
80                 if (value <= 0)
81                 {
82                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value,
83                         SR.GetString(SR.ValueMustBePositive)));
84                 }
85                 this.maxReceivedMessageSize = value;
86             }
87         }
88
89         public abstract string Scheme { get; }
90
91         internal static IChannelFactory<TChannel> CreateChannelFactory<TChannel>(TransportBindingElement transport)
92         {
93             Binding binding = new CustomBinding(transport);
94             return binding.BuildChannelFactory<TChannel>();
95         }
96
97         internal static IChannelListener CreateChannelListener<TChannel>(TransportBindingElement transport)
98             where TChannel : class, IChannel
99         {
100             Binding binding = new CustomBinding(transport);
101             return binding.BuildChannelListener<TChannel>();
102         }
103
104         public override T GetProperty<T>(BindingContext context)
105         {
106             if (context == null)
107             {
108                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
109             }
110
111             if (typeof(T) == typeof(ChannelProtectionRequirements))
112             {
113                 ChannelProtectionRequirements myRequirements = this.GetProtectionRequirements(context);
114                 myRequirements.Add(context.GetInnerProperty<ChannelProtectionRequirements>() ?? new ChannelProtectionRequirements());
115                 return (T)(object)myRequirements;
116             }
117
118             // to cover all our bases, let's iterate through the BindingParameters to make sure
119             // we haven't missed a query (since we're the Transport and we're at the bottom)
120 #pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null
121             Collection<BindingElement> bindingElements = context.BindingParameters.FindAll<BindingElement>();
122
123             T result = default(T);
124             for (int i = 0; i < bindingElements.Count; i++)
125             {
126                 result = bindingElements[i].GetIndividualProperty<T>();
127                 if (result != default(T))
128                 {
129                     return result;
130                 }
131             }
132
133             if (typeof(T) == typeof(MessageVersion))
134             {
135                 return (T)(object)TransportDefaults.GetDefaultMessageEncoderFactory().MessageVersion;
136             }
137
138             if (typeof(T) == typeof(XmlDictionaryReaderQuotas))
139             {
140                 return (T)(object)new XmlDictionaryReaderQuotas();
141             }
142
143             return null;
144         }
145
146         ChannelProtectionRequirements GetProtectionRequirements(AddressingVersion addressingVersion)
147         {
148             ChannelProtectionRequirements result = new ChannelProtectionRequirements();
149             result.IncomingSignatureParts.AddParts(addressingVersion.SignedMessageParts);
150             result.OutgoingSignatureParts.AddParts(addressingVersion.SignedMessageParts);
151             return result;
152         }
153
154         internal ChannelProtectionRequirements GetProtectionRequirements(BindingContext context)
155         {
156             AddressingVersion addressingVersion = AddressingVersion.WSAddressing10;
157 #pragma warning suppress 56506 // Microsoft, CustomBinding.Elements can never be null
158             MessageEncodingBindingElement messageEncoderBindingElement = context.Binding.Elements.Find<MessageEncodingBindingElement>();
159             if (messageEncoderBindingElement != null)
160             {
161                 addressingVersion = messageEncoderBindingElement.MessageVersion.Addressing;
162             }
163             return GetProtectionRequirements(addressingVersion);
164         }
165
166         internal static void ExportWsdlEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext,
167             string wsdlTransportUri, AddressingVersion addressingVersion)
168         {
169             ExportWsdlEndpoint(exporter, endpointContext, wsdlTransportUri, endpointContext.Endpoint.Address, addressingVersion);
170         }
171
172         internal static void ExportWsdlEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext,
173             string wsdlTransportUri, EndpointAddress address, AddressingVersion addressingVersion)
174         {
175             if (exporter == null)
176             {
177                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
178             }
179
180             if (endpointContext == null)
181             {
182                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointContext");
183             }
184
185             // Set SoapBinding Transport URI
186 #pragma warning suppress 56506 // Microsoft, these properties cannot be null in this context
187             BindingElementCollection bindingElements = endpointContext.Endpoint.Binding.CreateBindingElements();
188             if (wsdlTransportUri != null)
189             {
190                 WsdlNS.SoapBinding soapBinding = SoapHelper.GetOrCreateSoapBinding(endpointContext, exporter);
191
192                 if (soapBinding != null)
193                 {
194                     soapBinding.Transport = wsdlTransportUri;
195                 }
196             }
197
198             if (endpointContext.WsdlPort != null)
199             {
200                 WsdlExporter.WSAddressingHelper.AddAddressToWsdlPort(endpointContext.WsdlPort, address, addressingVersion);
201             }
202         }
203         internal override bool IsMatch(BindingElement b)
204         {
205             if (b == null)
206             {
207                 return false;
208             }
209             TransportBindingElement transport = b as TransportBindingElement;
210             if (transport == null)
211             {
212                 return false;
213             }
214             if (this.maxBufferPoolSize != transport.MaxBufferPoolSize)
215             {
216                 return false;
217             }
218             if (this.maxReceivedMessageSize != transport.MaxReceivedMessageSize)
219             {
220                 return false;
221             }
222             return true;
223         }
224     }
225 }