Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 1121 → Rev 1122

/TCPproxy/trunk/MainForm.cs
0,0 → 1,2342
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
 
// FIXME:
// - add soap validation
// - icons for all items in the tree
// - update text view, not override whole text
// - use pool of threads?
// - do not store intermediate info, just row packets and the parsed fragments to display
// - make the text fragment store switchable
namespace TCPproxy
{
public class MainForm : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button startButton;
private System.Windows.Forms.MenuItem saveXmlMenuItem;
private System.Windows.Forms.ListBox logBox;
private System.Windows.Forms.MenuItem tcpShowByTimeMenuItem;
private System.Windows.Forms.SaveFileDialog saveLogDialog;
private System.Windows.Forms.MenuItem clearMenuItem;
private System.Windows.Forms.StatusBarPanel connectionStatusBar;
private System.Windows.Forms.Label levelLabel;
private TCPproxy.ViewControl messagesBox;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.Button saveButton;
private System.Windows.Forms.MenuItem saveHttpMenuItem;
private System.Windows.Forms.TextBox resendPortBox;
private System.Windows.Forms.MenuItem selectAllmenuItem;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.MenuItem autoExpandMenuItem;
private System.Windows.Forms.MenuItem copyMenuItem;
private System.Windows.Forms.Splitter splitter2;
private System.Windows.Forms.ContextMenu viewContextMenu;
private System.Windows.Forms.TreeView messageView;
private System.Windows.Forms.Splitter splitter1;
private System.Windows.Forms.MenuItem saveTcpMenuItem;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.MenuItem closeConnectionMenuItem;
private System.Windows.Forms.Panel panel4;
private System.Windows.Forms.ImageList saveButtonImageList;
private System.Windows.Forms.StatusBar statusBar;
private System.Windows.Forms.MenuItem saveLogMenuItem;
private System.Windows.Forms.ContextMenu saveLogMenu;
private System.Windows.Forms.Button stopButton;
private System.Windows.Forms.ContextMenu messagesContextMenu;
private System.Windows.Forms.MenuItem tcpShowByDirectionMenuItem;
private System.Windows.Forms.TextBox listenPortBox;
private System.Windows.Forms.ComboBox levelBox;
private System.Windows.Forms.Button clearButton;
private System.Windows.Forms.ImageList treeImageList;
private System.Windows.Forms.MenuItem wordWrapMenuItem;
private System.Windows.Forms.TextBox resendHostBox;
#region private fields
 
private TcpListener tcpListener = null;
private LogMessages logMessages = null;
private Hashtable treeNodes = new Hashtable();
 
private TcpShowMode tcpShowMode = TcpShowMode.ByDirection;
private bool autoExpand = true;
 
#endregion private fields
 
#region web forms fields
 
 
#endregion web forms fields
 
#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.resendHostBox = new System.Windows.Forms.TextBox();
this.wordWrapMenuItem = new System.Windows.Forms.MenuItem();
this.treeImageList = new System.Windows.Forms.ImageList(this.components);
this.clearButton = new System.Windows.Forms.Button();
this.levelBox = new System.Windows.Forms.ComboBox();
this.listenPortBox = new System.Windows.Forms.TextBox();
this.tcpShowByDirectionMenuItem = new System.Windows.Forms.MenuItem();
this.messagesContextMenu = new System.Windows.Forms.ContextMenu();
this.stopButton = new System.Windows.Forms.Button();
this.saveLogMenu = new System.Windows.Forms.ContextMenu();
this.saveLogMenuItem = new System.Windows.Forms.MenuItem();
this.statusBar = new System.Windows.Forms.StatusBar();
this.saveButtonImageList = new System.Windows.Forms.ImageList(this.components);
this.panel4 = new System.Windows.Forms.Panel();
this.closeConnectionMenuItem = new System.Windows.Forms.MenuItem();
this.panel1 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
this.saveTcpMenuItem = new System.Windows.Forms.MenuItem();
this.splitter1 = new System.Windows.Forms.Splitter();
this.messageView = new System.Windows.Forms.TreeView();
this.viewContextMenu = new System.Windows.Forms.ContextMenu();
this.splitter2 = new System.Windows.Forms.Splitter();
this.copyMenuItem = new System.Windows.Forms.MenuItem();
this.autoExpandMenuItem = new System.Windows.Forms.MenuItem();
this.label1 = new System.Windows.Forms.Label();
this.selectAllmenuItem = new System.Windows.Forms.MenuItem();
this.resendPortBox = new System.Windows.Forms.TextBox();
this.saveHttpMenuItem = new System.Windows.Forms.MenuItem();
this.saveButton = new System.Windows.Forms.Button();
this.panel3 = new System.Windows.Forms.Panel();
this.messagesBox = new TCPproxy.ViewControl();
this.levelLabel = new System.Windows.Forms.Label();
this.connectionStatusBar = new System.Windows.Forms.StatusBarPanel();
this.clearMenuItem = new System.Windows.Forms.MenuItem();
this.saveLogDialog = new System.Windows.Forms.SaveFileDialog();
this.tcpShowByTimeMenuItem = new System.Windows.Forms.MenuItem();
this.logBox = new System.Windows.Forms.ListBox();
this.saveXmlMenuItem = new System.Windows.Forms.MenuItem();
this.startButton = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.panel4.SuspendLayout();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.panel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.connectionStatusBar)).BeginInit();
this.SuspendLayout();
//
// resendHostBox
//
this.resendHostBox.Location = new System.Drawing.Point(88, 48);
this.resendHostBox.Name = "resendHostBox";
this.resendHostBox.TabIndex = 3;
this.resendHostBox.Text = "";
//
// wordWrapMenuItem
//
this.wordWrapMenuItem.Index = 3;
this.wordWrapMenuItem.Text = "Word &Wrap";
this.wordWrapMenuItem.Click += new System.EventHandler(this.wordWrapMenuItem_Click);
//
// treeImageList
//
this.treeImageList.ImageSize = new System.Drawing.Size(16, 16);
this.treeImageList.TransparentColor = System.Drawing.Color.Transparent;
//
// clearButton
//
this.clearButton.Location = new System.Drawing.Point(288, 16);
this.clearButton.Name = "clearButton";
this.clearButton.TabIndex = 6;
this.clearButton.Text = "Clear";
this.clearButton.Click += new System.EventHandler(this.clearButton_Click);
//
// levelBox
//
this.levelBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.levelBox.Items.AddRange(new object[] {
"All",
"Info",
"Important"});
this.levelBox.Location = new System.Drawing.Point(472, 16);
this.levelBox.Name = "levelBox";
this.levelBox.Size = new System.Drawing.Size(121, 21);
this.levelBox.TabIndex = 8;
this.levelBox.SelectedIndexChanged += new System.EventHandler(this.levelBox_SelectedIndexChanged);
//
// listenPortBox
//
this.listenPortBox.Location = new System.Drawing.Point(88, 16);
this.listenPortBox.Name = "listenPortBox";
this.listenPortBox.TabIndex = 2;
this.listenPortBox.Text = "";
//
// tcpShowByDirectionMenuItem
//
this.tcpShowByDirectionMenuItem.Checked = true;
this.tcpShowByDirectionMenuItem.Index = 1;
this.tcpShowByDirectionMenuItem.Text = "TCP Show by &Direction";
this.tcpShowByDirectionMenuItem.Click += new System.EventHandler(this.tcpShowByDirectionMenuItem_Click);
//
// messagesContextMenu
//
this.messagesContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.selectAllmenuItem,
this.copyMenuItem,
this.clearMenuItem,
this.wordWrapMenuItem});
this.messagesContextMenu.Popup += new System.EventHandler(this.messagesContextMenu_Popup);
//
// stopButton
//
this.stopButton.Location = new System.Drawing.Point(192, 16);
this.stopButton.Name = "stopButton";
this.stopButton.TabIndex = 5;
this.stopButton.Text = "Stop";
this.stopButton.Visible = false;
this.stopButton.Click += new System.EventHandler(this.stopButton_Click);
//
// saveLogMenu
//
this.saveLogMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.saveLogMenuItem,
this.saveTcpMenuItem,
this.saveHttpMenuItem,
this.saveXmlMenuItem});
//
// saveLogMenuItem
//
this.saveLogMenuItem.Index = 0;
this.saveLogMenuItem.Text = "Save Log";
this.saveLogMenuItem.Click += new System.EventHandler(this.saveLogMenuItem_Click);
//
// statusBar
//
this.statusBar.Location = new System.Drawing.Point(0, 619);
this.statusBar.Name = "statusBar";
this.statusBar.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
this.connectionStatusBar});
this.statusBar.ShowPanels = true;
this.statusBar.Size = new System.Drawing.Size(780, 22);
this.statusBar.TabIndex = 0;
//
// saveButtonImageList
//
this.saveButtonImageList.ImageSize = new System.Drawing.Size(16, 16);
this.saveButtonImageList.TransparentColor = System.Drawing.Color.Transparent;
//
// panel4
//
this.panel4.Controls.Add(this.messagesBox);
this.panel4.Controls.Add(this.splitter2);
this.panel4.Controls.Add(this.logBox);
this.panel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel4.Location = new System.Drawing.Point(163, 0);
this.panel4.Name = "panel4";
this.panel4.Size = new System.Drawing.Size(617, 539);
this.panel4.TabIndex = 13;
//
// closeConnectionMenuItem
//
this.closeConnectionMenuItem.Index = 0;
this.closeConnectionMenuItem.Text = "&Close connection";
this.closeConnectionMenuItem.Click += new System.EventHandler(this.closeConnectionMenuItem_Click);
//
// panel1
//
this.panel1.Controls.Add(this.panel3);
this.panel1.Controls.Add(this.panel2);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(780, 619);
this.panel1.TabIndex = 1;
//
// panel2
//
this.panel2.Controls.Add(this.levelLabel);
this.panel2.Controls.Add(this.levelBox);
this.panel2.Controls.Add(this.saveButton);
this.panel2.Controls.Add(this.clearButton);
this.panel2.Controls.Add(this.stopButton);
this.panel2.Controls.Add(this.startButton);
this.panel2.Controls.Add(this.label2);
this.panel2.Controls.Add(this.label1);
this.panel2.Controls.Add(this.resendPortBox);
this.panel2.Controls.Add(this.resendHostBox);
this.panel2.Controls.Add(this.listenPortBox);
this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel2.Location = new System.Drawing.Point(0, 539);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(780, 80);
this.panel2.TabIndex = 3;
//
// saveTcpMenuItem
//
this.saveTcpMenuItem.Index = 1;
this.saveTcpMenuItem.Text = "Save TCP";
this.saveTcpMenuItem.Click += new System.EventHandler(this.saveTcpMenuItem_Click);
//
// splitter1
//
this.splitter1.Location = new System.Drawing.Point(160, 0);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(3, 539);
this.splitter1.TabIndex = 12;
this.splitter1.TabStop = false;
//
// messageView
//
this.messageView.ContextMenu = this.viewContextMenu;
this.messageView.Dock = System.Windows.Forms.DockStyle.Left;
this.messageView.HideSelection = false;
this.messageView.ImageList = this.treeImageList;
this.messageView.Location = new System.Drawing.Point(0, 0);
this.messageView.Name = "messageView";
this.messageView.Size = new System.Drawing.Size(160, 539);
this.messageView.TabIndex = 11;
this.messageView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.messageView_AfterSelect);
this.messageView.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.messageView_BeforeSelect);
//
// viewContextMenu
//
this.viewContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.closeConnectionMenuItem,
this.tcpShowByDirectionMenuItem,
this.tcpShowByTimeMenuItem,
this.autoExpandMenuItem});
this.viewContextMenu.Popup += new System.EventHandler(this.listContextMenu_Popup);
//
// splitter2
//
this.splitter2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.splitter2.Location = new System.Drawing.Point(0, 468);
this.splitter2.Name = "splitter2";
this.splitter2.Size = new System.Drawing.Size(617, 3);
this.splitter2.TabIndex = 9;
this.splitter2.TabStop = false;
//
// copyMenuItem
//
this.copyMenuItem.Index = 1;
this.copyMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlC;
this.copyMenuItem.Text = "&Copy";
this.copyMenuItem.Click += new System.EventHandler(this.copyMenuItem_Click);
//
// autoExpandMenuItem
//
this.autoExpandMenuItem.Index = 3;
this.autoExpandMenuItem.Text = "Auto &Expand";
this.autoExpandMenuItem.Click += new System.EventHandler(this.autoExpandMenuItem_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 20);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(73, 16);
this.label1.TabIndex = 3;
this.label1.Text = "Listen on port";
//
// selectAllmenuItem
//
this.selectAllmenuItem.Index = 0;
this.selectAllmenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlA;
this.selectAllmenuItem.Text = "Select &All";
this.selectAllmenuItem.Click += new System.EventHandler(this.selectAllMenuItem_Click);
//
// resendPortBox
//
this.resendPortBox.Location = new System.Drawing.Point(192, 48);
this.resendPortBox.Name = "resendPortBox";
this.resendPortBox.Size = new System.Drawing.Size(72, 20);
this.resendPortBox.TabIndex = 4;
this.resendPortBox.Text = "";
//
// saveHttpMenuItem
//
this.saveHttpMenuItem.Index = 2;
this.saveHttpMenuItem.Text = "Save HTTP";
this.saveHttpMenuItem.Click += new System.EventHandler(this.saveHttpMenuItem_Click);
//
// saveButton
//
this.saveButton.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
this.saveButton.ImageList = this.saveButtonImageList;
this.saveButton.Location = new System.Drawing.Point(288, 48);
this.saveButton.Name = "saveButton";
this.saveButton.TabIndex = 7;
this.saveButton.Text = "Save Log";
this.saveButton.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.saveButton.Click += new System.EventHandler(this.saveButton_Click);
//
// panel3
//
this.panel3.Controls.Add(this.panel4);
this.panel3.Controls.Add(this.splitter1);
this.panel3.Controls.Add(this.messageView);
this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel3.Location = new System.Drawing.Point(0, 0);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(780, 539);
this.panel3.TabIndex = 5;
//
// messagesBox
//
this.messagesBox.ContextMenu = this.messagesContextMenu;
this.messagesBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.messagesBox.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.messagesBox.Location = new System.Drawing.Point(0, 0);
this.messagesBox.Name = "messagesBox";
this.messagesBox.Size = new System.Drawing.Size(617, 468);
this.messagesBox.TabIndex = 7;
this.messagesBox.WordWrap = true;
//
// levelLabel
//
this.levelLabel.AutoSize = true;
this.levelLabel.Location = new System.Drawing.Point(384, 20);
this.levelLabel.Name = "levelLabel";
this.levelLabel.Size = new System.Drawing.Size(86, 16);
this.levelLabel.TabIndex = 9;
this.levelLabel.Text = "Messages Level";
//
// connectionStatusBar
//
this.connectionStatusBar.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
this.connectionStatusBar.Width = 764;
//
// clearMenuItem
//
this.clearMenuItem.Index = 2;
this.clearMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlL;
this.clearMenuItem.Text = "C&lear";
this.clearMenuItem.Click += new System.EventHandler(this.clearButton_Click);
//
// saveLogDialog
//
this.saveLogDialog.DefaultExt = "txt";
this.saveLogDialog.Filter = "Text Files|*.txt|All Files|*.*";
this.saveLogDialog.Title = "Save Log";
//
// tcpShowByTimeMenuItem
//
this.tcpShowByTimeMenuItem.Index = 2;
this.tcpShowByTimeMenuItem.Text = "TCP Show by &Time";
this.tcpShowByTimeMenuItem.Click += new System.EventHandler(this.tcpShowByTimeMenuItem_Click);
//
// logBox
//
this.logBox.Dock = System.Windows.Forms.DockStyle.Bottom;
this.logBox.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.logBox.HorizontalScrollbar = true;
this.logBox.ItemHeight = 16;
this.logBox.Location = new System.Drawing.Point(0, 471);
this.logBox.Name = "logBox";
this.logBox.ScrollAlwaysVisible = true;
this.logBox.Size = new System.Drawing.Size(617, 68);
this.logBox.TabIndex = 8;
//
// saveXmlMenuItem
//
this.saveXmlMenuItem.Index = 3;
this.saveXmlMenuItem.Text = "Save XML";
this.saveXmlMenuItem.Click += new System.EventHandler(this.saveXmlMenuItem_Click);
//
// startButton
//
this.startButton.Location = new System.Drawing.Point(192, 16);
this.startButton.Name = "startButton";
this.startButton.TabIndex = 5;
this.startButton.Text = "Start";
this.startButton.Click += new System.EventHandler(this.startButton_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(8, 52);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(56, 16);
this.label2.TabIndex = 4;
this.label2.Text = "Resend to";
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(780, 641);
this.Controls.Add(this.panel1);
this.Controls.Add(this.statusBar);
this.MinimumSize = new System.Drawing.Size(400, 200);
this.Name = "MainForm";
this.Text = "TCPproxy";
this.panel4.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.panel2.ResumeLayout(false);
this.panel3.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.connectionStatusBar)).EndInit();
this.ResumeLayout(false);
}
#endregion
 
