using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Xml;
using System.Runtime.Serialization.Formatters.Binary;
using MiniHttpd;
using MiniHttpd.Aspx;
using System.IO;
namespace MiniHttpdApp
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class MiniHttpdAppForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Splitter splitter1;
private System.Windows.Forms.Splitter splitter2;
private System.Windows.Forms.PropertyGrid propertyGrid;
private System.Windows.Forms.MainMenu mainMenu;
private System.Windows.Forms.RichTextBox outputBox;
private System.Windows.Forms.TreeView fileTreeView;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuExit;
private System.Windows.Forms.MenuItem menuStartServer;
private System.Windows.Forms.MenuItem menuStopServer;
private System.Windows.Forms.NotifyIcon notifyIcon;
private System.Windows.Forms.ContextMenu treeContextMenu;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.OpenFileDialog addFileDialog;
private System.Windows.Forms.FolderBrowserDialog folderAddDialog;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.MenuItem menuTransferMonitor;
private System.Windows.Forms.ContextMenu notifyIconMenu;
private System.Windows.Forms.MenuItem menuNotifyIconExit;
private System.Windows.Forms.MenuItem menuItem5;
private System.Windows.Forms.MenuItem menuAbout;
private System.Windows.Forms.MenuItem menuNotifyIconOpen;
private System.Windows.Forms.MenuItem menuItem7;
private System.Windows.Forms.MenuItem menuNotifyIconStartServer;
private System.Windows.Forms.MenuItem menuNotifyIconStopServer;
private System.Windows.Forms.ToolTip fileTreeViewTooltip;
private System.Windows.Forms.MenuItem menuClearLog;
private System.Windows.Forms.MenuItem menuItem6;
private System.Windows.Forms.MenuItem menuItem8;
private System.Windows.Forms.MenuItem menuEditUsers;
private System.ComponentModel.IContainer components;
public MiniHttpdAppForm()
{
//
// Required for Windows Form Designer support
//
Application.EnableVisualStyles();
InitializeComponent();
InitMenuItems();
notifyIcon.Icon = this.Icon;
server = new AspxWebServer();
server.Started += new EventHandler(server_StateChanged);
server.Stopped += new EventHandler(server_StateChanged);
ConsoleWriter writer = new ConsoleWriter();
writer.OnWrite += new MiniHttpdApp.ConsoleWriter.WriteEventHandler(writer_OnWrite);
server.Log = writer;
server_StateChanged(this, null);
rootPath = Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
settings = new Settings(this);
propertyGrid.SelectedObject = settings;
settings.IndexPageStyle = IndexPageStyle.Advanced;
settings.RootType = DirectoryType.Virtual;
transferMonitor = new TransferMonitorForm(server);
LoadSettings();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region File Tree Menus
MenuItem treeMenuRemove;
MenuItem treeMenuAddFile;
MenuItem treeMenuAddDirectory;
MenuItem treeMenuCreateVirtualDirectory;
MenuItem treeMenuCreateRedirect;
MenuItem treeMenuCopyUrl;
void InitMenuItems()
{
treeMenuRemove = new MenuItem("&Remove");
treeMenuAddFile = new MenuItem("Add &File");
treeMenuAddDirectory = new MenuItem("Add &Directory");
treeMenuCreateVirtualDirectory = new MenuItem("Create &Virtual Directory");
treeMenuCreateRedirect = new MenuItem("Create Redirec&t");
treeMenuCopyUrl = new MenuItem("Copy &URL");
treeMenuRemove.Click += new EventHandler(treeMenuRemove_Click);
treeMenuAddFile.Click += new EventHandler(treeMenuAddFile_Click);
treeMenuAddDirectory.Click += new EventHandler(treeMenuAddDirectory_Click);
treeMenuCreateVirtualDirectory.Click += new EventHandler(treeMenuCreateVirtualDirectory_Click);
treeMenuCreateRedirect.Click += new EventHandler(treeMenuCreateRedirect_Click);
treeMenuCopyUrl.Click += new EventHandler(treeMenuCopyUrl_Click);
}
private void treeContextMenu_Popup(object sender, System.EventArgs e)
{
if(fileTreeView.SelectedNode == null)
return;
treeContextMenu.MenuItems.Clear();
int category = 0;
if(GetTreeMenuCopyUrl() != null)
{
treeContextMenu.MenuItems.Add(treeMenuCopyUrl);
category = -1;
}
if(GetTreeMenuAddFileNode() != null)
{
if(category != 0)
{
category = 0;
treeContextMenu.MenuItems.Add(new MenuItem("-"));
}
treeContextMenu.MenuItems.Add(treeMenuAddFile);
}
if(GetTreeMenuAddDirectoryNode() != null)
treeContextMenu.MenuItems.Add(treeMenuAddDirectory);
if(GetTreeMenuCreateVirtualDirectoryNode() != null)
{
if(category != 1)
{
category = 1;
treeContextMenu.MenuItems.Add(new MenuItem("-"));
}
treeContextMenu.MenuItems.Add(treeMenuCreateVirtualDirectory);
}
if(GetTreeMenuCreateRedirect() != null)
{
if(category != 1)
{
category = 1;
treeContextMenu.MenuItems.Add(new MenuItem("-"));
}
treeContextMenu.MenuItems.Add(treeMenuCreateRedirect);
}
if(GetTreeMenuRemoveNode() != null)
{
if(category != 2)
{
category = 2;
treeContextMenu.MenuItems.Add(new MenuItem("-"));
}
treeContextMenu.MenuItems.Add(treeMenuRemove);
}
}
TreeNode GetTreeMenuCopyUrl()
{
if(fileTreeView.SelectedNode != null
&& fileTreeView.SelectedNode.Tag != null
&& fileTreeView.SelectedNode.Tag is IResource)
return fileTreeView.SelectedNode;
else
return null;
}
TreeNode GetTreeMenuRemoveNode()
{
TreeNode node = fileTreeView.SelectedNode;
if(node == null)
return null;
if(node.Tag == null)
return null;
if(node.Parent == null || !(node.Parent.Tag is VirtualDirectory))
return null;
return node;
}
TreeNode GetTreeMenuAddFileNode()
{
TreeNode node = fileTreeView.SelectedNode;
if(node == null)
return null;
if(node.Tag != null && node.Tag is DriveDirectory)
return null;
if(node.Tag == null || !(node.Tag is VirtualDirectory))
{
if(node.Parent != null && node.Parent.Tag != null && node.Parent.Tag is VirtualDirectory)
node = node.Parent;
else
return null;
}
return node;
}
TreeNode GetTreeMenuAddDirectoryNode()
{
return GetTreeMenuAddFileNode();
}
TreeNode GetTreeMenuCreateVirtualDirectoryNode()
{
TreeNode node = fileTreeView.SelectedNode;
if(node == null)
return null;
if(node.Tag != null && node.Tag is DriveDirectory)
return null;
if(node.Tag is VirtualDirectory)
return node;
if(node.Parent != null
&& node.Parent.Tag != null
&& node.Parent.Tag is VirtualDirectory)
return node.Parent;
return null;
}
TreeNode GetTreeMenuCreateRedirect()
{
return GetTreeMenuCreateVirtualDirectoryNode();
}
private void treeMenuRemove_Click(object sender, EventArgs e)
{
TreeNode node = GetTreeMenuRemoveNode();
if(node == null)
return;
(node.Parent.Tag as VirtualDirectory).Remove((node.Tag as IResource).Name);
RefreshParentOfNode(node);
}
void AddFile(TreeNode node, ICollection files)
{
IFile lastFile;
try
{
foreach(string path in addFileDialog.FileNames)
{
try
{
lastFile = (node.Tag as VirtualDirectory).AddFile(path);
}
catch(DirectoryException ex)
{
server.Log.WriteLine("Add File: " + ex.Message);
return;
}
}
}
finally
{
RefreshNode(node, null);
}
}
private void treeMenuAddFile_Click(object sender, EventArgs e)
{
TreeNode node = GetTreeMenuAddFileNode();
if(node == null)
return;
if(addFileDialog.ShowDialog(this) != DialogResult.OK)
return;
if(addFileDialog.FileNames.Length == 0)
return;
AddFile(node, addFileDialog.FileNames);
}
private void treeMenuAddDirectory_Click(object sender, EventArgs e)
{
TreeNode node = GetTreeMenuAddDirectoryNode();
if(node == null)
return;
if(folderAddDialog.ShowDialog(this) != DialogResult.OK)
return;
IDirectory dir;
try
{
dir = (node.Tag as VirtualDirectory).AddDirectory(folderAddDialog.SelectedPath);
}
catch(Exception ex)
{
server.Log.WriteLine("Add Directory: " + ex.Message);
return;
}
RefreshNode(node, dir.Name);
}
private void treeMenuCreateVirtualDirectory_Click(object sender, EventArgs e)
{
TreeNode node = GetTreeMenuCreateVirtualDirectoryNode();
if(node == null)
return;
TextBoxForm form = new TextBoxForm();
form.Text = "Create Virtual Directory";
form.Caption = "Enter the name of the new directory to create:";
if(form.ShowDialog(this) != DialogResult.OK)
return;
try
{
(node.Tag as VirtualDirectory).AddDirectory(new VirtualDirectory(form.TextBox.Text, node.Tag as VirtualDirectory));
}
catch(Exception ex)
{
server.Log.WriteLine("Create Virtual Directory: " + ex.Message);
return;
}
RefreshNode(node, form.TextBox.Text);
}
private void treeMenuCreateRedirect_Click(object sender, EventArgs e)
{
TreeNode node = GetTreeMenuCreateRedirect();
if(node == null)
return;
NewRedirectForm form = new NewRedirectForm();
if(form.ShowDialog(this) != DialogResult.OK)
return;
try
{
(node.Tag as VirtualDirectory).AddFile(new RedirectFile(form.RedirectName, form.RedirectTarget, node.Tag as VirtualDirectory));
}
catch(Exception ex)
{
server.Log.WriteLine("Create Redirect: " + ex.Message);
return;
}
RefreshNode(node, form.RedirectName);
}
private void treeMenuCopyUrl_Click(object sender, EventArgs e)
{
if(fileTreeView.SelectedNode != null
&& fileTreeView.SelectedNode.Tag != null
&& fileTreeView.SelectedNode.Tag is IResource)
Clipboard.SetDataObject(server.GetUrl(fileTreeView.SelectedNode.Tag as IResource).ToString().Replace(" ", "%20"));
}
void RefreshNode(TreeNode node, string selectNodeName)
{
if(node.Nodes.Count == 0)
{
RefreshParentOfNode(fileTreeView.SelectedNode);
if(selectNodeName != null)
{
fileTreeView.SelectedNode = FindNodeWithText(fileTreeView.SelectedNode, selectNodeName);
if(fileTreeView.SelectedNode.Nodes.Count != 0)
fileTreeView.SelectedNode.Expand();
}
}
else
{
node.Collapse();
node.Expand();
if(selectNodeName != null)
{
fileTreeView.SelectedNode = FindNodeWithText(node, selectNodeName);
if(fileTreeView.SelectedNode.Nodes.Count != 0)
fileTreeView.SelectedNode.Expand();
}
}
}
TreeNode FindNodeWithText(TreeNode node, string text)
{
if(node == null)
return null;
for(int i = 0; i < node.Nodes.Count; i++)
if(string.Equals(node.Nodes[i].Text, text))
return node.Nodes[i];
return null;
}
void RefreshParentOfNode(TreeNode node)
{
int index = node.Index;
TreeNode parentNode = node.Parent;
parentNode.Collapse();
parentNode.Expand();
if(index < parentNode.Nodes.Count)
fileTreeView.SelectedNode = parentNode.Nodes[index];
else
fileTreeView.SelectedNode = parentNode.Nodes[parentNode.Nodes.Count-1];
}
#endregion
void OnRootNodeChanged()
{
fileTreeView.Nodes.Clear();
TreeNode root = new TreeNode("Root");
root.Tag = server.Root;
root.Nodes.Add(new TreeNode());
root.Expand();
fileTreeView.Nodes.Add(root);
}
#region Settings
class Settings
{
class FolderSelector : System.Drawing.Design.UITypeEditor
{
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
Settings settings = context.Instance as Settings;
settings.form.folderAddDialog.SelectedPath = value as string;
if(settings.form.folderAddDialog.ShowDialog(settings.form) != DialogResult.OK)
return value;
return settings.form.folderAddDialog.SelectedPath;
}
public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return System.Drawing.Design.UITypeEditorEditStyle.Modal;
}
}
MiniHttpdAppForm form;
public Settings(MiniHttpdAppForm form)
{
this.form = form;
}
[Category("Directories")]
[Description("The root folder to serve when RootType is set to Drive.")]
[Editor(typeof(FolderSelector), typeof(System.Drawing.Design.UITypeEditor))]
public string RootFolder
{
get
{
return form.rootPath;
}
set
{
form.server.Root = new AspxAppDirectory(value);
form.OnRootNodeChanged();
RootType = DirectoryType.Drive;
if(value == null)
return;
form.rootPath = value;
form.propertyGrid.Refresh();
}
}
[Category("Directories"), Description("The type of the root folder, either a root folder or a drive on disk.")]
public DirectoryType RootType
{
get
{
return form.rootType;
}
set
{
form.rootType = value;
if(value == DirectoryType.Drive)
{
if(form.server.Root is VirtualDirectory)
{
BinaryFormatter formatter = new BinaryFormatter();
if(form.serializedVirtualRoot != null)
form.serializedVirtualRoot.Close();
form.serializedVirtualRoot = new MemoryStream();
formatter.Serialize(form.serializedVirtualRoot, form.server.Root);
}
form.server.Root = new AspxAppDirectory(form.rootPath);
form.OnRootNodeChanged();
}
else
{
if(form.serializedVirtualRoot != null)
{
BinaryFormatter formatter = new BinaryFormatter();
form.serializedVirtualRoot.Seek(0, SeekOrigin.Begin);
form.server.Root = formatter.Deserialize(form.serializedVirtualRoot) as VirtualDirectory;
}
else
form.server.Root = new VirtualDirectory();
}
form.OnRootNodeChanged();
}
}
[Category("Directories"), Description("The style of the index page.")]
public IndexPageStyle IndexPageStyle
{
get
{
if(form.server.IndexPage is IndexPageEx)
return IndexPageStyle.Advanced;
return IndexPageStyle.Basic;
}
set
{
if(value == IndexPageStyle.Basic)
form.server.IndexPage = new IndexPage();
else
form.server.IndexPage = new IndexPageEx();
}
}
[Category("Connection"), Description("The server's host address to be used when copying URLs.")]
public string HostName
{
get
{
return form.server.HostName;
}
set
{
form.server.HostName = value;
}
}
[Category("Connection"), Description("The port on which the server is to run; default is 80.")]
public int Port
{
get
{
return form.server.Port;
}
set
{
form.server.Port = value;
}
}
[Category("Connection"), Description("Start serving when the application is started.")]
public bool AutoStart
{
get
{
return form.autoStart;
}
set
{
form.autoStart = value;
}
}
[Category("Logging"), Description("Make note in the log when a client connects to the server.")]
public bool LogConnections
{
get
{
return form.server.LogConnections;
}
set
{
form.server.LogConnections = value;
}
}
[Category("Logging"), Description("Make note in the log when a client requests a resource.")]
public bool LogRequests
{
get
{
return form.server.LogRequests;
}
set
{
form.server.LogRequests = value;
}
}
[Category("Logging"), Description("Write the log output to MiniHttpd.log.")]
public bool LogToFile
{
get
{
return form.logToFile;
}
set
{
form.logToFile = value;
}
}
[Category("Security"), Description("Ask for authentication when a client connects to the server.")]
public bool AuthenticateClients
{
get
{
return form.server.RequireAuthentication;
}
set
{
form.server.RequireAuthentication = value;
}
}
}
#endregion
Settings settings;
HttpWebServer server;
bool autoStart;
bool logToFile;
DirectoryType rootType;
string rootPath;
//VirtualDirectory virtualRoot;
MemoryStream serializedVirtualRoot;
StreamWriter logWriter;
public bool isFirstUse;
enum DirectoryType
{
Drive,
Virtual
}
enum IndexPageStyle
{
Basic,
Advanced
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.propertyGrid = new System.Windows.Forms.PropertyGrid();
this.mainMenu = new System.Windows.Forms.MainMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuExit = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.menuStartServer = new System.Windows.Forms.MenuItem();
this.menuStopServer = new System.Windows.Forms.MenuItem();
this.menuItem4 = new System.Windows.Forms.MenuItem();
this.menuTransferMonitor = new System.Windows.Forms.MenuItem();
this.menuItem6 = new System.Windows.Forms.MenuItem();
this.menuClearLog = new System.Windows.Forms.MenuItem();
this.menuItem5 = new System.Windows.Forms.MenuItem();
this.menuAbout = new System.Windows.Forms.MenuItem();
this.splitter1 = new System.Windows.Forms.Splitter();
this.outputBox = new System.Windows.Forms.RichTextBox();
this.splitter2 = new System.Windows.Forms.Splitter();
this.fileTreeView = new System.Windows.Forms.TreeView();
this.treeContextMenu = new System.Windows.Forms.ContextMenu();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.notifyIconMenu = new System.Windows.Forms.ContextMenu();
this.menuNotifyIconStartServer = new System.Windows.Forms.MenuItem();
this.menuNotifyIconStopServer = new System.Windows.Forms.MenuItem();
this.menuItem7 = new System.Windows.Forms.MenuItem();
this.menuNotifyIconOpen = new System.Windows.Forms.MenuItem();
this.menuNotifyIconExit = new System.Windows.Forms.MenuItem();
this.addFileDialog = new System.Windows.Forms.OpenFileDialog();
this.folderAddDialog = new System.Windows.Forms.FolderBrowserDialog();
this.fileTreeViewTooltip = new System.Windows.Forms.ToolTip(this.components);
this.menuItem8 = new System.Windows.Forms.MenuItem();
this.menuEditUsers = new System.Windows.Forms.MenuItem();
this.SuspendLayout();
//
// propertyGrid
//
this.propertyGrid.CommandsVisibleIfAvailable = true;
this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Left;
this.propertyGrid.LargeButtons = false;
this.propertyGrid.LineColor = System.Drawing.SystemColors.ScrollBar;
this.propertyGrid.Location = new System.Drawing.Point(0, 0);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.Size = new System.Drawing.Size(136, 387);
this.propertyGrid.TabIndex = 0;
this.propertyGrid.Text = "propertyGrid1";
this.propertyGrid.ViewBackColor = System.Drawing.SystemColors.Window;
this.propertyGrid.ViewForeColor = System.Drawing.SystemColors.WindowText;
//
// mainMenu
//
this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1,
this.menuItem2,
this.menuItem4,
this.menuItem5});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuExit});
this.menuItem1.Text = "&File";
//
// menuExit
//
this.menuExit.Index = 0;
this.menuExit.Text = "E&xit";
this.menuExit.Click += new System.EventHandler(this.menuExit_Click);
//
// menuItem2
//
this.menuItem2.Index = 1;
this.menuItem2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuStartServer,
this.menuStopServer,
this.menuItem8,
this.menuEditUsers});
this.menuItem2.Text = "&Server";
//
// menuStartServer
//
this.menuStartServer.Index = 0;
this.menuStartServer.Text = "&Start Server";
this.menuStartServer.Click += new System.EventHandler(this.menuStartServer_Click);
//
// menuStopServer
//
this.menuStopServer.Index = 1;
this.menuStopServer.Text = "S&top Server";
this.menuStopServer.Click += new System.EventHandler(this.menuStopServer_Click);
//
// menuItem4
//
this.menuItem4.Index = 2;
this.menuItem4.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuTransferMonitor,
this.menuItem6,
this.menuClearLog});
this.menuItem4.Text = "&View";
//
// menuTransferMonitor
//
this.menuTransferMonitor.Index = 0;
this.menuTransferMonitor.Text = "Transfer &Monitor";
this.menuTransferMonitor.Click += new System.EventHandler(this.menuTransferMonitor_Click);
//
// menuItem6
//
this.menuItem6.Index = 1;
this.menuItem6.Text = "-";
//
// menuClearLog
//
this.menuClearLog.Index = 2;
this.menuClearLog.Text = "Clear &Log";
this.menuClearLog.Click += new System.EventHandler(this.menuClearLog_Click);
//
// menuItem5
//
this.menuItem5.Index = 3;
this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuAbout});
this.menuItem5.Text = "&Help";
//
// menuAbout
//
this.menuAbout.Index = 0;
this.menuAbout.Text = "&About";
this.menuAbout.Click += new System.EventHandler(this.menuAbout_Click);
//
// splitter1
//
this.splitter1.Location = new System.Drawing.Point(136, 0);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(3, 387);
this.splitter1.TabIndex = 2;
this.splitter1.TabStop = false;
//
// outputBox
//
this.outputBox.Dock = System.Windows.Forms.DockStyle.Bottom;
this.outputBox.Location = new System.Drawing.Point(139, 291);
this.outputBox.Name = "outputBox";
this.outputBox.Size = new System.Drawing.Size(453, 96);
this.outputBox.TabIndex = 5;
this.outputBox.Text = "";
this.outputBox.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.outputBox_LinkClicked);
//
// splitter2
//
this.splitter2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.splitter2.Location = new System.Drawing.Point(139, 288);
this.splitter2.Name = "splitter2";
this.splitter2.Size = new System.Drawing.Size(453, 3);
this.splitter2.TabIndex = 6;
this.splitter2.TabStop = false;
//
// fileTreeView
//
this.fileTreeView.AllowDrop = true;
this.fileTreeView.ContextMenu = this.treeContextMenu;
this.fileTreeView.Dock = System.Windows.Forms.DockStyle.Fill;
this.fileTreeView.FullRowSelect = true;
this.fileTreeView.ImageIndex = -1;
this.fileTreeView.Location = new System.Drawing.Point(139, 0);
this.fileTreeView.Name = "fileTreeView";
this.fileTreeView.PathSeparator = "/";
this.fileTreeView.SelectedImageIndex = -1;
this.fileTreeView.Size = new System.Drawing.Size(453, 288);
this.fileTreeView.Sorted = true;
this.fileTreeView.TabIndex = 7;
this.fileTreeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.fileTreeView_KeyDown);
this.fileTreeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.fileTreeView_MouseDown);
this.fileTreeView.DragOver += new System.Windows.Forms.DragEventHandler(this.fileTreeView_DragOver);
this.fileTreeView.DoubleClick += new System.EventHandler(this.fileTreeView_DoubleClick);
this.fileTreeView.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.fileTreeView_BeforeExpand);
this.fileTreeView.MouseMove += new System.Windows.Forms.MouseEventHandler(this.fileTreeView_MouseMove);
this.fileTreeView.DragLeave += new System.EventHandler(this.fileTreeView_DragLeave);
this.fileTreeView.DragDrop += new System.Windows.Forms.DragEventHandler(this.fileTreeView_DragDrop);
//
// treeContextMenu
//
this.treeContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem3});
this.treeContextMenu.Popup += new System.EventHandler(this.treeContextMenu_Popup);
//
// menuItem3
//
this.menuItem3.Index = 0;
this.menuItem3.Text = "Test";
//
// notifyIcon
//
this.notifyIcon.ContextMenu = this.notifyIconMenu;
this.notifyIcon.Text = "MiniHttpd";
this.notifyIcon.Visible = true;
this.notifyIcon.DoubleClick += new System.EventHandler(this.notifyIcon_DoubleClick);
//
// notifyIconMenu
//
this.notifyIconMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuNotifyIconStartServer,
this.menuNotifyIconStopServer,
this.menuItem7,
this.menuNotifyIconOpen,
this.menuNotifyIconExit});
//
// menuNotifyIconStartServer
//
this.menuNotifyIconStartServer.Index = 0;
this.menuNotifyIconStartServer.Text = "&Start Server";
this.menuNotifyIconStartServer.Click += new System.EventHandler(this.menuStartServer_Click);
//
// menuNotifyIconStopServer
//
this.menuNotifyIconStopServer.Index = 1;
this.menuNotifyIconStopServer.Text = "Sto&p Server";
//
// menuItem7
//
this.menuItem7.Index = 2;
this.menuItem7.Text = "-";
//
// menuNotifyIconOpen
//
this.menuNotifyIconOpen.DefaultItem = true;
this.menuNotifyIconOpen.Index = 3;
this.menuNotifyIconOpen.Text = "&Open MiniHttpd";
this.menuNotifyIconOpen.Click += new System.EventHandler(this.menuNotifyIconOpen_Click);
//
// menuNotifyIconExit
//
this.menuNotifyIconExit.Index = 4;
this.menuNotifyIconExit.Text = "E&xit";
this.menuNotifyIconExit.Click += new System.EventHandler(this.menuNotifyIconExit_Click);
//
// addFileDialog
//
this.addFileDialog.Filter = "All Files|*.*";
this.addFileDialog.Multiselect = true;
this.addFileDialog.RestoreDirectory = true;
//
// folderAddDialog
//
this.folderAddDialog.Description = "Add Folder";
//
// fileTreeViewTooltip
//
this.fileTreeViewTooltip.AutomaticDelay = 0;
this.fileTreeViewTooltip.AutoPopDelay = 5000;
this.fileTreeViewTooltip.InitialDelay = 0;
this.fileTreeViewTooltip.ReshowDelay = 0;
//
// menuItem8
//
this.menuItem8.Index = 2;
this.menuItem8.Text = "-";
//
// menuEditUsers
//
this.menuEditUsers.Index = 3;
this.menuEditUsers.Text = "Edit &Users";
this.menuEditUsers.Click += new System.EventHandler(this.menuEditUsers_Click);
//
// MiniHttpdAppForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(592, 387);
this.Controls.Add(this.fileTreeView);
this.Controls.Add(this.splitter2);
this.Controls.Add(this.outputBox);
this.Controls.Add(this.splitter1);
this.Controls.Add(this.propertyGrid);
this.Menu = this.mainMenu;
this.Name = "MiniHttpdAppForm";
this.Text = "MiniHttpd";
this.Resize += new System.EventHandler(this.MiniHttpdAppForm_Resize);
this.Closing += new System.ComponentModel.CancelEventHandler(this.MiniHttpdAppForm_Closing);
this.Load += new System.EventHandler(this.MiniHttpdAppForm_Load);
this.Deactivate += new System.EventHandler(this.MiniHttpdAppForm_Deactivate);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new MiniHttpdAppForm());
}
private void MiniHttpdAppForm_Load(object sender, System.EventArgs e)
{
if(settings.AutoStart)
server.Start();
MiniHttpdAppForm_Resize(this, null);
if(fileTreeView.TopNode != null &&
fileTreeView.TopNode.FirstNode != null &&
fileTreeView.TopNode.FirstNode.Tag == null &&
(server.Root == null ||
server.Root is VirtualDirectory))
server.Log.WriteLine("Drag and drop files and folders onto the tree to serve them.");
if(!server.IsRunning)
server.Log.WriteLine("Click Server -> Start to start the server.");
}
void LoadSettings()
{
if(InvokeRequired)
{
Invoke(new MethodInvoker(LoadSettings));
return;
}
XmlDocument doc;
XmlElement docElement;
try
{
doc = new XmlDocument();
doc.Load("MiniHttpdSettings.xml");
docElement = doc.DocumentElement;
}
catch
{
isFirstUse = true;
return;
}
try
{
settings.RootFolder = docElement["RootFolder"].InnerText;
}
catch { }
try
{
settings.RootType = (DirectoryType)Enum.Parse(typeof(DirectoryType), docElement["RootType"].InnerText);
}
catch { }
try
{
serializedVirtualRoot = new MemoryStream(Convert.FromBase64String(docElement["VirtualDir"].InnerText));
if(settings.RootType == DirectoryType.Virtual)
{
BinaryFormatter formatter = new BinaryFormatter();
serializedVirtualRoot.Seek(0, SeekOrigin.Begin);
server.Root = formatter.Deserialize(serializedVirtualRoot) as VirtualDirectory;
}
}
catch { }
OnRootNodeChanged();
try
{
settings.Port = int.Parse(docElement["Port"].InnerText);
}
catch { }
try
{
settings.AutoStart = bool.Parse(docElement["AutoStart"].InnerText);
}
catch { }
try
{
settings.LogConnections = bool.Parse(docElement["LogConnections"].InnerText);
}
catch { }
try
{
settings.LogRequests = bool.Parse(docElement["LogRequests"].InnerText);
}
catch { }
try
{
settings.LogToFile = bool.Parse(docElement["LogToFile"].InnerText);
}
catch { }
try
{
settings.HostName = docElement["HostName"].InnerText;
}
catch { }
try
{
settings.IndexPageStyle = (IndexPageStyle)Enum.Parse(typeof(IndexPageStyle), docElement["IndexPageStyle"].InnerText);
}
catch { }
try
{
this.WindowState = (FormWindowState)Enum.Parse(typeof(FormWindowState), docElement["WindowState"].InnerText);
}
catch { }
try
{
settings.AuthenticateClients = bool.Parse(docElement["EnableAuthentication"].InnerText);
}
catch { }
try
{
foreach(XmlElement user in docElement["Users"].ChildNodes)
(server.Authenticator as BasicAuthenticator).AddUserByHash(user["Name"].InnerText, user["Password"].InnerText);
}
//catch { }
finally
{
}
}
void SaveSettings()
{
if(InvokeRequired)
{
Invoke(new MethodInvoker(SaveSettings));
return;
}
try
{
XmlDocument doc = new XmlDocument();
doc.AppendChild(doc.CreateElement("MiniHttpdSettings"));
XmlElement element;
XmlElement docElement = doc.DocumentElement;
element = doc.CreateElement("VirtualDir");
docElement.AppendChild(element);
if(server.Root is VirtualDirectory)
{
serializedVirtualRoot = new System.IO.MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(serializedVirtualRoot, server.Root);
element.InnerText = Convert.ToBase64String(serializedVirtualRoot.ToArray());
}
else
element.InnerText = Convert.ToBase64String(serializedVirtualRoot.ToArray());
element = doc.CreateElement("RootFolder");
docElement.AppendChild(element);
element.InnerText = rootPath;
element = doc.CreateElement("RootType");
docElement.AppendChild(element);
element.InnerText = settings.RootType.ToString();
element = doc.CreateElement("Port");
docElement.AppendChild(element);
element.InnerText = settings.Port.ToString();
element = doc.CreateElement("AutoStart");
docElement.AppendChild(element);
element.InnerText = settings.AutoStart.ToString();
element = doc.CreateElement("LogConnections");
docElement.AppendChild(element);
element.InnerText = settings.LogConnections.ToString();
element = doc.CreateElement("LogRequests");
docElement.AppendChild(element);
element.InnerText = settings.LogRequests.ToString();
element = doc.CreateElement("LogToFile");
docElement.AppendChild(element);
element.InnerText = settings.LogToFile.ToString();
element = doc.CreateElement("HostName");
docElement.AppendChild(element);
element.InnerText = settings.HostName;
element = doc.CreateElement("IndexPageStyle");
docElement.AppendChild(element);
element.InnerText = settings.IndexPageStyle.ToString();
element = doc.CreateElement("WindowState");
docElement.AppendChild(element);
element.InnerText = this.WindowState.ToString();
element = doc.CreateElement("EnableAuthentication");
docElement.AppendChild(element);
element.InnerText = settings.AuthenticateClients.ToString();
element = doc.CreateElement("Users");
docElement.AppendChild(element);
foreach(string username in (server.Authenticator as BasicAuthenticator).Users)
{
XmlElement user = doc.CreateElement("User");
XmlElement nameElement = doc.CreateElement("Name");
XmlElement passwordElement = doc.CreateElement("Password");
nameElement.InnerText = username;
passwordElement.InnerText = (server.Authenticator as BasicAuthenticator).GetPasswordHash(username);
user.AppendChild(nameElement);
user.AppendChild(passwordElement);
element.AppendChild(user);
}
doc.Save("MiniHttpdSettings.xml");
}
#if !DEBUG
catch(Exception e)
{
server.Log.WriteLine("Error saving settings:");
server.Log.WriteLine(e);
}
#endif
finally
{
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
static internal extern IntPtr SendMessage(IntPtr hwnd, Int32 msg, Int32 wParam, Int32 lParam);
bool newLine;
delegate void OnWriteDelegate(char[] buffer, int index, int count);
private void writer_OnWrite(char[] buffer, int index, int count)
{
if(InvokeRequired)
{
Invoke(new OnWriteDelegate(writer_OnWrite), new object[] {buffer, index, count});
return;
}
if(outputBox.IsDisposed)
return;
if(settings.LogToFile)
{
if(logWriter == null)
{
try
{
FileStream stream = new FileStream("minihttpd.log", FileMode.Append, FileAccess.Write, FileShare.Read, 128);
logWriter = new StreamWriter(stream);
logWriter.AutoFlush = true;
logWriter.WriteLine("-------------------------------------------------------");
logWriter.WriteLine("* Beginning log at " + DateTime.Now);
logWriter.WriteLine("-------------------------------------------------------");
}
catch { }
}
logWriter.Write(buffer, index, count);
}
string text = new string(buffer, index, count);
if(text.Length == 0)
return;
bool oldNewLine = newLine;
newLine = false;
if(text.EndsWith("\r\n"))
{
text = text.Substring(0, text.Length-2);
newLine = true;
}
else if(text.EndsWith("\n"))
{
text = text.Substring(0, text.Length-1);
newLine = true;
}
outputBox.AppendText((oldNewLine ? "\r\n" : "") + text);
// Scroll to bottom
SendMessage(this.outputBox.Handle, 0x0115, 7, 0);
}
private void server_StateChanged(object sender, EventArgs e)
{
if(InvokeRequired)
{
Invoke(new EventHandler(server_StateChanged), new object[] {sender, e});
return;
}
menuStartServer.Enabled = menuNotifyIconStartServer.Enabled = !server.IsRunning;
menuStopServer.Enabled = menuNotifyIconStopServer.Enabled = server.IsRunning;
if(server.IsRunning)
notifyIcon.Text = "MiniHttpd - running on port " + server.Port;
else
notifyIcon.Text = "MiniHttpd";
}
private void MiniHttpdAppForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if(server != null)
server.Stop();
SaveSettings();
}
private void menuExit_Click(object sender, System.EventArgs e)
{
this.Close();
}
private void menuStartServer_Click(object sender, System.EventArgs e)
{
server.Start();
}
private void menuStopServer_Click(object sender, System.EventArgs e)
{
server.Stop();
}
private void fileTreeView_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
{
e.Node.Nodes.Clear();
IDirectory dir = e.Node.Tag as IDirectory;
if(dir == null)
return;
TreeNode[] nodes;
ICollection subItems;
try
{
subItems = dir.GetDirectories();
}
catch(IOException ex)
{
server.Log.WriteLine(ex.Message);
return;
}
nodes = new TreeNode[subItems.Count];
int i = 0;
foreach(IDirectory subDir in subItems)
{
TreeNode node = new TreeNode(subDir.Name);
node.Nodes.Add(new TreeNode());
node.Tag = subDir;
nodes[i++] = node;
}
e.Node.Nodes.AddRange(nodes);
subItems = dir.GetFiles();
nodes = new TreeNode[subItems.Count];
i = 0;
foreach(IFile file in subItems)
{
TreeNode node = new TreeNode(file.Name);
node.Tag = file;
nodes[i++] = node;
}
e.Node.Nodes.AddRange(nodes);
if(e.Node.Nodes.Count == 0)
{
TreeNode empty = new TreeNode("Empty");
empty.ForeColor = System.Drawing.SystemColors.GrayText;
e.Node.Nodes.Add(empty);
}
}
private void outputBox_LinkClicked(object sender, System.Windows.Forms.LinkClickedEventArgs e)
{
try
{
System.Diagnostics.Process.Start(e.LinkText);
}
catch(Win32Exception)
{
}
}
private void MiniHttpdAppForm_Resize(object sender, System.EventArgs e)
{
if(this.WindowState == FormWindowState.Minimized)
{
transferMonitor.Hide();
this.Hide();
notifyIcon.Visible = true;
}
}
private void notifyIcon_DoubleClick(object sender, System.EventArgs e)
{
this.Show();
if(this.WindowState == FormWindowState.Minimized)
this.WindowState = FormWindowState.Normal;
this.Activate();
notifyIcon.Visible = false;
}
private void fileTreeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
TreeNode node = fileTreeView.GetNodeAt(e.X, e.Y);
fileTreeView.SelectedNode = node;
}
private void fileTreeView_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
switch(e.KeyCode)
{
case Keys.Enter:
fileTreeView_DoubleClick(this, null);
break;
case Keys.Delete:
treeMenuRemove_Click(this, null);
break;
}
}
private void fileTreeView_DoubleClick(object sender, System.EventArgs e)
{
if(GetTreeMenuCopyUrl() != null)
System.Diagnostics.Process.Start(server.GetUrl(fileTreeView.SelectedNode.Tag as IResource).ToString());
}
TransferMonitorForm transferMonitor;
private void menuTransferMonitor_Click(object sender, System.EventArgs e)
{
transferMonitor.Show();
}
private void menuNotifyIconExit_Click(object sender, System.EventArgs e)
{
this.Close();
}
private void menuAbout_Click(object sender, System.EventArgs e)
{
AboutForm form = new AboutForm();
form.ShowDialog(this);
}
private void fileTreeView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
fileTreeView.HideSelection = true;
TreeNode selectedNode = fileTreeView.SelectedNode;
TreeNode node = fileTreeView.GetNodeAt(fileTreeView.PointToClient(new Point(e.X, e.Y)));
if(!e.Data.GetDataPresent("FileDrop"))
{
e.Effect = DragDropEffects.None;
return;
}
fileTreeView.SelectedNode = node;
node = GetTreeMenuAddFileNode();
if(node == null)
{
e.Effect = DragDropEffects.None;
fileTreeView.SelectedNode = selectedNode;
return;
}
string[] files = e.Data.GetData("FileDrop") as string[];
VirtualDirectory dir = node.Tag as VirtualDirectory;
string lastNode = null;
foreach(string path in files)
{
try
{
if(Directory.Exists(path))
lastNode = dir.AddDirectory(path).Name;
else if(File.Exists(path))
lastNode = dir.AddFile(path).Name;
}
catch(Exception ex)
{
server.Log.WriteLine("Error: " + ex.Message);
continue;
}
}
RefreshNode(node, lastNode);
}
private void fileTreeView_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{
TreeNode selectedNode = fileTreeView.SelectedNode;
TreeNode node = fileTreeView.GetNodeAt(fileTreeView.PointToClient(new Point(e.X, e.Y)));
if(!e.Data.GetDataPresent("FileDrop"))
{
e.Effect = DragDropEffects.None;
return;
}
fileTreeView.HideSelection = false;
fileTreeView.SelectedNode = node;
node = GetTreeMenuAddFileNode();
if(node == null)
{
e.Effect = DragDropEffects.None;
fileTreeView.SelectedNode = selectedNode;
return;
}
e.Effect = DragDropEffects.Copy;
}
private void fileTreeView_DragLeave(object sender, System.EventArgs e)
{
fileTreeView.HideSelection = true;
}
private void MiniHttpdAppForm_Deactivate(object sender, System.EventArgs e)
{
SaveSettings();
}
private void menuNotifyIconOpen_Click(object sender, System.EventArgs e)
{
notifyIcon_DoubleClick(this, null);
}
private void menuClearLog_Click(object sender, System.EventArgs e)
{
outputBox.Clear();
}
TreeNode lastTooltipNode;
private void fileTreeView_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
TreeNode node = fileTreeView.GetNodeAt(fileTreeView.PointToClient(new Point(MousePosition.X, MousePosition.Y)));
if(node == null)
return;
if(lastTooltipNode == node)
return;
string text = "";
if(node.Tag != null)
if(node.Tag is IPhysicalResource)
text = "Location: " + (node.Tag as IPhysicalResource).Path;
else if(node.Tag is RedirectFile)
text = "Location: " + (node.Tag as RedirectFile).Redirect;
fileTreeViewTooltip.SetToolTip(fileTreeView, text);
lastTooltipNode = node;
}
private void menuEditUsers_Click(object sender, System.EventArgs e)
{
EditUsersForm form = new EditUsersForm(server.Authenticator as BasicAuthenticator);
form.ShowDialog(this);
settings.AuthenticateClients = form.EnableAuthentication;
propertyGrid.Refresh();
}
}
}