add FTP handler + mime type guesser
This commit is contained in:
parent
e049b1a090
commit
1f901943e3
|
@ -1,5 +1,6 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using HeyRed.Mime;
|
||||||
|
|
||||||
namespace Shoko;
|
namespace Shoko;
|
||||||
|
|
||||||
|
@ -13,17 +14,18 @@ class FileProtoHandler : ProtoHandler
|
||||||
|
|
||||||
public override void Load()
|
public override void Load()
|
||||||
{
|
{
|
||||||
var file = HttpUtility.UrlDecode(new UriBuilder(URL).Path);
|
var file = HttpUtility.UrlDecode(URL.AbsolutePath);
|
||||||
|
|
||||||
if(URL.Host.Length > 0)
|
if(URL.Host.Length > 0)
|
||||||
file = "//" + URL.Host + file;
|
file = "//" + URL.Host + file;
|
||||||
|
|
||||||
MediaType = "text/plain"; // TODO: magic numbers
|
MediaType = "text/plain";
|
||||||
Status = "OK";
|
Status = "OK";
|
||||||
|
|
||||||
if(File.Exists(file))
|
if(File.Exists(file))
|
||||||
{
|
{
|
||||||
var stream = new FileStream(file, FileMode.Open);
|
var stream = new FileStream(file, FileMode.Open);
|
||||||
|
MediaType = MimeGuesser.GuessMimeType(stream);
|
||||||
Content = stream;
|
Content = stream;
|
||||||
}
|
}
|
||||||
else if(Directory.Exists(file))
|
else if(Directory.Exists(file))
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using FluentFTP;
|
||||||
|
using HeyRed.Mime;
|
||||||
|
|
||||||
|
namespace Shoko;
|
||||||
|
|
||||||
|
[Protocol("ftp")]
|
||||||
|
[Protocol("ftps")]
|
||||||
|
class FtpProtoHandler : ProtoHandler
|
||||||
|
{
|
||||||
|
public FtpProtoHandler(Uri url)
|
||||||
|
{
|
||||||
|
URL = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Load()
|
||||||
|
{
|
||||||
|
var file = URL.AbsolutePath;
|
||||||
|
|
||||||
|
var conn = new FtpClient
|
||||||
|
{
|
||||||
|
Host = URL.Host,
|
||||||
|
Port = URL.Port
|
||||||
|
};
|
||||||
|
|
||||||
|
if (URL.UserInfo.Length > 0)
|
||||||
|
{
|
||||||
|
var userinfo = URL.UserInfo.Split(":",2);
|
||||||
|
var user = userinfo[0];
|
||||||
|
var pass = userinfo.Length > 1 ? userinfo[1] : "";
|
||||||
|
conn.Credentials = new NetworkCredential(user, pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(URL.Scheme == "ftps")
|
||||||
|
{
|
||||||
|
conn.Config.EncryptionMode = FtpEncryptionMode.Explicit;
|
||||||
|
conn.Config.ValidateAnyCertificate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Config.LogToConsole = true;
|
||||||
|
conn.Config.LogHost = true;
|
||||||
|
conn.Config.LogUserName = true;
|
||||||
|
conn.Config.LogPassword = true;
|
||||||
|
|
||||||
|
conn.Connect();
|
||||||
|
|
||||||
|
MediaType = "text/plain"; // TODO: magic numbers
|
||||||
|
Status = "OK";
|
||||||
|
|
||||||
|
var info = conn.GetObjectInfo(file);
|
||||||
|
|
||||||
|
if(info is not null)
|
||||||
|
{
|
||||||
|
switch(info.Type)
|
||||||
|
{
|
||||||
|
case FtpObjectType.File:
|
||||||
|
//Content = conn.OpenRead(file);
|
||||||
|
if(conn.DownloadBytes(out byte[] bytes, info.FullName))
|
||||||
|
{
|
||||||
|
Content = new MemoryStream(bytes);
|
||||||
|
MediaType = MimeGuesser.GuessMimeType(Content);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FtpObjectType.Directory:
|
||||||
|
MediaType = "text/gemini";
|
||||||
|
var entries = conn.GetListing(info.FullName);
|
||||||
|
var str = "# "+file+"\r\n";
|
||||||
|
|
||||||
|
foreach(var entry in entries)
|
||||||
|
{
|
||||||
|
var path = entry.Name;
|
||||||
|
if(entry.Type == FtpObjectType.Directory) path += "/";
|
||||||
|
var target = new Uri(URL, path).ToString();
|
||||||
|
if(entry.Type == FtpObjectType.Link) target = new Uri(URL, info.LinkTarget).ToString();
|
||||||
|
str += string.Format("=>{0} {1}\r\n", target, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Content = new MemoryStream(Encoding.UTF8.GetBytes(str));
|
||||||
|
break;
|
||||||
|
case FtpObjectType.Link:
|
||||||
|
MediaType = "text/gemini";
|
||||||
|
Content = new MemoryStream(Encoding.UTF8.GetBytes("=>"+new Uri(URL, info.LinkTarget).ToString()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(conn.DirectoryExists(file))
|
||||||
|
{
|
||||||
|
MediaType = "text/gemini";
|
||||||
|
var entries = conn.GetListing(file);
|
||||||
|
var str = "# "+file+"\r\n";
|
||||||
|
|
||||||
|
foreach(var entry in entries)
|
||||||
|
{
|
||||||
|
var path = entry.Name;
|
||||||
|
if(entry.Type == FtpObjectType.Directory) path += "/";
|
||||||
|
str += string.Format("=>{0} {1}\r\n", new Uri(URL, path).ToString(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Content = new MemoryStream(Encoding.UTF8.GetBytes(str));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Content = new MemoryStream(Encoding.UTF8.GetBytes("file not found"));
|
||||||
|
Status = "not found";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loaded = true;
|
||||||
|
}
|
||||||
|
public override void Render()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using HeyRed.Mime;
|
||||||
|
|
||||||
namespace Shoko;
|
namespace Shoko;
|
||||||
|
|
||||||
|
@ -16,10 +17,10 @@ class ResProtoHandler : ProtoHandler
|
||||||
var path = HttpUtility.HtmlDecode(new UriBuilder(URL).Path);
|
var path = HttpUtility.HtmlDecode(new UriBuilder(URL).Path);
|
||||||
Status = "OK";
|
Status = "OK";
|
||||||
Loaded = true;
|
Loaded = true;
|
||||||
MediaType = "text/plain";
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Content = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
|
Content = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
|
||||||
|
MediaType = MimeGuesser.GuessMimeType(Content);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue