1
0
Fork 0

(untested) Extensively refactor request handler.

This commit is contained in:
Starbeamrainbowlabs 2016-07-06 20:03:03 +01:00
parent 40be688f26
commit 008cb25636
1 changed files with 111 additions and 70 deletions

View File

@ -11,6 +11,14 @@ using System.Reflection;
namespace GalleryShare namespace GalleryShare
{ {
enum OutputFunction
{
None,
SpecialFile,
DirectoryListing,
SendFile
}
class GalleryServer class GalleryServer
{ {
int port; int port;
@ -60,90 +68,54 @@ namespace GalleryShare
/// <param name="cycle">The Http request to handle.</param> /// <param name="cycle">The Http request to handle.</param>
private async Task Handle(HttpListenerContext cycle) private async Task Handle(HttpListenerContext cycle)
{ {
if(cycle.Request.RawUrl == @"/!Transform-DirListing.xslt") OutputFunction outFunction = OutputFunction.None;
if (cycle.Request.RawUrl.StartsWith("/!"))
outFunction = OutputFunction.SpecialFile;
string requestedPath = GetFullReqestedPath(cycle.Request.RawUrl);
if (Directory.Exists(requestedPath))
outFunction = OutputFunction.DirectoryListing;
if (File.Exists(requestedPath))
outFunction = OutputFunction.SendFile;
switch(outFunction)
{ {
/*string[] resNames = Assembly.GetExecutingAssembly().GetManifestResourceNames(); case OutputFunction.SpecialFile:
foreach (string resName in resNames) await sendSpecialFile(cycle);
Console.WriteLine(resName);*/ break;
cycle.Response.ContentType = "text/xsl";
byte[] xsltData = await Utilities.GetEmbeddedResourceContent(@"GalleryShare.XSLT.DirectoryListing.xslt");
await cycle.Response.OutputStream.WriteAsync(xsltData, 0, xsltData.Length);
logCycle(cycle);
cycle.Response.Close();
return;
}
string requestedPath = Path.GetFullPath(Path.Combine(servingDirectory, "." + cycle.Request.RawUrl));
if (!File.Exists(requestedPath) && !Directory.Exists(requestedPath))
{
await sendMessage(cycle, 404, "Error: File or directory '{0}' not found.", requestedPath);
logCycle(cycle);
return;
}
FileAttributes reqPathAttrs = File.GetAttributes(requestedPath);
StreamWriter responseData = new StreamWriter(cycle.Response.OutputStream);
if(reqPathAttrs.HasFlag(FileAttributes.Directory))
{
List<string> dirFiles = new List<string>(Directory.GetFiles(requestedPath));
List<string> dirDirectories = new List<string>(Directory.GetDirectories(requestedPath));
cycle.Response.ContentType = "text/xml";
await responseData.FlushAsync(); case OutputFunction.DirectoryListing:
XmlWriterSettings writerSettings = new XmlWriterSettings(); cycle.Response.ContentType = "text/xml";
writerSettings.Async = true; await sendDirectoryListing(cycle.Response.OutputStream, cycle.Request.RawUrl, requestedPath);
XmlWriter xmlData = XmlWriter.Create(cycle.Response.OutputStream, writerSettings); break;
await xmlData.WriteStartDocumentAsync(); case OutputFunction.SendFile:
await xmlData.WriteProcessingInstructionAsync("xsl-stylesheet", "type=\"text/xsl\" href=\"/!Transform-DirListing.xslt\"");
await xmlData.WriteStartElementAsync(null, "DirectoryListing", null); break;
foreach (string directoryname in dirDirectories) default:
{ await sendMessage(cycle, 404, "Error: File or directory '{0}' not found.", requestedPath);
await xmlData.WriteStartElementAsync(null, "ListingEntry", null); break;
await xmlData.WriteAttributeStringAsync(null, "Type", null, "Directory");
await xmlData.WriteElementStringAsync(null, "Name", null, directoryname);
// TODO: Write out the number of items in directory
// TODO: Write out thumbnail url
await xmlData.WriteEndElementAsync();
}
foreach (string filename in dirFiles)
{
await xmlData.WriteStartElementAsync(null, "ListingEntry", null);
await xmlData.WriteAttributeStringAsync(null, "Type", null, "File");
await xmlData.WriteElementStringAsync(null, "Name", null, filename);
// TODO: Write out thumbnail url
await xmlData.WriteEndElementAsync();
}
await xmlData.WriteEndDocumentAsync();
await xmlData.FlushAsync();
} }
logCycle(cycle); logCycle(cycle);
responseData.Close();
cycle.Response.Close(); cycle.Response.Close();
} }
private string GetFullReqestedPath(string rawUrl)
{
return Path.GetFullPath(Path.Combine(servingDirectory, "." + rawUrl));
}
private async Task sendMessage(HttpListenerContext cycle, int statusCode, string message, params object[] paramObjects) private async Task sendMessage(HttpListenerContext cycle, int statusCode, string message, params object[] paramObjects)
{ {
StreamWriter responseData = new StreamWriter(cycle.Response.OutputStream); StreamWriter responseData = new StreamWriter(cycle.Response.OutputStream);
cycle.Response.StatusCode = statusCode; cycle.Response.StatusCode = statusCode;
await responseData.WriteLineAsync(string.Format(message, paramObjects)); await responseData.WriteLineAsync(string.Format(message, paramObjects));
responseData.Close(); /*responseData.Close();
cycle.Response.Close(); cycle.Response.Close();*/
} }
private void logCycle(HttpListenerContext cycle) private void logCycle(HttpListenerContext cycle)
@ -156,6 +128,75 @@ namespace GalleryShare
cycle.Request.RawUrl cycle.Request.RawUrl
); );
} }
private async Task sendDirectoryListing(Stream outgoingData, string rawUrl, string requestedPath)
{
List<string> dirFiles = new List<string>(Directory.GetFiles(requestedPath));
List<string> dirDirectories = new List<string>(Directory.GetDirectories(requestedPath));
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.Async = true;
XmlWriter xmlData = XmlWriter.Create(outgoingData, writerSettings);
await xmlData.WriteStartDocumentAsync();
await xmlData.WriteProcessingInstructionAsync("xsl-stylesheet", "type=\"text/xsl\" href=\"/!Transform-DirListing.xslt\"");
await xmlData.WriteStartElementAsync(null, "DirectoryListing", null);
await xmlData.WriteElementStringAsync(null, "CurrentDirectory", null, rawUrl);
await xmlData.WriteStartElementAsync(null, "Contents", null);
foreach (string directoryname in dirDirectories)
{
await xmlData.WriteStartElementAsync(null, "ListingEntry", null);
await xmlData.WriteAttributeStringAsync(null, "Type", null, "Directory");
await xmlData.WriteElementStringAsync(null, "Name", null, directoryname);
// TODO: Write out the number of items in directory
// TODO: Write out thumbnail url
await xmlData.WriteEndElementAsync();
}
foreach (string filename in dirFiles)
{
await xmlData.WriteStartElementAsync(null, "ListingEntry", null);
await xmlData.WriteAttributeStringAsync(null, "Type", null, "File");
await xmlData.WriteElementStringAsync(null, "Name", null, filename);
// TODO: Write out thumbnail url
await xmlData.WriteEndElementAsync();
}
await xmlData.WriteEndDocumentAsync();
await xmlData.FlushAsync();
}
private async Task sendSpecialFile(HttpListenerContext cycle)
{
string specialFileName = cycle.Request.RawUrl.Substring(2);
string outputFileName = string.Empty;
switch(specialFileName)
{
case "Transform-DirListing.xslt":
outputFileName = @"GalleryShare.XSLT.DirectoryListing.xslt";
break;
}
if (outputFileName == string.Empty)
{
await sendMessage(cycle, 404, "Error: Unknown special file '{0}' requested.", specialFileName);
return;
}
/*string[] resNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
foreach (string resName in resNames)
Console.WriteLine(resName);*/
cycle.Response.ContentType = "text/xsl";
byte[] xsltData = await Utilities.GetEmbeddedResourceContent(outputFileName);
await cycle.Response.OutputStream.WriteAsync(xsltData, 0, xsltData.Length);
}
} }
} }