mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-29 11:34:13 +02:00
101 lines
2.9 KiB
C#
101 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Text;
|
|
using CefSharp;
|
|
using TweetLib.Core.Browser;
|
|
|
|
namespace TweetDuck.Resources {
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|