private async Task ProcessHTTPHandlerAsync(string pageName, bool embeddedResource, HttpRequestMessage request, HttpResponseMessage response, CancellationToken cancellationToken)
{
string fileName = GetResourceFileName(pageName, embeddedResource);
Type handlerType;
if (!m_handlerTypeCache.TryGetValue(fileName, out handlerType))
{
if (!ResourceExists(fileName, embeddedResource))
{
response.StatusCode = HttpStatusCode.NotFound;
return;
}
using (Stream source = await OpenResourceAsync(fileName, embeddedResource, cancellationToken))
{
string handlerHeader, className;
// Parse class name from ASHX handler header parameters
using (StreamReader reader = new StreamReader(source))
handlerHeader = (await reader.ReadToEndAsync()).RemoveCrLfs().Trim();
// Clean up header formatting to make parsing easier
handlerHeader = handlerHeader.RemoveDuplicateWhiteSpace().Replace(" =", "=").Replace("= ", "=");
string[] tokens = handlerHeader.Split(' ');
if (!tokens.Any(token => token.Equals("WebHandler", StringComparison.OrdinalIgnoreCase)))
throw new InvalidOperationException($"Expected \"WebHandler\" file type not found in ASHX file header: {handlerHeader}");
Dictionary<string, string> parameters = handlerHeader.ReplaceCaseInsensitive("WebHandler", "").Replace("<%", "").Replace("%>", "").Replace("@", "").Trim().ParseKeyValuePairs(' ');
if (!parameters.TryGetValue("Class", out className))
throw new InvalidOperationException($"Missing \"Class\" parameter in ASHX file header: {handlerHeader}");
// Remove quotes from class name
className = className.Substring(1, className.Length - 2).Trim();
handlerType = AssemblyInfo.FindType(className);
if (m_handlerTypeCache.TryAdd(fileName, handlerType))
OnStatusMessage($"Cached handler type [{handlerType?.FullName}] for file \"{fileName}\"");
}
}
IHostedHttpHandler handler = null;
if ((object)handlerType != null)
handler = Activator.CreateInstance(handlerType) as IHostedHttpHandler;
if ((object)handler == null)
throw new InvalidOperationException($"Failed to create hosted HTTP handler \"{handlerType?.FullName}\" - make sure class implements IHostedHttpHandler interface.");
if (ClientCacheEnabled && handler.UseClientCache)
{
if (PublishResponseContent(request, response, handler.GetContentHash(request)))
await handler.ProcessRequestAsync(request, response, cancellationToken);
}
else
{
await handler.ProcessRequestAsync(request, response, cancellationToken);
}
}