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);
}
}
}
|