diff --git a/.gitignore b/.gitignore index 1b0e567..3fa9123 100644 --- a/.gitignore +++ b/.gitignore @@ -188,3 +188,4 @@ _Pvt_Extensions/ ModelManifest.xml .vs +/Sunfish/ShareWeb/TestFS diff --git a/Sunfish/Sunfish/Extensions.cs b/Sunfish/Sunfish/Extensions.cs index d8f5060..bacac4e 100644 --- a/Sunfish/Sunfish/Extensions.cs +++ b/Sunfish/Sunfish/Extensions.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Windows.Forms; namespace DolphinWebXplorer2 @@ -9,5 +10,16 @@ { MessageBox.Show(ex.Message, ex.GetType().Name, MessageBoxButtons.OK, MessageBoxIcon.Error); } + + public static void TransferFrom(this Stream s,Stream from) + { + byte[] buf = new byte[10240];// 10Kb + int readed=buf.Length; + while (readed == buf.Length) + { + readed = from.Read(buf, 0, buf.Length); + s.Write(buf, 0, readed); + } + } } } diff --git a/Sunfish/Sunfish/Middleware/HttpServer.cs b/Sunfish/Sunfish/Middleware/HttpServer.cs index f68a03b..e4e0f28 100644 --- a/Sunfish/Sunfish/Middleware/HttpServer.cs +++ b/Sunfish/Sunfish/Middleware/HttpServer.cs @@ -198,7 +198,7 @@ string[] cttp = contentType.Split(';'); string ctype = cttp[0]; Dictionary cttParams = null; - BufferedStream bfs = new BufferedStream(input,1024*1024); + BufferedStream bfs = new BufferedStream(input, 1024 * 1024); if (cttp.Length > 1) { cttParams = new Dictionary(); @@ -329,7 +329,7 @@ while (true) { - b=onebyte[0] = br.ReadByte(); + b = onebyte[0] = br.ReadByte(); ms.Write(onebyte, 0, 1); if (b == signal[signalIdx]) { @@ -369,12 +369,18 @@ #endregion #region Output - protected void Error404() + public void NotFound() { Response.StatusCode = 404; Response.StatusDescription = "Not found"; } + public void Redirect(string to) + { + Response.StatusCode = 307; //Temporary Redirect + Response.Headers["Location"] = to; + } + public void Write(string s) { if (s != null) @@ -401,8 +407,9 @@ public void Close() { - if (swout != null) - swout.Close(); + if (swout == null) + GetOut(); + swout.Close(); } #endregion diff --git a/Sunfish/Sunfish/Middleware/VFS.cs b/Sunfish/Sunfish/Middleware/VFS.cs index 52f556f..be135ea 100644 --- a/Sunfish/Sunfish/Middleware/VFS.cs +++ b/Sunfish/Sunfish/Middleware/VFS.cs @@ -11,7 +11,7 @@ { private Dictionary vf = new Dictionary(); - public void AddVirtualFolder(string path,VFSFolder folder) + public void AddVirtualFolder(string path, VFSFolder folder) { if (string.IsNullOrWhiteSpace(path)) path = "/"; @@ -24,24 +24,63 @@ vf[path] = folder; } + private VFSFolder LocateFolder(ref string path) + { + VFSFolder candidate = null; + string candidatePath = null; + string candidateRelativePath = null; + foreach (string k in vf.Keys) + { + if (candidate == null || + (path.StartsWith(k) && k.Length > candidatePath.Length)) + { + candidate = vf[k]; + candidatePath = k; + candidateRelativePath = path.Substring(k.Length); + } + } + path = candidateRelativePath; + return candidate; + } + public Stream OpenRead(string path) { - return null; + VFSFolder folder = LocateFolder(ref path); + if (folder == null) + return null; + return folder.OpenRead(path); } public Stream OpenWrite(string path) { - return null; + VFSFolder folder = LocateFolder(ref path); + if (folder == null) + return null; + return folder.OpenWrite(path); + } + + public VFSItem GetItem(string path) + { + VFSFolder folder = LocateFolder(ref path); + if (folder == null) + return null; + return folder.GetItem(path); } public string[] ListFiles(string path) { - return null; + VFSFolder folder = LocateFolder(ref path); + if (folder == null) + return null; + return folder.ListFiles(path); } public string[] ListDirectories(string path) { - return null; + VFSFolder folder = LocateFolder(ref path); + if (folder == null) + return null; + return folder.ListDirectories(path); } } } diff --git a/Sunfish/Sunfish/Middleware/VFSFolder.cs b/Sunfish/Sunfish/Middleware/VFSFolder.cs index 42fdf2d..ca62830 100644 --- a/Sunfish/Sunfish/Middleware/VFSFolder.cs +++ b/Sunfish/Sunfish/Middleware/VFSFolder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -8,5 +9,10 @@ { public abstract class VFSFolder { + public abstract Stream OpenRead(string path); + public abstract Stream OpenWrite(string path); + public abstract VFSItem GetItem(string path); + public abstract string[] ListFiles(string path); + public abstract string[] ListDirectories(string path); } } diff --git a/Sunfish/Sunfish/Middleware/VFSFolderFileSystem.cs b/Sunfish/Sunfish/Middleware/VFSFolderFileSystem.cs index 647710e..0769988 100644 --- a/Sunfish/Sunfish/Middleware/VFSFolderFileSystem.cs +++ b/Sunfish/Sunfish/Middleware/VFSFolderFileSystem.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; using System.Text; using System.Threading.Tasks; @@ -8,12 +10,50 @@ { public class VFSFolderFileSystem:VFSFolder { + private string basePath; + public VFSFolderFileSystem(string path) { - + basePath = path; } public bool AllowSubfolder { get; set; } = true; public bool ReadOnly { get; set; } = true; + + public override Stream OpenRead(string path) + { + path = Path.Combine(basePath, path); + try + { + return File.OpenRead(path); + }catch { }; + return null; + } + + public override Stream OpenWrite(string path) + { + throw new NotImplementedException(); + } + + public override VFSItem GetItem(string path) + { + string fpath = Path.Combine(basePath, path); + FileInfo fi = new FileInfo(fpath); + DirectoryInfo di = new DirectoryInfo(fpath); + if (!fi.Exists && !di.Exists) + return null; + return new VFSItem(this,fpath,di.Exists); + } + + public override string[] ListDirectories(string path) + { + throw new NotImplementedException(); + } + + public override string[] ListFiles(string path) + { + throw new NotImplementedException(); + } + } } diff --git a/Sunfish/Sunfish/Middleware/VFSItem.cs b/Sunfish/Sunfish/Middleware/VFSItem.cs new file mode 100644 index 0000000..4de6bff --- /dev/null +++ b/Sunfish/Sunfish/Middleware/VFSItem.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DolphinWebXplorer2.Middleware +{ + public class VFSItem + { + private VFSFolder vfolder; + private string name; + + public VFSItem(VFSFolder vfolder, string path, bool isFolder) + { + this.vfolder = vfolder; + this.Path = path; + this.Folder = isFolder; + Name = System.IO.Path.GetFileName(Path); + } + + public Stream OpenRead() + { + return vfolder.OpenRead(Path); + } + + public string Path { get; } + public string Name { get; } + public bool Folder { get; } + } +} diff --git a/Sunfish/Sunfish/Services/WebService.cs b/Sunfish/Sunfish/Services/WebService.cs index 9b9539a..daadde7 100644 --- a/Sunfish/Sunfish/Services/WebService.cs +++ b/Sunfish/Sunfish/Services/WebService.cs @@ -19,20 +19,71 @@ allowSubfolderNavigation = ssc.GetConf(WebServiceConfigurator.CFG_NAVIGATION); } + private void ErrorPage(int code, HttpCall call, string text) + { + call.Response.StatusCode = code; + call.Write(text); + } + + private void Error500(HttpCall call, string text) + { + ErrorPage(500, call, text); + } + + private void DownloadAt(string path, HttpCall call) + { + using (Stream s = vfs.OpenRead(path)) + { + if (s == null) + { + Error500(call, "Problem transfering file"); + return; + } + call.Out.BaseStream.TransferFrom(s); + } + } + + private void DownloadAt(VFSItem item, HttpCall call) + { + using (Stream s = item.OpenRead()) + { + if (s == null) + { + Error500(call, "Problem transfering file"); + return; + } + call.Out.BaseStream.TransferFrom(s); + } + } + public override void Process(string path, HttpCall call) { if (path.EndsWith("/")) { //Directory entry, go for index file or navigation + if (index != null) + { + VFSItem idx = vfs.GetItem(path + index); + if (idx != null) + DownloadAt(idx, call); + } + //allowNavigation + DownloadAt("/$sunfish/index.html", call); } else { - using (Stream s = vfs.OpenRead(path)) + VFSItem idx = vfs.GetItem(path); + if (idx != null) { - //call.Out. + if (idx.Folder) + call.Redirect(path + "/"); + else + DownloadAt(idx, call); } + else + call.NotFound(); + //DownloadAt("/$sunfish/404.html", call); } - call.Write("PoFale!!"); } protected override void Start() diff --git a/Sunfish/Sunfish/Sunfish.cs b/Sunfish/Sunfish/Sunfish.cs index c37fe35..406acf7 100644 --- a/Sunfish/Sunfish/Sunfish.cs +++ b/Sunfish/Sunfish/Sunfish.cs @@ -41,6 +41,12 @@ { srvs.Add(SunfishService.Instance(ssc)); } + if (conf.Active) + { + //Bypass set active check + conf.Active = false; + SetActive(true); + } } public static void Save() diff --git a/Sunfish/Sunfish/Sunfish.csproj b/Sunfish/Sunfish/Sunfish.csproj index 54dfa8a..473dd61 100644 --- a/Sunfish/Sunfish/Sunfish.csproj +++ b/Sunfish/Sunfish/Sunfish.csproj @@ -109,6 +109,7 @@ +