1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2024-10-17 09:42:45 +02:00
TweetDuck/Browser/Handling/ResourceProvider.cs

102 lines
3.0 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using CefSharp;
using TweetLib.Core.Browser;
using IOFile = System.IO.File;
namespace TweetDuck.Browser.Handling {
internal sealed class ResourceProvider : IResourceProvider<IResourceHandler> {
private readonly Dictionary<string, ICachedResource> cache = new Dictionary<string, ICachedResource>();
public IResourceHandler Status(HttpStatusCode code, string message) {
return CreateStatusHandler(code, message);
}
public IResourceHandler File(string path) {
string key = new Uri(path).LocalPath;
if (cache.TryGetValue(key, out var cachedResource)) {
return cachedResource.GetResource();
}
cachedResource = FileWithCaching(path);
cache[key] = cachedResource;
return cachedResource.GetResource();
}
private ICachedResource FileWithCaching(string path) {
try {
return new CachedFile(System.IO.File.ReadAllBytes(path), Path.GetExtension(path));
} catch (FileNotFoundException) {
return new CachedStatus(HttpStatusCode.NotFound, "File not found.");
} catch (DirectoryNotFoundException) {
return new CachedStatus(HttpStatusCode.NotFound, "Directory not found.");
} catch (Exception e) {
return new CachedStatus(HttpStatusCode.InternalServerError, e.Message);
}
}
public void ClearCache() {
cache.Clear();
}
private static ResourceHandler CreateHandler(byte[] bytes) {
var handler = ResourceHandler.FromStream(new MemoryStream(bytes), autoDisposeStream: true);
handler.Headers.Set("Access-Control-Allow-Origin", "*");
return handler;
}
private static IResourceHandler CreateFileContentsHandler(byte[] bytes, string extension) {
if (bytes.Length == 0) {
return CreateStatusHandler(HttpStatusCode.NoContent, "File is empty."); // FromByteArray crashes CEF internals with no contents
}
else {
var handler = CreateHandler(bytes);
handler.MimeType = Cef.GetMimeType(extension);
return handler;
}
}
private static IResourceHandler CreateStatusHandler(HttpStatusCode code, string message) {
var handler = CreateHandler(Encoding.UTF8.GetBytes(message));
handler.StatusCode = (int) code;
return handler;
}
private interface ICachedResource {
IResourceHandler GetResource();
}
private sealed class CachedFile : ICachedResource {
private readonly byte[] bytes;
private readonly string extension;
public CachedFile(byte[] bytes, string extension) {
this.bytes = bytes;
this.extension = extension;
}
public IResourceHandler GetResource() {
return CreateFileContentsHandler(bytes, extension);
}
}
private sealed class CachedStatus : ICachedResource {
private readonly HttpStatusCode code;
private readonly string message;
public CachedStatus(HttpStatusCode code, string message) {
this.code = code;
this.message = message;
}
public IResourceHandler GetResource() {
return CreateStatusHandler(code, message);
}
}
}
}