mirror of
https://gitlab.com/sbrl/GalleryShare.git
synced 2018-06-12 22:45:16 +00:00
Initial routing rewrite.
The routes aren't functioning correctly yet.
This commit is contained in:
parent
de2117f9bf
commit
60b7560d21
10 changed files with 408 additions and 143 deletions
|
@ -10,26 +10,17 @@ using System.Xml;
|
|||
using System.Reflection;
|
||||
|
||||
using System.Drawing;
|
||||
using GalleryShare.RequestRouter;
|
||||
|
||||
namespace GalleryShare
|
||||
{
|
||||
enum OutputFunction
|
||||
public class GalleryServer
|
||||
{
|
||||
None,
|
||||
SpecialFile,
|
||||
DirectoryListing,
|
||||
SendFile
|
||||
}
|
||||
|
||||
class GalleryServer
|
||||
{
|
||||
static MimeSharp.Mime mimeDB = new MimeSharp.Mime();
|
||||
|
||||
int port;
|
||||
string servingDirectory = Environment.CurrentDirectory;
|
||||
Size thumbnailSize = new Size(300, 200);
|
||||
|
||||
HttpListener server = new HttpListener();
|
||||
MasterHttpRouter router;
|
||||
string prefix;
|
||||
|
||||
Dictionary<string, string> pathReplacements = new Dictionary<string, string>()
|
||||
|
@ -66,6 +57,11 @@ namespace GalleryShare
|
|||
/// </summary>
|
||||
public async Task Start()
|
||||
{
|
||||
Console.Write("Setting up router...");
|
||||
router = new MasterHttpRouter(this, "GalleryShare");
|
||||
router.UrlTransformer = GetFullReqestedPath;
|
||||
Console.WriteLine("done.");
|
||||
|
||||
server.Start();
|
||||
Console.WriteLine("Listening for requests on {0}.", prefix);
|
||||
Console.WriteLine("Serving from {0}. Browser url: http://localhost:{1}/", servingDirectory, Port);
|
||||
|
@ -82,36 +78,7 @@ namespace GalleryShare
|
|||
/// <param name="cycle">The Http request to handle.</param>
|
||||
private async Task Handle(HttpListenerContext cycle)
|
||||
{
|
||||
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)
|
||||
{
|
||||
case OutputFunction.SpecialFile:
|
||||
await sendSpecialFile(cycle);
|
||||
break;
|
||||
|
||||
case OutputFunction.DirectoryListing:
|
||||
cycle.Response.ContentType = "application/xml";
|
||||
await sendDirectoryListing(cycle.Response.OutputStream, cycle.Request.RawUrl, requestedPath);
|
||||
break;
|
||||
|
||||
case OutputFunction.SendFile:
|
||||
await sendFile(cycle, requestedPath);
|
||||
break;
|
||||
|
||||
default:
|
||||
await sendMessage(cycle, 404, "Error: File or directory '{0}' not found.", requestedPath);
|
||||
break;
|
||||
}
|
||||
await router.RouteRequest(cycle);
|
||||
|
||||
logCycle(cycle);
|
||||
cycle.Response.Close();
|
||||
|
@ -127,16 +94,6 @@ namespace GalleryShare
|
|||
return result;
|
||||
}
|
||||
|
||||
private async Task sendMessage(HttpListenerContext cycle, int statusCode, string message, params object[] paramObjects)
|
||||
{
|
||||
StreamWriter responseData = new StreamWriter(cycle.Response.OutputStream);
|
||||
|
||||
cycle.Response.StatusCode = statusCode;
|
||||
await responseData.WriteLineAsync(string.Format(message, paramObjects));
|
||||
/*responseData.Close();
|
||||
cycle.Response.Close();*/
|
||||
}
|
||||
|
||||
private void logCycle(HttpListenerContext cycle)
|
||||
{
|
||||
Console.WriteLine("[{0}] [{1}] [{2}] {3} {4}",
|
||||
|
@ -147,97 +104,6 @@ namespace GalleryShare
|
|||
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;
|
||||
writerSettings.Indent = true;
|
||||
writerSettings.IndentChars = "\t";
|
||||
XmlWriter xmlData = XmlWriter.Create(outgoingData, writerSettings);
|
||||
|
||||
await xmlData.WriteStartDocumentAsync();
|
||||
await xmlData.WriteProcessingInstructionAsync("xml-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.Substring(servingDirectory.Length));
|
||||
await xmlData.WriteElementStringAsync(null, "ItemCount", null, Directory.GetFileSystemEntries(directoryName).Length.ToString());
|
||||
|
||||
// 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.Substring(servingDirectory.Length));
|
||||
|
||||
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":
|
||||
cycle.Response.ContentType = "text/xsl";
|
||||
outputFileName = @"GalleryShare.Embed.DirectoryListing.xslt";
|
||||
break;
|
||||
case "Theme.css":
|
||||
cycle.Response.ContentType = "text/css";
|
||||
outputFileName = @"GalleryShare.Embed.Theme.css";
|
||||
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);*/
|
||||
byte[] xsltData = await Utilities.GetEmbeddedResourceContent(outputFileName);
|
||||
await cycle.Response.OutputStream.WriteAsync(xsltData, 0, xsltData.Length);
|
||||
}
|
||||
|
||||
private async Task sendFile(HttpListenerContext cycle, string requestedPath)
|
||||
{
|
||||
if(cycle.Request.QueryString["type"] == "thumbnail")
|
||||
{
|
||||
// Send a thumbnail!
|
||||
Console.WriteLine("Sending thumbnail for '{0}'", requestedPath);
|
||||
await ThumbnailGenerator.SendThumbnailPng(requestedPath, thumbnailSize, cycle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the raw file
|
||||
|
||||
cycle.Response.ContentType = mimeDB.Lookup(requestedPath);
|
||||
|
||||
Stream fileData = File.OpenRead(requestedPath);
|
||||
await fileData.CopyToAsync(cycle.Response.OutputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,11 +44,19 @@
|
|||
<Compile Include="GalleryServer.cs" />
|
||||
<Compile Include="Utilities.cs" />
|
||||
<Compile Include="ThumbnailGenerator.cs" />
|
||||
<Compile Include="RequestRouter\IRequestRoute.cs" />
|
||||
<Compile Include="RequestRouter\MasterHttpRouter.cs" />
|
||||
<Compile Include="RequestRouter\HttpRequestRouteAttribute.cs" />
|
||||
<Compile Include="RequestRouter\RouteSendFile.cs" />
|
||||
<Compile Include="RequestRouter\RouteSpecialFile.cs" />
|
||||
<Compile Include="RequestRouter\RouteDirectoryListing.cs" />
|
||||
<Compile Include="RequestRouter\RouteDefault.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="packages\Magick.NET-Q8-x64.7.0.2.100\build\net40-client\Magick.NET-Q8-x64.targets" Condition="Exists('packages\Magick.NET-Q8-x64.7.0.2.100\build\net40-client\Magick.NET-Q8-x64.targets')" />
|
||||
<ItemGroup>
|
||||
<Folder Include="Embed\" />
|
||||
<Folder Include="RequestRouter\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Embed\**" />
|
||||
|
|
22
GalleryShare/RequestRouter/HttpRequestRouteAttribute.cs
Normal file
22
GalleryShare/RequestRouter/HttpRequestRouteAttribute.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
namespace GalleryShare.RequestRouter
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a class to be a http reqeust router that's part of the given routing group.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class is an attribute. Please don't try to inherit from it.
|
||||
/// To create a new request router, please implement GalleryShare.RequestRouter.IRequestRoute, not this class.
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||
public sealed class HttpRequestRoute : Attribute
|
||||
{
|
||||
public string RoutingGroup;
|
||||
|
||||
public HttpRequestRoute(string inRoutingGroup)
|
||||
{
|
||||
RoutingGroup = inRoutingGroup;
|
||||
}
|
||||
}
|
||||
}
|
34
GalleryShare/RequestRouter/IRequestRoute.cs
Normal file
34
GalleryShare/RequestRouter/IRequestRoute.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
using System.Dynamic;
|
||||
|
||||
namespace GalleryShare.RequestRouter
|
||||
{
|
||||
public interface IRequestRoute
|
||||
{
|
||||
/// <summary>
|
||||
/// The priority of the request route.
|
||||
/// Higher priority routes will always be chosen to handle requests over lower priority ones.
|
||||
/// Note that only 1 route may handle any given request.
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
|
||||
void SetParentServer(GalleryServer inGalleryServer);
|
||||
|
||||
/// <summary>
|
||||
/// Works out whether the request route hander can handle a request to the given path.
|
||||
/// </summary>
|
||||
/// <param name="urlPath">The path to check to see if it can be handled.</param>
|
||||
/// <returns>Whether the request route can handle a request to the given path.</returns>
|
||||
bool CanHandle(string rawUrl, string requestedPath);
|
||||
/// <summary>
|
||||
/// Handles a HTTP request asynchronously.
|
||||
/// Note that the master request router will close the request for you, so you don't need to bother.
|
||||
/// </summary>
|
||||
/// <param name="cycle">The Http request to handle.</param>
|
||||
/// <param name="requestedPath">The transformed url path of the given request.</param>
|
||||
Task HandleRequestAsync(HttpListenerContext cycle, string requestedPath);
|
||||
}
|
||||
}
|
||||
|
78
GalleryShare/RequestRouter/MasterHttpRouter.cs
Normal file
78
GalleryShare/RequestRouter/MasterHttpRouter.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Security.Claims;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GalleryShare.RequestRouter
|
||||
{
|
||||
public delegate string UrlPathTransformer(string rawUrl);
|
||||
|
||||
public class MasterHttpRouter
|
||||
{
|
||||
public bool DebugMode = true;
|
||||
|
||||
List<IRequestRoute> requestRoutes = new List<IRequestRoute>();
|
||||
UrlPathTransformer urlTransformer;
|
||||
|
||||
public UrlPathTransformer UrlTransformer
|
||||
{
|
||||
get { return urlTransformer; }
|
||||
set { urlTransformer = value; }
|
||||
}
|
||||
|
||||
public MasterHttpRouter(GalleryServer parentServer, string routingGroup)
|
||||
{
|
||||
// Add the default route
|
||||
requestRoutes.Add(new RouteDefault());
|
||||
// Search for and add the rest of the routes
|
||||
foreach(Type currentType in getRequestRouters(routingGroup))
|
||||
{
|
||||
IRequestRoute nextRoute = (IRequestRoute)Activator.CreateInstance(currentType);
|
||||
nextRoute.SetParentServer(parentServer);
|
||||
requestRoutes.Add(nextRoute);
|
||||
}
|
||||
|
||||
// Sort the request reoutes by priority
|
||||
requestRoutes.Sort((routeA, routeB) => -routeA.Priority.CompareTo(routeB.Priority));
|
||||
}
|
||||
|
||||
public async Task RouteRequest(HttpListenerContext cycle)
|
||||
{
|
||||
foreach(IRequestRoute currentRoute in requestRoutes)
|
||||
{
|
||||
if (DebugMode) Console.Write("Trying {0} (Priority {1}) - ", currentRoute.GetType(), currentRoute.Priority);
|
||||
string transformedUrl = UrlTransformer(cycle.Request.RawUrl);
|
||||
|
||||
if (!currentRoute.CanHandle(cycle.Request.RawUrl, transformedUrl))
|
||||
{
|
||||
if(DebugMode) Console.WriteLine("false. Trying next route.");
|
||||
continue;
|
||||
}
|
||||
if(DebugMode) Console.WriteLine("true. Sending to route.");
|
||||
await currentRoute.HandleRequestAsync(cycle, transformedUrl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Type> getRequestRouters(string routingGroup)
|
||||
{
|
||||
foreach(Type requestRoute in Assembly.GetCallingAssembly().GetExportedTypes().Where(cType =>
|
||||
cType.GetInterfaces().Contains(typeof(IRequestRoute))))
|
||||
{
|
||||
foreach(HttpRequestRoute attr in requestRoute.GetCustomAttributes())
|
||||
{
|
||||
if(attr.RoutingGroup == routingGroup)
|
||||
{
|
||||
yield return requestRoute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
39
GalleryShare/RequestRouter/RouteDefault.cs
Normal file
39
GalleryShare/RequestRouter/RouteDefault.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using GalleryShare.RequestRouter;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
|
||||
namespace GalleryShare
|
||||
{
|
||||
public class RouteDefault : IRequestRoute
|
||||
{
|
||||
public int Priority { get; } = 0;
|
||||
|
||||
public string DefaultResponse { get; set; } = "Error: 404 - No route was found to handle the specified url.\n";
|
||||
|
||||
public RouteDefault()
|
||||
{
|
||||
}
|
||||
|
||||
public bool CanHandle(string rawUrl, string requestedPath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetParentServer(GalleryServer inParentServer)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task HandleRequestAsync(HttpListenerContext cycle, string requestedPath)
|
||||
{
|
||||
cycle.Response.StatusCode = 404;
|
||||
cycle.Response.ContentType = "text/plain";
|
||||
cycle.Response.ContentLength64 = DefaultResponse.Length;
|
||||
|
||||
StreamWriter responseData = new StreamWriter(cycle.Response.OutputStream) { AutoFlush = true };
|
||||
await responseData.WriteLineAsync(DefaultResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
79
GalleryShare/RequestRouter/RouteDirectoryListing.cs
Normal file
79
GalleryShare/RequestRouter/RouteDirectoryListing.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GalleryShare.RequestRouter
|
||||
{
|
||||
[HttpRequestRoute("GalleryShare")]
|
||||
public class RouteDirectoryListing : IRequestRoute
|
||||
{
|
||||
GalleryServer parentServer;
|
||||
|
||||
public int Priority { get; } = 5;
|
||||
|
||||
public RouteDirectoryListing()
|
||||
{
|
||||
}
|
||||
|
||||
public bool CanHandle(string rawUrl, string requestedPath)
|
||||
{
|
||||
if(Directory.Exists(requestedPath))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetParentServer(GalleryServer inParentServer)
|
||||
{
|
||||
parentServer = inParentServer;
|
||||
}
|
||||
|
||||
public async Task HandleRequestAsync(HttpListenerContext cycle, string requestedPath)
|
||||
{
|
||||
cycle.Response.ContentType = "application/xml";
|
||||
|
||||
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;
|
||||
writerSettings.Indent = true;
|
||||
writerSettings.IndentChars = "\t";
|
||||
XmlWriter xmlData = XmlWriter.Create(cycle.Response.OutputStream, writerSettings);
|
||||
|
||||
await xmlData.WriteStartDocumentAsync();
|
||||
await xmlData.WriteProcessingInstructionAsync("xml-stylesheet", "type=\"text/xsl\" href=\"/!Transform-DirListing.xslt\"");
|
||||
await xmlData.WriteStartElementAsync(null, "DirectoryListing", null);
|
||||
await xmlData.WriteElementStringAsync(null, "CurrentDirectory", null, cycle.Request.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.Substring(parentServer.ServingDirectory.Length));
|
||||
await xmlData.WriteElementStringAsync(null, "ItemCount", null, Directory.GetFileSystemEntries(directoryName).Length.ToString());
|
||||
|
||||
// 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.Substring(parentServer.ServingDirectory.Length));
|
||||
|
||||
await xmlData.WriteEndElementAsync();
|
||||
}
|
||||
|
||||
await xmlData.WriteEndDocumentAsync();
|
||||
await xmlData.FlushAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
56
GalleryShare/RequestRouter/RouteSendFile.cs
Normal file
56
GalleryShare/RequestRouter/RouteSendFile.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
|
||||
namespace GalleryShare.RequestRouter
|
||||
{
|
||||
[HttpRequestRoute("GalleryShare")]
|
||||
public class RouteSendFile : IRequestRoute
|
||||
{
|
||||
static MimeSharp.Mime mimeDB = new MimeSharp.Mime();
|
||||
|
||||
|
||||
Size thumbnailSize = new Size(300, 200);
|
||||
|
||||
public int Priority { get; } = 5;
|
||||
|
||||
public RouteSendFile()
|
||||
{
|
||||
}
|
||||
|
||||
public void SetParentServer(GalleryServer inParentServer)
|
||||
{
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// The SendFile route can only handle requests to paths that are a valid file on disk.
|
||||
/// </remarks>
|
||||
public bool CanHandle(string rawUrl, string requestedPath)
|
||||
{
|
||||
if (File.Exists(requestedPath))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task HandleRequestAsync(HttpListenerContext cycle, string requestedPath)
|
||||
{
|
||||
if(cycle.Request.QueryString["type"] == "thumbnail")
|
||||
{
|
||||
// Send a thumbnail!
|
||||
Console.WriteLine("Sending thumbnail for '{0}'", requestedPath);
|
||||
await ThumbnailGenerator.SendThumbnailPng(requestedPath, thumbnailSize, cycle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the raw file
|
||||
|
||||
cycle.Response.ContentType = mimeDB.Lookup(requestedPath);
|
||||
|
||||
Stream fileData = File.OpenRead(requestedPath);
|
||||
await fileData.CopyToAsync(cycle.Response.OutputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
71
GalleryShare/RequestRouter/RouteSpecialFile.cs
Normal file
71
GalleryShare/RequestRouter/RouteSpecialFile.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
|
||||
namespace GalleryShare.RequestRouter
|
||||
{
|
||||
[HttpRequestRoute("GalleryShare")]
|
||||
public class RouteSpecialFile : IRequestRoute
|
||||
{
|
||||
public int Priority { get; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary mapping special file names to their actual filenames and content types.
|
||||
/// </summary>
|
||||
Dictionary<string, SpecialFileEntry> specialFileMap = new Dictionary<string, SpecialFileEntry>()
|
||||
{
|
||||
{ "Transform-DirListing.xslt", new SpecialFileEntry(@"GalleryShare.Embed.DirectoryListing.xslt", "text/xsl") },
|
||||
{ "Theme.css", new SpecialFileEntry(@"GalleryShare.Embed.Theme.css", "text/css") }
|
||||
};
|
||||
|
||||
public RouteSpecialFile()
|
||||
{
|
||||
}
|
||||
|
||||
public void SetParentServer(GalleryServer inParentServer)
|
||||
{
|
||||
}
|
||||
|
||||
public bool CanHandle(string rawUrl, string requestedPath)
|
||||
{
|
||||
if (rawUrl.StartsWith("/!"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task HandleRequestAsync(HttpListenerContext cycle, string requestedPath)
|
||||
{
|
||||
string specialFileName = cycle.Request.RawUrl.Substring(2);
|
||||
string outputFileName = string.Empty;
|
||||
|
||||
if(specialFileMap.ContainsKey(specialFileName))
|
||||
{
|
||||
outputFileName = specialFileMap[specialFileName].FileName;
|
||||
cycle.Response.ContentType = specialFileMap[specialFileName].ContentType;
|
||||
}
|
||||
|
||||
if (outputFileName == string.Empty)
|
||||
{
|
||||
await Utilities.SendMessage(cycle, 404, "Error: Unknown special file '{0}' requested.", specialFileName);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] xsltData = await Utilities.GetEmbeddedResourceContent(outputFileName);
|
||||
await cycle.Response.OutputStream.WriteAsync(xsltData, 0, xsltData.Length);
|
||||
}
|
||||
}
|
||||
|
||||
class SpecialFileEntry
|
||||
{
|
||||
public string FileName;
|
||||
public string ContentType;
|
||||
|
||||
|
||||
public SpecialFileEntry(string inFileName, string inContentType)
|
||||
{
|
||||
FileName = inFileName;
|
||||
ContentType = inContentType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Net.Mime;
|
||||
using System.Net;
|
||||
|
||||
namespace GalleryShare
|
||||
{
|
||||
|
@ -46,6 +47,17 @@ namespace GalleryShare
|
|||
stream.Dispose();
|
||||
return embeddedContent;
|
||||
}
|
||||
|
||||
|
||||
public static async Task SendMessage(HttpListenerContext cycle, int statusCode, string message, params object[] paramObjects)
|
||||
{
|
||||
StreamWriter responseData = new StreamWriter(cycle.Response.OutputStream);
|
||||
|
||||
cycle.Response.StatusCode = statusCode;
|
||||
await responseData.WriteLineAsync(string.Format(message, paramObjects));
|
||||
/*responseData.Close();
|
||||
cycle.Response.Close();*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue