Subversion Repositories general

Rev

Rev 1197 | Rev 1199 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1092 dev 1
using System;
2
using System.Drawing;
3
using System.Collections;
4
using System.Windows.Forms;
5
using System.IO;
6
using System.Net;
7
using System.Text;
8
using System.Text.RegularExpressions;
9
using System.Xml;
10
 
11
// FIXME:
12
//   - add soap validation
13
//   - icons for all items in the tree
14
//   - use pool of threads?
15
//   - do not store intermediate info, just row packets and the parsed fragments to display
16
//   - make the text fragment store switchable
1125 dev 17
//   - save/restore window layout
1092 dev 18
namespace TCPproxy
19
{
20
	public class MainForm : System.Windows.Forms.Form
21
	{
1194 dev 22
		#region constants and settings
1197 dev 23
 
1194 dev 24
		private const int RECENT_LENGTH = 5;
25
 
26
		#endregion constants and settings
27
 
1125 dev 28
		#region private fields
29
 
1194 dev 30
		private ListenForm   listenForm     = new ListenForm();
1125 dev 31
		private TcpListener  tcpListener    = null;
32
		private LogMessages  logMessages    = null;
33
		private Hashtable    treeNodes      = new Hashtable();
1194 dev 34
		private ArrayList    recentItems    = new ArrayList();
1125 dev 35
 
1194 dev 36
        private int          listenPort;
37
        private string       resendHost;
38
        private int          resendPort;
1125 dev 39
		private TcpShowMode  tcpShowMode    = TcpShowMode.ByDirection;
40
		private bool         autoExpand     = true;
41
 
1194 dev 42
		private string       defaultCaption;
43
 
1125 dev 44
		#endregion private fields
45
 
46
		#region web forms fields
1194 dev 47
        private System.ComponentModel.IContainer components;
1092 dev 48
		private System.Windows.Forms.SaveFileDialog saveLogDialog;
1194 dev 49
        private System.Windows.Forms.StatusBarPanel connectionStatusBar;
50
        private System.Windows.Forms.MenuItem selectAllmenuItem;
51
        private System.Windows.Forms.MenuItem copyMenuItem;
52
        private System.Windows.Forms.ContextMenu viewContextMenu;
53
        private System.Windows.Forms.MenuItem closeConnectionMenuItem;
1092 dev 54
		private System.Windows.Forms.ImageList saveButtonImageList;
1194 dev 55
        private System.Windows.Forms.StatusBar statusBar;
56
        private System.Windows.Forms.ContextMenu messagesContextMenu;
1092 dev 57
		private System.Windows.Forms.ImageList treeImageList;
58
		private System.Windows.Forms.MenuItem wordWrapMenuItem;
1197 dev 59
        private MainMenu mainMenu;
60
        private MenuItem fileMenu;
61
        private MenuItem loadBinLogMenuItem;
62
        private MenuItem saveBinLogMenuItem;
63
        private MenuItem menuSeparator1;
64
        private MenuItem exitMenuItem;
65
        private MenuItem viewMenu;
66
        private MenuItem clearMainMenuItem;
67
        private MenuItem messagesMenu;
68
        private MenuItem saveFullLogMenuItem;
69
        private MenuItem saveTcoLogMenuItem;
70
        private MenuItem saveHttpLogMenuItem;
71
        private MenuItem saveXmlLogMenuItem;
72
        private MenuItem menuSeparator2;
73
        private MenuItem allMessagesMenuItem;
74
        private MenuItem importantMessagesMenuItem;
75
        private MenuItem infoMessagesMenuItem;
76
        private MenuItem menuSeparator3;
77
        private MenuItem tcpShowByDirectionMenuItem;
78
        private MenuItem tcpShowByTimeMenuItem;
79
        private MenuItem menuSeparator4;
80
        private MenuItem autoExpandMenuItem;
81
        private MenuItem wordWrapMainMenuItem;
82
        private MenuItem helpMenu;
1194 dev 83
        private Panel panel1;
84
        private Panel panel3;
85
        private Panel panel4;
86
        private ViewControl messagesBox;
87
        private Splitter splitter2;
88
        private ListBox logBox;
89
        private Splitter splitter1;
90
        private TreeView messageView;
1197 dev 91
        private MenuItem startMenuItem;
92
        private MenuItem stopMenuItem;
93
        private MenuItem menuSeparator5;
94
		private MenuItem recentListeningMenu;
95
		private MenuItem recentListeningNoItem;
96
        private MenuItem aboutMenuItem;
1092 dev 97
		#endregion web forms fields
98
 
99
		#region Windows Form Designer generated code
100
		/// <summary>
101
		/// Required method for Designer support - do not modify
102
		/// the contents of this method with the code editor.
103
		/// </summary>
104
		private void InitializeComponent() {
105
			this.components = new System.ComponentModel.Container();
1194 dev 106
			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
1092 dev 107
			this.wordWrapMenuItem = new System.Windows.Forms.MenuItem();
108
			this.treeImageList = new System.Windows.Forms.ImageList(this.components);
109
			this.messagesContextMenu = new System.Windows.Forms.ContextMenu();
1194 dev 110
			this.selectAllmenuItem = new System.Windows.Forms.MenuItem();
111
			this.copyMenuItem = new System.Windows.Forms.MenuItem();
1092 dev 112
			this.statusBar = new System.Windows.Forms.StatusBar();
1194 dev 113
			this.connectionStatusBar = new System.Windows.Forms.StatusBarPanel();
1092 dev 114
			this.saveButtonImageList = new System.Windows.Forms.ImageList(this.components);
115
			this.closeConnectionMenuItem = new System.Windows.Forms.MenuItem();
1194 dev 116
			this.viewContextMenu = new System.Windows.Forms.ContextMenu();
117
			this.saveLogDialog = new System.Windows.Forms.SaveFileDialog();
1197 dev 118
			this.mainMenu = new System.Windows.Forms.MainMenu();
119
			this.fileMenu = new System.Windows.Forms.MenuItem();
120
			this.startMenuItem = new System.Windows.Forms.MenuItem();
121
			this.stopMenuItem = new System.Windows.Forms.MenuItem();
122
			this.menuSeparator5 = new System.Windows.Forms.MenuItem();
123
			this.loadBinLogMenuItem = new System.Windows.Forms.MenuItem();
124
			this.saveBinLogMenuItem = new System.Windows.Forms.MenuItem();
125
			this.menuSeparator1 = new System.Windows.Forms.MenuItem();
126
			this.saveFullLogMenuItem = new System.Windows.Forms.MenuItem();
127
			this.saveTcoLogMenuItem = new System.Windows.Forms.MenuItem();
128
			this.saveHttpLogMenuItem = new System.Windows.Forms.MenuItem();
129
			this.saveXmlLogMenuItem = new System.Windows.Forms.MenuItem();
130
			this.menuSeparator2 = new System.Windows.Forms.MenuItem();
131
			this.exitMenuItem = new System.Windows.Forms.MenuItem();
132
			this.viewMenu = new System.Windows.Forms.MenuItem();
133
			this.clearMainMenuItem = new System.Windows.Forms.MenuItem();
134
			this.messagesMenu = new System.Windows.Forms.MenuItem();
135
			this.allMessagesMenuItem = new System.Windows.Forms.MenuItem();
136
			this.infoMessagesMenuItem = new System.Windows.Forms.MenuItem();
137
			this.importantMessagesMenuItem = new System.Windows.Forms.MenuItem();
138
			this.menuSeparator3 = new System.Windows.Forms.MenuItem();
139
			this.tcpShowByDirectionMenuItem = new System.Windows.Forms.MenuItem();
140
			this.tcpShowByTimeMenuItem = new System.Windows.Forms.MenuItem();
141
			this.menuSeparator4 = new System.Windows.Forms.MenuItem();
142
			this.autoExpandMenuItem = new System.Windows.Forms.MenuItem();
143
			this.wordWrapMainMenuItem = new System.Windows.Forms.MenuItem();
144
			this.helpMenu = new System.Windows.Forms.MenuItem();
145
			this.aboutMenuItem = new System.Windows.Forms.MenuItem();
1092 dev 146
			this.panel1 = new System.Windows.Forms.Panel();
147
			this.panel3 = new System.Windows.Forms.Panel();
1194 dev 148
			this.panel4 = new System.Windows.Forms.Panel();
1092 dev 149
			this.messagesBox = new TCPproxy.ViewControl();
1194 dev 150
			this.splitter2 = new System.Windows.Forms.Splitter();
1092 dev 151
			this.logBox = new System.Windows.Forms.ListBox();
1194 dev 152
			this.splitter1 = new System.Windows.Forms.Splitter();
153
			this.messageView = new System.Windows.Forms.TreeView();
1197 dev 154
			this.recentListeningMenu = new System.Windows.Forms.MenuItem();
155
			this.recentListeningNoItem = new System.Windows.Forms.MenuItem();
1194 dev 156
			((System.ComponentModel.ISupportInitialize)(this.connectionStatusBar)).BeginInit();
1092 dev 157
			this.panel1.SuspendLayout();
158
			this.panel3.SuspendLayout();
1194 dev 159
			this.panel4.SuspendLayout();
1092 dev 160
			this.SuspendLayout();
1197 dev 161
			//
1092 dev 162
			// wordWrapMenuItem
1197 dev 163
			//
1194 dev 164
			this.wordWrapMenuItem.Index = 2;
1092 dev 165
			this.wordWrapMenuItem.Text = "Word &Wrap";
166
			this.wordWrapMenuItem.Click += new System.EventHandler(this.wordWrapMenuItem_Click);
1197 dev 167
			//
1092 dev 168
			// treeImageList
1197 dev 169
			//
1194 dev 170
			this.treeImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("treeImageList.ImageStream")));
171
			this.treeImageList.TransparentColor = System.Drawing.Color.Magenta;
1197 dev 172
			//
1092 dev 173
			// messagesContextMenu
1197 dev 174
			//
1092 dev 175
			this.messagesContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
1194 dev 176
            this.selectAllmenuItem,
177
            this.copyMenuItem,
178
            this.wordWrapMenuItem});
1197 dev 179
			//
1194 dev 180
			// selectAllmenuItem
1197 dev 181
			//
1194 dev 182
			this.selectAllmenuItem.Index = 0;
183
			this.selectAllmenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlA;
184
			this.selectAllmenuItem.Text = "Select &All";
185
			this.selectAllmenuItem.Click += new System.EventHandler(this.selectAllMenuItem_Click);
1197 dev 186
			//
1194 dev 187
			// copyMenuItem
1197 dev 188
			//
1194 dev 189
			this.copyMenuItem.Index = 1;
190
			this.copyMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlC;
191
			this.copyMenuItem.Text = "&Copy";
192
			this.copyMenuItem.Click += new System.EventHandler(this.copyMenuItem_Click);
1197 dev 193
			//
1092 dev 194
			// statusBar
1197 dev 195
			//
1092 dev 196
			this.statusBar.Location = new System.Drawing.Point(0, 619);
197
			this.statusBar.Name = "statusBar";
198
			this.statusBar.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
1194 dev 199
            this.connectionStatusBar});
1092 dev 200
			this.statusBar.ShowPanels = true;
201
			this.statusBar.Size = new System.Drawing.Size(780, 22);
202
			this.statusBar.TabIndex = 0;
1197 dev 203
			//
1194 dev 204
			// connectionStatusBar
1197 dev 205
			//
1194 dev 206
			this.connectionStatusBar.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
207
			this.connectionStatusBar.Width = 764;
1197 dev 208
			//
1092 dev 209
			// saveButtonImageList
1197 dev 210
			//
1194 dev 211
			this.saveButtonImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("saveButtonImageList.ImageStream")));
212
			this.saveButtonImageList.TransparentColor = System.Drawing.Color.Magenta;
1197 dev 213
			//
1092 dev 214
			// closeConnectionMenuItem
1197 dev 215
			//
1092 dev 216
			this.closeConnectionMenuItem.Index = 0;
217
			this.closeConnectionMenuItem.Text = "&Close connection";
218
			this.closeConnectionMenuItem.Click += new System.EventHandler(this.closeConnectionMenuItem_Click);
1197 dev 219
			//
1194 dev 220
			// viewContextMenu
1197 dev 221
			//
1194 dev 222
			this.viewContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
223
            this.closeConnectionMenuItem});
1197 dev 224
			//
1194 dev 225
			// saveLogDialog
1197 dev 226
			//
1194 dev 227
			this.saveLogDialog.DefaultExt = "txt";
228
			this.saveLogDialog.Filter = "Text Files|*.txt|All Files|*.*";
229
			this.saveLogDialog.Title = "Save Log";
1197 dev 230
			//
1194 dev 231
			// mainMenu
1197 dev 232
			//
233
			this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
234
	            this.fileMenu,
235
	            this.viewMenu,
236
	            this.helpMenu});
237
			//
1194 dev 238
			// fileMenu
1197 dev 239
			//
240
			this.fileMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
241
	            this.startMenuItem,
242
	            this.stopMenuItem,
243
	            this.recentListeningMenu,
244
	            this.menuSeparator5,
245
	            this.loadBinLogMenuItem,
246
	            this.saveBinLogMenuItem,
247
	            this.menuSeparator1,
248
	            this.saveFullLogMenuItem,
249
	            this.saveTcoLogMenuItem,
250
	            this.saveHttpLogMenuItem,
251
	            this.saveXmlLogMenuItem,
252
	            this.menuSeparator2,
253
	            this.exitMenuItem});
1194 dev 254
			this.fileMenu.Text = "File";
1197 dev 255
			//
1194 dev 256
			// startMenuItem
1197 dev 257
			//
1194 dev 258
			this.startMenuItem.Text = "Start...";
259
			this.startMenuItem.Click += new System.EventHandler(this.startMenuItem_Click);
1197 dev 260
			//
1194 dev 261
			// stopMenuItem
1197 dev 262
			//
1194 dev 263
			this.stopMenuItem.Enabled = false;
264
			this.stopMenuItem.Text = "Stop";
265
			this.stopMenuItem.Click += new System.EventHandler(this.stopMenuItem_Click);
1197 dev 266
			//
1194 dev 267
			// menuSeparator5
1197 dev 268
			//
269
			this.menuSeparator5.Text = "-";
270
			//
1194 dev 271
			// loadBinLogMenuItem
1197 dev 272
			//
1194 dev 273
			this.loadBinLogMenuItem.Text = "Load Bin Log...";
1197 dev 274
			//
1194 dev 275
			// saveBinLogMenuItem
1197 dev 276
			//
1194 dev 277
			this.saveBinLogMenuItem.Text = "Save Bin Log...";
278
			this.saveBinLogMenuItem.Click += new System.EventHandler(this.saveBinLogMenuItem_Click);
1197 dev 279
			//
1194 dev 280
			// menuSeparator1
1197 dev 281
			//
282
			this.menuSeparator1.Text = "-";
283
			//
1194 dev 284
			// saveFullLogMenuItem
1197 dev 285
			//
1194 dev 286
			this.saveFullLogMenuItem.Text = "Save Full Text Log...";
287
			this.saveFullLogMenuItem.Click += new System.EventHandler(this.saveLogMenuItem_Click);
1197 dev 288
			//
1194 dev 289
			// saveTcoLogMenuItem
1197 dev 290
			//
1194 dev 291
			this.saveTcoLogMenuItem.Text = "Save TCP Log...";
292
			this.saveTcoLogMenuItem.Click += new System.EventHandler(this.saveTcpMenuItem_Click);
1197 dev 293
			//
1194 dev 294
			// saveHttpLogMenuItem
1197 dev 295
			//
1194 dev 296
			this.saveHttpLogMenuItem.Text = "Save Http Log...";
297
			this.saveHttpLogMenuItem.Click += new System.EventHandler(this.saveHttpMenuItem_Click);
1197 dev 298
			//
1194 dev 299
			// saveXmlLogMenuItem
1197 dev 300
			//
1194 dev 301
			this.saveXmlLogMenuItem.Text = "Save XML Log...";
302
			this.saveXmlLogMenuItem.Click += new System.EventHandler(this.saveXmlMenuItem_Click);
1197 dev 303
			//
1194 dev 304
			// menuSeparator2
1197 dev 305
			//
306
			this.menuSeparator2.Text = "-";
307
			//
1194 dev 308
			// exitMenuItem
1197 dev 309
			//
1194 dev 310
			this.exitMenuItem.Text = "Exit";
1197 dev 311
			//
1194 dev 312
			// viewMenu
1197 dev 313
			//
314
			this.viewMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
315
	            this.clearMainMenuItem,
316
	            this.messagesMenu,
317
	            this.menuSeparator3,
318
	            this.tcpShowByDirectionMenuItem,
319
	            this.tcpShowByTimeMenuItem,
320
	            this.menuSeparator4,
321
	            this.autoExpandMenuItem,
322
	            this.wordWrapMainMenuItem});
1194 dev 323
			this.viewMenu.Text = "View";
1197 dev 324
			//
1194 dev 325
			// clearMainMenuItem
1197 dev 326
			//
1194 dev 327
			this.clearMainMenuItem.Text = "Clear";
328
			this.clearMainMenuItem.Click += new System.EventHandler(this.clearMenuItem_Click);
1197 dev 329
			//
1194 dev 330
			// messagesMenu
1197 dev 331
			//
332
			this.messagesMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
333
	            this.allMessagesMenuItem,
334
	            this.infoMessagesMenuItem,
335
	            this.importantMessagesMenuItem});
1194 dev 336
			this.messagesMenu.Text = "Messages";
1197 dev 337
			//
1194 dev 338
			// allMessagesMenuItem
1197 dev 339
			//
1194 dev 340
			this.allMessagesMenuItem.Checked = true;
341
			this.allMessagesMenuItem.Text = "All";
342
			this.allMessagesMenuItem.Click += new System.EventHandler(this.messagesMenuItem_Click);
1197 dev 343
			//
1194 dev 344
			// infoMessagesMenuItem
1197 dev 345
			//
1194 dev 346
			this.infoMessagesMenuItem.Text = "Info";
347
			this.infoMessagesMenuItem.Click += new System.EventHandler(this.messagesMenuItem_Click);
1197 dev 348
			//
1194 dev 349
			// importantMessagesMenuItem
1197 dev 350
			//
1194 dev 351
			this.importantMessagesMenuItem.Text = "Important";
352
			this.importantMessagesMenuItem.Click += new System.EventHandler(this.messagesMenuItem_Click);
1197 dev 353
			//
1194 dev 354
			// menuSeparator3
1197 dev 355
			//
356
			this.menuSeparator3.Text = "-";
357
			//
1194 dev 358
			// tcpShowByDirectionMenuItem
1197 dev 359
			//
1194 dev 360
			this.tcpShowByDirectionMenuItem.Checked = true;
361
			this.tcpShowByDirectionMenuItem.Text = "TCP Show by Direction";
362
			this.tcpShowByDirectionMenuItem.Click += new System.EventHandler(this.tcpShowByDirectionMenuItem_Click);
1197 dev 363
			//
1194 dev 364
			// tcpShowByTimeMenuItem
1197 dev 365
			//
1194 dev 366
			this.tcpShowByTimeMenuItem.Text = "TCP Show by Time";
367
			this.tcpShowByTimeMenuItem.Click += new System.EventHandler(this.tcpShowByTimeMenuItem_Click);
1197 dev 368
			//
1194 dev 369
			// menuSeparator4
1197 dev 370
			//
371
			this.menuSeparator4.Text = "-";
372
			//
1194 dev 373
			// autoExpandMenuItem
1197 dev 374
			//
1194 dev 375
			this.autoExpandMenuItem.Text = "Auto Expand";
376
			this.autoExpandMenuItem.Click += new System.EventHandler(this.autoExpandMenuItem_Click);
1197 dev 377
			//
1194 dev 378
			// wordWrapMainMenuItem
1197 dev 379
			//
1194 dev 380
			this.wordWrapMainMenuItem.Text = "Word Wrap";
381
			this.wordWrapMainMenuItem.Click += new System.EventHandler(this.wordWrapMenuItem_Click);
1197 dev 382
			//
1194 dev 383
			// helpMenu
1197 dev 384
			//
385
			this.helpMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
386
            	this.aboutMenuItem});
1194 dev 387
			this.helpMenu.Text = "Help";
1197 dev 388
			//
1194 dev 389
			// aboutMenuItem
1197 dev 390
			//
1194 dev 391
			this.aboutMenuItem.Text = "About...";
392
			this.aboutMenuItem.Click += new System.EventHandler(this.aboutMenuItem_Click);
1197 dev 393
			//
1092 dev 394
			// panel1
1197 dev 395
			//
1092 dev 396
			this.panel1.Controls.Add(this.panel3);
397
			this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
1194 dev 398
			this.panel1.Location = new System.Drawing.Point(0, 24);
1092 dev 399
			this.panel1.Name = "panel1";
1194 dev 400
			this.panel1.Size = new System.Drawing.Size(780, 595);
401
			this.panel1.TabIndex = 11;
1197 dev 402
			//
1092 dev 403
			// panel3
1197 dev 404
			//
1092 dev 405
			this.panel3.Controls.Add(this.panel4);
406
			this.panel3.Controls.Add(this.splitter1);
407
			this.panel3.Controls.Add(this.messageView);
408
			this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
409
			this.panel3.Location = new System.Drawing.Point(0, 0);
410
			this.panel3.Name = "panel3";
1194 dev 411
			this.panel3.Size = new System.Drawing.Size(780, 595);
1092 dev 412
			this.panel3.TabIndex = 5;
1197 dev 413
			//
1194 dev 414
			// panel4
1197 dev 415
			//
1194 dev 416
			this.panel4.Controls.Add(this.messagesBox);
417
			this.panel4.Controls.Add(this.splitter2);
418
			this.panel4.Controls.Add(this.logBox);
419
			this.panel4.Dock = System.Windows.Forms.DockStyle.Fill;
420
			this.panel4.Location = new System.Drawing.Point(163, 0);
421
			this.panel4.Name = "panel4";
422
			this.panel4.Size = new System.Drawing.Size(617, 595);
423
			this.panel4.TabIndex = 13;
1197 dev 424
			//
1092 dev 425
			// messagesBox
1197 dev 426
			//
1092 dev 427
			this.messagesBox.ContextMenu = this.messagesContextMenu;
428
			this.messagesBox.Dock = System.Windows.Forms.DockStyle.Fill;
1194 dev 429
			this.messagesBox.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
1092 dev 430
			this.messagesBox.Location = new System.Drawing.Point(0, 0);
431
			this.messagesBox.Name = "messagesBox";
1194 dev 432
			this.messagesBox.Size = new System.Drawing.Size(617, 524);
1092 dev 433
			this.messagesBox.TabIndex = 7;
434
			this.messagesBox.WordWrap = true;
1197 dev 435
			//
1194 dev 436
			// splitter2
1197 dev 437
			//
1194 dev 438
			this.splitter2.Dock = System.Windows.Forms.DockStyle.Bottom;
439
			this.splitter2.Location = new System.Drawing.Point(0, 524);
440
			this.splitter2.Name = "splitter2";
441
			this.splitter2.Size = new System.Drawing.Size(617, 3);
442
			this.splitter2.TabIndex = 9;
443
			this.splitter2.TabStop = false;
1197 dev 444
			//
1092 dev 445
			// logBox
1197 dev 446
			//
1092 dev 447
			this.logBox.Dock = System.Windows.Forms.DockStyle.Bottom;
1194 dev 448
			this.logBox.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
1092 dev 449
			this.logBox.HorizontalScrollbar = true;
450
			this.logBox.ItemHeight = 16;
1194 dev 451
			this.logBox.Location = new System.Drawing.Point(0, 527);
1092 dev 452
			this.logBox.Name = "logBox";
453
			this.logBox.ScrollAlwaysVisible = true;
454
			this.logBox.Size = new System.Drawing.Size(617, 68);
455
			this.logBox.TabIndex = 8;
1197 dev 456
			//
1194 dev 457
			// splitter1
1197 dev 458
			//
1194 dev 459
			this.splitter1.Location = new System.Drawing.Point(160, 0);
460
			this.splitter1.Name = "splitter1";
461
			this.splitter1.Size = new System.Drawing.Size(3, 595);
462
			this.splitter1.TabIndex = 12;
463
			this.splitter1.TabStop = false;
1197 dev 464
			//
1194 dev 465
			// messageView
1197 dev 466
			//
1194 dev 467
			this.messageView.ContextMenu = this.viewContextMenu;
468
			this.messageView.Dock = System.Windows.Forms.DockStyle.Left;
469
			this.messageView.HideSelection = false;
470
			this.messageView.ImageIndex = 0;
471
			this.messageView.ImageList = this.treeImageList;
472
			this.messageView.Location = new System.Drawing.Point(0, 0);
473
			this.messageView.Name = "messageView";
474
			this.messageView.SelectedImageIndex = 0;
475
			this.messageView.Size = new System.Drawing.Size(160, 595);
476
			this.messageView.TabIndex = 11;
1197 dev 477
			//
1194 dev 478
			// recentListeningMenu
1197 dev 479
			//
480
			this.recentListeningMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
481
            	this.recentListeningNoItem});
1194 dev 482
			this.recentListeningMenu.Text = "Recent Listenings";
1197 dev 483
			//
1194 dev 484
			// recentListeningNoItem
1197 dev 485
			//
1194 dev 486
			this.recentListeningNoItem.Enabled = false;
487
			this.recentListeningNoItem.Text = "(no items)";
1197 dev 488
			//
1092 dev 489
			// MainForm
1197 dev 490
			//
1092 dev 491
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
492
			this.ClientSize = new System.Drawing.Size(780, 641);
493
			this.Controls.Add(this.panel1);
494
			this.Controls.Add(this.statusBar);
1197 dev 495
			this.Menu = this.mainMenu;
1092 dev 496
			this.MinimumSize = new System.Drawing.Size(400, 200);
497
			this.Name = "MainForm";
498
			this.Text = "TCPproxy";
1194 dev 499
			((System.ComponentModel.ISupportInitialize)(this.connectionStatusBar)).EndInit();
1092 dev 500
			this.panel1.ResumeLayout(false);
501
			this.panel3.ResumeLayout(false);
1194 dev 502
			this.panel4.ResumeLayout(false);
1092 dev 503
			this.ResumeLayout(false);
1194 dev 504
			this.PerformLayout();
505
 
1092 dev 506
		}
507
		#endregion
508
 
509
		#region windows forms methods
510
		public MainForm()
511
		{
512
			InitializeComponent();
513
			logMessages = new LogMessages(logBox);
1194 dev 514
			try {
515
				LoadFromRegistry();
516
				LoadRecentItemsFromRegistry();
517
			}
518
			catch(Exception) {}
519
 
520
			// update visual elements
521
			UpdateMessagesMenuItems();
522
 
523
			if(tcpShowMode == TcpShowMode.ByDirection) {
524
				tcpShowByDirectionMenuItem.Checked = true;
525
				tcpShowByTimeMenuItem.Checked      = false;
526
			}
527
			else {
528
				tcpShowByDirectionMenuItem.Checked = false;
529
				tcpShowByTimeMenuItem.Checked      = true;
530
			}
531
 
532
			autoExpandMenuItem.Checked   = autoExpand;
533
			wordWrapMainMenuItem.Checked = messagesBox.WordWrap;
534
 
535
			// save default values
536
			defaultCaption = this.Text;
1092 dev 537
		}
