Subversion Repositories general

Rev

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

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