#region windows forms methods
public MainForm()
{
InitializeComponent();
logMessages = new LogMessages(logBox);
LoadFromRegistry();
if(levelBox.SelectedIndex < 0) levelBox.SelectedIndex = 0;
}
 
protected override void Dispose( bool disposing )
{
if(tcpListener != null)
{
tcpListener.StopListening(); // stop listening
tcpListener.CancelAll(); // cancel all open connections
}
 
SaveToRegistry(); // save settings
 
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
 
[STAThread]
static void Main()
{
Application.Run(new MainForm());
}
 
private void LoadFromRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
@"Software\Echelon\TCPproxy");
 
if(subkey != null)
{
listenPortBox.Text = (string)subkey.GetValue("Listen Port", "");
resendHostBox.Text = (string)subkey.GetValue("Resend Host", "");
resendPortBox.Text = (string)subkey.GetValue("Resend Port", "");
levelBox.SelectedIndex = (int)subkey.GetValue("Message Level", 0);
autoExpand = (int)subkey.GetValue("Auto Expand", 1) == 1;
messagesBox.WordWrap = (int)subkey.GetValue("Word Wrap", 1) == 1;
 
object tcpShowModeStr = (object)subkey.GetValue("Tcp Show Mode", TcpShowMode.ByDirection);
tcpShowMode = (tcpShowModeStr as string) == "ByDirection"
? TcpShowMode.ByDirection : TcpShowMode.ByTime;
}
}
 
private void SaveToRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(
@"Software\Echelon\TCPproxy");
 
subkey.SetValue("Listen Port", listenPortBox.Text);
subkey.SetValue("Resend Host", resendHostBox.Text);
subkey.SetValue("Resend Port", resendPortBox.Text);
subkey.SetValue("Message Level", levelBox.SelectedIndex);
subkey.SetValue("Tcp Show Mode", tcpShowMode);
subkey.SetValue("Auto Expand", autoExpand ? 1 : 0);
subkey.SetValue("Word Wrap", messagesBox.WordWrap ? 1 : 0);
}
 
private void startButton_Click(object sender, System.EventArgs e)
{
int listenPort = -1;
IPAddress resendHost;
int resendPort = -1;
ArrayList tcpConnections = new ArrayList();
 
// parse listen port
try
{
listenPort = int.Parse(listenPortBox.Text);
}
catch(FormatException)
{
MessageBox.Show("Listen port must be an integer number");
return;
}
 
// get resend host
if(resendHostBox.Text == "")
{
resendHost = null;
}
else
{
Regex ipRegex = new Regex(@"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$");
if(ipRegex.Match(resendHostBox.Text).Success)
{
try
{
resendHost = IPAddress.Parse(resendHostBox.Text);
}
catch(FormatException)
{
MessageBox.Show("Wrong IP address of the resend host");
return;
}
}
else
{
IPHostEntry hostInfo = Dns.GetHostByName(resendHostBox.Text);
 
if(hostInfo.AddressList.Length > 0)
{
resendHost = hostInfo.AddressList[0];
}
else
{
MessageBox.Show("Cannot find IP address of the resend host");
return;
}
}
 
// parse resend port
try
{
resendPort = int.Parse(resendPortBox.Text);
}
catch(FormatException)
{
MessageBox.Show("Resend port must be an integer number");
return;
}
}
 
// listen to the port
try
{
Start(listenPort, resendHost, resendPort);
}
catch(Exception ex)
{
MessageBox.Show("Cannot start listening: " + ex.Message, "TCPproxy",
MessageBoxButtons.OK, MessageBoxIcon.Error);
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
return;
}
 
startButton.Visible = false;
stopButton.Visible = true;
listenPortBox.Enabled = false;
resendHostBox.Enabled = false;
resendPortBox.Enabled = false;
}
 
private void stopButton_Click(object sender, System.EventArgs e)
{
if(tcpListener != null) tcpListener.StopListening();
 
startButton.Visible = true;
stopButton.Visible = false;
listenPortBox.Enabled = true;
resendHostBox.Enabled = true;
resendPortBox.Enabled = true;
}
 
private void clearButton_Click(object sender, System.EventArgs e)
{
treeNodes.Clear();
messageView.Nodes.Clear();
messagesBox.Clear();
logMessages.Clear();
}
 
private void saveButton_Click(object sender, System.EventArgs e)
{
saveLogMenu.Show(saveButton, new Point(saveButton.Width, 0));
}
 
private void messagesContextMenu_Popup(object sender, System.EventArgs e)
{
wordWrapMenuItem.Checked = messagesBox.WordWrap;
}
 
private void selectAllMenuItem_Click(object sender, System.EventArgs e)
{
messagesBox.SelectAll();
}
 
private void copyMenuItem_Click(object sender, System.EventArgs e)
{
string sel = messagesBox.SelectedText;
if(sel != null) Clipboard.SetDataObject(sel);
}
 
private void wordWrapMenuItem_Click(object sender, System.EventArgs e)
{
messagesBox.WordWrap = !messagesBox.WordWrap;
}
 
private void autoExpandMenuItem_Click(object sender, System.EventArgs e)
{
autoExpand = !autoExpand;
}
 
private void messageView_BeforeSelect(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
{
if(messageView.SelectedNode == null) return;
 
object tag = messageView.SelectedNode.Tag;
if(tag is TreeNodeData)
{
TreeNodeData data = (TreeNodeData)tag;
data.SaveViewState();
}
}
 
private void messageView_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
if(messageView.SelectedNode == null) return;
 
object tag = messageView.SelectedNode.Tag;
if(tag is TreeNodeData)
{
TreeNodeData data = (TreeNodeData)tag;
data.Show();
}
}
 
private void closeConnectionMenuItem_Click(object sender, System.EventArgs e)
{
if(messageView.SelectedNode == null) return;
 
object tag = messageView.SelectedNode.Tag;
if(tag is TcpNodeData)
CloseTcpConnection(((TcpNodeData)tag).Tcp);
else if(tag is TcpNodeData)
CloseTcpConnection(((TcpNodeData)messageView.SelectedNode.Parent.Tag).Tcp);
else if(tag is XmlNodeData)
CloseTcpConnection(((TcpNodeData)messageView.SelectedNode.Parent.Parent.Tag).Tcp);
}
 
private void tcpShowByDirectionMenuItem_Click(object sender, System.EventArgs e)
{
tcpShowMode = TcpShowMode.ByDirection;
 
if(messageView.SelectedNode == null) return;
 
object tag = messageView.SelectedNode.Tag;
if(tag is TcpNodeData)
UpdateTcpNodeInternal(((TcpNodeData)tag).Tcp);
}
 
private void tcpShowByTimeMenuItem_Click(object sender, System.EventArgs e)
{
tcpShowMode = TcpShowMode.ByTime;
 
if(messageView.SelectedNode == null) return;
 
object tag = messageView.SelectedNode.Tag;
if(tag is TcpNodeData)
UpdateTcpNodeInternal(((TcpNodeData)tag).Tcp);
}
 
