Subversion Repositories general

Rev

Rev 1232 | Rev 1234 | 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
 
1233 dev 1765
			private object      stateMarker                    = null;
1766
			private object      requestStartMarker             = null;
1767
			private object      requestMethodMarker            = null;
1768
			private object      requestUriMarker               = null;
1769
			private object      requestVersionMarker           = null;
1770
			private object      requestTransferEncodingMarker  = null;
1771
			private object      requestLengthMarker            = null;
1772
			private object      requestContentEncodingMarker   = null;
1773
			private object      requestContentTypeMarker       = null;
1774
			private object      requestCharsetMarker           = null;
1775
			private object      requestHeadersMarker           = null;
1776
			private object      responseStartMarker            = null;
1777
			private object      responseVersionMarker          = null;
1778
			private object      responseStatusMarker           = null;
1779
			private object      responseTransferEncodingMarker = null;
1780
			private object      responseLengthMarker           = null;
1781
			private object      responseContentEncodingMarker  = null;
1782
			private object      responseContentTypeMarker      = null;
1783
			private object      responseCharsetMarker          = null;
1784
			private object      responseHeadersMarker          = null;
1785
			private object      requestBodyMarker              = null;
1786
			private object      responseBodyMarker             = null;
1787
			private IEnumerator requestHeadersEnum             = null;
1788
			private IEnumerator responseHeadersEnum            = null;
1092 dev 1789
 
1790
			public HttpMessage Http
1791
			{
1792
				get { return http; }
1793
				set { http = value; }
1794
			}
1795
 
1796
			public bool RequestXmlShown
1797
			{
1798
				get { return requestXmlShown; }
1799
				set { requestXmlShown = value; }
1800
			}
1801
 
1802
			public bool ResponseXmlShown
1803
			{
1804
				get { return responseXmlShown; }
1805
				set { responseXmlShown = value; }
1806
			}
1807
 
1808
			public HttpNodeData(MainForm owner, TreeNode node) : base(owner, node)
1809
			{
1810
			}
1811
 
1233 dev 1812
			private string EncodingToString(HttpTransferEncoding encoding)
1092 dev 1813
			{
1814
				switch(encoding)
1815
				{
1233 dev 1816
					case HttpTransferEncoding.None:     return "none";
1817
					case HttpTransferEncoding.Identity: return "identity";
1818
					case HttpTransferEncoding.Chunked:  return "chunked";
1819
					case HttpTransferEncoding.Gzip:     return "gzip";
1820
					case HttpTransferEncoding.Compress: return "compress";
1821
					case HttpTransferEncoding.Deflate:  return "deflate";
1822
					default:                            return "<unknown>";
1092 dev 1823
				}
1824
			}
1825
 
1233 dev 1826
			private string EncodingToString(HttpContentEncoding encoding)
1827
			{
1828
				switch(encoding)
1829
				{
1830
					case HttpContentEncoding.None:     return "none";
1831
					case HttpContentEncoding.Identity: return "identity";
1832
					case HttpContentEncoding.Gzip:     return "gzip";
1833
					case HttpContentEncoding.Compress: return "compress";
1834
					case HttpContentEncoding.Deflate:  return "deflate";
1835
					default:                           return "<unknown>";
1836
				}
1837
			}
1838
 
1092 dev 1839
			protected override void InitView()
1840
			{
1841
				try
1842
				{
1843
					lock(http)
1844
					{
1845
						owner.messagesBox.Clear();
1846
 
1847
						owner.messagesBox.AppendNewLine();
1233 dev 1848
						owner.messagesBox.AppendText("Complete:                   ",
1092 dev 1849
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1850
						stateMarker = owner.messagesBox.BeginMark();
1851
						owner.messagesBox.AppendText(http.RequestComplete && http.ResponseComplete ? "YES" : "NO",
1852
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1853
						owner.messagesBox.EndMark(stateMarker);
1854
						owner.messagesBox.AppendNewLine();
1855
						owner.messagesBox.AppendNewLine();
1856
 
1857
						// request info
1233 dev 1858
						owner.messagesBox.AppendText("Request Start:              ",
1125 dev 1859
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1860
						requestStartMarker = owner.messagesBox.BeginMark();
1861
						owner.messagesBox.AppendText(http.RequestStartTimestamp == DateTime.MinValue
1862
							? "<unknown>" : http.RequestStartTimestamp.ToString("HH:mm:ss.ffff"),
1863
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1864
						owner.messagesBox.EndMark(requestStartMarker);
1865
						owner.messagesBox.AppendNewLine();
1866
 
1233 dev 1867
						owner.messagesBox.AppendText("Request Method:             ",
1092 dev 1868
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1869
						requestMethodMarker = owner.messagesBox.BeginMark();
1870
						owner.messagesBox.AppendText(http.RequestMethod,
1871
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1872
						owner.messagesBox.EndMark(requestMethodMarker);
1873
						owner.messagesBox.AppendNewLine();
1874
 
1233 dev 1875
						owner.messagesBox.AppendText("Request URI:                ",
1092 dev 1876
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1877
						requestUriMarker = owner.messagesBox.BeginMark();
1878
						owner.messagesBox.AppendText(http.RequestUri,
1879
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1880
						owner.messagesBox.EndMark(requestUriMarker);
1881
						owner.messagesBox.AppendNewLine();
1882
 
1233 dev 1883
						owner.messagesBox.AppendText("Request Version:            ",
1092 dev 1884
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1885
						requestVersionMarker = owner.messagesBox.BeginMark();
1886
						owner.messagesBox.AppendText(http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
1887
							: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
1888
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1889
						owner.messagesBox.EndMark(requestVersionMarker);
1890
						owner.messagesBox.AppendNewLine();
1891
 
1233 dev 1892
						owner.messagesBox.AppendText("Request Transfer Encoding:  ",
1092 dev 1893
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1233 dev 1894
						requestTransferEncodingMarker = owner.messagesBox.BeginMark();
1895
						owner.messagesBox.AppendText(EncodingToString(http.RequestTransferEncoding),
1896
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1897
						owner.messagesBox.EndMark(requestTransferEncodingMarker);
1898
						owner.messagesBox.AppendNewLine();
1899
 
1900
						owner.messagesBox.AppendText("Request Content Length:     ",
1901
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1092 dev 1902
						requestLengthMarker = owner.messagesBox.BeginMark();
1903
						owner.messagesBox.AppendText(http.RequestLength < 0 ? "<unknown>" : http.RequestLength.ToString(),
1904
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1905
						owner.messagesBox.EndMark(requestLengthMarker);
1906
						owner.messagesBox.AppendNewLine();
1907
 
1233 dev 1908
						owner.messagesBox.AppendText("Request Content Encoding:   ",
1092 dev 1909
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1233 dev 1910
						requestContentEncodingMarker = owner.messagesBox.BeginMark();
1911
						owner.messagesBox.AppendText(EncodingToString(http.RequestContentEncoding),
1092 dev 1912
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1233 dev 1913
						owner.messagesBox.EndMark(requestContentEncodingMarker);
1092 dev 1914
						owner.messagesBox.AppendNewLine();
1915
 
1233 dev 1916
						owner.messagesBox.AppendText("Request Content Type:       ",
1092 dev 1917
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1918
						requestContentTypeMarker = owner.messagesBox.BeginMark();
1919
						owner.messagesBox.AppendText(http.RequestContentType == null ? "<unknown>"
1920
							: http.RequestContentType + "/" + http.RequestContentSubtype,
1921
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1922
						owner.messagesBox.EndMark(requestContentTypeMarker);
1923
						owner.messagesBox.AppendNewLine();
1924
 
1233 dev 1925
						owner.messagesBox.AppendText("Request Content Charset:    ",
1092 dev 1926
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1927
						requestCharsetMarker = owner.messagesBox.BeginMark();
1928
						owner.messagesBox.AppendText(http.RequestCharset == null ? "<unknown>" : http.RequestCharset,
1929
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1930
						owner.messagesBox.EndMark(requestCharsetMarker);
1931
						owner.messagesBox.AppendNewLine();
1932
 
1933
						owner.messagesBox.AppendText("Request Headers:",
1934
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1935
						owner.messagesBox.AppendNewLine();
1936
						requestHeadersMarker = owner.messagesBox.BeginMark();
1937
						owner.messagesBox.EndMark(requestHeadersMarker);
1938
 
1939
						requestHeadersEnum = http.RequestHeaders.GetEnumerator();
1940
						ShowHeaders(requestHeadersEnum, requestHeadersMarker);
1941
 
1942
						// response info
1943
						owner.messagesBox.AppendNewLine();
1233 dev 1944
						owner.messagesBox.AppendText("Response Start:             ",
1125 dev 1945
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1946
						responseStartMarker = owner.messagesBox.BeginMark();
1947
						owner.messagesBox.AppendText(http.ResponseStartTimestamp == DateTime.MinValue
1948
							? "<unknown>" : http.ResponseStartTimestamp.ToString("HH:mm:ss.ffff"),
1949
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1950
						owner.messagesBox.EndMark(responseStartMarker);
1951
						owner.messagesBox.AppendNewLine();
1952
 
1233 dev 1953
						owner.messagesBox.AppendText("Response Version:           ",
1092 dev 1954
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1955
						responseVersionMarker = owner.messagesBox.BeginMark();
1956
						owner.messagesBox.AppendText(http.ResponseVersion == HttpVersion.V0_9
1957
							? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
1958
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1959
						owner.messagesBox.EndMark(responseVersionMarker);
1960
						owner.messagesBox.AppendNewLine();
1961
 
1233 dev 1962
						owner.messagesBox.AppendText("Response Status:            ",
1092 dev 1963
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1964
						responseStatusMarker = owner.messagesBox.BeginMark();
1965
						owner.messagesBox.AppendText(http.ResponseStatusCode + " " + http.ResponseStatusMessage,
1966
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1967
						owner.messagesBox.EndMark(responseStatusMarker);
1968
						owner.messagesBox.AppendNewLine();
1969
 
1233 dev 1970
						owner.messagesBox.AppendText("Response Transfer Encoding: ",
1092 dev 1971
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1233 dev 1972
						responseTransferEncodingMarker = owner.messagesBox.BeginMark();
1973
						owner.messagesBox.AppendText(EncodingToString(http.ResponseTransferEncoding),
1974
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1975
						owner.messagesBox.EndMark(responseTransferEncodingMarker);
1976
						owner.messagesBox.AppendNewLine();
1977
 
1978
						owner.messagesBox.AppendText("Response Content Length:    ",
1979
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1092 dev 1980
						responseLengthMarker = owner.messagesBox.BeginMark();
1981
						owner.messagesBox.AppendText(http.ResponseLength < 0 ? "<unknown>" : http.ResponseLength.ToString(),
1982
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1983
						owner.messagesBox.EndMark(responseLengthMarker);
1984
						owner.messagesBox.AppendNewLine();
1985
 
1233 dev 1986
						owner.messagesBox.AppendText("Response Content Encoding:  ",
1092 dev 1987
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1233 dev 1988
						responseContentEncodingMarker = owner.messagesBox.BeginMark();
1989
						owner.messagesBox.AppendText(EncodingToString(http.ResponseContentEncoding),
1092 dev 1990
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1233 dev 1991
						owner.messagesBox.EndMark(responseContentEncodingMarker);
1092 dev 1992
						owner.messagesBox.AppendNewLine();
1993
 
1233 dev 1994
						owner.messagesBox.AppendText("Response Content Type:      ",
1092 dev 1995
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
1996
						responseContentTypeMarker = owner.messagesBox.BeginMark();
1997
						owner.messagesBox.AppendText(http.ResponseContentType == null ? "<unknown>"
1998
							: http.ResponseContentType + "/" + http.ResponseContentSubtype,
1999
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2000
						owner.messagesBox.EndMark(responseContentTypeMarker);
2001
						owner.messagesBox.AppendNewLine();
2002
 
1233 dev 2003
						owner.messagesBox.AppendText("Response Content Charset:   ",
1092 dev 2004
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
2005
						responseCharsetMarker = owner.messagesBox.BeginMark();
2006
						owner.messagesBox.AppendText(http.ResponseCharset == null ? "<unknown>" : http.ResponseCharset,
2007
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2008
						owner.messagesBox.EndMark(responseCharsetMarker);
2009
						owner.messagesBox.AppendNewLine();
2010
 
2011
						owner.messagesBox.AppendText("Response Headers:",
2012
							Color.DarkRed, Color.Transparent, false, false, 0, 0);
2013
						owner.messagesBox.AppendNewLine();
2014
						responseHeadersMarker = owner.messagesBox.BeginMark();
2015
						owner.messagesBox.EndMark(responseHeadersMarker);
2016
 
2017
						responseHeadersEnum = http.ResponseHeaders.GetEnumerator();
2018
						ShowHeaders(responseHeadersEnum, responseHeadersMarker);
2019
 
2020
						owner.messagesBox.AppendNewLine();
2021
						requestBodyMarker = owner.messagesBox.BeginMark();
2022
						owner.messagesBox.EndMark(requestBodyMarker);
2023
						ShowBody(requestBodyMarker, http.RequestBody, http.RequestLength, http.RequestText, Color.Green);
2024
 
2025
						owner.messagesBox.AppendNewLine();
2026
						responseBodyMarker = owner.messagesBox.BeginMark();
2027
						owner.messagesBox.EndMark(responseBodyMarker);
2028
						ShowBody(responseBodyMarker, http.ResponseBody, http.ResponseLength, http.ResponseText, Color.Blue);
2029
					}
2030
				}
2031
				finally
2032
				{
2033
					owner.messagesBox.EndUpdate();
2034
				}
2035
			}
2036
 
2037
			protected override void UpdateView()
2038
			{
2039
				try
2040
				{
2041
					owner.messagesBox.BeginUpdate();
2042
 
2043
					lock(http)
2044
					{
2045
						owner.messagesBox.ChangeText(stateMarker, http.RequestComplete && http.ResponseComplete ? "YES" : "NO",
2046
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2047
						owner.messagesBox.ChangeText(requestMethodMarker, http.RequestMethod,
2048
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2049
						owner.messagesBox.ChangeText(requestUriMarker, http.RequestUri,
2050
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2051
						owner.messagesBox.ChangeText(requestVersionMarker, http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
2052
							: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
2053
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1233 dev 2054
						owner.messagesBox.ChangeText(requestTransferEncodingMarker, EncodingToString(http.RequestTransferEncoding),
2055
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1092 dev 2056
						owner.messagesBox.ChangeText(requestLengthMarker, http.RequestLength < 0
2057
							? "<unknown>" : http.RequestLength.ToString(),
2058
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1233 dev 2059
						owner.messagesBox.ChangeText(requestContentEncodingMarker, EncodingToString(http.RequestContentEncoding),
1092 dev 2060
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2061
						owner.messagesBox.ChangeText(requestContentTypeMarker, http.RequestContentType == null ? "<unknown>"
2062
							: http.RequestContentType + "/" + http.RequestContentSubtype,
2063
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2064
						owner.messagesBox.ChangeText(requestCharsetMarker, http.RequestCharset == null
2065
							? "<unknown>" : http.RequestCharset,
2066
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2067
 
2068
						ShowHeaders(requestHeadersEnum, requestHeadersMarker);
2069
 
2070
						owner.messagesBox.ChangeText(responseVersionMarker, http.ResponseVersion == HttpVersion.V0_9
2071
							? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1",
2072
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2073
						owner.messagesBox.ChangeText(responseStatusMarker, http.ResponseStatusCode + " " + http.ResponseStatusMessage,
2074
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1233 dev 2075
						owner.messagesBox.ChangeText(responseTransferEncodingMarker, EncodingToString(http.ResponseTransferEncoding),
2076
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1092 dev 2077
						owner.messagesBox.ChangeText(responseLengthMarker, http.ResponseLength < 0
2078
							? "<unknown>" : http.ResponseLength.ToString(),
2079
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
1233 dev 2080
						owner.messagesBox.ChangeText(responseContentEncodingMarker, EncodingToString(http.ResponseContentEncoding),
1092 dev 2081
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2082
						owner.messagesBox.ChangeText(responseContentTypeMarker, http.ResponseContentType == null ? "<unknown>"
2083
							: http.ResponseContentType + "/" + http.ResponseContentSubtype,
2084
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2085
						owner.messagesBox.ChangeText(responseCharsetMarker, http.ResponseCharset == null
2086
							? "<unknown>" : http.ResponseCharset,
2087
							Color.DarkRed, Color.LightGray, false, false, 0, 27);
2088
 
2089
						ShowHeaders(responseHeadersEnum, responseHeadersMarker);
2090
 
2091
						owner.messagesBox.DeleteText(requestBodyMarker);
2092
						ShowBody(requestBodyMarker, http.RequestBody, http.RequestLength, http.RequestText, Color.Green);
2093
						owner.messagesBox.DeleteText(responseBodyMarker);
2094
						ShowBody(responseBodyMarker, http.ResponseBody, http.ResponseLength, http.ResponseText, Color.Blue);
2095
					}
2096
				}
2097
				finally
2098
				{
2099
					owner.messagesBox.EndUpdate();
2100
				}
2101
			}
2102
 
2103
			private void ShowHeaders(IEnumerator headers, object marker)
2104
			{
2105
				while(headers.MoveNext())
2106
				{
2107
					HttpHeader h = (HttpHeader)headers.Current;
2108
 
2109
					bool first = true;
2110
					foreach(string val in h.Values)
2111
					{
2112
						if(first)
2113
						{
2114
							owner.messagesBox.InsertText(marker, h.Name + ":",
2115
								Color.DarkRed, Color.Transparent, false, false, 4, 4);
2116
							owner.messagesBox.InsertText(marker, null,
2117
								Color.DarkRed, Color.Transparent, false, false, 6 - 4 - 1, 4);
2118
							first = false;
2119
						}
2120
						else
2121
						{
2122
							owner.messagesBox.InsertText(marker, null,
2123
								Color.DarkRed, Color.Transparent, false, false, 6 + h.Name.Length, 6 + h.Name.Length);
2124
						}
2125
						owner.messagesBox.InsertText(marker, val,
2126
							Color.DarkRed, Color.LightGray, false, false, 0, 6 + h.Name.Length);
2127
						owner.messagesBox.InsertNewLine(marker);
2128
					}
2129
				}
2130
			}
2131
 
2132
			private void ShowBody(object marker, byte[] body, int len, string text, Color color)
2133
			{
2134
				if(text != null)
2135
				{
2136
					ArrayList lines = Utils.SplitLine(text);
2137
					for(int i = 0; i < lines.Count; i++)
2138
					{
2139
						owner.messagesBox.InsertText(marker, (string)lines[i], color, Color.LightGray, false, false, 0, 0);
2140
						owner.messagesBox.InsertNewLine(marker);
2141
					}
2142
				}
2143
				else if(body != null)
2144
				{
2145
					ArrayList lines = Utils.SplitLine(Utils.BytesToString(body, len));
2146
					for(int i = 0; i < lines.Count; i++)
2147
					{
2148
						owner.messagesBox.InsertText(marker, (string)lines[i], color, Color.LightGray, false, false, 0, 0);
2149
						owner.messagesBox.InsertNewLine(marker);
2150
					}
2151
				}
2152
			}
2153
 
2154
			public override void WriteLog(StreamWriter writer)
2155
			{
2156
				// request info
2157
				writer.WriteLine(
1233 dev 2158
					"Complete:                   " + (http.RequestComplete && http.ResponseComplete ? "YES" : "NO") + "\r\n"
2159
					+ "\r\nRequest Method:             " + http.RequestMethod
2160
					+ "\r\nRequest URI:                " + http.RequestUri
2161
					+ "\r\nRequest Version:            " + (http.RequestVersion == HttpVersion.V0_9 ? "HTTP/0.9"
1092 dev 2162
						: http.RequestVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1")
1233 dev 2163
					+ "\r\nRequest Transfer Encoding:  " + EncodingToString(http.RequestTransferEncoding)
2164
					+ "\r\nRequest Content Length:     " + (http.RequestLength < 0 ? "<unknown>" : http.RequestLength.ToString())
2165
					+ "\r\nRequest Content Encoding:   " + EncodingToString(http.RequestContentEncoding)
2166
					+ "\r\nRequest Content Type:       " + (http.RequestContentType == null ? "<unknown>"
1092 dev 2167
						: http.RequestContentType + "/" + http.RequestContentSubtype)
1233 dev 2168
					+ "\r\nRequest Content Charset:    " + (http.RequestCharset == null ? "<unknown>" : http.RequestCharset)
1092 dev 2169
					+ "\r\nRequest Headers:");
2170
 
2171
				foreach(HttpHeader h in http.RequestHeaders)
2172
				{
2173
					int indent = 0;
2174
					foreach(string val in h.Values)
2175
					{
2176
						if(indent == 0)
2177
						{
2178
							writer.WriteLine("    {0}: {1}", h.Name, val);
2179
							indent = 6 + h.Name.Length;
2180
						}
2181
						else
2182
						{
2183
							writer.WriteLine("{0," + indent + "}{1}", " ", val);
2184
						}
2185
					}
2186
				}
2187
 
2188
				// response info
2189
				writer.WriteLine(
1233 dev 2190
					"\r\nResponse Version:           " + (http.ResponseVersion == HttpVersion.V0_9
1092 dev 2191
						? "HTTP/0.9" : http.ResponseVersion == HttpVersion.V1_0 ? "HTTP/1.0" : "HTTP/1.1")
1233 dev 2192
					+ "\r\nResponse Status:            " + http.ResponseStatusCode + " " + http.ResponseStatusMessage
2193
					+ "\r\nResponse Transfer Encoding: " + EncodingToString(http.ResponseTransferEncoding)
2194
					+ "\r\nResponse Content Length:    " + (http.ResponseLength < 0
1092 dev 2195
						? "<unknown>" : http.ResponseLength.ToString())
1233 dev 2196
					+ "\r\nResponse Content Encoding:  " + EncodingToString(http.ResponseContentEncoding)
2197
					+ "\r\nResponse Content Type:      " + (http.ResponseContentType == null ? "<unknown>"
1092 dev 2198
						: http.ResponseContentType + "/" + http.ResponseContentSubtype)
1233 dev 2199
					+ "\r\nResponse Content Charset:   " + (http.ResponseCharset == null ? "<unknown>" : http.ResponseCharset)
1092 dev 2200
					+ "\r\nResponse Headers:");
2201
 
2202
				foreach(HttpHeader h in http.ResponseHeaders)
2203
				{
2204
					int indent = 0;
2205
					foreach(string val in h.Values)
2206
					{
2207
						if(indent == 0)
2208
						{
2209
							writer.WriteLine("    {0}: {1}", h.Name, val);
2210
							indent = 6 + h.Name.Length;
2211
						}
2212
						else
2213
						{
2214
							writer.WriteLine("{0," + indent + "}{1}", " ", val);
2215
						}
2216
					}
2217
				}
2218
				writer.WriteLine();
2219
 
2220
				// request body
2221
				if(http.RequestText != null)
2222
				{
2223
					writer.WriteLine(http.RequestText);
2224
				}
2225
				else if(http.RequestBody != null)
2226
				{
2227
					writer.WriteLine(Utils.BytesToString(http.RequestBody, http.RequestLength));
2228
				}
2229
 
2230
				// response body
2231
				if(http.ResponseText != null)
2232
				{
2233
					writer.WriteLine(http.ResponseText);
2234
				}
2235
				else if(http.ResponseBody != null)
2236
				{
2237
					writer.WriteLine(Utils.BytesToString(http.ResponseBody, http.ResponseLength));
2238
				}
2239
 
2240
				writer.WriteLine("===============================================================");
2241
				writer.WriteLine();
2242
			}
2243
		}
2244
 
2245
		private class XmlNodeData : TreeNodeData
2246
		{
2247
			private XmlMessage xml;
2248
 
2249
			public XmlMessage Xml
2250
			{
2251
				get { return xml; }
2252
				set { xml = value; }
2253
			}
2254
 
2255
			public XmlNodeData(MainForm owner, TreeNode node) : base(owner, node)
2256
			{
2257
			}
2258
 
2259
			protected override void InitView()
2260
			{
2261
				try
2262
				{
2263
					// update main screen if necessary
2264
					owner.messagesBox.BeginUpdate();
2265
 
2266
					lock(xml)
2267
					{
2268
						owner.messagesBox.Clear();
2269
						if(xml.ParseException != null)
2270
						{
2271
							owner.messagesBox.AppendText("Cannot parse XML:",
2272
								Color.Red, Color.Transparent, false, false, 0, 0);
2273
							owner.messagesBox.AppendNewLine();
2274
							owner.messagesBox.AppendText(xml.ParseException.Message,
2275
								Color.Red, Color.Transparent, false, false, 2, 2);
2276
							owner.messagesBox.AppendNewLine();
2277
						}
2278
						else if(xml.Xml != null)
2279
						{
2280
							ShowXmlNode(xml.Xml, 0);
2281
						}
2282
					}
2283
				}
2284
				finally
2285
				{
2286
					owner.messagesBox.EndUpdate();
2287
				}
2288
			}
2289
 
2290
			protected override void UpdateView()
2291
			{
2292
			}
2293
 
2294
			private void ShowXmlNode(XmlNode node, int indent)
2295
			{
2296
				if(node.NodeType == XmlNodeType.Document)
2297
				{
2298
					foreach(XmlNode subnode in node.ChildNodes)
2299
					{
2300
						ShowXmlNode(subnode, indent);
2301
					}
2302
				}
2303
				else if(node.NodeType == XmlNodeType.XmlDeclaration)
2304
				{
2305
					owner.messagesBox.AppendText("<?" + node.Name + " " + node.Value + " ?>",
2306
						Color.Blue, Color.Transparent, false, false, indent, indent+2);
2307
					owner.messagesBox.AppendNewLine();
2308
				}
2309
				else if(node.NodeType == XmlNodeType.Comment)
2310
				{
2311
					owner.messagesBox.AppendText("<!--", Color.Gray, Color.Transparent, false, false, indent, indent + 2);
2312
					ShowNormalizedXmlValue(node.Value, Color.Gray, Color.Thistle, false, false, indent);
2313
					owner.messagesBox.AppendText("-->", Color.Gray, Color.Transparent, false, false, 0, indent + 2);
2314
					owner.messagesBox.AppendNewLine();
2315
				}
2316
				else if(node.NodeType == XmlNodeType.Element)
2317
				{
2318
					owner.messagesBox.AppendText("<", Color.Blue, Color.Transparent, false, false, indent, indent + 2);
2319
					owner.messagesBox.AppendText(node.Name, Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
2320
 
2321
					foreach(XmlAttribute attr in node.Attributes)
2322
					{
2323
						bool xmlAttr = attr.Name.StartsWith("xml");
2324
						owner.messagesBox.AppendText(attr.Name, xmlAttr ? Color.Red : Color.DarkRed, Color.Transparent, false, false, 1, indent + 2);
2325
						owner.messagesBox.AppendText("=\"", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2326
						owner.messagesBox.AppendText(attr.Value, xmlAttr ? Color.Red : Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
2327
						owner.messagesBox.AppendText("\"", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2328
					}
2329
 
2330
					if(!node.HasChildNodes)
2331
					{
2332
						owner.messagesBox.AppendText(" />", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2333
						owner.messagesBox.AppendNewLine();
2334
					}
2335
					else
2336
					{
2337
						owner.messagesBox.AppendText(">", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2338
 
2339
						bool elementExists = false;
2340
						bool lastText      = true;
2341
						foreach(XmlNode subnode in node.ChildNodes)
2342
						{
2343
							if(subnode.NodeType == XmlNodeType.Text)
2344
							{
2345
								if(elementExists) owner.messagesBox.AppendNewLine();
2346
								ShowNormalizedXmlValue(subnode.Value, Color.Black, Color.LightGray, false, false, indent);
2347
								lastText = true;
2348
							}
2349
							else
2350
							{
2351
								if(lastText) owner.messagesBox.AppendNewLine();
2352
								ShowXmlNode(subnode, indent + 2);
2353
								elementExists = true;
2354
								lastText      = false;
2355
							}
2356
						}
2357
 
2358
						if(elementExists) owner.messagesBox.AppendText(null, Color.Black, Color.Transparent, false, false, indent, indent + 2);
2359
						owner.messagesBox.AppendText("</", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2360
						owner.messagesBox.AppendText(node.Name, Color.DarkRed, Color.Transparent, false, false, 0, indent + 2);
2361
						owner.messagesBox.AppendText(">", Color.Blue, Color.Transparent, false, false, 0, indent + 2);
2362
						owner.messagesBox.AppendNewLine();
2363
					}
2364
				}
2365
			}
2366
 
2367
			private void ShowNormalizedXmlValue(string s, Color color, Color backColor, bool italic, bool bold, int indent)
2368
			{
2369
				int begin;
2370
				int end;
2371
 
2372
				bool newLineFound = false;
2373
				foreach(char c in s)
2374
				{
2375
					if(c == '\n')
2376
					{
2377
						newLineFound = true;
2378
						break;
2379
					}
2380
				}
2381
 
2382
				if(newLineFound)
2383
				{
2384
					owner.messagesBox.AppendNewLine();
2385
					owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent);
2386
					owner.messagesBox.AppendText(null, color, backColor, italic, bold, 2, 2);
2387
				}
2388
 
2389
				// trim
2390
				for(begin = 0; begin < s.Length; begin++)
2391
				{
2392
					char c = s[begin];
2393
					if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
2394
				}
2395
				for(end = s.Length-1; end >= 0; end--)
2396
				{
2397
					char c = s[end];
2398
					if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
2399
				}
2400
 
2401
				StringBuilder b = new StringBuilder(s.Length);
2402
				for(int i = begin; i <= end; i++)
2403
				{
2404
					char c = s[i];
2405
 
2406
					switch(c)
2407
					{
2408
						case '\n':
2409
							if(b.Length > 0)
2410
							{
2411
								owner.messagesBox.AppendText(b.ToString(), color, backColor, italic, bold, 0, indent + 2);
2412
								b.Length = 0;
2413
							}
2414
 
2415
							owner.messagesBox.AppendNewLine();
2416
							owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent);
2417
							owner.messagesBox.AppendText(null, color, backColor, italic, bold, 2, 2);
2418
							break;
2419
 
2420
						case '\r':
2421
							break;
2422
 
2423
						case '\t':
2424
							b.Append("  ");
2425
							break;
2426
 
2427
						default:
2428
							b.Append(c);
2429
							break;
2430
					}
2431
				}
2432
 
2433
				if(b.Length > 0)
2434
					owner.messagesBox.AppendText(b.ToString(), color, backColor, italic, bold, 0, indent + 2);
2435
 
2436
				if(newLineFound)
2437
				{
2438
					owner.messagesBox.AppendNewLine();
2439
					owner.messagesBox.AppendText(null, color, Color.Transparent, italic, bold, indent, indent + 2);
2440
				}
2441
			}
2442
 
2443
			public override void WriteLog(StreamWriter writer)
2444
			{
2445
				WriteXmlNode(writer, xml.Xml, "");
2446
				writer.WriteLine("===============================================================");
2447
				writer.WriteLine();
2448
			}
2449
 
2450
			private void WriteXmlNode(StreamWriter writer, XmlNode node, string indent)
2451
			{
2452
				if(node.NodeType == XmlNodeType.Document)
2453
				{
2454
					foreach(XmlNode subnode in node.ChildNodes)
2455
					{
2456
						WriteXmlNode(writer, subnode, indent);
2457
					}
2458
				}
2459
				else if(node.NodeType == XmlNodeType.XmlDeclaration)
2460
				{
2461
					writer.WriteLine(indent + "<?" + node.Name + " " + node.Value + " ?>");
2462
				}
2463
				else if(node.NodeType == XmlNodeType.Comment)
2464
				{
2465
					writer.Write(indent + "<!--");
2466
					WriteNormalizedXmlValue(writer, node.Value, indent);
2467
					writer.WriteLine("-->");
2468
				}
2469
				else if(node.NodeType == XmlNodeType.Element)
2470
				{
2471
					writer.Write(indent + "<" + node.Name);
2472
 
2473
					foreach(XmlAttribute attr in node.Attributes)
2474
					{
2475
						bool xmlAttr = attr.Name.StartsWith("xml");
2476
						writer.Write(" " + attr.Name + "=\"" + attr.Value + "\"");
2477
					}
2478
 
2479
					if(!node.HasChildNodes)
2480
					{
2481
						writer.WriteLine(" />");
2482
					}
2483
					else
2484
					{
2485
						writer.Write(">");
2486
 
2487
						bool elementExists = false;
2488
						bool lastText      = true;
2489
						foreach(XmlNode subnode in node.ChildNodes)
2490
						{
2491
							if(subnode.NodeType == XmlNodeType.Text)
2492
							{
2493
								if(elementExists) writer.WriteLine();
2494
								WriteNormalizedXmlValue(writer, subnode.Value, indent);
2495
								lastText = true;
2496
							}
2497
							else
2498
							{
2499
								if(lastText) writer.WriteLine();
2500
								WriteXmlNode(writer, subnode, indent + "  ");
2501
								elementExists = true;
2502
								lastText      = false;
2503
							}
2504
						}
2505
 
2506
						if(elementExists) writer.Write(indent);
2507
						writer.WriteLine("</" + node.Name + ">");
2508
					}
2509
				}
2510
			}
2511
 
2512
			private void WriteNormalizedXmlValue(StreamWriter writer, string s, string indent)
2513
			{
2514
				int begin;
2515
				int end;
2516
 
2517
				bool newLineFound = false;
2518
				foreach(char c in s)
2519
				{
2520
					if(c == '\n')
2521
					{
2522
						newLineFound = true;
2523
						break;
2524
					}
2525
				}
2526
 
2527
				if(newLineFound)
2528
				{
2529
					writer.WriteLine();
2530
					writer.Write(indent + "  ");
2531
				}
2532
 
2533
				// trim
2534
				for(begin = 0; begin < s.Length; begin++)
2535
				{
2536
					char c = s[begin];
2537
					if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
2538
				}
2539
				for(end = s.Length-1; end >= 0; end--)
2540
				{
2541
					char c = s[end];
2542
					if(c != '\n' && c != '\r' && c != '\t' && c != ' ') break;
2543
				}
2544
 
2545
				StringBuilder b = new StringBuilder(s.Length);
2546
				for(int i = begin; i <= end; i++)
2547
				{
2548
					char c = s[i];
2549
 
2550
					switch(c)
2551
					{
2552
						case '\n':
2553
							if(b.Length > 0)
2554
							{
2555
								writer.Write(b.ToString());
2556
								b.Length = 0;
2557
							}
2558
 
2559
							writer.WriteLine();
2560
							writer.Write(indent + "  ");
2561
							break;
2562
 
2563
						case '\r':
2564
							break;
2565
 
2566
						case '\t':
2567
							b.Append("  ");
2568
							break;
2569
 
2570
						case '&':
2571
							b.Append("&amp;");
2572
							break;
2573
 
2574
						case '<':
2575
							b.Append("&lt;");
2576
							break;
2577
 
2578
						case '>':
2579
							b.Append("&gt;");
2580
							break;
2581
 
2582
						default:
2583
							b.Append(c);
2584
							break;
2585
					}
2586
				}
2587
 
2588
				if(b.Length > 0)
2589
					writer.Write(b.ToString());
2590
 
2591
				if(newLineFound)
2592
				{
2593
					writer.WriteLine();
2594
					writer.Write(indent + "  ");
2595
				}
2596
			}
2597
		}
2598
 
2599
		#endregion node display classes
2600
 
2601
		#region other classes
2602
		private abstract class Utils
2603
		{
2604
			public static string BytesToString(byte[] bytes, int length)
2605
			{
2606
				if(bytes == null) return null;
2607
 
2608
				char[]  chars   = new char[length + 1];
2609
				Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();
2610
				int     charLen = decoder.GetChars(bytes, 0, length, chars, 0);
2611
 
2612
				for(int i = 0; i < charLen; i++)
2613
				{
2614
					char c = chars[i];
2615
					if(c != '\n' && c != '\r' && Char.IsControl(c)) chars[i] = '.';
2616
				}
2617
 
2618
				return (new System.String(chars)).Substring(0, charLen);
2619
			}
2620
 
2621
			public static ArrayList SplitLine(string line)
2622
			{
2623
				if(line == null) return null;
2624
 
2625
				ArrayList    res = new ArrayList();
2626
				StringBuilder b  = new StringBuilder(200);
2627
 
2628
				foreach(char c in line)
2629
				{
2630
					switch(c)
2631
					{
2632
						case '\r':
2633
							break;
2634
 
2635
						case '\n':
2636
							res.Add(b.ToString());
2637
							b.Length = 0;
2638
							break;
2639
 
2640
						default:
2641
							b.Append(c);
2642
							break;
2643
					}
2644
				}
2645
 
2646
				res.Add(b.ToString());
2647
 
2648
				return res;
2649
			}
2650
		}
2651
		#endregion other classes
2652
	}
2653
 
2654
	public class LogMessages
2655
	{
2656
		private ArrayList messages = new ArrayList();
2657
		private ListBox   logBox;
2658
		private LogLevel  level = LogLevel.Debug;
2659
 
2660
		public LogLevel Level
2661
		{
2662
			get { return level; }
2663
			set { level = value; Update(); }
2664
		}
2665
 
2666
		public LogMessages(ListBox logBox)
2667
		{
2668
			this.logBox = logBox;
2669
		}
2670
 
2671
		public ArrayList Messages
2672
		{
2673
			get { return new ArrayList(messages); }
2674
		}
2675
 
2676
		public void Add(LogMessage message)
2677
		{
2678
			messages.Add(message);
2679
			if(Show(message))
2680
				logBox.TopIndex = logBox.Items.Count - 1;
2681
		}
2682
 
2683
		public void Clear()
2684
		{
2685
			messages.Clear();
2686
			logBox.Items.Clear();
2687
		}
2688
 
2689
		public void Update()
2690
		{
2691
			logBox.BeginUpdate();
2692
 
2693
			logBox.Items.Clear();
2694
			foreach(LogMessage message in messages)
2695
			{
2696
				Show(message);
2697
			}
2698
			logBox.TopIndex = logBox.Items.Count - 1;
2699
 
2700
			logBox.EndUpdate();
2701
		}
2702
 
2703
		private bool Show(LogMessage message)
2704
		{
2705
			if(message.Level > this.level) return false;
2706
 
2707
			try
2708
			{
2709
				logBox.Items.Add(message.ToString());
2710
			}
2711
			catch(ObjectDisposedException) {}
2712
 
2713
			return true;
2714
		}
2715
	}
2716
 
2717
	public class LogMessage
2718
	{
2719
		private TcpConnection tcp;
2720
		private LogLevel      level;
2721
		private string        message;
2722
		private Exception     exception;
2723
		private DateTime      timestamp = DateTime.Now;
2724
 
2725
		public TcpConnection Tcp
2726
		{
2727
			get { return tcp; }
2728
			set { tcp = value; }
2729
		}
2730
 
2731
		public LogLevel Level
2732
		{
2733
			get { return level; }
2734
			set { level = value; }
2735
		}
2736
 
2737
		public string Message
2738
		{
2739
			get { return message; }
2740
			set { message = value; }
2741
		}
2742
 
2743
		public Exception Exception
2744
		{
2745
			get { return exception; }
2746
			set { exception = value; }
2747
		}
2748
 
2749
		public DateTime Timestamp
2750
		{
2751
			get { return timestamp; }
2752
			set { timestamp = value; }
2753
		}
2754
 
2755
		public LogMessage(TcpConnection tcp, LogLevel level, string message, Exception exception)
2756
		{
2757
			this.tcp       = tcp;
2758
			this.level     = level;
2759
			this.message   = message;
2760
			this.exception = exception;
2761
		}
2762
 
2763
		public override string ToString()
2764
		{
2765
			string l = "     ";
2766
			switch(level)
2767
			{
2768
				case LogLevel.Debug:     l = "debug"; break;
2769
				case LogLevel.Info:      l = "info "; break;
2770
				case LogLevel.Important: l = "Imp  "; break;
2771
				case LogLevel.Warning:   l = "Warn "; break;
2772
				case LogLevel.Error:     l = "ERROR"; break;
2773
				case LogLevel.Critical:  l = "CRIT "; break;
2774
			}
2775
 
2776
			return (tcp == null ? "...." : tcp.Id) + " " + l + " " + timestamp.ToString("HH:mm:ss.ffff") + " "
2777
				+ (exception != null ? exception.Message : message);
2778
		}
2779
	}
2780
 
2781
	public enum TcpShowMode
2782
	{
2783
		ByDirection,
2784
		ByTime
2785
	}
1194 dev 2786
 
2787
	public class RecentItem : IComparable
2788
	{
2789
		private int listenPort;
2790
 
2791
		public int ListenPort
2792
		{
2793
			get { return listenPort; }
2794
			set { listenPort = value; }
2795
		}
2796
 
2797
		private string resendHost;
2798
 
2799
		public string ResendHost
2800
		{
2801
			get { return resendHost; }
2802
			set { resendHost = value; }
2803
		}
2804
 
2805
		private int resendPort;
2806
 
2807
		public int ResendPort
2808
		{
2809
			get { return resendPort; }
2810
			set { resendPort = value; }
2811
		}
2812
 
2813
		private DateTime timestamp;
2814
 
2815
		public DateTime Timestamp
2816
		{
2817
			get { return timestamp; }
2818
		}
2819
 
2820
		public RecentItem(int listenPort, string resendHost, int resendPort)
2821
		{
2822
			this.listenPort = listenPort;
2823
			this.resendHost = resendHost;
2824
			this.resendPort = resendPort;
2825
		}
2826
 
2827
		public override string ToString()
2828
		{
1197 dev 2829
			return string.Format("{0} to {1}:{2} at {3:HH:mm:ss.ff}",
1194 dev 2830
				listenPort, resendHost, resendPort, timestamp);
2831
		}
2832
 
2833
		public override bool Equals(object obj)
2834
		{
2835
			if(!(obj is RecentItem)) return false;
2836
 
2837
			RecentItem i2 = (RecentItem)obj;
2838
 
2839
			return (i2.listenPort == this.listenPort) && (i2.resendHost == this.resendHost)
2840
				&& (i2.resendPort == this.resendPort);
2841
		}
2842
 
2843
		public override int GetHashCode()
2844
		{
2845
			return this.resendHost.GetHashCode();
2846
		}
2847
 
2848
		public string SaveToRegistry()
2849
		{
1197 dev 2850
			return string.Format("{0}:{1}:{2}:{3}",
1194 dev 2851
				listenPort, resendPort, timestamp.Ticks, resendHost);
2852
		}
2853
 
2854
		public static RecentItem LoadFromRegistry(string str)
2855
		{
2856
			Regex re = new Regex(@"^(\d+):(\d+):(\d+):(.+)$");
2857
			Match m  = re.Match(str);
2858
			if(!m.Success) throw new Exception("Cannot parse recent item");
2859
 
1197 dev 2860
			RecentItem item = new RecentItem(int.Parse(m.Groups[1].Value),
1194 dev 2861
				m.Groups[4].Value, int.Parse(m.Groups[2].Value));
2862
 
2863
			item.timestamp = new DateTime(long.Parse(m.Groups[3].Value));
2864
 
2865
			return item;
2866
		}
2867
 
2868
		public void UpdateTimestamp()
2869
		{
2870
			timestamp = DateTime.Now;
2871
		}
2872
 
2873
		public void UpdateTimestamp(RecentItem second)
2874
		{
2875
			if(second.timestamp > timestamp)
2876
				timestamp = second.timestamp;
2877
		}
2878
 
2879
		#region IComparable Members
2880
 
2881
		int IComparable.CompareTo(object obj)
2882
		{
2883
			if(!(obj is RecentItem))
2884
				throw new Exception("Cannot compare");
2885
 
2886
			return this.timestamp.CompareTo(((RecentItem)obj).timestamp);
2887
		}
2888
 
2889
		#endregion
2890
	}
1092 dev 2891
}