WIP
parent
85caed9f34
commit
1b96e6b95b
|
@ -1,35 +1,165 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ln.templates;
|
||||
|
||||
namespace ln.http.resources
|
||||
{
|
||||
|
||||
public delegate Resource ResourceTypeHook(DirectoryResource directoryResource, FileInfo fileInfo);
|
||||
public delegate Resource ResourceTypeHookDelegate(DirectoryResource directoryResource, FileInfo fileInfo);
|
||||
|
||||
public class DirectoryResource : Resource
|
||||
public class DirectoryResource : Resource, TemplateProvider
|
||||
{
|
||||
public ResourceTypeHook ResourceTypeHook { get; set; }
|
||||
public ResourceTypeHookDelegate ResourceTypeHook { get; set; }
|
||||
|
||||
DirectoryInfo DirectoryInfo { get; }
|
||||
Dictionary<string, DirectoryResource> cache = new Dictionary<string, DirectoryResource>();
|
||||
public virtual DirectoryInfo DirectoryInfo { get; }
|
||||
|
||||
protected Dictionary<string, Resource> cache = new Dictionary<string, Resource>();
|
||||
|
||||
public DirectoryResource(String path)
|
||||
:base(System.IO.Path.GetFileName(path))
|
||||
: base(System.IO.Path.GetFileName(path))
|
||||
{
|
||||
DirectoryInfo = new DirectoryInfo(path);
|
||||
}
|
||||
public DirectoryResource(Resource container,String path)
|
||||
:base(container, System.IO.Path.GetFileName(path))
|
||||
public DirectoryResource(Resource container, String path)
|
||||
: base(container, System.IO.Path.GetFileName(path))
|
||||
{
|
||||
DirectoryInfo = new DirectoryInfo(path);
|
||||
if (container is DirectoryResource)
|
||||
{
|
||||
DirectoryResource parent = container as DirectoryResource;
|
||||
ResourceTypeHook = parent.ResourceTypeHook;
|
||||
}
|
||||
}
|
||||
|
||||
protected String GetCombinedPath(string rel)
|
||||
{
|
||||
return System.IO.Path.Combine(DirectoryInfo.FullName, rel);
|
||||
}
|
||||
|
||||
public override bool Contains(string name)
|
||||
{
|
||||
String cPath = GetCombinedPath(name);
|
||||
bool exists = File.Exists(cPath) || Directory.Exists(cPath);
|
||||
|
||||
if (!exists && cache.ContainsKey(name))
|
||||
cache.Remove(name);
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
public override void AddResource(Resource resource)
|
||||
{
|
||||
cache.Add(resource.Name,resource);
|
||||
}
|
||||
|
||||
public override void RemoveResource(Resource resource)
|
||||
{
|
||||
if (cache.ContainsValue(resource))
|
||||
cache.Remove(resource.Name);
|
||||
}
|
||||
|
||||
public override Resource GetResource(string name)
|
||||
{
|
||||
if (!Contains(name))
|
||||
return null;
|
||||
|
||||
if (cache.ContainsKey(name))
|
||||
return cache[name];
|
||||
|
||||
String cPath = GetCombinedPath(name);
|
||||
|
||||
if (Directory.Exists(cPath))
|
||||
{
|
||||
return new DirectoryResource(this, cPath);
|
||||
}
|
||||
else if (File.Exists(cPath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(cPath);
|
||||
|
||||
Resource resource = null;
|
||||
if (ResourceTypeHook != null)
|
||||
{
|
||||
resource = ResourceTypeHook(this, fileInfo);
|
||||
}
|
||||
if (resource == null)
|
||||
{
|
||||
resource = new FileResource(this, fileInfo);
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
|
||||
public override IEnumerable<Resource> GetResources()
|
||||
{
|
||||
return DirectoryInfo.EnumerateFileSystemInfos().Select((x) => GetResource(x.Name));
|
||||
}
|
||||
|
||||
public override HttpResponse GetResponse(HttpRequest httpRequest)
|
||||
{
|
||||
if (DefaultResource != null)
|
||||
return httpRequest.Redirect(String.Join("/", DefaultResource.Path));
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Template FindTemplate(string templatePath)
|
||||
{
|
||||
if ((templatePath[0] == '/') && (Container is DirectoryResource))
|
||||
{
|
||||
return RootDirectoryResource.FindTemplate(templatePath);
|
||||
}
|
||||
Resource current = this;
|
||||
Queue<String> path = new Queue<string>(templatePath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
while (path.Count > 0)
|
||||
{
|
||||
current = current.GetResource(path.Dequeue());
|
||||
}
|
||||
if (current is TemplateResource)
|
||||
{
|
||||
return (current as TemplateResource).Template;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public DirectoryResource RootDirectoryResource
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Container is DirectoryResource)
|
||||
{
|
||||
DirectoryResource parent = Container as DirectoryResource;
|
||||
return parent.RootDirectoryResource;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FileResource : DirectoryResource
|
||||
{
|
||||
|
||||
DirectoryResource DirectoryResource { get; }
|
||||
public override DirectoryInfo DirectoryInfo => DirectoryResource.DirectoryInfo;
|
||||
|
||||
public FileInfo FileInfo { get; }
|
||||
|
||||
public FileResource(DirectoryResource directoryResource,FileInfo fileInfo)
|
||||
:base(directoryResource,fileInfo.Name)
|
||||
{
|
||||
DirectoryResource = directoryResource;
|
||||
FileInfo = fileInfo;
|
||||
}
|
||||
|
||||
public override bool Contains(string name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void AddResource(Resource resource)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
@ -42,15 +172,36 @@ namespace ln.http.resources
|
|||
|
||||
public override IEnumerable<Resource> GetResources()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return new Resource[0];
|
||||
}
|
||||
|
||||
public override HttpResponse GetResponse(HttpRequest httpRequest)
|
||||
{
|
||||
if (DefaultResource != null)
|
||||
return httpRequest.Redirect(String.Join("/", DefaultResource.Path));
|
||||
if (!httpRequest.Method.Equals("GET"))
|
||||
throw new NotImplementedException(String.Format("Method {0} is not supported by this resource", httpRequest.Method));
|
||||
|
||||
HttpResponse response = new HttpResponse(httpRequest, FileInfo.OpenRead());
|
||||
|
||||
throw new NotImplementedException();
|
||||
response.SetHeader("content-type", GuessContentType());
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public string GuessContentType()
|
||||
{
|
||||
String ext = FileInfo.Extension;
|
||||
|
||||
switch (ext)
|
||||
{
|
||||
case ".html":
|
||||
return "text/html";
|
||||
case ".txt":
|
||||
return "text/plain";
|
||||
default:
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
10
Resource.cs
10
Resource.cs
|
@ -101,5 +101,15 @@ namespace ln.http.resources
|
|||
return ResourcePathList.Select((x) => x.Name).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public Resource Root
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Container != null)
|
||||
return Container.Root;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ln.http.resources;
|
||||
using ln.http;
|
||||
using ln.templates;
|
||||
|
||||
namespace ln.http.resources
|
||||
{
|
||||
public class TemplateResource : Resource
|
||||
{
|
||||
public Template Template { get; }
|
||||
|
||||
public TemplateResource(Resource container,string filename)
|
||||
:base(container,System.IO.Path.GetFileName(filename))
|
||||
{
|
||||
Template = new Template(filename, (container as TemplateProvider));
|
||||
}
|
||||
|
||||
public override IEnumerable<Resource> GetResources()
|
||||
{
|
||||
return new Resource[0];
|
||||
}
|
||||
|
||||
public override bool Contains(string name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void AddResource(Resource resource)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void RemoveResource(Resource resource)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override HttpResponse GetResponse(HttpRequest httpRequest)
|
||||
{
|
||||
HttpResponse httpResponse = new HttpResponse(httpRequest);
|
||||
|
||||
Template.Context context = new Template.Context(Template);
|
||||
context.ExpressionContext.AddMappedValue("__root__", Root);
|
||||
context.ExpressionContext.AddMappedValue("request", httpRequest);
|
||||
context.ExpressionContext.AddMappedValue("response", httpResponse);
|
||||
|
||||
httpResponse.ContentWriter.Write(Template.Generate(context));
|
||||
|
||||
return httpResponse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -38,12 +38,17 @@
|
|||
<Compile Include="Resource.cs" />
|
||||
<Compile Include="DirectoryResource.cs" />
|
||||
<Compile Include="BaseResource.cs" />
|
||||
<Compile Include="TemplateResource.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ln.http\ln.http.csproj">
|
||||
<Project>{CEEEEB41-3059-46A2-A871-2ADE22C013D9}</Project>
|
||||
<Name>ln.http</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ln.templates\ln.templates.csproj">
|
||||
<Project>{AD0267BB-F08C-4BE1-A88D-010D49041761}</Project>
|
||||
<Name>ln.templates</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
Loading…
Reference in New Issue