diff --git a/Sunfish/Sunfish/Form1.Designer.cs b/Sunfish/Sunfish/Form1.Designer.cs index f1a11b4..7cf3041 100644 --- a/Sunfish/Sunfish/Form1.Designer.cs +++ b/Sunfish/Sunfish/Form1.Designer.cs @@ -44,6 +44,7 @@ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.btShowIp = new System.Windows.Forms.Button(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.cbRootList = new System.Windows.Forms.CheckBox(); ((System.ComponentModel.ISupportInitialize)(this.nudPort)).BeginInit(); this.cmsItem.SuspendLayout(); this.SuspendLayout(); @@ -51,7 +52,7 @@ // btDone // this.btDone.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btDone.Location = new System.Drawing.Point(213, 514); + this.btDone.Location = new System.Drawing.Point(238, 521); this.btDone.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.btDone.Name = "btDone"; this.btDone.Size = new System.Drawing.Size(138, 35); @@ -64,7 +65,7 @@ // nudPort // this.nudPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.nudPort.Location = new System.Drawing.Point(268, 9); + this.nudPort.Location = new System.Drawing.Point(293, 9); this.nudPort.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.nudPort.Maximum = new decimal(new int[] { 64000, @@ -86,7 +87,7 @@ // this.cbActive.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.cbActive.AutoSize = true; - this.cbActive.Location = new System.Drawing.Point(119, 12); + this.cbActive.Location = new System.Drawing.Point(153, 12); this.cbActive.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.cbActive.Name = "cbActive"; this.cbActive.Size = new System.Drawing.Size(132, 24); @@ -102,7 +103,7 @@ this.btAdd.Font = new System.Drawing.Font("Lucida Console", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.btAdd.ImageIndex = 0; this.btAdd.ImageList = this.il16; - this.btAdd.Location = new System.Drawing.Point(9, 514); + this.btAdd.Location = new System.Drawing.Point(9, 521); this.btAdd.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.btAdd.Name = "btAdd"; this.btAdd.Size = new System.Drawing.Size(34, 35); @@ -125,7 +126,7 @@ this.btSub.Font = new System.Drawing.Font("Lucida Console", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.btSub.ImageKey = "bt_minus.bmp"; this.btSub.ImageList = this.il16; - this.btSub.Location = new System.Drawing.Point(52, 514); + this.btSub.Location = new System.Drawing.Point(52, 521); this.btSub.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.btSub.Name = "btSub"; this.btSub.Size = new System.Drawing.Size(34, 35); @@ -148,7 +149,7 @@ this.lbPaths.Location = new System.Drawing.Point(0, 49); this.lbPaths.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.lbPaths.Name = "lbPaths"; - this.lbPaths.Size = new System.Drawing.Size(358, 453); + this.lbPaths.Size = new System.Drawing.Size(383, 460); this.lbPaths.TabIndex = 7; this.lbPaths.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.lbPaths_DrawItem); this.lbPaths.SelectedIndexChanged += new System.EventHandler(this.lbPaths_SelectedIndexChanged); @@ -201,7 +202,7 @@ this.btShowIp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btShowIp.Font = new System.Drawing.Font("Lucida Console", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.btShowIp.Image = global::DolphinWebXplorer2.Properties.Resources.messagebox_info; - this.btShowIp.Location = new System.Drawing.Point(170, 514); + this.btShowIp.Location = new System.Drawing.Point(195, 521); this.btShowIp.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.btShowIp.Name = "btShowIp"; this.btShowIp.Size = new System.Drawing.Size(34, 35); @@ -210,11 +211,25 @@ this.btShowIp.UseVisualStyleBackColor = true; this.btShowIp.Click += new System.EventHandler(this.btShowIp_Click); // + // cbRootList + // + this.cbRootList.AutoSize = true; + this.cbRootList.Location = new System.Drawing.Point(12, 12); + this.cbRootList.Name = "cbRootList"; + this.cbRootList.Size = new System.Drawing.Size(114, 24); + this.cbRootList.TabIndex = 9; + this.cbRootList.Text = "Root menu"; + this.toolTip1.SetToolTip(this.cbRootList, "If there is no service located at root sunfish will show a listing page with all " + + "availables services and paths."); + this.cbRootList.UseVisualStyleBackColor = true; + this.cbRootList.CheckedChanged += new System.EventHandler(this.cbRootList_CheckedChanged); + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(360, 558); + this.ClientSize = new System.Drawing.Size(385, 565); + this.Controls.Add(this.cbRootList); this.Controls.Add(this.btShowIp); this.Controls.Add(this.lbPaths); this.Controls.Add(this.btSub); @@ -253,6 +268,7 @@ private System.Windows.Forms.ToolStripMenuItem aƱadirToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem borrarToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.CheckBox cbRootList; } } diff --git a/Sunfish/Sunfish/Form1.cs b/Sunfish/Sunfish/Form1.cs index 933e49d..ca82c75 100644 --- a/Sunfish/Sunfish/Form1.cs +++ b/Sunfish/Sunfish/Form1.cs @@ -33,6 +33,7 @@ Enabled = false; nudPort.Value = Sunfish.Port; cbActive.Checked = Sunfish.Active; + cbRootList.Checked = Sunfish.RootMenu; lbPaths.Items.Clear(); foreach (SunfishService s in Sunfish.Services) lbPaths.Items.Add(s); @@ -243,7 +244,7 @@ if (!Directory.Exists(file)) fil = Path.GetDirectoryName(fil); ssc.Name = Path.GetFileName(fil); - ssc.Location = Path.GetFileName(fil); + ssc.Location = '/' + Path.GetFileName(fil); ssc.Enabled = true; ssc.Settings[Services.WebServiceConfigurator.CFG_PATH] = fil; ssc.Settings[Services.WebServiceConfigurator.CFG_SHARE] = true; @@ -254,5 +255,9 @@ } } + private void cbRootList_CheckedChanged(object sender, EventArgs e) + { + Sunfish.RootMenu = cbRootList.Checked; + } } } diff --git a/Sunfish/Sunfish/Form1.resx b/Sunfish/Sunfish/Form1.resx index 7eed72d..0650a43 100644 --- a/Sunfish/Sunfish/Form1.resx +++ b/Sunfish/Sunfish/Form1.resx @@ -128,7 +128,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAq - AQAAAk1TRnQBSQFMAgEBAgEAAXgBAAF4AQABEAEAARABAAT/AQUBAAj/AUIBTQF2BwABdgMAASgDAAFA + AQAAAk1TRnQBSQFMAgEBAgEAAYABAAGAAQABEAEAARABAAT/AQUBAAj/AUIBTQF2BwABdgMAASgDAAFA AwABEAMAAQEBAAEEBgABAhgAAYACAAGAAwACgAEAAYADAAGAAQABgAEAAoACAAPAAQADgAMAAf8CAAH/ AwAC/wEAAf8DAAH/AQAB/wEAAv8CAAP//wD/AAMAAUIBTQE+BwABPgMAASgDAAFAAwABEAMAAQEBAAEB BQABgBcAA/8BAAT/BAAE/wQABP8EAAH8AT8C/wQAAfwBPwL/BAAB/AE/Av8EAAHgAQcB4AEHBAAB4AEH @@ -136,6 +136,9 @@ BAAL + + 17, 17 + 185, 17 diff --git a/Sunfish/Sunfish/Middleware/HttpServer.cs b/Sunfish/Sunfish/Middleware/HttpServer.cs index 10a31c1..019e7c9 100644 --- a/Sunfish/Sunfish/Middleware/HttpServer.cs +++ b/Sunfish/Sunfish/Middleware/HttpServer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Net; +using System.Security.Principal; using System.Text; using System.Threading; using System.Web; @@ -32,7 +33,14 @@ if (lis != null) return; lis = new HttpListener(); + + // WARNING: This require the server to be launched as administrative process + // This is very problematic due the actions that the server do are width administrator + // rights, even the (future) embedded execution of C#, the file upload and deletion + // and also the execution of server applications. + lis.Prefixes.Add("http://+:" + port + "/"); + try { lis.Start(); @@ -67,10 +75,16 @@ { processors.Add(Thread.CurrentThread); } - CallNewProcessor((HttpListenerContext)octx); - lock (processors) + try { - processors.Remove(Thread.CurrentThread); + CallNewProcessor((HttpListenerContext)octx); + } + finally + { + lock (processors) + { + processors.Remove(Thread.CurrentThread); + } } } @@ -121,14 +135,13 @@ public bool MultiThread { get { return multiThread; } set { multiThread = value; } } } - public abstract class HttpServerProcessor + abstract class HttpServerProcessor { protected HttpListenerRequest Request; protected HttpListenerResponse Response; protected System.Security.Principal.IPrincipal User; protected HttpPost Post; private StreamWriter swout; - private string path; private Dictionary getArgs = new Dictionary(); internal HttpServer server; @@ -140,7 +153,7 @@ Request = ctx.Request; Response = ctx.Response; User = ctx.User; - System.Text.Encoding utf8EncoderNoBOM = new System.Text.UTF8Encoding(false); + Encoding utf8EncoderNoBOM = new UTF8Encoding(false); swout = new StreamWriter(Response.OutputStream, utf8EncoderNoBOM); Response.Headers[HttpResponseHeader.ContentType] = "text/html"; Response.Headers[HttpResponseHeader.ContentEncoding] = "UTF-8"; @@ -175,7 +188,6 @@ private void GetHeaders() { - path = Request.Url.LocalPath; string qs = Request.Url.Query; if (qs.StartsWith("?")) ReadEncodedArguments(qs.Substring(1)); @@ -235,10 +247,10 @@ OutStream.Write(data, offset, count); } - public string nl2br(string s) - { - return s.Replace("\r\n", "
").Replace("\n", "
").Replace("\r", "
"); - } + //public string nl2br(string s) + //{ + // return s.Replace("\r\n", "
").Replace("\n", "
").Replace("\r", "
"); + //} public string UrlEncode(string url) { @@ -254,11 +266,75 @@ protected Stream OutStream { get { return Response.OutputStream; } } protected StreamWriter Out { get { return swout; } } - public string Path { get { return path; } } public Dictionary GET { get { return getArgs; } } public Dictionary POST { get { return getArgs; } } } + public class HttpCall + { + private StreamWriter swout; + private Dictionary parameters = new Dictionary(); + + internal HttpCall(HttpListenerContext ctx) + { + Request = ctx.Request; + Response = ctx.Response; + User = ctx.User; + //if ("POST" == Request.HttpMethod) + //Post = new HttpPost(this, Request.InputStream, Request.ContentType, Request.ContentEncoding); + //Parameters = parameters; + } + + private void GetHeaders() + { + string qs = Request.Url.Query; + if (qs.StartsWith("?")) + ReadEncodedParameters(qs.Substring(1), parameters); + } + + static void ReadEncodedParameters(string qs, Dictionary parameters) + { + string[] args = qs.Split('&'); + foreach (string arg in args) + { + int ppos = arg.IndexOf('='); + if (ppos == -1) + parameters[arg] = "true"; + else + { + string aname = arg.Substring(0, ppos); + string aval = arg.Substring(ppos + 1); + parameters[aname] = HttpUtility.UrlDecode(aval); + } + } + } + + public void OpenOutput() + { + Encoding utf8EncoderNoBOM = new UTF8Encoding(false); + swout = new StreamWriter(Response.OutputStream, utf8EncoderNoBOM); + Response.Headers[HttpResponseHeader.ContentType] = "text/html"; + Response.Headers[HttpResponseHeader.ContentEncoding] = "UTF-8"; + } + + private StreamWriter GetOut() + { + //if (swout == null) + //{ + // swout= + //} + return null; + } + + public HttpListenerRequest Request { get; } + public HttpListenerResponse Response { get; } + public IPrincipal User { get; } + public HttpPost Post { get; } + + public StreamWriter Out => GetOut(); + } + + public class LogError { public LogError(Exception e) @@ -282,10 +358,10 @@ private char[] mimeBoundaryChr; private byte[] mimeBoundaryBytes; - public HttpPost(HttpServerProcessor owner, Stream input, string contentType, Encoding enc) + internal HttpPost(HttpServerProcessor owner, Stream input, string contentType, Encoding enc) { this.owner = owner; - this.encoding = enc; + encoding = enc; string[] cttp = contentType.Split(';'); this.contentType = cttp[0]; if (cttp.Length > 1) @@ -307,7 +383,7 @@ private void ReadPost(Stream input) { MemoryStream ms = new MemoryStream(); - byte[] buf = new byte[10240]; + byte[] buf = new byte[102400]; int readed = 0; while ((readed = input.Read(buf, 0, buf.Length)) > 0) { diff --git a/Sunfish/Sunfish/Program.cs b/Sunfish/Sunfish/Program.cs index 14edaf5..ee094c9 100644 --- a/Sunfish/Sunfish/Program.cs +++ b/Sunfish/Sunfish/Program.cs @@ -7,7 +7,7 @@ { static class Program { - public static string VERSION = "2.0(alpha)"; + public static string VERSION = "2.0(alpha2)"; private static Form1 mainform; /// /// Punto de entrada principal para la aplicación. diff --git a/Sunfish/Sunfish/Services/WebServiceConfigurator.cs b/Sunfish/Sunfish/Services/WebServiceConfigurator.cs index c6b42c9..e6da77e 100644 --- a/Sunfish/Sunfish/Services/WebServiceConfigurator.cs +++ b/Sunfish/Sunfish/Services/WebServiceConfigurator.cs @@ -30,8 +30,8 @@ IsDirectoiryPath = true, IsFilePath = true, }, - new ConfigurationString(CFG_INDEX,"Default document") - { + new ConfigurationString(CFG_INDEX,"Default document") + { Tooltip = "Default document for directory path", DefaultValue ="index.html" }, @@ -58,7 +58,8 @@ new ConfigurationBool(CFG_EXECUTE,"Allow execute") { Tooltip ="Allow application execution on server." - } + }, + new ConfigurationMessage(ConfigurationMessage.MessageType.WARNING,"WARNING: Sunfish is exeuted as elevated process, any antion and process started by sunfish will be also elevated.") }, Advanced = AdvancedEditing }; diff --git a/Sunfish/Sunfish/Sunfish.cs b/Sunfish/Sunfish/Sunfish.cs index 4f640e5..e15b919 100644 --- a/Sunfish/Sunfish/Sunfish.cs +++ b/Sunfish/Sunfish/Sunfish.cs @@ -120,8 +120,19 @@ return s; } + public static SunfishService GetServiceForPath(string path) + { + SunfishService candidate = null; + foreach (SunfishService s in srvs) + if (path.StartsWith(s.Configuration.Location) && + (candidate == null || (candidate.Configuration.Location.Length < s.Configuration.Location.Length))) + candidate = s; + return candidate; + } + public static bool Active { get => conf.Active; set => SetActive(value); } public static int Port { get => conf.Port; set => SetPort(value); } + public static bool RootMenu { get => conf.SunfishRoot; set => conf.SunfishRoot = value; } public static SunfishService[] Services => srvs.ToArray(); } } diff --git a/Sunfish/Sunfish/Sunfish.csproj b/Sunfish/Sunfish/Sunfish.csproj index edef0dd..4a046e1 100644 --- a/Sunfish/Sunfish/Sunfish.csproj +++ b/Sunfish/Sunfish/Sunfish.csproj @@ -62,6 +62,9 @@ + + app.manifest + diff --git a/Sunfish/Sunfish/SunfishServerProcessor.cs b/Sunfish/Sunfish/SunfishServerProcessor.cs index c39a7f3..7719e1e 100644 --- a/Sunfish/Sunfish/SunfishServerProcessor.cs +++ b/Sunfish/Sunfish/SunfishServerProcessor.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Text; using System.Threading.Tasks; @@ -11,7 +12,22 @@ { protected override void Process() { - Error404(); + SunfishService s = Sunfish.GetServiceForPath(Request.Url.LocalPath); + Response.Headers[HttpResponseHeader.ContentType] = "text/plain"; + Out.WriteLine("Sunfish here"); + return; + if (s == null) + if (Sunfish.RootMenu) + { + Error404(); + return; + } + else + { + Error404(); + return; + } + //WebCall c = new WebCall(Request, Response, User, Post, GET); } } }