Subversion Repositories general

Rev

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