File: ServiceHttpModule.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (134 lines) | stat: -rw-r--r-- 6,068 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
131
132
133
134
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------

namespace System.ServiceModel.Activation
{
    using System.Diagnostics;
    using System.Runtime;
    using System.Security;
    using System.ServiceModel;
    using System.Web;

    class ServiceHttpModule : IHttpModule
    {
        [Fx.Tag.SecurityNote(Critical = "Holds pointer to BeginProcessRequest which is SecurityCritical." +
            "This callback is called outside the PermitOnly context.")]
        [SecurityCritical]
        static BeginEventHandler beginEventHandler;
        static CompletedAsyncResult cachedAsyncResult = new CompletedAsyncResult(null, null);

        [Fx.Tag.SecurityNote(Critical = "This callback is called outside the PermitOnly context.")]
        [SecurityCritical]
        static EndEventHandler endEventHandler;

        static bool disabled;

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - called outside PermitOnly context.")]
        public void Dispose()
        {
        }

        [Fx.Tag.SecurityNote(Critical = "Entry-point from ASP.NET, accesses begin/bndProcessRequest which are SecurityCritical.")]
        [SecurityCritical]
        public void Init(HttpApplication context)
        {
            if (ServiceHttpModule.beginEventHandler == null)
            {
                ServiceHttpModule.beginEventHandler = new BeginEventHandler(BeginProcessRequest);
            }
            if (ServiceHttpModule.endEventHandler == null)
            {
                ServiceHttpModule.endEventHandler = new EndEventHandler(EndProcessRequest);
            }
            context.AddOnPostAuthenticateRequestAsync(
                ServiceHttpModule.beginEventHandler,
                ServiceHttpModule.endEventHandler);
        }

        [Fx.Tag.SecurityNote(Critical = "Entry-point from asp.net, called outside PermitOnly context. ASP.NET calls are critical." +
            "HostedHttpRequestAsyncResult..ctor is critical because it captures HostedImpersonationContext (and makes it available later) " +
            "so caller must ensure that this is called in the right place.")]
        [SecurityCritical]
        static public IAsyncResult BeginProcessRequest(object sender, EventArgs e, AsyncCallback cb, object extraData)
        {
            if (ServiceHttpModule.disabled)
            {
                return GetCompletedAsyncResult(cb, extraData);
            }
            
            try
            {
                ServiceHostingEnvironment.SafeEnsureInitialized();
            }
            catch (SecurityException exception)
            {
                ServiceHttpModule.disabled = true;

                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Warning);

                // If requesting a .svc file, the HttpHandler will try to handle it.  It will call
                // SafeEnsureInitialized() again, which will fail with the same exception (it is
                // idempotent on failure).  This is the correct behavior.
                return GetCompletedAsyncResult(cb, extraData);
            }            
                        
            HttpApplication application = (HttpApplication) sender;

            // Check to see whether the extension is supported.
            string extension = application.Request.CurrentExecutionFilePathExtension;
            if (string.IsNullOrEmpty(extension))
            {
                return GetCompletedAsyncResult(cb, extraData);
            }

            ServiceHostingEnvironment.ServiceType serviceType = ServiceHostingEnvironment.GetServiceType(extension);
            // do extension check first so that we do not need to do it in aspnetrouting/configurationbasedactivation
            if (serviceType == ServiceHostingEnvironment.ServiceType.Unknown)
            {
                return GetCompletedAsyncResult(cb, extraData);
            }
            
            // check for AspNetcompat
            if (ServiceHostingEnvironment.AspNetCompatibilityEnabled)
            {                
                // remap httphandler for xamlx in CBA, since there is No physical file and 
                // the xamlx httphandlerfactory will do file exist checking
                if (serviceType == ServiceHostingEnvironment.ServiceType.Workflow && ServiceHostingEnvironment.IsConfigurationBasedService(application))
                {                    
                    IHttpHandler cbaHandler = new ServiceHttpHandlerFactory().GetHandler(
                        application.Context, application.Request.RequestType,
                        application.Request.RawUrl.ToString(), application.Request.PhysicalApplicationPath);
                    application.Context.RemapHandler(cbaHandler);
                }
                return GetCompletedAsyncResult(cb, extraData);
            }

            if (serviceType == ServiceHostingEnvironment.ServiceType.WCF)
            {
                return new HostedHttpRequestAsyncResult(application, false, false, cb, extraData);
            }
            if (serviceType == ServiceHostingEnvironment.ServiceType.Workflow)
            {
                return new HostedHttpRequestAsyncResult(application, false, true, cb, extraData);
            }
            return GetCompletedAsyncResult(cb, extraData);
        }

        private static CompletedAsyncResult GetCompletedAsyncResult(AsyncCallback cb, object state)
        {
            return (cb == null) ? cachedAsyncResult : new CompletedAsyncResult(cb, state);
        }

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - called outside PermitOnly context.")]
        static public void EndProcessRequest(IAsyncResult ar)
        {
            //No need to call CompletedAsyncResult.End as the asyncResult has already completed.
            if (ar is HostedHttpRequestAsyncResult)
            {
                HostedHttpRequestAsyncResult.End(ar);
            }
        }
    }
}