538
 
1194 dev 539
		protected override void Dispose(bool disposing)
1092 dev 540
		{
1194 dev 541
			if(tcpListener != null) {
1092 dev 542
				tcpListener.StopListening();    // stop listening
543
				tcpListener.CancelAll();        // cancel all open connections
544
			}
545
 
1194 dev 546
			// save settings
1197 dev 547
			SaveToRegistry();
1194 dev 548
			SaveRecentItemsToRegistry();
1092 dev 549
 
550
			if( disposing )
551
			{
552
				if (components != null)
553
				{
554
					components.Dispose();
555
				}
556
			}
557
			base.Dispose( disposing );
558
		}
559
 
560
		[STAThread]
561
		static void Main()
562
		{
563
			Application.Run(new MainForm());
564
		}
565
 
1194 dev 566
		private LogLevel ParseLogLevel(string str)
567
		{
568
			if(str == "Important")
569
				return LogLevel.Important;
570
			else if(str == "Info")
571
				return LogLevel.Info;
572
			else
573
				return LogLevel.Debug;
574
		}
575
 
1092 dev 576
		private void LoadFromRegistry()
577
		{
578
			Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
1125 dev 579
				@"Software\Anatoli Klassen\TCPproxy");
1092 dev 580
 
1194 dev 581
			if(subkey == null) return;
1092 dev 582
 
1194 dev 583
			listenPort           = (int)subkey.GetValue("Listen Port", 0);
584
			resendHost           = (string)subkey.GetValue("Resend Host", "");
585
			resendPort           = (int)subkey.GetValue("Resend Port", 0);
586
			logMessages.Level    = ParseLogLevel((string)subkey.GetValue("Messages Level", ""));
587
			autoExpand           = (int)subkey.GetValue("Auto Expand", 1) == 1;
588
			messagesBox.WordWrap = (int)subkey.GetValue("Word Wrap", 1) == 1;
1125 dev 589
 
1194 dev 590
			object tcpShowModeStr  = (object)subkey.GetValue("Tcp Show Mode", TcpShowMode.ByDirection);
591
			tcpShowMode            = (tcpShowModeStr as string) == "ByDirection"
592
				? TcpShowMode.ByDirection : TcpShowMode.ByTime;
593
 
594
//			this.Top   = (int)subkey.GetValue("Window.Top", this.Top);
595
//			this.Left  = (int)subkey.GetValue("Window.Left", this.Left);
596
//			this.Hight = (int)subkey.GetValue("Window.Hight", this.Hight);
597
//			this.Width = (int)subkey.GetValue("Window.Width", this.Width);
598
		}
599
 
600
		private void LoadRecentItemsFromRegistry()
601
		{
602
			Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
603
				@"Software\Anatoli Klassen\TCPproxy\Recent Listenings");
604
 
605
			if(subkey == null) return;
606
 
607
			foreach(string name in subkey.GetValueNames()) {
608
				if(name == "") continue;
609
				AddRecentItem(RecentItem.LoadFromRegistry((string)subkey.GetValue(name, "")));
1092 dev 610
			}
611
		}
612
 
613
		private void SaveToRegistry()
614
		{
615
			Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(
1125 dev 616
				@"Software\Anatoli Klassen\TCPproxy");
1092 dev 617
 
1194 dev 618
			subkey.SetValue("Listen Port",    listenPort);
619
			subkey.SetValue("Resend Host",    resendHost == null ? "" : resendHost);
620
			subkey.SetValue("Resend Port",    resendPort);
621
			subkey.SetValue("Messages Level", logMessages.Level);
622
			subkey.SetValue("Tcp Show Mode",  tcpShowMode);
623
			subkey.SetValue("Auto Expand",    autoExpand ? 1 : 0);
624
			subkey.SetValue("Word Wrap",      messagesBox.WordWrap ? 1 : 0);
1125 dev 625
 
626
			subkey.SetValue("Window.Top",    this.Top);
627
			subkey.SetValue("Window.Left",   this.Left);
628
			subkey.SetValue("Window.Hight",  this.Height);
629
			subkey.SetValue("Window.Width",  this.Width);
1092 dev 630
		}
631
 
1194 dev 632
		private void SaveRecentItemsToRegistry()
1092 dev 633
		{
1194 dev 634
			Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(
635
				@"Software\Anatoli Klassen\TCPproxy\Recent Listenings");
1092 dev 636
 
1194 dev 637
			// load existing from registry
638
			ArrayList old = new ArrayList();
639
			foreach(string name in subkey.GetValueNames()) {
640
				if(name == "") continue;
641
				old.Add(RecentItem.LoadFromRegistry((string)subkey.GetValue(name, "")));
1092 dev 642
			}
643
 
1194 dev 644
			// merge - for the case another program instance has changed the list
645
			foreach(RecentItem item in old) {
646
				int existingIdx = recentItems.IndexOf(item);
647
				if(existingIdx >= 0)
648
					((RecentItem)recentItems[existingIdx]).UpdateTimestamp(item);
649
				else
650
					recentItems.Add(item);
1092 dev 651
			}
652
 
1194 dev 653
			recentItems.Sort();
654
			if(recentItems.Count > 0) // take tail
1197 dev 655
				recentItems = recentItems.GetRange(Math.Max(0, recentItems.Count - RECENT_LENGTH),
1194 dev 656
					Math.Min(recentItems.Count, RECENT_LENGTH));
1092 dev 657
 
1194 dev 658
			int count = 0;
659
			foreach(RecentItem item in recentItems) {
660
				subkey.SetValue(string.Format("{0:0000}", count++), item.SaveToRegistry());
1092 dev 661
			}
1194 dev 662
		}
1092 dev 663
 
1194 dev 664
		private void startMenuItem_Click(object sender, System.EventArgs e)
665
		{
666
			IPAddress resendIp;
667
 
1197 dev 668
			if(!listenForm.Execute(this,
1194 dev 669
				ref listenPort, ref resendHost, out resendIp, ref resendPort)) return;
670
 
671
			StartListening(listenPort, resendIp, resendPort);
672
		}
673
 
674
		private void StartListening(int listenPort, IPAddress resendIp, int resendPort)
675
		{
1092 dev 676
			// listen to the port
677
			try
678
			{
1194 dev 679
				Start(listenPort, resendIp, resendPort);
1092 dev 680
			}
681
			catch(Exception ex)
682
			{
683
				MessageBox.Show("Cannot start listening: " + ex.Message, "TCPproxy",
684
					MessageBoxButtons.OK, MessageBoxIcon.Error);
685
				Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
686
				return;
687
			}
688
 
1194 dev 689
			AddRecentItem(listenPort, resendHost, resendPort);
690
 
691
			startMenuItem.Enabled = false;
692
			stopMenuItem.Enabled  = true;
693
 
1197 dev 694
			foreach(MenuItem subitem in recentListeningMenu.MenuItems) {
1194 dev 695
				subitem.Enabled = false;
696
			}
697
 
1197 dev 698
			this.Text = string.Format("{0}: {1} to {2}:{3}",
1194 dev 699
				defaultCaption, listenPort, resendHost, resendPort);
1092 dev 700
		}
701
 
1194 dev 702
		private void stopMenuItem_Click(object sender, System.EventArgs e)
1092 dev 703
		{
704
			if(tcpListener != null) tcpListener.StopListening();
705
 
1194 dev 706
			startMenuItem.Enabled = true;
707
			stopMenuItem.Enabled  = false;
708
 
1197 dev 709
			if(recentItems.Count > 0) {
710
				foreach(MenuItem subitem in recentListeningMenu.MenuItems) {
711
					subitem.Enabled = true;
712
				}
1194 dev 713
			}
714
 
715
			this.Text = defaultCaption;
1092 dev 716
		}
717
 
1194 dev 718
		private void clearMenuItem_Click(object sender, System.EventArgs e)
1092 dev 719
		{
1125 dev 720
			// close all connetions
721
			foreach(object tcp in treeNodes.Keys)
722
				if(tcp is TcpConnection)
723
					((TcpConnection)tcp).Cancel();
724
 
1092 dev 725
			treeNodes.Clear();
726
			messageView.Nodes.Clear();
727
			messagesBox.Clear();
728
			logMessages.Clear();
729
		}
730
 
731
		private void selectAllMenuItem_Click(object sender, System.EventArgs e)
732
		{
733
			messagesBox.SelectAll();
734
		}
735
 
736
		private void copyMenuItem_Click(object sender, System.EventArgs e)
737
		{
738
			string sel = messagesBox.SelectedText;
739
			if(sel != null) Clipboard.SetDataObject(sel);
740
		}
741
 
742
		private void wordWrapMenuItem_Click(object sender, System.EventArgs e)
743
		{
1194 dev 744
			messagesBox.WordWrap         = !messagesBox.WordWrap;
745
			wordWrapMenuItem.Checked     = messagesBox.WordWrap;
746
			wordWrapMainMenuItem.Checked = messagesBox.WordWrap;
1092 dev 747
		}
748
 
749
		private void autoExpandMenuItem_Click(object sender, System.EventArgs e)
750
		{
1194 dev 751
			autoExpand                 = !autoExpand;
752
			autoExpandMenuItem.Checked = autoExpand;
1092 dev 753
		}
754
 
1194 dev 755
		private void aboutMenuItem_Click(object sender, EventArgs e)
756
		{
757
			(new AboutForm()).ShowDialog(this);
758
		}
759
 