private void listContextMenu_Popup(object sender, System.EventArgs e)
{
if(tcpShowMode == TcpShowMode.ByDirection)
{
tcpShowByDirectionMenuItem.Checked = true;
tcpShowByTimeMenuItem.Checked = false;
}
else
{
tcpShowByDirectionMenuItem.Checked = false;
tcpShowByTimeMenuItem.Checked = true;
}
 
autoExpandMenuItem.Checked = autoExpand;
}
 
private void saveLogMenuItem_Click(object sender, System.EventArgs e)
{
if(saveLogDialog.ShowDialog() == DialogResult.OK)
{
SaveLog(saveLogDialog.FileName);
}
}
 
private void saveTcpMenuItem_Click(object sender, System.EventArgs e)
{
if(saveLogDialog.ShowDialog() == DialogResult.OK)
{
SaveTcp(saveLogDialog.FileName);
}
}
 
private void saveHttpMenuItem_Click(object sender, System.EventArgs e)
{
if(saveLogDialog.ShowDialog() == DialogResult.OK)
{
SaveHttp(saveLogDialog.FileName);
}
}
 
private void saveXmlMenuItem_Click(object sender, System.EventArgs e)
{
if(saveLogDialog.ShowDialog() == DialogResult.OK)
{
SaveXml(saveLogDialog.FileName);
}
}
 
private void levelBox_SelectedIndexChanged(object sender, System.EventArgs e)
{
LogLevel level = LogLevel.Debug;
 
if(levelBox.SelectedIndex == 1)
level = LogLevel.Info;
else if(levelBox.SelectedIndex == 2)
level = LogLevel.Important;
 
logMessages.Level = level;
}
 
#endregion windows forms methods
 
#region core methods
private void Start(int listenPort, IPAddress resendHost, int resendPort)
{
if(tcpListener != null) tcpListener.StopListening();
 
tcpListener = new TcpListener(listenPort, resendHost, resendPort);
tcpListener.Log += new TcpLogEventHandler(TcpConnectionLog);
tcpListener.NewTcp += new TcpConnectionEventHandler(AddTcpConnetion);
tcpListener.StartListening();
}
 
private void CloseTcpConnection(TcpConnection tcp)
{
if(tcp == null) return;
 
tcp.Cancel();
}
 
private void SaveLog(string fileName)
{
StreamWriter writer = new StreamWriter(fileName);
 
foreach(LogMessage message in logMessages.Messages)
{
writer.WriteLine(message);
}
 
writer.Close();
}
 
private void SaveTcp(string fileName)
{
StreamWriter writer = new StreamWriter(fileName);
 
foreach(TreeNode tcpNode in messageView.Nodes)
{
TcpNodeData data = (TcpNodeData)tcpNode.Tag;
data.WriteLog(writer);
}
 
writer.Close();
}
 
private void SaveHttp(string fileName)
{
StreamWriter writer = new StreamWriter(fileName);
 
foreach(TreeNode tcpNode in messageView.Nodes)
{
foreach(TreeNode httpNode in tcpNode.Nodes)
{
HttpNodeData data = (HttpNodeData)httpNode.Tag;
data.WriteLog(writer);
}
}
 
writer.Close();
}
 
private void SaveXml(string fileName)
{
StreamWriter writer = new StreamWriter(fileName);
 
foreach(TreeNode tcpNode in messageView.Nodes)
{
foreach(TreeNode httpNode in tcpNode.Nodes)
{
foreach(TreeNode xmlNode in httpNode.Nodes)
{
XmlNodeData data = (XmlNodeData)xmlNode.Tag;
data.WriteLog(writer);
}
}
}
 
writer.Close();
}
 
#endregion core methods
 
#region network events handlers
private void TcpConnectionLog(object sender, TcpLogEventArgs e)
{
TcpConnection tcp = sender as TcpConnection;
LogMessage message = new LogMessage(tcp, e.Level, e.Message, e.Exception);
 
try
{
this.BeginInvoke(new AddLogMessageHandler(AddLogMessageInternal), new object[] { message } );
}
catch(InvalidOperationException ex)
{
if(!this.Disposing && !this.IsDisposed)
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
}
}
 
private void AddTcpConnetion(object sender, TcpConnectionEventArgs e)
{
e.Tcp.Log += new TcpLogEventHandler(TcpConnectionLog);
e.Tcp.Update += new TcpEventHandler(UpdateTcpNode);
e.Tcp.Close += new TcpEventHandler(UpdateTcpNode);
e.Tcp.NewHttp += new TcpHttpEventHandler(AddHttpMessageNode);
 
try
{
this.BeginInvoke(new AddTcpNodeHandler(AddTcpNodeInternal), new object[] { e.Tcp } );
}
catch(InvalidOperationException ex)
{
if(!this.Disposing && !this.IsDisposed)
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
}
}
 
private void UpdateTcpNode(object sender, TcpEventArgs e)
{
try
{
this.BeginInvoke(new UpdateTcpNodeHandler(UpdateTcpNodeInternal), new object[] { (TcpConnection)sender } );
}
catch(InvalidOperationException ex)
{
if(!this.Disposing && !this.IsDisposed)
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
}
}
 
private void AddHttpMessageNode(object sender, TcpHttpEventArgs e)
{
e.Http.Update += new TcpEventHandler(UpdateHttpNode);
 
try
{
this.BeginInvoke(new AddHttpNodeHandler(AddHttpNodeInternal),
new object[] { (TcpConnection)sender, e.Http } );
}
catch(InvalidOperationException ex)
{
if(!this.Disposing && !this.IsDisposed)
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
}
}
 
private void UpdateHttpNode(object sender, TcpEventArgs e)
{
try
{
this.BeginInvoke(new UpdateHttpNodeHandler(UpdateHttpNodeInternal), new object[] { (HttpMessage)sender } );
}
catch(InvalidOperationException ex)
{
if(!this.Disposing && !this.IsDisposed)
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
}
}
 
#endregion network events handlers
 
#region handlers for async GUI events
private delegate void AddLogMessageHandler(LogMessage message);
private delegate void AddTcpNodeHandler(TcpConnection tcp);
private delegate void UpdateTcpNodeHandler(TcpConnection tcp);
private delegate void AddHttpNodeHandler(TcpConnection tcp, HttpMessage http);
private delegate void UpdateHttpNodeHandler(HttpMessage http);
 
private void AddLogMessageInternal(LogMessage message)
{
logMessages.Add(message);
 
if(message.Exception != null)
{
Console.WriteLine(message.Exception.Message + " (" + message.Exception.GetType().Name
+ ")\n" + message.Exception.StackTrace);
}
}
 
private void AddTcpNodeInternal(TcpConnection tcp)
{
TreeNode treeNode = new TreeNode(tcp.ToString());
TcpNodeData data = new TcpNodeData(this, treeNode);
 
data.Tcp = tcp;
treeNode.Tag = data;
treeNode.ImageIndex = 1;
treeNode.SelectedImageIndex = 1;
treeNodes[tcp] = data;
 
messageView.Nodes.Add(treeNode);
treeNode.EnsureVisible();
}
 
private void UpdateTcpNodeInternal(TcpConnection tcp)
{
TcpNodeData data = treeNodes[tcp] as TcpNodeData;
if(data == null) throw new ArgumentException("Unknown TCP node");
 
string title = tcp.ToString();
if(title != data.Node.Text) data.Node.Text = title;
if(tcp.LocalState == SocketState.Closed && tcp.RemoteState == SocketState.Closed)
{
data.Node.ImageIndex = 2;
data.Node.SelectedImageIndex = 2;
}
 
if(messageView.SelectedNode == null || data != messageView.SelectedNode.Tag)
data.ViewExpired = true; // got update for invisible TCP node, update it later
else
data.Show();
}
 
private void AddHttpNodeInternal(TcpConnection tcp, HttpMessage http)
{
TreeNode treeNode = new TreeNode(http.ToString());
HttpNodeData data = new HttpNodeData(this, treeNode);
 
data.Http = http;
treeNode.Tag = data;
treeNodes[http] = data;
 
TcpNodeData tcpData = treeNodes[tcp] as TcpNodeData;
if(tcpData == null) throw new ArgumentException("No node found for TCP message");
 
tcpData.Node.Nodes.Add(treeNode);
if(autoExpand) tcpData.Node.Expand();
tcpData.Node.EnsureVisible();
}
 
