File: HttpUnhandledOperationInvoker.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 (141 lines) | stat: -rw-r--r-- 7,159 bytes parent folder | download | duplicates (6)
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
135
136
137
138
139
140
141
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
#pragma warning disable 1634, 1691
namespace System.ServiceModel.Dispatcher
{
    using System;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Net;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Diagnostics;
    using System.ServiceModel.Web;
    using System.ServiceModel.Syndication;
    using System.Xml.Linq;
    using System.ServiceModel.Description;

    internal class HttpUnhandledOperationInvoker : IOperationInvoker
    {
        const string HtmlContentType = "text/html; charset=UTF-8";

        public bool IsSynchronous
        {
            get { return true; }
        }
        public object[] AllocateInputs()
        {
            return new object[1];
        }

        public Uri HelpUri { get; set; }

        [SuppressMessage("Reliability", "Reliability104:CaughtAndHandledExceptionsRule", Justification = "The exception is thrown for tracing purposes")]
        public object Invoke(object instance, object[] inputs, out object[] outputs)
        {            
            Message message = inputs[0] as Message;
            outputs = null;
#pragma warning disable 56506 // Microsoft, message.Properties is never null
            if (message == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                    SR2.GetString(SR2.HttpUnhandledOperationInvokerCalledWithoutMessage)));
            }
            // We might be here because we desire a redirect...
            Uri newLocation = null;
            Uri to = message.Headers.To;
            if (message.Properties.ContainsKey(WebHttpDispatchOperationSelector.RedirectPropertyName))
            {
                newLocation = message.Properties[WebHttpDispatchOperationSelector.RedirectPropertyName] as Uri;
            }
            if (newLocation != null && to != null)
            {
                // ...redirect
                Message redirectResult = WebOperationContext.Current.CreateStreamResponse(s => HelpHtmlBuilder.CreateTransferRedirectPage(to.AbsoluteUri, newLocation.AbsoluteUri).Save(s, SaveOptions.OmitDuplicateNamespaces), Atom10Constants.HtmlMediaType);
                WebOperationContext.Current.OutgoingResponse.Location = newLocation.AbsoluteUri;
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.TemporaryRedirect;
                WebOperationContext.Current.OutgoingResponse.ContentType = HtmlContentType;

                // Note that no exception is thrown along this path, even if the debugger is attached
                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.WebRequestRedirect,
                        SR2.GetString(SR2.TraceCodeWebRequestRedirect, to, newLocation));
                }
                return redirectResult;
            }
            // otherwise we are here to issue either a 404 or a 405
            bool uriMatched = false;
            if (message.Properties.ContainsKey(WebHttpDispatchOperationSelector.HttpOperationSelectorUriMatchedPropertyName))
            {
                uriMatched = (bool) message.Properties[WebHttpDispatchOperationSelector.HttpOperationSelectorUriMatchedPropertyName];
            }
#pragma warning enable 56506
            Message result = null;
            Uri helpUri = this.HelpUri != null ? UriTemplate.RewriteUri(this.HelpUri, WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Host]) : null;
            if (uriMatched)
            {
                WebHttpDispatchOperationSelectorData allowedMethodsData = null;
                if (message.Properties.TryGetValue(WebHttpDispatchOperationSelector.HttpOperationSelectorDataPropertyName, out allowedMethodsData))
                {
                    WebOperationContext.Current.OutgoingResponse.Headers[HttpResponseHeader.Allow] = allowedMethodsData.AllowHeader;
                }
                result = WebOperationContext.Current.CreateStreamResponse(s => HelpHtmlBuilder.CreateMethodNotAllowedPage(helpUri).Save(s, SaveOptions.OmitDuplicateNamespaces), Atom10Constants.HtmlMediaType);
            }
            else
            {
                result = WebOperationContext.Current.CreateStreamResponse(s => HelpHtmlBuilder.CreateEndpointNotFound(helpUri).Save(s, SaveOptions.OmitDuplicateNamespaces), Atom10Constants.HtmlMediaType);

            }
            WebOperationContext.Current.OutgoingResponse.StatusCode = uriMatched ? HttpStatusCode.MethodNotAllowed : HttpStatusCode.NotFound;
            WebOperationContext.Current.OutgoingResponse.ContentType = HtmlContentType;

            try
            {
                if (!uriMatched)
                {
                    if (Debugger.IsAttached)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.WebRequestDidNotMatchOperation,
                            OperationContext.Current.IncomingMessageHeaders.To)));
                    }
                    else
                    {
                        DiagnosticUtility.TraceHandledException(new InvalidOperationException(SR2.GetString(SR2.WebRequestDidNotMatchOperation,
                                OperationContext.Current.IncomingMessageHeaders.To)), TraceEventType.Warning);
                    }
                }
                else
                {
                    if (Debugger.IsAttached)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.WebRequestDidNotMatchMethod,
                            WebOperationContext.Current.IncomingRequest.Method, OperationContext.Current.IncomingMessageHeaders.To)));
                    }
                    else
                    {
                        DiagnosticUtility.TraceHandledException(new InvalidOperationException(SR2.GetString(SR2.WebRequestDidNotMatchMethod,
                                WebOperationContext.Current.IncomingRequest.Method, OperationContext.Current.IncomingMessageHeaders.To)), TraceEventType.Warning);
                    }
                }
            }
            catch (InvalidOperationException)
            {
                // catch the exception - its only used for tracing
            }
            return result;
        }

        public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
        {
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
        }

        public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
        }
    }
}