1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 
5 namespace System.ServiceModel.Channels
6 {
7     using System;
8     using System.Collections.Generic;
9     using System.Runtime.CompilerServices;
10     using System.ServiceModel.Description;
11     using System.Web.Services.Description;
12     using System.Xml;
13     using System.Xml.Schema;
14 
15     [TypeForwardedFrom("System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
16     public class ContextBindingElementImporter : IPolicyImportExtension, IWsdlImportExtension
17     {
ContextBindingElementImporter()18         public ContextBindingElementImporter()
19         {
20             // empty
21         }
22 
BeforeImport(ServiceDescriptionCollection wsdlDocuments, XmlSchemaSet xmlSchemas, ICollection<XmlElement> policy)23         public void BeforeImport(ServiceDescriptionCollection wsdlDocuments, XmlSchemaSet xmlSchemas, ICollection<XmlElement> policy)
24         {
25             // empty
26         }
27 
ImportContract(WsdlImporter importer, WsdlContractConversionContext context)28         public void ImportContract(WsdlImporter importer, WsdlContractConversionContext context)
29         {
30             // empty
31         }
32 
ImportEndpoint(WsdlImporter importer, WsdlEndpointConversionContext context)33         public void ImportEndpoint(WsdlImporter importer, WsdlEndpointConversionContext context)
34         {
35             if (context == null)
36             {
37                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
38             }
39             if (context.Endpoint == null)
40             {
41                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context.Endpoint");
42             }
43             if (context.Endpoint.Binding == null)
44             {
45                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context.Endpoint.Binding");
46             }
47 
48             // Try to post-process the unrecognized RequireHttpCookie assertion to augment the AllowCookies value
49             // of HttpTransportBindingElement
50 
51             CustomBinding customBinding = context.Endpoint.Binding as CustomBinding;
52             if (customBinding != null)
53             {
54                 UnrecognizedAssertionsBindingElement unrecognized = null;
55                 unrecognized = customBinding.Elements.Find<UnrecognizedAssertionsBindingElement>();
56                 HttpTransportBindingElement http = null;
57                 if (unrecognized != null)
58                 {
59                     XmlElement httpUseCookieAssertion = null;
60                     if (ContextBindingElementPolicy.TryGetHttpUseCookieAssertion(unrecognized.BindingAsserions, out httpUseCookieAssertion))
61                     {
62                         foreach (BindingElement element in customBinding.Elements)
63                         {
64                             http = element as HttpTransportBindingElement;
65                             if (http != null)
66                             {
67                                 http.AllowCookies = true;
68                                 unrecognized.BindingAsserions.Remove(httpUseCookieAssertion);
69                                 if (unrecognized.BindingAsserions.Count == 0)
70                                 {
71                                     customBinding.Elements.Remove(unrecognized);
72                                 }
73                                 break;
74                             }
75                         }
76                     }
77 
78                 }
79 
80                 // Try to upgrade to standard binding
81 
82                 BindingElementCollection bindingElements = customBinding.CreateBindingElements();
83                 Binding binding;
84                 if (!WSHttpContextBinding.TryCreate(bindingElements, out binding)
85                     && !NetTcpContextBinding.TryCreate(bindingElements, out binding))
86                 {
87                     // Work around BasicHttpBinding.TryCreate insensitivity to HttpTransportBindingElement.AllowCookies value
88 
89                     if (http == null)
90                     {
91                         foreach (BindingElement bindingElement in bindingElements)
92                         {
93                             http = bindingElement as HttpTransportBindingElement;
94                             if (http != null)
95                             {
96                                 break;
97                             }
98                         }
99                     }
100                     if (http != null && http.AllowCookies)
101                     {
102                         http.AllowCookies = false;
103                         if (BasicHttpBinding.TryCreate(bindingElements, out binding))
104                         {
105                             ((BasicHttpBinding)binding).AllowCookies = true;
106                         }
107                     }
108                 }
109 
110                 if (binding != null)
111                 {
112                     binding.Name = context.Endpoint.Binding.Name;
113                     binding.Namespace = context.Endpoint.Binding.Namespace;
114                     context.Endpoint.Binding = binding;
115                 }
116             }
117         }
118 
ImportPolicy(MetadataImporter importer, PolicyConversionContext context)119         public virtual void ImportPolicy(MetadataImporter importer, PolicyConversionContext context)
120         {
121             if (context == null)
122             {
123                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
124             }
125             if (context.BindingElements == null)
126             {
127                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.PolicyImportContextBindingElementCollectionIsNull)));
128             }
129 
130             ContextBindingElement contextBindingElement;
131             XmlElement httpUseCookieAssertion = null;
132             if (ContextBindingElementPolicy.TryImportRequireContextAssertion(context.GetBindingAssertions(), out contextBindingElement))
133             {
134                 context.BindingElements.Insert(0, contextBindingElement);
135             }
136             else if (ContextBindingElementPolicy.TryGetHttpUseCookieAssertion(context.GetBindingAssertions(), out httpUseCookieAssertion))
137             {
138                 foreach (BindingElement bindingElement in context.BindingElements)
139                 {
140                     HttpTransportBindingElement http = bindingElement as HttpTransportBindingElement;
141                     if (http != null)
142                     {
143                         http.AllowCookies = true;
144                         context.GetBindingAssertions().Remove(httpUseCookieAssertion);
145                         break;
146                     }
147                 }
148             }
149         }
150     }
151 }
152