private void UpdateHttpNodeInternal(HttpMessage http)
{
HttpNodeData httpData = treeNodes[http] as HttpNodeData;
if(httpData == null) throw new ArgumentException("No node found for HTTP message");
 
string title = http.ToString();
if(httpData.Node.Text != title) httpData.Node.Text = title;
 
if(!httpData.RequestXmlShown && http.RequestXml != null)
{
httpData.RequestXmlShown = true;
AddXmlNode(httpData.Node, "Request XML", http.RequestXml);
if(autoExpand) httpData.Node.Expand();
}
 
if(!httpData.ResponseXmlShown && http.ResponseXml != null)
{
httpData.ResponseXmlShown = true;
AddXmlNode(httpData.Node, "Response XML", http.ResponseXml);
if(autoExpand) httpData.Node.Expand();
}
 
// update text view
if(messageView.SelectedNode == null || httpData != messageView.SelectedNode.Tag)
httpData.ViewExpired = true;
else
httpData.Show();
}
 
private void AddXmlNode(TreeNode parent, string title, XmlMessage xml)
{
TreeNode treeNode = new TreeNode(title);
XmlNodeData data = new XmlNodeData(this, treeNode);
 
data.Xml = xml;
treeNode.Tag = data;
treeNodes[xml] = data;
 
parent.Nodes.Add(treeNode);
}
 
#endregion handlers for async GUI events
 
#region node display classes
private abstract class TreeNodeData
{
protected TreeNode node;
protected object viewState;
protected bool viewExpired;
protected MainForm owner;
protected bool shown = false;
 
public TreeNode Node
{
get { return node; }
}
 
public TreeNodeData(MainForm owner, TreeNode node)
{
this.owner = owner;
this.node = node;
}
 
public bool ViewExpired
{
get { return viewExpired; }
set { viewExpired = value; }
}
 
public void SaveViewState()
{
viewState = owner.messagesBox.SaveState(false);
}
 
protected virtual bool ForceInitView()
{
return false;
}
 
protected abstract void InitView();
protected abstract void UpdateView();
 
public void Show()
{
if(!shown || viewState == null || ForceInitView())
{
InitView();
shown = true;
if(viewState == null) viewState = owner.messagesBox.SaveState(false);
}
else
{
owner.messagesBox.RestoreState(viewState, true);
if(viewExpired) UpdateView();
}
}
 
public abstract void WriteLog(StreamWriter writer);
}
 
private class TcpNodeData : TreeNodeData
{
private TcpConnection tcp;
 
private TcpShowMode lastShowMode;
private object localStateMarker = null;
private object remoteStateMarker = null;
private object startMarker = null;
private object localEndMarker = null;
private object remoteEndMarker = null;
private object clientMarker = null;
private object serverMarker = null;
private object sentMarker = null;
private object receivedMarker = null;
private object textMarker1 = null;
private object textMarker2 = null;
private IEnumerator messagesEnum = null;
 
public TcpConnection Tcp
{
get { return tcp; }
set { tcp = value; }
}
 
public TcpNodeData(MainForm owner, TreeNode node) : base(owner, node)
{
}
 
 
protected override bool ForceInitView()
{
return (lastShowMode != owner.tcpShowMode);
}
 
protected override void InitView()
{
lastShowMode = owner.tcpShowMode;
 
try
{
owner.messagesBox.BeginUpdate();
 
lock(tcp)
{
owner.messagesBox.Clear();
 
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText("ID: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
owner.messagesBox.AppendText(tcp.Id,
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("State: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
localStateMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(tcp.LocalState.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(localStateMarker);
owner.messagesBox.AppendText(null,
Color.DarkRed, Color.Transparent, false, false, 1, 12);
remoteStateMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(tcp.RemoteState.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(remoteStateMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Start: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
startMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(tcp.StartTimestamp.ToString("HH:mm:ss.ffff"),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(startMarker);
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText("Local End: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
localEndMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(tcp.LocalEndTimestamp.ToString("HH:mm:ss.ffff"),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(localEndMarker);
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText("Remote End: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
remoteEndMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(tcp.RemoteEndTimestamp.ToString("HH:mm:ss.ffff"),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(remoteEndMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Client: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
clientMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText((tcp.LocalPoint == null) ? "" : tcp.LocalPoint.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(clientMarker);
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText("Server: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
serverMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText((tcp.RemotePoint == null) ? "" : tcp.RemotePoint.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(serverMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Sent: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
sentMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(tcp.SentBytes.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(sentMarker);
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText("Received: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
receivedMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(tcp.ReceivedBytes.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.EndMark(receivedMarker);
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendNewLine();
 
messagesEnum = tcp.Messages.GetEnumerator();
 
textMarker1 = owner.messagesBox.BeginMark();
owner.messagesBox.EndMark(textMarker1);
 
owner.messagesBox.AppendNewLine();
textMarker2 = owner.messagesBox.BeginMark();
owner.messagesBox.EndMark(textMarker2);
 
ShowMessages();
}
}
finally
{
owner.messagesBox.EndUpdate();
}
}
 
protected override void UpdateView()
{
try
{
owner.messagesBox.BeginUpdate();
 
lock(tcp)
{
owner.messagesBox.ChangeText(localStateMarker, tcp.LocalState.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.ChangeText(remoteStateMarker, tcp.RemoteState.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
 
owner.messagesBox.ChangeText(startMarker, tcp.StartTimestamp.ToString("HH:mm:ss.ffff"),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.ChangeText(localEndMarker, tcp.LocalEndTimestamp.ToString("HH:mm:ss.ffff"),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.ChangeText(remoteEndMarker, tcp.RemoteEndTimestamp.ToString("HH:mm:ss.ffff"),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
 
owner.messagesBox.ChangeText(clientMarker, (tcp.LocalPoint == null) ? "" : tcp.LocalPoint.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.ChangeText(serverMarker, (tcp.RemotePoint == null) ? "" : tcp.RemotePoint.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
 
owner.messagesBox.ChangeText(sentMarker, tcp.SentBytes.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
owner.messagesBox.ChangeText(receivedMarker, tcp.ReceivedBytes.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 12);
 
ShowMessages();
}
}
finally
{
owner.messagesBox.EndUpdate();
}
}
 
private void ShowMessages()
{
while(messagesEnum.MoveNext())
{
TcpMessage message = (TcpMessage)messagesEnum.Current;
object marker = (owner.tcpShowMode == TcpShowMode.ByTime
|| message.Direction == TcpMessageDirection.Local) ? textMarker1 : textMarker2;
 
if(owner.tcpShowMode == TcpShowMode.ByTime)
{
owner.messagesBox.InsertText(marker,
message.Timestamp.ToString("HH:mm:ss.ffff") + " (" + message.Length + ")",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
owner.messagesBox.InsertNewLine(marker);
}
 
string str = Utils.BytesToString(message.Bytes, message.Length);
ArrayList lines = Utils.SplitLine(str);
for(int i = 0; i < lines.Count; i++)
{
owner.messagesBox.InsertText(marker, (string)lines[i],
message.Direction == TcpMessageDirection.Local ? Color.Green : Color.Blue,
Color.LightGray, false, false, 0, 0);
 
if(owner.tcpShowMode == TcpShowMode.ByTime || i != lines.Count - 1)
owner.messagesBox.InsertNewLine(marker);
}
}
}
 
public override void WriteLog(StreamWriter writer)
{
writer.WriteLine(
"Start: " + tcp.StartTimestamp.ToString("HH:mm:ss.ffff")
+ "\r\nLocal End: " + tcp.LocalEndTimestamp.ToString("HH:mm:ss.ffff")
+ "\r\nRemote End: " + tcp.RemoteEndTimestamp.ToString("HH:mm:ss.ffff")
+ "\r\nClient: " + ((tcp.LocalPoint == null) ? "" : tcp.LocalPoint.ToString())
+ "\r\nServer: " + ((tcp.RemotePoint == null) ? "" : tcp.RemotePoint.ToString())
+ "\r\nSent: " + tcp.SentBytes
+ "\r\nReceived: " + tcp.ReceivedBytes);
 
foreach(TcpMessage message in tcp.Messages)
{
string str = Utils.BytesToString(message.Bytes, message.Length);
if(!str.EndsWith("\n")) str += "\r\n";
 
writer.WriteLine();
if(message.Direction == TcpMessageDirection.Local)
writer.WriteLine(">>> {0:HH:mm:ss.ffff} >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", message.Timestamp);
else
writer.WriteLine("<<< {0:HH:mm:ss.ffff} <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", message.Timestamp);
writer.Write(str);
}
writer.WriteLine("===============================================================");
writer.WriteLine();
}
}
 
private class HttpNodeData : TreeNodeData
{
private HttpMessage http;
private bool requestXmlShown = false;
private bool responseXmlShown = false;
 
private object stateMarker = null;
private object requestMethodMarker = null;
private object requestUriMarker = null;
private object requestVersionMarker = null;
private object requestLengthMarker = null;
private object requestEncodingMarker = null;
private object requestContentTypeMarker = null;
private object requestCharsetMarker = null;
private object requestHeadersMarker = null;
private object responseVersionMarker = null;
private object responseStatusMarker = null;
private object responseLengthMarker = null;
private object responseEncodingMarker = null;
private object responseContentTypeMarker = null;
private object responseCharsetMarker = null;
private object responseHeadersMarker = null;
private object requestBodyMarker = null;
private object responseBodyMarker = null;
private IEnumerator requestHeadersEnum = null;
private IEnumerator responseHeadersEnum = null;
 
public HttpMessage Http
{
get { return http; }
set { http = value; }
}
 
public bool RequestXmlShown
{
get { return requestXmlShown; }
set { requestXmlShown = value; }
}
 
public bool ResponseXmlShown
{
get { return responseXmlShown; }
set { responseXmlShown = value; }
}
 
public HttpNodeData(MainForm owner, TreeNode node) : base(owner, node)
{
}
 
private string EncodingToString(HttpEncoding encoding)
{
switch(encoding)
{
case HttpEncoding.Identify: return "identify";
case HttpEncoding.Gzip: return "gzip";
case HttpEncoding.Compress: return "compress";
case HttpEncoding.Deflate: return "deflate";
default: return "<unknown>";
}
}
 
protected override void InitView()
{
try
{
lock(http)
{
owner.messagesBox.Clear();
 
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText("Complete: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
stateMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.RequestComplete && http.ResponseComplete ? "YES" : "NO",
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(stateMarker);
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendNewLine();
 
// request info
owner.messagesBox.AppendText("Request Method: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
requestMethodMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.RequestMethod,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(requestMethodMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Request URI: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
requestUriMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.RequestUri,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(requestUriMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Request Version: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
requestVersionMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(requestVersionMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Request Content Length: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
requestLengthMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.RequestLength < 0 ? "<unknown>" : http.RequestLength.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(requestLengthMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Request Content Encoding: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
requestEncodingMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(EncodingToString(http.RequestEncoding),
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(requestEncodingMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Request Content Type: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
requestContentTypeMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.RequestContentType == null ? "<unknown>"
: http.RequestContentType + "/" + http.RequestContentSubtype,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(requestContentTypeMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Request Content Charset: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
requestCharsetMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.RequestCharset == null ? "<unknown>" : http.RequestCharset,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(requestCharsetMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Request Headers:",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
owner.messagesBox.AppendNewLine();
requestHeadersMarker = owner.messagesBox.BeginMark();
owner.messagesBox.EndMark(requestHeadersMarker);
 
requestHeadersEnum = http.RequestHeaders.GetEnumerator();
ShowHeaders(requestHeadersEnum, requestHeadersMarker);
 
// response info
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText("Response Version: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
responseVersionMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.ResponseVersion == HttpVersion.V0_9
? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(responseVersionMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Response Status: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
responseStatusMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.ResponseStatusCode + " " + http.ResponseStatusMessage,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(responseStatusMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Response Content Length: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
responseLengthMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.ResponseLength < 0 ? "<unknown>" : http.ResponseLength.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(responseLengthMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Response Content Encoding: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
responseEncodingMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(EncodingToString(http.ResponseEncoding),
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(responseEncodingMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Response Content Type: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
responseContentTypeMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.ResponseContentType == null ? "<unknown>"
: http.ResponseContentType + "/" + http.ResponseContentSubtype,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(responseContentTypeMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Response Content Charset: ",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
responseCharsetMarker = owner.messagesBox.BeginMark();
owner.messagesBox.AppendText(http.ResponseCharset == null ? "<unknown>" : http.ResponseCharset,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.EndMark(responseCharsetMarker);
owner.messagesBox.AppendNewLine();
 
owner.messagesBox.AppendText("Response Headers:",
Color.DarkRed, Color.Transparent, false, false, 0, 0);
owner.messagesBox.AppendNewLine();
responseHeadersMarker = owner.messagesBox.BeginMark();
owner.messagesBox.EndMark(responseHeadersMarker);
 
responseHeadersEnum = http.ResponseHeaders.GetEnumerator();
ShowHeaders(responseHeadersEnum, responseHeadersMarker);
 
owner.messagesBox.AppendNewLine();
requestBodyMarker = owner.messagesBox.BeginMark();
owner.messagesBox.EndMark(requestBodyMarker);
ShowBody(requestBodyMarker, http.RequestBody, http.RequestLength, http.RequestText, Color.Green);
 
owner.messagesBox.AppendNewLine();
responseBodyMarker = owner.messagesBox.BeginMark();
owner.messagesBox.EndMark(responseBodyMarker);
ShowBody(responseBodyMarker, http.ResponseBody, http.ResponseLength, http.ResponseText, Color.Blue);
}
}
finally
{
owner.messagesBox.EndUpdate();
}
}
 
protected override void UpdateView()
{
try
{
owner.messagesBox.BeginUpdate();
 
lock(http)
{
owner.messagesBox.ChangeText(stateMarker, http.RequestComplete && http.ResponseComplete ? "YES" : "NO",
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(requestMethodMarker, http.RequestMethod,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(requestUriMarker, http.RequestUri,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(requestVersionMarker, http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(requestLengthMarker, http.RequestLength < 0
? "<unknown>" : http.RequestLength.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(requestEncodingMarker, EncodingToString(http.RequestEncoding),
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(requestContentTypeMarker, http.RequestContentType == null ? "<unknown>"
: http.RequestContentType + "/" + http.RequestContentSubtype,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(requestCharsetMarker, http.RequestCharset == null
? "<unknown>" : http.RequestCharset,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
 
ShowHeaders(requestHeadersEnum, requestHeadersMarker);
 
owner.messagesBox.ChangeText(responseVersionMarker, http.ResponseVersion == HttpVersion.V0_9
? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(responseStatusMarker, http.ResponseStatusCode + " " + http.ResponseStatusMessage,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(responseLengthMarker, http.ResponseLength < 0
? "<unknown>" : http.ResponseLength.ToString(),
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(responseEncodingMarker, EncodingToString(http.ResponseEncoding),
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(responseContentTypeMarker, http.ResponseContentType == null ? "<unknown>"
: http.ResponseContentType + "/" + http.ResponseContentSubtype,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
owner.messagesBox.ChangeText(responseCharsetMarker, http.ResponseCharset == null
? "<unknown>" : http.ResponseCharset,
Color.DarkRed, Color.LightGray, false, false, 0, 27);
 
ShowHeaders(responseHeadersEnum, responseHeadersMarker);
 
owner.messagesBox.DeleteText(requestBodyMarker);
ShowBody(requestBodyMarker, http.RequestBody, http.RequestLength, http.RequestText, Color.Green);
owner.messagesBox.DeleteText(responseBodyMarker);
ShowBody(responseBodyMarker, http.ResponseBody, http.ResponseLength, http.ResponseText, Color.Blue);
}
}
finally
{
owner.messagesBox.EndUpdate();
}
}
 
private void ShowHeaders(IEnumerator headers, object marker)
{
while(headers.MoveNext())
{
HttpHeader h = (HttpHeader)headers.Current;
 
bool first = true;
foreach(string val in h.Values)
{
if(first)
{
owner.messagesBox.InsertText(marker, h.Name + ":",
Color.DarkRed, Color.Transparent, false, false, 4, 4);
owner.messagesBox.InsertText(marker, null,
Color.DarkRed, Color.Transparent, false, false, 6 - 4 - 1, 4);
first = false;
}
else
{
owner.messagesBox.InsertText(marker, null,
Color.DarkRed, Color.Transparent, false, false, 6 + h.Name.Length, 6 + h.Name.Length);
}
owner.messagesBox.InsertText(marker, val,
Color.DarkRed, Color.LightGray, false, false, 0, 6 + h.Name.Length);
owner.messagesBox.InsertNewLine(marker);
}
}
}
 
private void ShowBody(object marker, byte[] body, int len, string text, Color color)
{
if(text != null)
{
ArrayList lines = Utils.SplitLine(text);
for(int i = 0; i < lines.Count; i++)
{
owner.messagesBox.InsertText(marker, (string)lines[i], color, Color.LightGray, false, false, 0, 0);
owner.messagesBox.InsertNewLine(marker);
}
}
else if(body != null)
{
ArrayList lines = Utils.SplitLine(Utils.BytesToString(body, len));
for(int i = 0; i < lines.Count; i++)
{
owner.messagesBox.InsertText(marker, (string)lines[i], color, Color.LightGray, false, false, 0, 0);
owner.messagesBox.InsertNewLine(marker);
}
}
}
 
public override void WriteLog(StreamWriter writer)
{
// request info
writer.WriteLine(
"Complete: " + (http.RequestComplete && http.ResponseComplete ? "YES" : "NO") + "\r\n"
+ "\r\nRequest Method: " + http.RequestMethod
+ "\r\nRequest URI: " + http.RequestUri
+ "\r\nRequest Version: " + (http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1")
+ "\r\nRequest Content Length: " + (http.RequestLength < 0 ? "<unknown>" : http.RequestLength.ToString())
+ "\r\nRequest Content Encoding: " + EncodingToString(http.RequestEncoding)
+ "\r\nRequest Content Type: " + (http.RequestContentType == null ? "<unknown>"
: http.RequestContentType + "/" + http.RequestContentSubtype)
+ "\r\nRequest Content Charset: " + (http.RequestCharset == null ? "<unknown>" : http.RequestCharset)
+ "\r\nRequest Headers:");
 
foreach(HttpHeader h in http.RequestHeaders)
{
int indent = 0;
foreach(string val in h.Values)
{
if(indent == 0)
{
writer.WriteLine(" {0}: {1}", h.Name, val);
indent = 6 + h.Name.Length;
}
else
{
writer.WriteLine("{0," + indent + "}{1}", " ", val);
}
}
}
 
// response info
writer.WriteLine(
"\r\nResponse Version: " + (http.ResponseVersion == HttpVersion.V0_9
? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1")
+ "\r\nResponse Status: " + http.ResponseStatusCode + " " + http.ResponseStatusMessage
+ "\r\nResponse Content Length: " + (http.ResponseLength < 0
? "<unknown>" : http.ResponseLength.ToString())
+ "\r\nResponse Content Encoding: " + EncodingToString(http.ResponseEncoding)
+ "\r\nResponse Content Type: " + (http.ResponseContentType == null ? "<unknown>"
: http.ResponseContentType + "/" + http.ResponseContentSubtype)
+ "\r\nResponse Content Charset: " + (http.ResponseCharset == null ? "<unknown>" : http.ResponseCharset)
+ "\r\nResponse Headers:");
 
foreach(HttpHeader h in http.ResponseHeaders)
{
int indent = 0;
foreach(string val in h.Values)
{
if(indent == 0)
{
writer.WriteLine(" {0}: {1}", h.Name, val);
indent = 6 + h.Name.Length;
}
else
{
writer.WriteLine("{0," + indent + "}{1}", " ", val);
}
}
}
writer.WriteLine();
 
// request body
if(http.RequestText != null)
{
writer.WriteLine(http.RequestText);
}
else if(http.RequestBody != null)
{
writer.WriteLine(Utils.BytesToString(http.RequestBody, http.RequestLength));
}
 
// response body
if(http.ResponseText != null)
{
writer.WriteLine(http.ResponseText);
}
else if(http.ResponseBody != null)
{
writer.WriteLine(Utils.BytesToString(http.ResponseBody, http.ResponseLength));
}
 
writer.WriteLine("===============================================================");
writer.WriteLine();
}
}
 
private class XmlNodeData : TreeNodeData
{
private XmlMessage xml;
 
public XmlMessage Xml
{
get { return xml; }
set { xml = value; }
}
 
public XmlNodeData(MainForm owner, TreeNode node) : base(owner, node)
{
}
 
protected override void InitView()
{
try
{
// update main screen if necessary
owner.messagesBox.BeginUpdate();
 
lock(xml)
{
owner.messagesBox.Clear();
if(xml.ParseException != null)
{
owner.messagesBox.AppendText("Cannot parse XML:",
Color.Red, Color.Transparent, false, false, 0, 0);
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText(xml.ParseException.Message,
Color.Red, Color.Transparent, false, false, 2, 2);
owner.messagesBox.AppendNewLine();
}
else if(xml.Xml != null)
{
ShowXmlNode(xml.Xml, 0);
}
}
}
finally
{
owner.messagesBox.EndUpdate();
}
}
 
protected override void UpdateView()
{
}
 
private void ShowXmlNode(XmlNode node, int indent)
{
if(node.NodeType == XmlNodeType.Document)
{
foreach(XmlNode subnode in node.ChildNodes)
{
ShowXmlNode(subnode, indent);
}
}
else if(node.NodeType == XmlNodeType.XmlDeclaration)
{
owner.messagesBox.AppendText("<?" + node.Name + " " + node.Value + " ?>",
Color.Blue, Color.Transparent, false, false, indent, indent+2);
owner.messagesBox.AppendNewLine();
}
else if(node.NodeType == XmlNodeType.Comment)
{
owner.messagesBox.AppendText("<!--", Color.Gray, Color.Transparent, false, false, indent, indent + 2);
ShowNormalizedXmlValue(node.Value, Color.Gray, Color.Thistle, false, false, indent);
owner.messagesBox.AppendText("-->", Color.Gray, Color.Transparent, false, false, 0, indent + 2);
owner.messagesBox.AppendNewLine();
}
else if(node.NodeType == XmlNodeType.Element)
{
owner.messagesBox.AppendText("<", Color.Blue, Color.Transparent, false, false, indent, indent + 2);
owner.messagesBox.AppendText(node.Name, Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
 
foreach(XmlAttribute attr in node.Attributes)
{
bool xmlAttr = attr.Name.StartsWith("xml");
owner.messagesBox.AppendText(attr.Name, xmlAttr ? Color.Red : Color.DarkRed, Color.Transparent, false, false, 1, indent + 2);
owner.messagesBox.AppendText("=\"", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
owner.messagesBox.AppendText(attr.Value, xmlAttr ? Color.Red : Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
owner.messagesBox.AppendText("\"", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
}
 
if(!node.HasChildNodes)
{
owner.messagesBox.AppendText(" />", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
owner.messagesBox.AppendNewLine();
}
else
{
owner.messagesBox.AppendText(">", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
 
bool elementExists = false;
bool lastText = true;
foreach(XmlNode subnode in node.ChildNodes)
{
if(subnode.NodeType == XmlNodeType.Text)
{
if(elementExists) owner.messagesBox.AppendNewLine();
ShowNormalizedXmlValue(subnode.Value, Color.Black, Color.LightGray, false, false, indent);
lastText = true;
}
else
{
if(lastText) owner.messagesBox.AppendNewLine();
ShowXmlNode(subnode, indent + 2);
elementExists = true;
lastText = false;
}
}
 
if(elementExists) owner.messagesBox.AppendText(null, Color.Black, Color.Transparent, false, false, indent, indent + 2);
owner.messagesBox.AppendText("</", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
owner.messagesBox.AppendText(node.Name, Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
owner.messagesBox.AppendText(">", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
owner.messagesBox.AppendNewLine();
}
}
}
 
private void ShowNormalizedXmlValue(string s, Color color, Color backColor, bool italic, bool bold, int indent)
{
int begin;
int end;
 
bool newLineFound = false;
foreach(char c in s)
{
if(c == '\n')
{
newLineFound = true;
break;
}
}
 
if(newLineFound)
{
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent);
owner.messagesBox.AppendText(null, color, backColor, italic, bold, 2, 2);
}
 
// trim
for(begin = 0; begin < s.Length; begin++)
{
char c = s[begin];
if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
}
for(end = s.Length-1; end >= 0; end--)
{
char c = s[end];
if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
}
 
StringBuilder b = new StringBuilder(s.Length);
for(int i = begin; i <= end; i++)
{
char c = s[i];
 
switch(c)
{
case '\n':
if(b.Length > 0)
{
owner.messagesBox.AppendText(b.ToString(), color, backColor, italic, bold, 0, indent + 2);
b.Length = 0;
}
 
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent);
owner.messagesBox.AppendText(null, color, backColor, italic, bold, 2, 2);
break;
 
case '\r':
break;
 
case '\t':
b.Append(" ");
break;
 
default:
b.Append(c);
break;
}
}
 
if(b.Length > 0)
owner.messagesBox.AppendText(b.ToString(), color, backColor, italic, bold, 0, indent + 2);
 
if(newLineFound)
{
owner.messagesBox.AppendNewLine();
owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent + 2);
}
}
 
public override void WriteLog(StreamWriter writer)
{
WriteXmlNode(writer, xml.Xml, "");
writer.WriteLine("===============================================================");
writer.WriteLine();
}
 
private void WriteXmlNode(StreamWriter writer, XmlNode node, string indent)
{
if(node.NodeType == XmlNodeType.Document)
{
foreach(XmlNode subnode in node.ChildNodes)
{
WriteXmlNode(writer, subnode, indent);
}
}
else if(node.NodeType == XmlNodeType.XmlDeclaration)
{
writer.WriteLine(indent + "<?" + node.Name + " " + node.Value + " ?>");
}
else if(node.NodeType == XmlNodeType.Comment)
{
writer.Write(indent + "<!--");
WriteNormalizedXmlValue(writer, node.Value, indent);
writer.WriteLine("-->");
}
else if(node.NodeType == XmlNodeType.Element)
{
writer.Write(indent + "<" + node.Name);
 
foreach(XmlAttribute attr in node.Attributes)
{
bool xmlAttr = attr.Name.StartsWith("xml");
writer.Write(" " + attr.Name + "=\"" + attr.Value + "\"");
}
 
if(!node.HasChildNodes)
{
writer.WriteLine(" />");
}
else
{
writer.Write(">");
 
bool elementExists = false;
bool lastText = true;
foreach(XmlNode subnode in node.ChildNodes)
{
if(subnode.NodeType == XmlNodeType.Text)
{
if(elementExists) writer.WriteLine();
WriteNormalizedXmlValue(writer, subnode.Value, indent);
lastText = true;
}
else
{
if(lastText) writer.WriteLine();
WriteXmlNode(writer, subnode, indent + " ");
elementExists = true;
lastText = false;
}
}
 
if(elementExists) writer.Write(indent);
writer.WriteLine("</" + node.Name + ">");
}
}
}
 
private void WriteNormalizedXmlValue(StreamWriter writer, string s, string indent)
{
int begin;
int end;
 
bool newLineFound = false;
foreach(char c in s)
{
if(c == '\n')
{
newLineFound = true;
break;
}
}
 
if(newLineFound)
{
writer.WriteLine();
writer.Write(indent + " ");
}
 
// trim
for(begin = 0; begin < s.Length; begin++)
{
char c = s[begin];
if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
}
for(end = s.Length-1; end >= 0; end--)
{
char c = s[end];
if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
}
 
StringBuilder b = new StringBuilder(s.Length);
for(int i = begin; i <= end; i++)
{
char c = s[i];
 
switch(c)
{
case '\n':
if(b.Length > 0)
{
writer.Write(b.ToString());
b.Length = 0;
}
 
writer.WriteLine();
writer.Write(indent + " ");
break;
 
case '\r':
break;
 
case '\t':
b.Append(" ");
break;
 
case '&':
b.Append("&amp;");
break;
 
case '<':
b.Append("&lt;");
break;
 
case '>':
b.Append("&gt;");
break;
 
default:
b.Append(c);
break;
}
}
 
if(b.Length > 0)
writer.Write(b.ToString());
 
if(newLineFound)
{
writer.WriteLine();
writer.Write(indent + " ");
}
}
}
 
#endregion node display classes
 
#region other classes
private abstract class Utils
{
public static string BytesToString(byte[] bytes, int length)
{
if(bytes == null) return null;
 
char[] chars = new char[length + 1];
Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();
int charLen = decoder.GetChars(bytes, 0, length, chars, 0);
 
for(int i = 0; i < charLen; i++)
{
char c = chars[i];
if(c != '\n' && c != '\r' && Char.IsControl(c)) chars[i] = '.';
}
 
return (new System.String(chars)).Substring(0, charLen);
}
 
public static ArrayList SplitLine(string line)
{
if(line == null) return null;
 
ArrayList res = new ArrayList();
StringBuilder b = new StringBuilder(200);
 
foreach(char c in line)
{
switch(c)
{
case '\r':
break;
 
case '\n':
res.Add(b.ToString());
b.Length = 0;
break;
 
default:
b.Append(c);
break;
}
}
 
res.Add(b.ToString());
 
return res;
}
}
#endregion other classes
}
 
public class LogMessages
{
private ArrayList messages = new ArrayList();
private ListBox logBox;
private LogLevel level = LogLevel.Debug;
 
public LogLevel Level
{
get { return level; }
set { level = value; Update(); }
}
 
public LogMessages(ListBox logBox)
{
this.logBox = logBox;
}
 
public ArrayList Messages
{
get { return new ArrayList(messages); }
}
 
public void Add(LogMessage message)
{
messages.Add(message);
if(Show(message))
logBox.TopIndex = logBox.Items.Count - 1;
}
 
public void Clear()
{
messages.Clear();
logBox.Items.Clear();
}
 
public void Update()
{
logBox.BeginUpdate();
 
logBox.Items.Clear();
foreach(LogMessage message in messages)
{
Show(message);
}
logBox.TopIndex = logBox.Items.Count - 1;
 
logBox.EndUpdate();
}
 
private bool Show(LogMessage message)
{
if(message.Level > this.level) return false;
 
try
{
logBox.Items.Add(message.ToString());
}
catch(ObjectDisposedException) {}
 
return true;
}
}
 
public class LogMessage
{
private TcpConnection tcp;
private LogLevel level;
private string message;
private Exception exception;
private DateTime timestamp = DateTime.Now;
 
public TcpConnection Tcp
{
get { return tcp; }
set { tcp = value; }
}
 
public LogLevel Level
{
get { return level; }
set { level = value; }
}
 
public string Message
{
get { return message; }
set { message = value; }
}
 
public Exception Exception
{
get { return exception; }
set { exception = value; }
}
 
public DateTime Timestamp
{
get { return timestamp; }
set { timestamp = value; }
}
 
public LogMessage(TcpConnection tcp, LogLevel level, string message, Exception exception)
{
this.tcp = tcp;
this.level = level;
this.message = message;
this.exception = exception;
}
 
public override string ToString()
{
string l = " ";
switch(level)
{
case LogLevel.Debug: l = "debug"; break;
case LogLevel.Info: l = "info "; break;
case LogLevel.Important: l = "Imp "; break;
case LogLevel.Warning: l = "Warn "; break;
case LogLevel.Error: l = "ERROR"; break;
case LogLevel.Critical: l = "CRIT "; break;
}
 
return (tcp == null ? "...." : tcp.Id) + " " + l + " " + timestamp.ToString("HH:mm:ss.ffff") + " "
+ (exception != null ? exception.Message : message);
}
}
 
public enum TcpShowMode
{
ByDirection,
ByTime
}
}