Subversion Repositories general

Rev

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