File: DiscoveryRequestHandler.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (145 lines) | stat: -rw-r--r-- 7,110 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
135
136
137
138
139
140
141
142
143
144
145
//------------------------------------------------------------------------------
// <copyright file="DiscoveryRequestHandler.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

namespace System.Web.Services.Discovery {
    using System;
    using System.IO;
    using System.Collections;
    using System.Web;
    using System.Xml;
    using System.Diagnostics;
    using System.ComponentModel;
    using System.Text;
    using System.Web.Services.Protocols;
    using System.Security;
    using System.Security.Permissions;
    using System.Web.Services.Diagnostics;

    /// <include file='doc\DiscoveryRequestHandler.uex' path='docs/doc[@for="DiscoveryRequestHandler"]/*' />
    /// <devdoc>
    ///    <para>[To be supplied.]</para>
    /// </devdoc>
    public sealed class DiscoveryRequestHandler : IHttpHandler {

        /// <include file='doc\DiscoveryRequestHandler.uex' path='docs/doc[@for="DiscoveryRequestHandler.IsReusable"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public bool IsReusable {
            get { return true; }
        }

        /// <include file='doc\DiscoveryRequestHandler.uex' path='docs/doc[@for="DiscoveryRequestHandler.ProcessRequest"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public void ProcessRequest(HttpContext context) {
            TraceMethod method = Tracing.On ? new TraceMethod(this, "ProcessRequest") : null;
            if (Tracing.On) Tracing.Enter("IHttpHandler.ProcessRequest", method, Tracing.Details(context.Request));

            new PermissionSet(PermissionState.Unrestricted).Demand();
            // string cacheKey;

            string physicalPath = context.Request.PhysicalPath;
            if ( CompModSwitches.DynamicDiscoverySearcher.TraceVerbose ) Debug.WriteLine("DiscoveryRequestHandle: handling " + physicalPath);

            // Check to see if file exists locally.
            if (File.Exists(physicalPath)) {
                DynamicDiscoveryDocument dynDisco = null;
                FileStream stream = null;
                try {
                    stream = new FileStream(physicalPath, FileMode.Open, FileAccess.Read);
                    XmlTextReader xmlReader = new XmlTextReader(stream);
                    xmlReader.WhitespaceHandling = WhitespaceHandling.Significant;
                    xmlReader.XmlResolver = null;
                    xmlReader.DtdProcessing = DtdProcessing.Prohibit;
                    if (xmlReader.IsStartElement("dynamicDiscovery", DynamicDiscoveryDocument.Namespace)) {
                        stream.Position = 0;
                        dynDisco = DynamicDiscoveryDocument.Load(stream);
                    }
                }
                finally {
                    if (stream != null) {
                        stream.Close();
                    }
                }

                if (dynDisco != null) {
                    string[] excludeList = new string[dynDisco.ExcludePaths.Length];
                    string discoFileDirectory = Path.GetDirectoryName(physicalPath);
                    string discoFileName = Path.GetFileName(physicalPath);

                    for (int i = 0; i < excludeList.Length; i++) {
                         // Exclude list now consists of relative paths, so this transformation not needed.
                         // excludeList[i] = Path.Combine(discoFileDirectory, dynDisco.ExcludePaths[i].Path);
                         excludeList[i] = dynDisco.ExcludePaths[i].Path;
                         }

                    // Determine start url path for search
                    DynamicDiscoSearcher searcher;
                    Uri searchStartUrl = context.Request.Url;
                    string escapedUri = RuntimeUtils.EscapeUri(searchStartUrl);
                    string searchStartUrlDir = GetDirPartOfPath( escapedUri );  // URL path without file name
                    string strLocalPath = GetDirPartOfPath(searchStartUrl.LocalPath);

                    if ( strLocalPath.Length == 0 ||       // no subdir present, host only
                         CompModSwitches.DynamicDiscoveryVirtualSearch.Enabled    // virtual search forced (for test suites).
                       ) {
                       discoFileName = GetFilePartOfPath( escapedUri );
                       searcher = new DynamicVirtualDiscoSearcher( discoFileDirectory, excludeList, searchStartUrlDir);
                    }
                    else
                        searcher = new DynamicPhysicalDiscoSearcher(discoFileDirectory, excludeList, searchStartUrlDir);

                    if ( CompModSwitches.DynamicDiscoverySearcher.TraceVerbose ) Debug.WriteLine( "*** DiscoveryRequestHandler.ProcessRequest() - startDir: " + searchStartUrlDir + " discoFileName :" + discoFileName);
                    searcher.Search(discoFileName);

                    DiscoveryDocument discoFile = searcher.DiscoveryDocument;

                    MemoryStream memStream = new MemoryStream(1024);
                    StreamWriter writer = new StreamWriter(memStream, new UTF8Encoding(false));
                    discoFile.Write(writer);
                    memStream.Position = 0;
                    byte[] data = new byte[(int)memStream.Length];
                    int bytesRead = memStream.Read(data, 0, data.Length);
                    context.Response.ContentType = ContentType.Compose("text/xml", Encoding.UTF8);
                    context.Response.OutputStream.Write(data, 0, bytesRead);
                }
                else {
                    // Else, just return the disco file
                    context.Response.ContentType = "text/xml";
                    context.Response.WriteFile(physicalPath);
                }
                if (Tracing.On) Tracing.Exit("IHttpHandler.ProcessRequest", method);
                return;
            }
            if (Tracing.On) Tracing.Exit("IHttpHandler.ProcessRequest", method);

            // Else, file is not found
            throw new HttpException(404, Res.GetString(Res.WebPathNotFound, context.Request.Path));
        }

        // -------------------------------------------------------------------------
        // Returns part of URL string to the left of the last slash.
        private static string GetDirPartOfPath(string str) {
            int lastSlash = str.LastIndexOf('/');
            return (lastSlash > 0) ? str.Substring(0, lastSlash) : "";
        }

        // -------------------------------------------------------------------------
        // Returns part of URL string to the right of the last slash.
        private static string GetFilePartOfPath(string str) {
            int lastSlash = str.LastIndexOf('/');
            if ( lastSlash < 0 )
                return str;
            else if ( lastSlash == str.Length - 1 )
                return "";
            return str.Substring(lastSlash + 1);
        }

    }
}