File: AutomaticEndpointGenerator.cs

package info (click to toggle)
mono 6.12.0.199%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,296,836 kB
  • sloc: cs: 11,181,803; xml: 2,850,076; ansic: 699,709; cpp: 123,344; perl: 59,361; javascript: 30,841; asm: 21,853; makefile: 20,405; sh: 15,009; python: 4,839; pascal: 925; sql: 859; sed: 16; php: 1
file content (130 lines) | stat: -rw-r--r-- 6,676 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// <copyright>
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>

namespace System.ServiceModel.Web
{
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Runtime;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Configuration;
    using System.ServiceModel.Description;

    internal abstract class AutomaticEndpointGenerator
    {
        private IDictionary<string, ContractDescription> implementedContracts;
        private string multipleContractsErrorMessage;
        private string noContractErrorMessage;
        private string standardEndpointKind;
        private Type singleImplementedContract;

        protected AutomaticEndpointGenerator(IDictionary<string, ContractDescription> implementedContracts, string multipleContractsErrorMessage, string noContractErrorMessage, string standardEndpointKind)
        {
            Fx.Assert(implementedContracts != null, "The 'implementedContracts' parameter should not be null.");
            Fx.Assert(multipleContractsErrorMessage != null, "The 'multipleContractsErrorMessage' parameter should not be null.");
            Fx.Assert(noContractErrorMessage != null, "The 'noContractErrorMessage' parameter should not be null.");
            Fx.Assert(standardEndpointKind != null, "The 'standardEndpointKind' parameter should not be null.");

            this.implementedContracts = implementedContracts;
            this.multipleContractsErrorMessage = multipleContractsErrorMessage;
            this.noContractErrorMessage = noContractErrorMessage;
            this.standardEndpointKind = standardEndpointKind;
        }

        protected abstract string BindingCollectionElementName { get; }

        public ServiceEndpoint GenerateServiceEndpoint(ServiceHostBase serviceHost, Uri baseAddress)
        {
            Fx.Assert(serviceHost != null, "The 'serviceHost' parameter should not be null.");
            Fx.Assert(baseAddress != null, "The 'baseAddress' parameter should not be null.");

            AuthenticationSchemes supportedSchemes = GetAuthenticationSchemes(baseAddress);
            Type contractType = this.GetSingleImplementedContract();
            ConfigLoader configLoader = new ConfigLoader(serviceHost.GetContractResolver(this.implementedContracts));
            ServiceEndpointElement serviceEndpointElement = new ServiceEndpointElement();
            
            serviceEndpointElement.Contract = contractType.FullName;
            this.SetBindingConfiguration(baseAddress.Scheme, serviceEndpointElement);
            serviceEndpointElement.Kind = this.standardEndpointKind;

            ServiceEndpoint serviceEndpoint = configLoader.LookupEndpoint(serviceEndpointElement, null, serviceHost, serviceHost.Description, true);
            this.ConfigureBinding(serviceEndpoint.Binding, baseAddress.Scheme, supportedSchemes, AspNetEnvironment.Enabled);

            // Setting the Endpoint address and listenUri now that we've set the binding security
            ConfigLoader.ConfigureEndpointAddress(serviceEndpointElement, serviceHost, serviceEndpoint);
            ConfigLoader.ConfigureEndpointListenUri(serviceEndpointElement, serviceHost, serviceEndpoint);

            return serviceEndpoint;
        }

        protected abstract void ConfigureBinding(Binding binding, string uriScheme, AuthenticationSchemes supportedAuthenticationSchemes, bool hostedEnvironment);

        private static AuthenticationSchemes GetAuthenticationSchemes(Uri baseAddress)
        {
            AuthenticationSchemes supportedSchemes = AspNetEnvironment.Current.GetAuthenticationSchemes(baseAddress);

            if (AspNetEnvironment.Current.IsSimpleApplicationHost)
            {
                // Cassini always reports the auth scheme as anonymous or Ntlm. Map this to Ntlm, except when forms auth
                // is requested
                if (supportedSchemes == (AuthenticationSchemes.Anonymous | AuthenticationSchemes.Ntlm))
                {
                    if (AspNetEnvironment.Current.IsWindowsAuthenticationConfigured())
                    {
                        supportedSchemes = AuthenticationSchemes.Ntlm;
                    }
                    else
                    {
                        supportedSchemes = AuthenticationSchemes.Anonymous;
                    }
                }
            }

            return supportedSchemes;
        }

        private Type GetSingleImplementedContract()
        {
            if (this.singleImplementedContract == null)
            {
                Fx.Assert(this.implementedContracts != null, "The 'implementedContracts' field should not be null.");
                Fx.Assert(this.multipleContractsErrorMessage != null, "The 'multipleContractsErrorMessage' field should not be null.");
                Fx.Assert(this.noContractErrorMessage != null, "The 'noContractErrorMessage' field should not be null.");

                if (this.implementedContracts.Count > 1)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(this.multipleContractsErrorMessage));
                }
                else if (this.implementedContracts.Count == 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(this.noContractErrorMessage));
                }

                foreach (ContractDescription contract in this.implementedContracts.Values)
                {
                    this.singleImplementedContract = contract.ContractType;
                    break;
                }
            }

            return this.singleImplementedContract;
        }

        private void SetBindingConfiguration(string uriScheme, ServiceEndpointElement serviceEndpointElement)
        {
            Fx.Assert(uriScheme != null, "The 'uriScheme' parameter should not be null.");
            Fx.Assert(serviceEndpointElement != null, "The 'serviceEndpointElement' parameter should not be null.");
            Fx.Assert(this.BindingCollectionElementName != null, "The 'this.BindingCollectionElementName' property should not be null.");

            ProtocolMappingItem protocolMappingItem = ConfigLoader.LookupProtocolMapping(uriScheme);
            if (protocolMappingItem != null &&
                string.Equals(protocolMappingItem.Binding, this.BindingCollectionElementName, StringComparison.Ordinal))
            {
                serviceEndpointElement.BindingConfiguration = protocolMappingItem.BindingConfiguration;
            }
        }
    }
}