Subversion Repositories general

Rev

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