1092 dev 760
		private void messageView_BeforeSelect(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
761
		{
762
			if(messageView.SelectedNode == null) return;
763
 
764
			object tag = messageView.SelectedNode.Tag;
765
			if(tag is TreeNodeData)
766
			{
767
				TreeNodeData data = (TreeNodeData)tag;
768
				data.SaveViewState();
769
			}
770
		}
771
 
772
		private void messageView_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
773
		{
774
			if(messageView.SelectedNode == null) return;
775
 
776
			object tag = messageView.SelectedNode.Tag;
777
			if(tag is TreeNodeData)
778
			{
779
				TreeNodeData data = (TreeNodeData)tag;
780
				data.Show();
781
			}
782
		}
783
 
784
		private void closeConnectionMenuItem_Click(object sender, System.EventArgs e)
785
		{
786
			if(messageView.SelectedNode == null) return;
787
 
788
			object tag = messageView.SelectedNode.Tag;
789
			if(tag is TcpNodeData)
790
				CloseTcpConnection(((TcpNodeData)tag).Tcp);
791
			else if(tag is TcpNodeData)
792
				CloseTcpConnection(((TcpNodeData)messageView.SelectedNode.Parent.Tag).Tcp);
793
			else if(tag is XmlNodeData)
794
				CloseTcpConnection(((TcpNodeData)messageView.SelectedNode.Parent.Parent.Tag).Tcp);
795
		}
796
 
797
		private void tcpShowByDirectionMenuItem_Click(object sender, System.EventArgs e)
798
		{
799
			tcpShowMode = TcpShowMode.ByDirection;
1194 dev 800
			tcpShowByDirectionMenuItem.Checked = true;
801
			tcpShowByTimeMenuItem.Checked      = false;
1092 dev 802
 
803
			if(messageView.SelectedNode == null) return;
804
 
805
			object tag = messageView.SelectedNode.Tag;
806
			if(tag is TcpNodeData)
807
				UpdateTcpNodeInternal(((TcpNodeData)tag).Tcp);
808
		}
809
 
810
		private void tcpShowByTimeMenuItem_Click(object sender, System.EventArgs e)
811
		{
812
			tcpShowMode = TcpShowMode.ByTime;
1194 dev 813
			tcpShowByDirectionMenuItem.Checked = false;
814
			tcpShowByTimeMenuItem.Checked      = true;
1092 dev 815
 
816
			if(messageView.SelectedNode == null) return;
817
 
818
			object tag = messageView.SelectedNode.Tag;
819
			if(tag is TcpNodeData)
820
				UpdateTcpNodeInternal(((TcpNodeData)tag).Tcp);
821
		}
822
 
823
		private void saveLogMenuItem_Click(object sender, System.EventArgs e)
824
		{
825
			if(saveLogDialog.ShowDialog() == DialogResult.OK)
826
			{
827
				SaveLog(saveLogDialog.FileName);
828
			}
829
		}
830
 
831
		private void saveTcpMenuItem_Click(object sender, System.EventArgs e)
832
		{
833
			if(saveLogDialog.ShowDialog() == DialogResult.OK)
834
			{
835
				SaveTcp(saveLogDialog.FileName);
836
			}
837
		}
838
 
839
		private void saveHttpMenuItem_Click(object sender, System.EventArgs e)
840
		{
841
			if(saveLogDialog.ShowDialog() == DialogResult.OK)
842
			{
843
				SaveHttp(saveLogDialog.FileName);
844
			}
845
		}
846
 
847
		private void saveXmlMenuItem_Click(object sender, System.EventArgs e)
848
		{
849
			if(saveLogDialog.ShowDialog() == DialogResult.OK)
850
			{
851
				SaveXml(saveLogDialog.FileName);
852
			}
853
		}
854
 
1194 dev 855
		private void messagesMenuItem_Click(object sender, EventArgs e)
1092 dev 856
		{
1194 dev 857
			if(sender == importantMessagesMenuItem)
858
				logMessages.Level = LogLevel.Important;
859
			else if(sender == infoMessagesMenuItem)
860
				logMessages.Level = LogLevel.Info;
861
			else
862
				logMessages.Level = LogLevel.Debug;
1092 dev 863
 
1194 dev 864
			UpdateMessagesMenuItems();
865
		}
1092 dev 866
 
1194 dev 867
		private void saveBinLogMenuItem_Click(object sender, EventArgs e)
868
		{
869
 
1092 dev 870
		}
871
 
1194 dev 872
		private void recentMenuItem_Click(object sender, EventArgs e)
873
		{
1198 dev 874
			int n = recentItems.Count-1;
1197 dev 875
			foreach(MenuItem menuItem in recentListeningMenu.MenuItems) {
876
				if(sender == menuItem) break;
1198 dev 877
				n--;
1197 dev 878
			}
1198 dev 879
			if(n < 0)
1197 dev 880
				throw new Exception("Unknown sender");
881
 
882
			RecentItem recentItem = (RecentItem)recentItems[n];
1194 dev 883
			IPAddress  resendIp;
884
 
885
			this.listenPort = recentItem.ListenPort;
886
			this.resendHost = recentItem.ResendHost;
887
			this.resendPort = recentItem.ResendPort;
1197 dev 888
 
1194 dev 889
			try
890
			{
891
				resendIp = HostUtils.ResendHostToIp(resendHost);
892
			}
893
			catch(Exception ex)
894
			{
895
				MessageBox.Show(ex.Message);
896
				return;
897
			}
898
 
899
			StartListening(listenPort, resendIp, resendPort);
900
		}
901
 
902
		private void UpdateMessagesMenuItems()
903
		{
904
			switch(logMessages.Level) {
905
				case LogLevel.Critical:
906
				case LogLevel.Error:
907
				case LogLevel.Warning:
908
				case LogLevel.Important:
909
					importantMessagesMenuItem.Checked = true;
910
					infoMessagesMenuItem.Checked      = false;
911
					allMessagesMenuItem.Checked       = false;
912
					break;
913
 
914
				case LogLevel.Info:
915
					importantMessagesMenuItem.Checked = false;
916
					infoMessagesMenuItem.Checked      = true;
917
					allMessagesMenuItem.Checked       = false;
918
					break;
919
 
920
				case LogLevel.Debug:
921
					importantMessagesMenuItem.Checked = false;
922
					infoMessagesMenuItem.Checked      = false;
923
					allMessagesMenuItem.Checked       = true;
924
					break;
925
			}
926
		}
927
 
928
		private void AddRecentItem(int listenPort, string resendHost, int resendPort)
929
		{
930
			RecentItem recentItem = new RecentItem(listenPort, resendHost, resendPort);
931
			recentItem.UpdateTimestamp();
932
			AddRecentItem(recentItem);
933
		}
934
 
935
		private void AddRecentItem(RecentItem recentItem)
936
		{
937
			int existingIdx = recentItems.IndexOf(recentItem);
938
			if(existingIdx >= 0) {
1198 dev 939
				recentItems.RemoveAt(existingIdx);
940
				this.recentListeningMenu.MenuItems.RemoveAt(recentItems.Count - existingIdx);
1194 dev 941
			}
942
 
1198 dev 943
			if(recentItems.Count == 0 && this.recentListeningMenu.MenuItems.Count == 1)
1197 dev 944
				this.recentListeningMenu.MenuItems.RemoveAt(0);
945
 
1194 dev 946
			recentItems.Add(recentItem);
947
 
1197 dev 948
			MenuItem menuItem = new MenuItem();
949
			this.recentListeningMenu.MenuItems.Add(0, menuItem);
950
			menuItem.Text   = string.Format("{0} to {1}:{2}",
1194 dev 951
				recentItem.ListenPort, recentItem.ResendHost, recentItem.ResendPort);
952
			menuItem.Click += new System.EventHandler(recentMenuItem_Click);
1198 dev 953
 
954
			// check overflow
955
			if(recentItems.Count > RECENT_LENGTH) {
956
				recentItems.RemoveAt(0);
957
				this.recentListeningMenu.MenuItems.RemoveAt(RECENT_LENGTH-1);
958
			}
1194 dev 959
		}
960
 
1092 dev 961
		#endregion windows forms methods
962
 
963
		#region core methods
964
		private void Start(int listenPort, IPAddress resendHost, int resendPort)
965
		{
966
			if(tcpListener != null) tcpListener.StopListening();
967
 
968
			tcpListener = new TcpListener(listenPort, resendHost, resendPort);
969
			tcpListener.Log    += new TcpLogEventHandler(TcpConnectionLog);
970
			tcpListener.NewTcp += new TcpConnectionEventHandler(AddTcpConnetion);
971
			tcpListener.StartListening();
972
		}
973
 
974
		private void CloseTcpConnection(TcpConnection tcp)
975
		{
976
			if(tcp == null) return;
977
 
978
			tcp.Cancel();
979
		}
980
 
981
		private void SaveLog(string fileName)
982
		{
983
			StreamWriter writer = new StreamWriter(fileName);
984
 
985
			foreach(LogMessage message in logMessages.Messages)
986
			{
987
				writer.WriteLine(message);
988
			}
989
 
990
			writer.Close();
991
		}
992
 
993
		private void SaveTcp(string fileName)
994
		{
995
			StreamWriter writer = new StreamWriter(fileName);
996
 
997
			foreach(TreeNode tcpNode in messageView.Nodes)
998
			{
999
				TcpNodeData data = (TcpNodeData)tcpNode.Tag;
1000
				data.WriteLog(writer);
1001
			}
1002
 
1003
			writer.Close();
1004
		}
1005
 
1006
		private void SaveHttp(string fileName)
1007
		{
1008
			StreamWriter writer = new StreamWriter(fileName);
1009
 
1010
			foreach(TreeNode tcpNode in messageView.Nodes)
1011
			{
1012
				foreach(TreeNode httpNode in tcpNode.Nodes)
1013
				{
1014
					HttpNodeData data = (HttpNodeData)httpNode.Tag;
1015
					data.WriteLog(writer);
1016
				}
1017
			}
1018
 
1019
			writer.Close();
1020
		}
1021
 
1022
		private void SaveXml(string fileName)
1023
		{
1024
			StreamWriter writer = new StreamWriter(fileName);
1025
 
1026
			foreach(TreeNode tcpNode in messageView.Nodes)
1027
			{
1028
				foreach(TreeNode httpNode in tcpNode.Nodes)
1029
				{
1030
					foreach(TreeNode xmlNode in httpNode.Nodes)
1031
					{
1032
						XmlNodeData data = (XmlNodeData)xmlNode.Tag;
1033
						data.WriteLog(writer);
1034
					}
1035
				}
1036
			}
1037
 
1038
			writer.Close();
1039
		}
1040
 
1041
		#endregion core methods
1042
 
1043
		#region network events handlers
1044
		private void TcpConnectionLog(object sender, TcpLogEventArgs e)
1045
		{
1125 dev 1046
			lock(this)
1047
			{
1048
				TcpConnection tcp = sender as TcpConnection;
1049
				LogMessage message = new LogMessage(tcp, e.Level, e.Message, e.Exception);
1092 dev 1050
 
1125 dev 1051
				try
1052
				{
1053
					this.BeginInvoke(new AddLogMessageHandler(AddLogMessageInternal), new object[] { message } );
1054
				}
1055
				catch(InvalidOperationException ex)
1056
				{
1057
					if(!this.Disposing && !this.IsDisposed)
1058
						Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
1059
				}
1092 dev 1060
			}
1061
		}
1062
 
1063
		private void AddTcpConnetion(object sender, TcpConnectionEventArgs e)
1064
		{
1125 dev 1065
			lock(this)
1066
			{
1067
				e.Tcp.Log     += new TcpLogEventHandler(TcpConnectionLog);
1068
				e.Tcp.Update  += new TcpEventHandler(UpdateTcpNode);
1069
				e.Tcp.Close   += new TcpEventHandler(UpdateTcpNode);
1070
				e.Tcp.NewHttp += new TcpHttpEventHandler(AddHttpMessageNode);
1092 dev 1071
 
1125 dev 1072
				try
1073
				{
1074
					this.BeginInvoke(new AddTcpNodeHandler(AddTcpNodeInternal), new object[] { e.Tcp } );
1075
				}
1076
				catch(InvalidOperationException ex)
1077
				{
1078
					if(!this.Disposing && !this.IsDisposed)
1079
						Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
1080
				}
1092 dev 1081
			}
1082
		}
1083
 
1084
		private void UpdateTcpNode(object sender, TcpEventArgs e)
1085
		{
1125 dev 1086
			lock(this)
1092 dev 1087
			{
1125 dev 1088
				try
1089
				{
1090
					this.BeginInvoke(new UpdateTcpNodeHandler(UpdateTcpNodeInternal), new object[] { (TcpConnection)sender } );
1091
				}
1092
				catch(InvalidOperationException ex)
1093
				{
1094
					if(!this.Disposing && !this.IsDisposed)
1095
						Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
1096
				}
1092 dev 1097
			}
1098
		}
1099
 
1100
		private void AddHttpMessageNode(object sender, TcpHttpEventArgs e)
1101
		{
1125 dev 1102
			lock(this)
1103
			{
1104
				e.Http.Update += new TcpEventHandler(UpdateHttpNode);
1092 dev 1105
 
1125 dev 1106
				try
1107
				{
1108
					this.BeginInvoke(new AddHttpNodeHandler(AddHttpNodeInternal),
1109
						new object[] { (TcpConnection)sender, e.Http } );
1110
				}
1111
				catch(InvalidOperationException ex)
1112
				{
1113
					if(!this.Disposing && !this.IsDisposed)
1114
						Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
1115
				}
1092 dev 1116
			}
1117
		}
1118
 
1119
		private void UpdateHttpNode(object sender, TcpEventArgs e)
1120
		{
1125 dev 1121
			lock(this)
1092 dev 1122
			{
1125 dev 1123
				try
1124
				{
1125
					this.BeginInvoke(new UpdateHttpNodeHandler(UpdateHttpNodeInternal), new object[] { (HttpMessage)sender } );
1126
				}
1127
				catch(InvalidOperationException ex)
1128
				{
1129
					if(!this.Disposing && !this.IsDisposed)
1130
						Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
1131
				}
1092 dev 1132
			}
1133
		}
1134
 
1135
		#endregion network events handlers
1136
 
1137
		#region handlers for async GUI events
1138
		private delegate void AddLogMessageHandler(LogMessage message);
1139
		private delegate void AddTcpNodeHandler(TcpConnection tcp);
1140
		private delegate void UpdateTcpNodeHandler(TcpConnection tcp);
1141
		private delegate void AddHttpNodeHandler(TcpConnection tcp, HttpMessage http);
1142
		private delegate void UpdateHttpNodeHandler(HttpMessage http);
1143
 
1144
		private void AddLogMessageInternal(LogMessage message)
1145
		{
1146
			logMessages.Add(message);
1147
 
1148
			if(message.Exception != null)
1149
			{
1150
				Console.WriteLine(message.Exception.Message + " (" + message.Exception.GetType().Name
1151
					+ ")\n" + message.Exception.StackTrace);
1152
			}
1153
		}
1154
 
1155
		private void AddTcpNodeInternal(TcpConnection tcp)
1156
		{
1157
			TreeNode    treeNode = new TreeNode(tcp.ToString());
1158
			TcpNodeData data     = new TcpNodeData(this, treeNode);
1159
 
1160
			data.Tcp = tcp;
1161
			treeNode.Tag                = data;
1162
			treeNode.ImageIndex         = 1;
1163
			treeNode.SelectedImageIndex = 1;
1164
			treeNodes[tcp] = data;
1165
 
1166
			messageView.Nodes.Add(treeNode);
1167
			treeNode.EnsureVisible();
1168
		}
1169
 
1170
		private void UpdateTcpNodeInternal(TcpConnection tcp)
1171
		{
1172
			TcpNodeData data = treeNodes[tcp] as TcpNodeData;
1125 dev 1173
			if(data == null) return; // might be call by Cancel
1092 dev 1174
 
1175
			string title = tcp.ToString();
1176
			if(title != data.Node.Text) data.Node.Text = title;
1177
			if(tcp.LocalState == SocketState.Closed && tcp.RemoteState == SocketState.Closed)
1178
			{
1179
				data.Node.ImageIndex         = 2;
1180
				data.Node.SelectedImageIndex = 2;
1181
			}
1182
 
1183
			if(messageView.SelectedNode == null || data != messageView.SelectedNode.Tag)
1184
				data.ViewExpired = true;  // got update for invisible TCP node, update it later
1185
			else
1186
				data.Show();
1187
		}
1188
 
1189
		private void AddHttpNodeInternal(TcpConnection tcp, HttpMessage http)
1190
		{
1191
			TreeNode     treeNode = new TreeNode(http.ToString());
1192
			HttpNodeData data     = new HttpNodeData(this, treeNode);
1193
 
1194
			data.Http = http;
1195
			treeNode.Tag = data;
1196
			treeNodes[http] = data;
1197
 
1198
			TcpNodeData tcpData = treeNodes[tcp] as TcpNodeData;
1199
			if(tcpData == null) throw new ArgumentException("No node found for TCP message");
1200
 
1201
			tcpData.Node.Nodes.Add(treeNode);
1202
			if(autoExpand) tcpData.Node.Expand();
1203
			tcpData.Node.EnsureVisible();
1204
		}
1205
 
1206
		private void UpdateHttpNodeInternal(HttpMessage http)
1207
		{
1208
			HttpNodeData httpData = treeNodes[http] as HttpNodeData;
1125 dev 1209
			if(httpData == null) return; // might be call by Cancel
1092 dev 1210
 
1211
			string title = http.ToString();
1212
			if(httpData.Node.Text != title) httpData.Node.Text = title;
1213
 
1214
			if(!httpData.RequestXmlShown && http.RequestXml != null)
1215
			{
1216
				httpData.RequestXmlShown = true;
1217
				AddXmlNode(httpData.Node, "Request XML", http.RequestXml);
1218
				if(autoExpand) httpData.Node.Expand();
1219
			}
1220
 
1221
			if(!httpData.ResponseXmlShown && http.ResponseXml != null)
1222
			{
1223
				httpData.ResponseXmlShown = true;
1224
				AddXmlNode(httpData.Node, "Response XML", http.ResponseXml);
1225
				if(autoExpand) httpData.Node.Expand();
1226
			}
1227
 
1228
			// update text view
1229
			if(messageView.SelectedNode == null || httpData != messageView.SelectedNode.Tag)
1230
				httpData.ViewExpired = true;
1231
			else
1232
				httpData.Show();
1233
		}
1234
 
1235
		private void AddXmlNode(TreeNode parent, string title, XmlMessage xml)
1236
		{
1237
			TreeNode    treeNode = new TreeNode(title);
1238
			XmlNodeData data = new XmlNodeData(this, treeNode);
1239
 
1240
			data.Xml       = xml;
1241
			treeNode.Tag   = data;
1242
			treeNodes[xml] = data;
1243
 
1244
			parent.Nodes.Add(treeNode);
1245
		}
1246
 
1247
		#endregion handlers for async GUI events
1248
 
1249
		#region node display classes
1250
		private abstract class TreeNodeData
1251
		{
1252
			protected TreeNode node;
1253
			protected object   viewState;
1254
			protected bool     viewExpired;
1255
			protected MainForm owner;
1256
			protected bool     shown = false;
1257
 
1258
			public TreeNode Node
1259
			{
1260
				get { return node; }
1261
			}
1262
 
1263
			public TreeNodeData(MainForm owner, TreeNode node)
1264
			{
1265
				this.owner = owner;
1266
				this.node  = node;
1267
			}
1268
 
1269
			public bool ViewExpired
1270
			{
1271
				get { return viewExpired; }
1272
				set { viewExpired = value; }
1273
			}
1274
 
1275
			public void SaveViewState()
1276
			{
1277
				viewState = owner.messagesBox.SaveState(false);
1278
			}
1279
 
1280
			protected virtual bool ForceInitView()
1281
			{
1282
				return false;
1283
			}
1284
 
1285
			protected abstract void InitView();
1286
			protected abstract void UpdateView();
1287
 
1288
			public void Show()
1289
			{
1290
				if(!shown || viewState == null || ForceInitView())
1291
				{
1292
					InitView();
1293
					shown = true;
1294
					if(viewState == null) viewState = owner.messagesBox.SaveState(false);
1295
				}
1296
				else
1297
				{
1298
					owner.messagesBox.RestoreState(viewState, true);
1299
					if(viewExpired) UpdateView();
1300
				}
1301
			}
1302
 
1303
			public abstract void WriteLog(StreamWriter writer);
1304
		}
1305
 
1306
		private class TcpNodeData : TreeNodeData
1307
		{
1308
			private TcpConnection tcp;
1309
 
1310
			private TcpShowMode lastShowMode;
1311
			private object      localStateMarker  = null;
1312
			private object      remoteStateMarker = null;
1313
			private object      startMarker       = null;
1314
			private object      localEndMarker    = null;
1315
			private object      remoteEndMarker   = null;
1316
			private object      clientMarker      = null;
1317
			private object      serverMarker      = null;
1318
			private object      sentMarker        = null;
1319
			private object      receivedMarker    = null;
1320
			private object      textMarker1       = null;
1321
			private object      textMarker2       = null;
1322
			private IEnumerator messagesEnum      = null;
1323
 
1324
			public TcpConnection Tcp
1325
			{
1326
				get { return tcp; }
1327
				set { tcp = value; }
1328
			}
1329
 
1330
			public TcpNodeData(MainForm owner, TreeNode node)	: base(owner, node)
1331
			{
1332
			}
1333
 
1334
 
1335
			protected override bool ForceInitView()
1336
			{
1337
				return (lastShowMode != owner.tcpShowMode);
1338
			}
1339
 
1340
			protected override void InitView()
1341
			{
1342
				lastShowMode = owner.tcpShowMode;
1343
 
1344
				try
1345
				{
1346
					owner.messagesBox.BeginUpdate();
1347
 
1348
					lock(tcp)
1349
					{
1350
						owner.messagesBox.Clear();
1351
 
1352
						owner.messagesBox.AppendNewLine();
1353
						owner.messagesBox.AppendText("ID:         ",
1354
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1355
						owner.messagesBox.AppendText(tcp.Id,
1356
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1357
						owner.messagesBox.AppendNewLine();
1358
 
1359
						owner.messagesBox.AppendText("State:      ",
1360
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1361
						localStateMarker = owner.messagesBox.BeginMark();
1362
						owner.messagesBox.AppendText(tcp.LocalState.ToString(),
1363
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1364
						owner.messagesBox.EndMark(localStateMarker);
1365
						owner.messagesBox.AppendText(null,
1366
							Color.DarkRed, Color.Transparent, false, false, 1, 12);
1367
						remoteStateMarker = owner.messagesBox.BeginMark();
1368
						owner.messagesBox.AppendText(tcp.RemoteState.ToString(),
1369
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1370
						owner.messagesBox.EndMark(remoteStateMarker);
1371
						owner.messagesBox.AppendNewLine();
1372
 
1373
						owner.messagesBox.AppendText("Start:      ",
1374
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1375
						startMarker = owner.messagesBox.BeginMark();
1376
						owner.messagesBox.AppendText(tcp.StartTimestamp.ToString("HH:mm:ss.ffff"),
1377
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1378
						owner.messagesBox.EndMark(startMarker);
1379
						owner.messagesBox.AppendNewLine();
1380
						owner.messagesBox.AppendText("Local End:  ",
1381
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1382
						localEndMarker = owner.messagesBox.BeginMark();
1383
						owner.messagesBox.AppendText(tcp.LocalEndTimestamp.ToString("HH:mm:ss.ffff"),
1384
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1385
						owner.messagesBox.EndMark(localEndMarker);
1386
						owner.messagesBox.AppendNewLine();
1387
						owner.messagesBox.AppendText("Remote End: ",
1388
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1389
						remoteEndMarker = owner.messagesBox.BeginMark();
1390
						owner.messagesBox.AppendText(tcp.RemoteEndTimestamp.ToString("HH:mm:ss.ffff"),
1391
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1392
						owner.messagesBox.EndMark(remoteEndMarker);
1393
						owner.messagesBox.AppendNewLine();
1394
 
1395
						owner.messagesBox.AppendText("Client:     ",
1396
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1397
						clientMarker = owner.messagesBox.BeginMark();
1398
						owner.messagesBox.AppendText((tcp.LocalPoint == null) ? "" : tcp.LocalPoint.ToString(),
1399
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1400
						owner.messagesBox.EndMark(clientMarker);
1401
						owner.messagesBox.AppendNewLine();
1402
						owner.messagesBox.AppendText("Server:     ",
1403
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1404
						serverMarker = owner.messagesBox.BeginMark();
1405
						owner.messagesBox.AppendText((tcp.RemotePoint == null) ? "" : tcp.RemotePoint.ToString(),
1406
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1407
						owner.messagesBox.EndMark(serverMarker);
1408
						owner.messagesBox.AppendNewLine();
1409
 
1410
						owner.messagesBox.AppendText("Sent:       ",
1411
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1412
						sentMarker = owner.messagesBox.BeginMark();
1413
						owner.messagesBox.AppendText(tcp.SentBytes.ToString(),
1414
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1415
						owner.messagesBox.EndMark(sentMarker);
1416
						owner.messagesBox.AppendNewLine();
1417
						owner.messagesBox.AppendText("Received:   ",
1418
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1419
						receivedMarker = owner.messagesBox.BeginMark();
1420
						owner.messagesBox.AppendText(tcp.ReceivedBytes.ToString(),
1421
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1422
						owner.messagesBox.EndMark(receivedMarker);
1423
						owner.messagesBox.AppendNewLine();
1424
						owner.messagesBox.AppendNewLine();
1425
 
1426
						messagesEnum = tcp.Messages.GetEnumerator();
1427
 
1428
						textMarker1 = owner.messagesBox.BeginMark();
1429
						owner.messagesBox.EndMark(textMarker1);
1430
 
1431
						owner.messagesBox.AppendNewLine();
1432
						textMarker2 = owner.messagesBox.BeginMark();
1433
						owner.messagesBox.EndMark(textMarker2);
1434
 
1435
						ShowMessages();
1436
					}
1437
				}
1438
				finally
1439
				{
1440
					owner.messagesBox.EndUpdate();
1441
				}
1442
			}
1443
 
1444
			protected override void UpdateView()
1445
			{
1446
				try
1447
				{
1448
					owner.messagesBox.BeginUpdate();
1449
 
1450
					lock(tcp)
1451
					{
1452
						owner.messagesBox.ChangeText(localStateMarker, tcp.LocalState.ToString(),
1453
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1454
						owner.messagesBox.ChangeText(remoteStateMarker, tcp.RemoteState.ToString(),
1455
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1456
 
1457
						owner.messagesBox.ChangeText(startMarker, tcp.StartTimestamp.ToString("HH:mm:ss.ffff"),
1458
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1459
						owner.messagesBox.ChangeText(localEndMarker, tcp.LocalEndTimestamp.ToString("HH:mm:ss.ffff"),
1460
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1461
						owner.messagesBox.ChangeText(remoteEndMarker, tcp.RemoteEndTimestamp.ToString("HH:mm:ss.ffff"),
1462
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1463
 
1464
						owner.messagesBox.ChangeText(clientMarker, (tcp.LocalPoint == null) ? "" : tcp.LocalPoint.ToString(),
1465
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1466
						owner.messagesBox.ChangeText(serverMarker, (tcp.RemotePoint == null) ? "" : tcp.RemotePoint.ToString(),
1467
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1468
 
1469
						owner.messagesBox.ChangeText(sentMarker, tcp.SentBytes.ToString(),
1470
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1471
						owner.messagesBox.ChangeText(receivedMarker, tcp.ReceivedBytes.ToString(),
1472
							Color.DarkRed, Color.LightGray, false, false, 0, 12);
1473
 
1474
						ShowMessages();
1475
					}
1476
				}
1477
				finally
1478
				{
1479
					owner.messagesBox.EndUpdate();
1480
				}
1481
			}
1482
 
1483
			private void ShowMessages()
1484
			{
1485
				while(messagesEnum.MoveNext())
1486
				{
1487
					TcpMessage message = (TcpMessage)messagesEnum.Current;
1488
					object     marker  = (owner.tcpShowMode == TcpShowMode.ByTime
1489
						|| message.Direction == TcpMessageDirection.Local) ? textMarker1 : textMarker2;
1490
 
1491
					if(owner.tcpShowMode == TcpShowMode.ByTime)
1492
					{
1493
						owner.messagesBox.InsertText(marker,
1494
							message.Timestamp.ToString("HH:mm:ss.ffff") + " ("	+ message.Length + ")",
1495
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1496
						owner.messagesBox.InsertNewLine(marker);
1497
					}
1498
 
1499
					string str = Utils.BytesToString(message.Bytes, message.Length);
1500
					ArrayList lines = Utils.SplitLine(str);
1501
					for(int i = 0; i < lines.Count; i++)
1502
					{
1503
						owner.messagesBox.InsertText(marker, (string)lines[i],
1504
							message.Direction == TcpMessageDirection.Local ? Color.Green : Color.Blue,
1505
							Color.LightGray, false, false, 0, 0);
1506
 
1507
						if(owner.tcpShowMode == TcpShowMode.ByTime || i != lines.Count - 1)
1508
							owner.messagesBox.InsertNewLine(marker);
1509
					}
1510
				}
1511
			}
1512
 
1513
			public override void WriteLog(StreamWriter writer)
1514
			{
1515
				writer.WriteLine(
1516
					"Start:      " + tcp.StartTimestamp.ToString("HH:mm:ss.ffff")
1517
					+ "\r\nLocal End:  " + tcp.LocalEndTimestamp.ToString("HH:mm:ss.ffff")
1518
					+ "\r\nRemote End: " + tcp.RemoteEndTimestamp.ToString("HH:mm:ss.ffff")
1519
					+ "\r\nClient:     " + ((tcp.LocalPoint  == null) ? "" : tcp.LocalPoint.ToString())
1520
					+ "\r\nServer:     " + ((tcp.RemotePoint == null) ? "" : tcp.RemotePoint.ToString())
1521
					+ "\r\nSent:       " + tcp.SentBytes
1522
					+ "\r\nReceived:   " + tcp.ReceivedBytes);
1523
 
1524
				foreach(TcpMessage message in tcp.Messages)
1525
				{
1526
					string str = Utils.BytesToString(message.Bytes, message.Length);
1527
					if(!str.EndsWith("\n")) str += "\r\n";
1528
 
1529
					writer.WriteLine();
1530
					if(message.Direction == TcpMessageDirection.Local)
1531
						writer.WriteLine(">>> {0:HH:mm:ss.ffff} >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", message.Timestamp);
1532
					else
1533
						writer.WriteLine("<<< {0:HH:mm:ss.ffff} <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", message.Timestamp);
1534
					writer.Write(str);
1535
				}
1536
				writer.WriteLine("===============================================================");
1537
				writer.WriteLine();
1538
			}
1539
		}
1540
 
1541
		private class HttpNodeData : TreeNodeData
1542
		{
1543
			private HttpMessage http;
1544
			private bool        requestXmlShown  = false;
1545
			private bool        responseXmlShown = false;
1546
 
1547
			private object      stateMarker               = null;
1125 dev 1548
			private object      requestStartMarker        = null;
1092 dev 1549
			private object      requestMethodMarker       = null;
1550
			private object      requestUriMarker          = null;
1551
			private object      requestVersionMarker      = null;
1552
			private object      requestLengthMarker       = null;
1553
			private object      requestEncodingMarker     = null;
1554
			private object      requestContentTypeMarker  = null;
1555
			private object      requestCharsetMarker      = null;
1556
			private object      requestHeadersMarker      = null;
1125 dev 1557
			private object      responseStartMarker       = null;
1092 dev 1558
			private object      responseVersionMarker     = null;
1559
			private object      responseStatusMarker      = null;
1560
			private object      responseLengthMarker      = null;
1561
			private object      responseEncodingMarker    = null;
1562
			private object      responseContentTypeMarker = null;
1563
			private object      responseCharsetMarker     = null;
1564
			private object      responseHeadersMarker     = null;
1565
			private object      requestBodyMarker         = null;
1566
			private object      responseBodyMarker        = null;
1567
			private IEnumerator requestHeadersEnum        = null;
1568
			private IEnumerator responseHeadersEnum       = null;
1569
 
1570
			public HttpMessage Http
1571
			{
1572
				get { return http; }
1573
				set { http = value; }
1574
			}
1575
 
1576
			public bool RequestXmlShown
1577
			{
1578
				get { return requestXmlShown; }
1579
				set { requestXmlShown = value; }
1580
			}
1581
 
1582
			public bool ResponseXmlShown
1583
			{
1584
				get { return responseXmlShown; }
1585
				set { responseXmlShown = value; }
1586
			}
1587
 
1588
			public HttpNodeData(MainForm owner, TreeNode node) : base(owner, node)
1589
			{
1590
			}
1591
 
1592
			private string EncodingToString(HttpEncoding encoding)
1593
			{
1594
				switch(encoding)
1595
				{
1596
					case HttpEncoding.Identify: return "identify";
1597
					case HttpEncoding.Gzip:     return "gzip";
1598
					case HttpEncoding.Compress: return "compress";
1599
					case HttpEncoding.Deflate:  return "deflate";
1600
					default:                    return "<unknown>";
1601
				}
1602
			}
1603
 
1604
			protected override void InitView()
1605
			{
1606
				try
1607
				{
1608
					lock(http)
1609
					{
1610
						owner.messagesBox.Clear();
1611
 
1612
						owner.messagesBox.AppendNewLine();
1613
						owner.messagesBox.AppendText("Complete:                  ",
1614
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1615
						stateMarker = owner.messagesBox.BeginMark();
1616
						owner.messagesBox.AppendText(http.RequestComplete && http.ResponseComplete ? "YES" : "NO",
1617
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1618
						owner.messagesBox.EndMark(stateMarker);
1619
						owner.messagesBox.AppendNewLine();
1620
						owner.messagesBox.AppendNewLine();
1621
 
1622
						// request info
1125 dev 1623
						owner.messagesBox.AppendText("Request Start:             ",
1624
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1625
						requestStartMarker = owner.messagesBox.BeginMark();
1626
						owner.messagesBox.AppendText(http.RequestStartTimestamp == DateTime.MinValue
1627
							? "<unknown>" : http.RequestStartTimestamp.ToString("HH:mm:ss.ffff"),
1628
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1629
						owner.messagesBox.EndMark(requestStartMarker);
1630
						owner.messagesBox.AppendNewLine();
1631
 
1092 dev 1632
						owner.messagesBox.AppendText("Request Method:            ",
1633
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1634
						requestMethodMarker = owner.messagesBox.BeginMark();
1635
						owner.messagesBox.AppendText(http.RequestMethod,
1636
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1637
						owner.messagesBox.EndMark(requestMethodMarker);
1638
						owner.messagesBox.AppendNewLine();
1639
 
1640
						owner.messagesBox.AppendText("Request URI:               ",
1641
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1642
						requestUriMarker = owner.messagesBox.BeginMark();
1643
						owner.messagesBox.AppendText(http.RequestUri,
1644
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1645
						owner.messagesBox.EndMark(requestUriMarker);
1646
						owner.messagesBox.AppendNewLine();
1647
 
1648
						owner.messagesBox.AppendText("Request Version:           ",
1649
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1650
						requestVersionMarker = owner.messagesBox.BeginMark();
1651
						owner.messagesBox.AppendText(http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
1652
							: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
1653
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1654
						owner.messagesBox.EndMark(requestVersionMarker);
1655
						owner.messagesBox.AppendNewLine();
1656
 
1657
						owner.messagesBox.AppendText("Request Content Length:    ",
1658
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1659
						requestLengthMarker = owner.messagesBox.BeginMark();
1660
						owner.messagesBox.AppendText(http.RequestLength < 0 ? "<unknown>" : http.RequestLength.ToString(),
1661
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1662
						owner.messagesBox.EndMark(requestLengthMarker);
1663
						owner.messagesBox.AppendNewLine();
1664
 
1665
						owner.messagesBox.AppendText("Request Content Encoding:  ",
1666
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1667
						requestEncodingMarker = owner.messagesBox.BeginMark();
1668
						owner.messagesBox.AppendText(EncodingToString(http.RequestEncoding),
1669
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1670
						owner.messagesBox.EndMark(requestEncodingMarker);
1671
						owner.messagesBox.AppendNewLine();
1672
 
1673
						owner.messagesBox.AppendText("Request Content Type:      ",
1674
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1675
						requestContentTypeMarker = owner.messagesBox.BeginMark();
1676
						owner.messagesBox.AppendText(http.RequestContentType == null ? "<unknown>"
1677
							: http.RequestContentType + "/" + http.RequestContentSubtype,
1678
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1679
						owner.messagesBox.EndMark(requestContentTypeMarker);
1680
						owner.messagesBox.AppendNewLine();
1681
 
1682
						owner.messagesBox.AppendText("Request Content Charset:   ",
1683
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1684
						requestCharsetMarker = owner.messagesBox.BeginMark();
1685
						owner.messagesBox.AppendText(http.RequestCharset == null ? "<unknown>" : http.RequestCharset,
1686
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1687
						owner.messagesBox.EndMark(requestCharsetMarker);
1688
						owner.messagesBox.AppendNewLine();
1689
 
1690
						owner.messagesBox.AppendText("Request Headers:",
1691
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1692
						owner.messagesBox.AppendNewLine();
1693
						requestHeadersMarker = owner.messagesBox.BeginMark();
1694
						owner.messagesBox.EndMark(requestHeadersMarker);
1695
 
1696
						requestHeadersEnum = http.RequestHeaders.GetEnumerator();
1697
						ShowHeaders(requestHeadersEnum, requestHeadersMarker);
1698
 
1699
						// response info
1700
						owner.messagesBox.AppendNewLine();
1125 dev 1701
						owner.messagesBox.AppendText("Response Start:            ",
1702
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1703
						responseStartMarker = owner.messagesBox.BeginMark();
1704
						owner.messagesBox.AppendText(http.ResponseStartTimestamp == DateTime.MinValue
1705
							? "<unknown>" : http.ResponseStartTimestamp.ToString("HH:mm:ss.ffff"),
1706
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1707
						owner.messagesBox.EndMark(responseStartMarker);
1708
						owner.messagesBox.AppendNewLine();
1709
 
1092 dev 1710
						owner.messagesBox.AppendText("Response Version:          ",
1711
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1712
						responseVersionMarker = owner.messagesBox.BeginMark();
1713
						owner.messagesBox.AppendText(http.ResponseVersion == HttpVersion.V0_9
1714
							? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
1715
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1716
						owner.messagesBox.EndMark(responseVersionMarker);
1717
						owner.messagesBox.AppendNewLine();
1718
 
1719
						owner.messagesBox.AppendText("Response Status:           ",
1720
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1721
						responseStatusMarker = owner.messagesBox.BeginMark();
1722
						owner.messagesBox.AppendText(http.ResponseStatusCode + " " + http.ResponseStatusMessage,
1723
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1724
						owner.messagesBox.EndMark(responseStatusMarker);
1725
						owner.messagesBox.AppendNewLine();
1726
 
1727
						owner.messagesBox.AppendText("Response Content Length:   ",
1728
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1729
						responseLengthMarker = owner.messagesBox.BeginMark();
1730
						owner.messagesBox.AppendText(http.ResponseLength < 0 ? "<unknown>" : http.ResponseLength.ToString(),
1731
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1732
						owner.messagesBox.EndMark(responseLengthMarker);
1733
						owner.messagesBox.AppendNewLine();
1734
 
1735
						owner.messagesBox.AppendText("Response Content Encoding: ",
1736
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1737
						responseEncodingMarker = owner.messagesBox.BeginMark();
1738
						owner.messagesBox.AppendText(EncodingToString(http.ResponseEncoding),
1739
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1740
						owner.messagesBox.EndMark(responseEncodingMarker);
1741
						owner.messagesBox.AppendNewLine();
1742
 
1743
						owner.messagesBox.AppendText("Response Content Type:     ",
1744
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1745
						responseContentTypeMarker = owner.messagesBox.BeginMark();
1746
						owner.messagesBox.AppendText(http.ResponseContentType == null ? "<unknown>"
1747
							: http.ResponseContentType + "/" + http.ResponseContentSubtype,
1748
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1749
						owner.messagesBox.EndMark(responseContentTypeMarker);
1750
						owner.messagesBox.AppendNewLine();
1751
 
1752
						owner.messagesBox.AppendText("Response Content Charset:  ",
1753
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1754
						responseCharsetMarker = owner.messagesBox.BeginMark();
1755
						owner.messagesBox.AppendText(http.ResponseCharset == null ? "<unknown>" : http.ResponseCharset,
1756
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1757
						owner.messagesBox.EndMark(responseCharsetMarker);
1758
						owner.messagesBox.AppendNewLine();
1759
 
1760
						owner.messagesBox.AppendText("Response Headers:",
1761
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1762
						owner.messagesBox.AppendNewLine();
1763
						responseHeadersMarker = owner.messagesBox.BeginMark();
1764
						owner.messagesBox.EndMark(responseHeadersMarker);
1765
 
1766
						responseHeadersEnum = http.ResponseHeaders.GetEnumerator();
1767
						ShowHeaders(responseHeadersEnum, responseHeadersMarker);
1768
 
1769
						owner.messagesBox.AppendNewLine();
1770
						requestBodyMarker = owner.messagesBox.BeginMark();
1771
						owner.messagesBox.EndMark(requestBodyMarker);
1772
						ShowBody(requestBodyMarker, http.RequestBody, http.RequestLength, http.RequestText, Color.Green);
1773
 
1774
						owner.messagesBox.AppendNewLine();
1775
						responseBodyMarker = owner.messagesBox.BeginMark();
1776
						owner.messagesBox.EndMark(responseBodyMarker);
1777
						ShowBody(responseBodyMarker, http.ResponseBody, http.ResponseLength, http.ResponseText, Color.Blue);
1778
					}
1779
				}
1780
				finally
1781
				{
1782
					owner.messagesBox.EndUpdate();
1783
				}
1784
			}
1785
 
1786
			protected override void UpdateView()
1787
			{
1788
				try
1789
				{
1790
					owner.messagesBox.BeginUpdate();
1791
 
1792
					lock(http)
1793
					{
1794
						owner.messagesBox.ChangeText(stateMarker, http.RequestComplete && http.ResponseComplete ? "YES" : "NO",
1795
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1796
						owner.messagesBox.ChangeText(requestMethodMarker, http.RequestMethod,
1797
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1798
						owner.messagesBox.ChangeText(requestUriMarker, http.RequestUri,
1799
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1800
						owner.messagesBox.ChangeText(requestVersionMarker, http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
1801
							: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
1802
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1803
						owner.messagesBox.ChangeText(requestLengthMarker, http.RequestLength < 0
1804
							? "<unknown>" : http.RequestLength.ToString(),
1805
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1806
						owner.messagesBox.ChangeText(requestEncodingMarker, EncodingToString(http.RequestEncoding),
1807
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1808
						owner.messagesBox.ChangeText(requestContentTypeMarker, http.RequestContentType == null ? "<unknown>"
1809
							: http.RequestContentType + "/" + http.RequestContentSubtype,
1810
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1811
						owner.messagesBox.ChangeText(requestCharsetMarker, http.RequestCharset == null
1812
							? "<unknown>" : http.RequestCharset,
1813
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1814
 
1815
						ShowHeaders(requestHeadersEnum, requestHeadersMarker);
1816
 
1817
						owner.messagesBox.ChangeText(responseVersionMarker, http.ResponseVersion == HttpVersion.V0_9
1818
							? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
1819
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1820
						owner.messagesBox.ChangeText(responseStatusMarker, http.ResponseStatusCode + " " + http.ResponseStatusMessage,
1821
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1822
						owner.messagesBox.ChangeText(responseLengthMarker, http.ResponseLength < 0
1823
							? "<unknown>" : http.ResponseLength.ToString(),
1824
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1825
						owner.messagesBox.ChangeText(responseEncodingMarker, EncodingToString(http.ResponseEncoding),
1826
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1827
						owner.messagesBox.ChangeText(responseContentTypeMarker, http.ResponseContentType == null ? "<unknown>"
1828
							: http.ResponseContentType + "/" + http.ResponseContentSubtype,
1829
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1830
						owner.messagesBox.ChangeText(responseCharsetMarker, http.ResponseCharset == null
1831
							? "<unknown>" : http.ResponseCharset,
1832
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1833
 
1834
						ShowHeaders(responseHeadersEnum, responseHeadersMarker);
1835
 
1836
						owner.messagesBox.DeleteText(requestBodyMarker);
1837
						ShowBody(requestBodyMarker, http.RequestBody, http.RequestLength, http.RequestText, Color.Green);
1838
						owner.messagesBox.DeleteText(responseBodyMarker);
1839
						ShowBody(responseBodyMarker, http.ResponseBody, http.ResponseLength, http.ResponseText, Color.Blue);
1840
					}
1841
				}
1842
				finally
1843
				{
1844
					owner.messagesBox.EndUpdate();
1845
				}
1846
			}
1847
 
1848
			private void ShowHeaders(IEnumerator headers, object marker)
1849
			{
1850
				while(headers.MoveNext())
1851
				{
1852
					HttpHeader h = (HttpHeader)headers.Current;
1853
 
1854
					bool first = true;
1855
					foreach(string val in h.Values)
1856
					{
1857
						if(first)
1858
						{
1859
							owner.messagesBox.InsertText(marker, h.Name + ":",
1860
								Color.DarkRed, Color.Transparent, false, false, 4, 4);
1861
							owner.messagesBox.InsertText(marker, null,
1862
								Color.DarkRed, Color.Transparent, false, false, 6 - 4 - 1, 4);
1863
							first = false;
1864
						}
1865
						else
1866
						{
1867
							owner.messagesBox.InsertText(marker, null,
1868
								Color.DarkRed, Color.Transparent, false, false, 6 + h.Name.Length, 6 + h.Name.Length);
1869
						}
1870
						owner.messagesBox.InsertText(marker, val,
1871
							Color.DarkRed, Color.LightGray, false, false, 0, 6 + h.Name.Length);
1872
						owner.messagesBox.InsertNewLine(marker);
1873
					}
1874
				}
1875
			}
1876
 
1877
			private void ShowBody(object marker, byte[] body, int len, string text, Color color)
1878
			{
1879
				if(text != null)
1880
				{
1881
					ArrayList lines = Utils.SplitLine(text);
1882
					for(int i = 0; i < lines.Count; i++)
1883
					{
1884
						owner.messagesBox.InsertText(marker, (string)lines[i], color, Color.LightGray, false, false, 0, 0);
1885
						owner.messagesBox.InsertNewLine(marker);
1886
					}
1887
				}
1888
				else if(body != null)
1889
				{
1890
					ArrayList lines = Utils.SplitLine(Utils.BytesToString(body, len));
1891
					for(int i = 0; i < lines.Count; i++)
1892
					{
1893
						owner.messagesBox.InsertText(marker, (string)lines[i], color, Color.LightGray, false, false, 0, 0);
1894
						owner.messagesBox.InsertNewLine(marker);
1895
					}
1896
				}
1897
			}
1898
 
1899
			public override void WriteLog(StreamWriter writer)
1900
			{
1901
				// request info
1902
				writer.WriteLine(
1903
					"Complete:                  " + (http.RequestComplete && http.ResponseComplete ? "YES" : "NO") + "\r\n"
1904
					+ "\r\nRequest Method:            " + http.RequestMethod
1905
					+ "\r\nRequest URI:               " + http.RequestUri
1906
					+ "\r\nRequest Version:           " + (http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
1907
						: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1")
1908
					+ "\r\nRequest Content Length:    " + (http.RequestLength < 0 ? "<unknown>" : http.RequestLength.ToString())
1909
					+ "\r\nRequest Content Encoding:  " + EncodingToString(http.RequestEncoding)
1910
					+ "\r\nRequest Content Type:      " + (http.RequestContentType == null ? "<unknown>"
1911
						: http.RequestContentType + "/" + http.RequestContentSubtype)
1912
					+ "\r\nRequest Content Charset:   " + (http.RequestCharset == null ? "<unknown>" : http.RequestCharset)
1913
					+ "\r\nRequest Headers:");
1914
 
1915
				foreach(HttpHeader h in http.RequestHeaders)
1916
				{
1917
					int indent = 0;
1918
					foreach(string val in h.Values)
1919
					{
1920
						if(indent == 0)
1921
						{
1922
							writer.WriteLine("    {0}: {1}", h.Name, val);
1923
							indent = 6 + h.Name.Length;
1924
						}
1925
						else
1926
						{
1927
							writer.WriteLine("{0," + indent + "}{1}", " ", val);
1928
						}
1929
					}
1930
				}
1931
 
1932
				// response info
1933
				writer.WriteLine(
1934
					"\r\nResponse Version:          " + (http.ResponseVersion == HttpVersion.V0_9
1935
						? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1")
1936
					+ "\r\nResponse Status:           " + http.ResponseStatusCode + " " + http.ResponseStatusMessage
1937
					+ "\r\nResponse Content Length:   " + (http.ResponseLength < 0
1938
						? "<unknown>" : http.ResponseLength.ToString())
1939
					+ "\r\nResponse Content Encoding: " + EncodingToString(http.ResponseEncoding)
1940
					+ "\r\nResponse Content Type:     " + (http.ResponseContentType == null ? "<unknown>"
1941
						: http.ResponseContentType + "/" + http.ResponseContentSubtype)
1942
					+ "\r\nResponse Content Charset:  " + (http.ResponseCharset == null ? "<unknown>" : http.ResponseCharset)
1943
					+ "\r\nResponse Headers:");
1944
 
1945
				foreach(HttpHeader h in http.ResponseHeaders)
1946
				{
1947
					int indent = 0;
1948
					foreach(string val in h.Values)
1949
					{
1950
						if(indent == 0)
1951
						{
1952
							writer.WriteLine("    {0}: {1}", h.Name, val);
1953
							indent = 6 + h.Name.Length;
1954
						}
1955
						else
1956
						{
1957
							writer.WriteLine("{0," + indent + "}{1}", " ", val);
1958
						}
1959
					}
1960
				}
1961
				writer.WriteLine();
1962
 
1963
				// request body
1964
				if(http.RequestText != null)
1965
				{
1966
					writer.WriteLine(http.RequestText);
1967
				}
1968
				else if(http.RequestBody != null)
1969
				{
1970
					writer.WriteLine(Utils.BytesToString(http.RequestBody, http.RequestLength));
1971
				}
1972
 
1973
				// response body
1974
				if(http.ResponseText != null)
1975
				{
1976
					writer.WriteLine(http.ResponseText);
1977
				}
1978
				else if(http.ResponseBody != null)
1979
				{
1980
					writer.WriteLine(Utils.BytesToString(http.ResponseBody, http.ResponseLength));
1981
				}
1982
 
1983
				writer.WriteLine("===============================================================");
1984
				writer.WriteLine();
1985
			}
1986
		}
1987
 
1988
		private class XmlNodeData : TreeNodeData
1989
		{
1990
			private XmlMessage xml;
1991
 
1992
			public XmlMessage Xml
1993
			{
1994
				get { return xml; }
1995
				set { xml = value; }
1996
			}
1997
 
1998
			public XmlNodeData(MainForm owner, TreeNode node) : base(owner, node)
1999
			{
2000
			}
2001
 
2002
			protected override void InitView()
2003
			{
2004
				try
2005
				{
2006
					// update main screen if necessary
2007
					owner.messagesBox.BeginUpdate();
2008
 
2009
					lock(xml)
2010
					{
2011
						owner.messagesBox.Clear();
2012
						if(xml.ParseException != null)
2013
						{
2014
							owner.messagesBox.AppendText("Cannot parse XML:",
2015
								Color.Red, Color.Transparent, false, false, 0, 0);
2016
							owner.messagesBox.AppendNewLine();
2017
							owner.messagesBox.AppendText(xml.ParseException.Message,
2018
								Color.Red, Color.Transparent, false, false, 2, 2);
2019
							owner.messagesBox.AppendNewLine();
2020
						}
2021
						else if(xml.Xml != null)
2022
						{
2023
							ShowXmlNode(xml.Xml, 0);
2024
						}
2025
					}
2026
				}
2027
				finally
2028
				{
2029
					owner.messagesBox.EndUpdate();
2030
				}
2031
			}
2032
 
2033
			protected override void UpdateView()
2034
			{
2035
			}
2036
 
2037
			private void ShowXmlNode(XmlNode node, int indent)
2038
			{
2039
				if(node.NodeType == XmlNodeType.Document)
2040
				{
2041
					foreach(XmlNode subnode in node.ChildNodes)
2042
					{
2043
						ShowXmlNode(subnode, indent);
2044
					}
2045
				}
2046
				else if(node.NodeType == XmlNodeType.XmlDeclaration)
2047
				{
2048
					owner.messagesBox.AppendText("<?" + node.Name + " " + node.Value + " ?>",
2049
						Color.Blue, Color.Transparent, false, false, indent, indent+2);
2050
					owner.messagesBox.AppendNewLine();
2051
				}
2052
				else if(node.NodeType == XmlNodeType.Comment)
2053
				{
2054
					owner.messagesBox.AppendText("<!--", Color.Gray, Color.Transparent, false, false, indent, indent + 2);
2055
					ShowNormalizedXmlValue(node.Value, Color.Gray, Color.Thistle, false, false, indent);
2056
					owner.messagesBox.AppendText("-->", Color.Gray, Color.Transparent, false, false, 0, indent + 2);
2057
					owner.messagesBox.AppendNewLine();
2058
				}
2059
				else if(node.NodeType == XmlNodeType.Element)
2060
				{
2061
					owner.messagesBox.AppendText("<", Color.Blue, Color.Transparent, false, false, indent, indent + 2);
2062
					owner.messagesBox.AppendText(node.Name, Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
2063
 
2064
					foreach(XmlAttribute attr in node.Attributes)
2065
					{
2066
						bool xmlAttr = attr.Name.StartsWith("xml");
2067
						owner.messagesBox.AppendText(attr.Name, xmlAttr ? Color.Red : Color.DarkRed, Color.Transparent, false, false, 1, indent + 2);
2068
						owner.messagesBox.AppendText("=\"", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2069
						owner.messagesBox.AppendText(attr.Value, xmlAttr ? Color.Red : Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
2070
						owner.messagesBox.AppendText("\"", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2071
					}
2072
 
2073
					if(!node.HasChildNodes)
2074
					{
2075
						owner.messagesBox.AppendText(" />", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2076
						owner.messagesBox.AppendNewLine();
2077
					}
2078
					else
2079
					{
2080
						owner.messagesBox.AppendText(">", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2081
 
2082
						bool elementExists = false;
2083
						bool lastText      = true;
2084
						foreach(XmlNode subnode in node.ChildNodes)
2085
						{
2086
							if(subnode.NodeType == XmlNodeType.Text)
2087
							{
2088
								if(elementExists) owner.messagesBox.AppendNewLine();
2089
								ShowNormalizedXmlValue(subnode.Value, Color.Black, Color.LightGray, false, false, indent);
2090
								lastText = true;
2091
							}
2092
							else
2093
							{
2094
								if(lastText) owner.messagesBox.AppendNewLine();
2095
								ShowXmlNode(subnode, indent + 2);
2096
								elementExists = true;
2097
								lastText      = false;
2098
							}
2099
						}
2100
 
2101
						if(elementExists) owner.messagesBox.AppendText(null, Color.Black, Color.Transparent, false, false, indent, indent + 2);
2102
						owner.messagesBox.AppendText("</", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2103
						owner.messagesBox.AppendText(node.Name, Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
2104
						owner.messagesBox.AppendText(">", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2105
						owner.messagesBox.AppendNewLine();
2106
					}
2107
				}
2108
			}
2109
 
2110
			private void ShowNormalizedXmlValue(string s, Color color, Color backColor, bool italic, bool bold, int indent)
2111
			{
2112
				int begin;
2113
				int end;
2114
 
2115
				bool newLineFound = false;
2116
				foreach(char c in s)
2117
				{
2118
					if(c == '\n')
2119
					{
2120
						newLineFound = true;
2121
						break;
2122
					}
2123
				}
2124
 
2125
				if(newLineFound)
2126
				{
2127
					owner.messagesBox.AppendNewLine();
2128
					owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent);
2129
					owner.messagesBox.AppendText(null, color, backColor, italic, bold, 2, 2);
2130
				}
2131
 
2132
				// trim
2133
				for(begin = 0; begin < s.Length; begin++)
2134
				{
2135
					char c = s[begin];
2136
					if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
2137
				}
2138
				for(end = s.Length-1; end >= 0; end--)
2139
				{
2140
					char c = s[end];
2141
					if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
2142
				}
2143
 
2144
				StringBuilder b = new StringBuilder(s.Length);
2145
				for(int i = begin; i <= end; i++)
2146
				{
2147
					char c = s[i];
2148
 
2149
					switch(c)
2150
					{
2151
						case '\n':
2152
							if(b.Length > 0)
2153
							{
2154
								owner.messagesBox.AppendText(b.ToString(), color, backColor, italic, bold, 0, indent + 2);
2155
								b.Length = 0;
2156
							}
2157
 
2158
							owner.messagesBox.AppendNewLine();
2159
							owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent);
2160
							owner.messagesBox.AppendText(null, color, backColor, italic, bold, 2, 2);
2161
							break;
2162
 
2163
						case '\r':
2164
							break;
2165
 
2166
						case '\t':
2167
							b.Append("  ");
2168
							break;
2169
 
2170
						default:
2171
							b.Append(c);
2172
							break;
2173
					}
2174
				}
2175
 
2176
				if(b.Length > 0)
2177
					owner.messagesBox.AppendText(b.ToString(), color, backColor, italic, bold, 0, indent + 2);
2178
 
2179
				if(newLineFound)
2180
				{
2181
					owner.messagesBox.AppendNewLine();
2182
					owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent + 2);
2183
				}
2184
			}
2185
 
2186
			public override void WriteLog(StreamWriter writer)
2187
			{
2188
				WriteXmlNode(writer, xml.Xml, "");
2189
				writer.WriteLine("===============================================================");
2190
				writer.WriteLine();
2191
			}
2192
 
2193
			private void WriteXmlNode(StreamWriter writer, XmlNode node, string indent)
2194
			{
2195
				if(node.NodeType == XmlNodeType.Document)
2196
				{
2197
					foreach(XmlNode subnode in node.ChildNodes)
2198
					{
2199
						WriteXmlNode(writer, subnode, indent);
2200
					}
2201
				}
2202
				else if(node.NodeType == XmlNodeType.XmlDeclaration)
2203
				{
2204
					writer.WriteLine(indent + "<?" + node.Name + " " + node.Value + " ?>");
2205
				}
2206
				else if(node.NodeType == XmlNodeType.Comment)
2207
				{
2208
					writer.Write(indent + "<!--");
2209
					WriteNormalizedXmlValue(writer, node.Value, indent);
2210
					writer.WriteLine("-->");
2211
				}
2212
				else if(node.NodeType == XmlNodeType.Element)
2213
				{
2214
					writer.Write(indent + "<" + node.Name);
2215
 
2216
					foreach(XmlAttribute attr in node.Attributes)
2217
					{
2218
						bool xmlAttr = attr.Name.StartsWith("xml");
2219
						writer.Write(" " + attr.Name + "=\"" + attr.Value + "\"");
2220
					}
2221
 
2222
					if(!node.HasChildNodes)
2223
					{
2224
						writer.WriteLine(" />");
2225
					}
2226
					else
2227
					{
2228
						writer.Write(">");
2229
 
2230
						bool elementExists = false;
2231
						bool lastText      = true;
2232
						foreach(XmlNode subnode in node.ChildNodes)
2233
						{
2234
							if(subnode.NodeType == XmlNodeType.Text)
2235
							{
2236
								if(elementExists) writer.WriteLine();
2237
								WriteNormalizedXmlValue(writer, subnode.Value, indent);
2238
								lastText = true;
2239
							}
2240
							else
2241
							{
2242
								if(lastText) writer.WriteLine();
2243
								WriteXmlNode(writer, subnode, indent + "  ");
2244
								elementExists = true;
2245
								lastText      = false;
2246
							}
2247
						}
2248
 
2249
						if(elementExists) writer.Write(indent);
2250
						writer.WriteLine("</" + node.Name + ">");
2251
					}
2252
				}
2253
			}
2254
 
2255
			private void WriteNormalizedXmlValue(StreamWriter writer, string s, string indent)
2256
			{
2257
				int begin;
2258
				int end;
2259
 
2260
				bool newLineFound = false;
2261
				foreach(char c in s)
2262
				{
2263
					if(c == '\n')
2264
					{
2265
						newLineFound = true;
2266
						break;
2267
					}
2268
				}
2269
 
2270
				if(newLineFound)
2271
				{
2272
					writer.WriteLine();
2273
					writer.Write(indent + "  ");
2274
				}
2275
 
2276
				// trim
2277
				for(begin = 0; begin < s.Length; begin++)
2278
				{
2279
					char c = s[begin];
2280
					if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
2281
				}
2282
				for(end = s.Length-1; end >= 0; end--)
2283
				{
2284
					char c = s[end];
2285
					if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
2286
				}
2287
 
2288
				StringBuilder b = new StringBuilder(s.Length);
2289
				for(int i = begin; i <= end; i++)
2290
				{
2291
					char c = s[i];
2292
 
2293
					switch(c)
2294
					{
2295
						case '\n':
2296
							if(b.Length > 0)
2297
							{
2298
								writer.Write(b.ToString());
2299
								b.Length = 0;
2300
							}
2301
 
2302
							writer.WriteLine();
2303
							writer.Write(indent + "  ");
2304
							break;
2305
 
2306
						case '\r':
2307
							break;
2308
 
2309
						case '\t':
2310
							b.Append("  ");
2311
							break;
2312
 
2313
						case '&':
2314
							b.Append("&amp;");
2315
							break;
2316
 
2317
						case '<':
2318
							b.Append("&lt;");
2319
							break;
2320
 
2321
						case '>':
2322
							b.Append("&gt;");
2323
							break;
2324
 
2325
						default:
2326
							b.Append(c);
2327
							break;
2328
					}
2329
				}
2330
 
2331
				if(b.Length > 0)
2332
					writer.Write(b.ToString());
2333
 
2334
				if(newLineFound)
2335
				{
2336
					writer.WriteLine();
2337
					writer.Write(indent + "  ");
2338
				}
2339
			}
2340
		}
2341
 
2342
		#endregion node display classes
2343
 
2344
		#region other classes
2345
		private abstract class Utils
2346
		{
2347
			public static string BytesToString(byte[] bytes, int length)
2348
			{
2349
				if(bytes == null) return null;
2350
 
2351
				char[]  chars   = new char[length + 1];
2352
				Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();
2353
				int     charLen = decoder.GetChars(bytes, 0, length, chars, 0);
2354
 
2355
				for(int i = 0; i < charLen; i++)
2356
				{
2357
					char c = chars[i];
2358
					if(c != '\n' && c != '\r' && Char.IsControl(c)) chars[i] = '.';
2359
				}
2360
 
2361
				return (new System.String(chars)).Substring(0, charLen);
2362
			}
2363
 
2364
			public static ArrayList SplitLine(string line)
2365
			{
2366
				if(line == null) return null;
2367
 
2368
				ArrayList    res = new ArrayList();
2369
				StringBuilder b  = new StringBuilder(200);
2370
 
2371
				foreach(char c in line)
2372
				{
2373
					switch(c)
2374
					{
2375
						case '\r':
2376
							break;
2377
 
2378
						case '\n':
2379
							res.Add(b.ToString());
2380
							b.Length = 0;
2381
							break;
2382
 
2383
						default:
2384
							b.Append(c);
2385
							break;
2386
					}
2387
				}
2388
 
2389
				res.Add(b.ToString());
2390
 
2391
				return res;
2392
			}
2393
		}
2394
		#endregion other classes
2395
	}
2396
 
2397
	public class LogMessages
2398
	{
2399
		private ArrayList messages = new ArrayList();
2400
		private ListBox   logBox;
2401
		private LogLevel  level = LogLevel.Debug;
2402
 
2403
		public LogLevel Level
2404
		{
2405
			get { return level; }
2406
			set { level = value; Update(); }
2407
		}
2408
 
2409
		public LogMessages(ListBox logBox)
2410
		{
2411
			this.logBox = logBox;
2412
		}
2413
 
2414
		public ArrayList Messages
2415
		{
2416
			get { return new ArrayList(messages); }
2417
		}
2418
 
2419
		public void Add(LogMessage message)
2420
		{
2421
			messages.Add(message);
2422
			if(Show(message))
2423
				logBox.TopIndex = logBox.Items.Count - 1;
2424
		}
2425
 
2426
		public void Clear()
2427
		{
2428
			messages.Clear();
2429
			logBox.Items.Clear();
2430
		}
2431
 
2432
		public void Update()
2433
		{
2434
			logBox.BeginUpdate();
2435
 
2436
			logBox.Items.Clear();
2437
			foreach(LogMessage message in messages)
2438
			{
2439
				Show(message);
2440
			}
2441
			logBox.TopIndex = logBox.Items.Count - 1;
2442
 
2443
			logBox.EndUpdate();
2444
		}
2445
 
2446
		private bool Show(LogMessage message)
2447
		{
2448
			if(message.Level > this.level) return false;
2449
 
2450
			try
2451
			{
2452
				logBox.Items.Add(message.ToString());
2453
			}
2454
			catch(ObjectDisposedException) {}
2455
 
2456
			return true;
2457
		}
2458
	}
2459
 
2460
	public class LogMessage
2461
	{
2462
		private TcpConnection tcp;
2463
		private LogLevel      level;
2464
		private string        message;
2465
		private Exception     exception;
2466
		private DateTime      timestamp = DateTime.Now;
2467
 
2468
		public TcpConnection Tcp
2469
		{
2470
			get { return tcp; }
2471
			set { tcp = value; }
2472
		}
2473
 
2474
		public LogLevel Level
2475
		{
2476
			get { return level; }
2477
			set { level = value; }
2478
		}
2479
 
2480
		public string Message
2481
		{
2482
			get { return message; }
2483
			set { message = value; }
2484
		}
2485
 
2486
		public Exception Exception
2487
		{
2488
			get { return exception; }
2489
			set { exception = value; }
2490
		}
2491
 
2492
		public DateTime Timestamp
2493
		{
2494
			get { return timestamp; }
2495
			set { timestamp = value; }
2496
		}
2497
 
2498
		public LogMessage(TcpConnection tcp, LogLevel level, string message, Exception exception)
2499
		{
2500
			this.tcp       = tcp;
2501
			this.level     = level;
2502
			this.message   = message;
2503
			this.exception = exception;
2504
		}
2505
 
2506
		public override string ToString()
2507
		{
2508
			string l = "     ";
2509
			switch(level)
2510
			{
2511
				case LogLevel.Debug:     l = "debug"; break;
2512
				case LogLevel.Info:      l = "info "; break;
2513
				case LogLevel.Important: l = "Imp  "; break;
2514
				case LogLevel.Warning:   l = "Warn "; break;
2515
				case LogLevel.Error:     l = "ERROR"; break;
2516
				case LogLevel.Critical:  l = "CRIT "; break;
2517
			}
2518
 
2519
			return (tcp == null ? "...." : tcp.Id) + " " + l + " " + timestamp.ToString("HH:mm:ss.ffff") + " "
2520
				+ (exception != null ? exception.Message : message);
2521
		}
2522
	}
2523
 
2524
	public enum TcpShowMode
2525
	{
2526
		ByDirection,
2527
		ByTime
2528
	}
1194 dev 2529
 
2530
	public class RecentItem : IComparable
2531
	{
2532
		private int listenPort;
2533
 
2534
		public int ListenPort
2535
		{
2536
			get { return listenPort; }
2537
			set { listenPort = value; }
2538
		}
2539
 
2540
		private string resendHost;
2541
 
2542
		public string ResendHost
2543
		{
2544
			get { return resendHost; }
2545
			set { resendHost = value; }
2546
		}
2547
 
2548
		private int resendPort;
2549
 
2550
		public int ResendPort
2551
		{
2552
			get { return resendPort; }
2553
			set { resendPort = value; }
2554
		}
2555
 
2556
		private DateTime timestamp;
2557
 
2558
		public DateTime Timestamp
2559
		{
2560
			get { return timestamp; }
2561
		}
2562
 
2563
		public RecentItem(int listenPort, string resendHost, int resendPort)
2564
		{
2565
			this.listenPort = listenPort;
2566
			this.resendHost = resendHost;
2567
			this.resendPort = resendPort;
2568
		}
2569
 
2570
		public override string ToString()
2571
		{
1197 dev 2572
			return string.Format("{0} to {1}:{2} at {3:HH:mm:ss.ff}",
1194 dev 2573
				listenPort, resendHost, resendPort, timestamp);
2574
		}
2575
 
2576
		public override bool Equals(object obj)
2577
		{
2578
			if(!(obj is RecentItem)) return false;
2579
 
2580
			RecentItem i2 = (RecentItem)obj;
2581
 
2582
			return (i2.listenPort == this.listenPort) && (i2.resendHost == this.resendHost)
2583
				&& (i2.resendPort == this.resendPort);
2584
		}
2585
 
2586
		public override int GetHashCode()
2587
		{
2588
			return this.resendHost.GetHashCode();
2589
		}
2590
 
2591
		public string SaveToRegistry()
2592
		{
1197 dev 2593
			return string.Format("{0}:{1}:{2}:{3}",
1194 dev 2594
				listenPort, resendPort, timestamp.Ticks, resendHost);
2595
		}
2596
 
2597
		public static RecentItem LoadFromRegistry(string str)
2598
		{
2599
			Regex re = new Regex(@"^(\d+):(\d+):(\d+):(.+)$");
2600
			Match m  = re.Match(str);
2601
			if(!m.Success) throw new Exception("Cannot parse recent item");
2602
 
1197 dev 2603
			RecentItem item = new RecentItem(int.Parse(m.Groups[1].Value),
1194 dev 2604
				m.Groups[4].Value, int.Parse(m.Groups[2].Value));
2605
 
2606
			item.timestamp = new DateTime(long.Parse(m.Groups[3].Value));
2607
 
2608
			return item;
2609
		}
2610
 
2611
		public void UpdateTimestamp()
2612
		{
2613
			timestamp = DateTime.Now;
2614
		}
2615
 
2616
		public void UpdateTimestamp(RecentItem second)
2617
		{
2618
			if(second.timestamp > timestamp)
2619
				timestamp = second.timestamp;
2620
		}
2621
 
2622
		#region IComparable Members
2623
 
2624
		int IComparable.CompareTo(object obj)
2625
		{
2626
			if(!(obj is RecentItem))
2627
				throw new Exception("Cannot compare");
2628
 
2629
			return this.timestamp.CompareTo(((RecentItem)obj).timestamp);
2630
		}
2631
 
2632
		#endregion
2633
	}
1092 dev 2634
}