parent
93b0cf4be9
commit
24ba4390a1
@ -1,72 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using Nancy;
|
|
||||||
using Nancy.Responses;
|
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Common.Cache;
|
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Api.Extensions;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Frontend
|
|
||||||
{
|
|
||||||
public class IndexModule : NancyModule
|
|
||||||
{
|
|
||||||
private readonly IDiskProvider _diskProvider;
|
|
||||||
private readonly ICached<string> _indexCache;
|
|
||||||
|
|
||||||
private readonly string _indexPath;
|
|
||||||
|
|
||||||
public IndexModule(IDiskProvider diskProvider, ICacheManger cacheManger, IAppFolderInfo appFolder)
|
|
||||||
{
|
|
||||||
_diskProvider = diskProvider;
|
|
||||||
|
|
||||||
_indexPath = Path.Combine(appFolder.StartUpFolder, "UI", "index.html");
|
|
||||||
|
|
||||||
_indexCache = cacheManger.GetCache<string>(typeof(IndexModule));
|
|
||||||
//Serve anything that doesn't have an extension
|
|
||||||
Get[@"/(.*)"] = x => Index();
|
|
||||||
}
|
|
||||||
|
|
||||||
private object Index()
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
Request.Path.Contains(".")
|
|
||||||
|| Request.Path.StartsWith("/static", StringComparison.CurrentCultureIgnoreCase)
|
|
||||||
|| Request.Path.StartsWith("/api", StringComparison.CurrentCultureIgnoreCase)
|
|
||||||
|| Request.Path.StartsWith("/signalr", StringComparison.CurrentCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
return new NotFoundResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var htmlResponse = new HtmlResponse();
|
|
||||||
|
|
||||||
htmlResponse.Contents = stream =>
|
|
||||||
{
|
|
||||||
var lastWrite = _diskProvider.GetLastFileWrite(_indexPath);
|
|
||||||
var text = _indexCache.Get(lastWrite.Ticks.ToString(), GetIndexText);
|
|
||||||
|
|
||||||
var streamWriter = new StreamWriter(stream);
|
|
||||||
|
|
||||||
streamWriter.Write(text);
|
|
||||||
streamWriter.Flush();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
htmlResponse.Headers.DisableCache();
|
|
||||||
|
|
||||||
return htmlResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private string GetIndexText()
|
|
||||||
{
|
|
||||||
var text = _diskProvider.ReadAllText(_indexPath);
|
|
||||||
|
|
||||||
text = text.Replace(".css", ".css?v=" + BuildInfo.Version);
|
|
||||||
text = text.Replace(".js", ".js?v=" + BuildInfo.Version);
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using Nancy;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Frontend
|
||||||
|
{
|
||||||
|
public class IsCacheableSpecification
|
||||||
|
{
|
||||||
|
public bool IsCacheable(Request request)
|
||||||
|
{
|
||||||
|
if (request.Path.Contains(".")) return false;
|
||||||
|
if (request.Path.StartsWith("/api", StringComparison.CurrentCultureIgnoreCase)) return false;
|
||||||
|
if (request.Path.StartsWith("/signalr", StringComparison.CurrentCultureIgnoreCase)) return false;
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
using System.IO;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Frontend.Mappers
|
||||||
|
{
|
||||||
|
public class IndexHtmlMapper : IMapHttpRequestsToDisk
|
||||||
|
{
|
||||||
|
private readonly string _indexPath;
|
||||||
|
|
||||||
|
public IndexHtmlMapper(IAppFolderInfo appFolderInfo)
|
||||||
|
{
|
||||||
|
_indexPath = Path.Combine(appFolderInfo.StartUpFolder, "UI", "index.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Map(string resourceUrl)
|
||||||
|
{
|
||||||
|
return _indexPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanHandle(string resourceUrl)
|
||||||
|
{
|
||||||
|
return !resourceUrl.Contains(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
using System.IO;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Frontend.Mappers
|
||||||
|
{
|
||||||
|
public class StaticResourceMapper : IMapHttpRequestsToDisk
|
||||||
|
{
|
||||||
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
|
|
||||||
|
public StaticResourceMapper(IAppFolderInfo appFolderInfo)
|
||||||
|
{
|
||||||
|
_appFolderInfo = appFolderInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Map(string resourceUrl)
|
||||||
|
{
|
||||||
|
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
||||||
|
path = path.Trim(Path.DirectorySeparatorChar);
|
||||||
|
|
||||||
|
return Path.Combine(_appFolderInfo.StartUpFolder, "UI", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanHandle(string resourceUrl)
|
||||||
|
{
|
||||||
|
return resourceUrl.StartsWith("/Content") || resourceUrl.EndsWith(".js") || resourceUrl.EndsWith(".css");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,56 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Frontend
|
|
||||||
{
|
|
||||||
public class StaticResourceMapper : IMapHttpRequestsToDisk
|
|
||||||
{
|
|
||||||
private readonly IAppFolderInfo _appFolderInfo;
|
|
||||||
private static readonly string[] Extensions = new[] {
|
|
||||||
".css",
|
|
||||||
".js",
|
|
||||||
".html",
|
|
||||||
".htm",
|
|
||||||
".jpg",
|
|
||||||
".jpeg",
|
|
||||||
".ico",
|
|
||||||
".icon",
|
|
||||||
".gif",
|
|
||||||
".png",
|
|
||||||
".woff",
|
|
||||||
".ttf",
|
|
||||||
".eot"
|
|
||||||
};
|
|
||||||
|
|
||||||
public StaticResourceMapper(IAppFolderInfo appFolderInfo)
|
|
||||||
{
|
|
||||||
_appFolderInfo = appFolderInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Map(string resourceUrl)
|
|
||||||
{
|
|
||||||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
|
||||||
path = path.Trim(Path.DirectorySeparatorChar);
|
|
||||||
|
|
||||||
|
|
||||||
return Path.Combine(_appFolderInfo.StartUpFolder, "UI", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanHandle(string resourceUrl)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(resourceUrl))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resourceUrl.StartsWith("/mediacover", StringComparison.CurrentCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Extensions.Any(resourceUrl.EndsWith);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using Nancy;
|
||||||
|
using Nancy.Responses;
|
||||||
|
using NzbDrone.Api.Frontend.Mappers;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Frontend
|
||||||
|
{
|
||||||
|
public class StaticResourceModule : NancyModule
|
||||||
|
{
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IEnumerable<IMapHttpRequestsToDisk> _requestMappers;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
private readonly ICached<string> _indexCache;
|
||||||
|
|
||||||
|
private readonly bool _caseSensitive;
|
||||||
|
|
||||||
|
public StaticResourceModule(IDiskProvider diskProvider, ICacheManger cacheManger, IEnumerable<IMapHttpRequestsToDisk> requestMappers, Logger logger)
|
||||||
|
{
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_requestMappers = requestMappers;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
_indexCache = cacheManger.GetCache<string>(typeof(StaticResourceModule));
|
||||||
|
|
||||||
|
Get["/{resource*}"] = x => Index();
|
||||||
|
Get["/*"] = x => Index();
|
||||||
|
|
||||||
|
if (!RuntimeInfo.IsProduction)
|
||||||
|
{
|
||||||
|
_caseSensitive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response Index()
|
||||||
|
{
|
||||||
|
var path = Request.Url.Path;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string.IsNullOrWhiteSpace(path) ||
|
||||||
|
path.StartsWith("/api", StringComparison.CurrentCultureIgnoreCase) ||
|
||||||
|
path.StartsWith("/signalr", StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var mapper = _requestMappers.SingleOrDefault(m => m.CanHandle(path));
|
||||||
|
|
||||||
|
|
||||||
|
if (mapper != null)
|
||||||
|
{
|
||||||
|
var filePath = mapper.Map(path);
|
||||||
|
|
||||||
|
if (_diskProvider.FileExists(filePath, _caseSensitive))
|
||||||
|
{
|
||||||
|
var response = new StreamResponse(() => File.OpenRead(filePath), MimeTypes.GetMimeType(filePath));
|
||||||
|
//_addCacheHeaders.ToResponse(context.Request, response);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Warn("File {0} not found", filePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Warn("Couldn't find handler for {0}", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NotFoundResponse();
|
||||||
|
|
||||||
|
/* htmlResponse.Contents = stream =>
|
||||||
|
{
|
||||||
|
var lastWrite = _diskProvider.GetLastFileWrite(_indexPath);
|
||||||
|
var text = _indexCache.Get(lastWrite.Ticks.ToString(), GetIndexText);
|
||||||
|
|
||||||
|
var streamWriter = new StreamWriter(stream);
|
||||||
|
|
||||||
|
streamWriter.Write(text);
|
||||||
|
streamWriter.Flush();
|
||||||
|
};*/
|
||||||
|
|
||||||
|
//htmlResponse.Headers.DisableCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* private string GetIndexText()
|
||||||
|
{
|
||||||
|
var text = _diskProvider.ReadAllText(_indexPath);
|
||||||
|
|
||||||
|
text = text.Replace(".css", ".css?v=" + BuildInfo.Version);
|
||||||
|
text = text.Replace(".js", ".js?v=" + BuildInfo.Version);
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue