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("&"); |
break; |
|
case '<': |
b.Append("<"); |
break; |
|
case '>': |
b.Append(">"); |
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 |
} |
} |