├── .gitignore ├── .gitmodules ├── FiddlerMsgPackViewer.sln ├── MsgPackViewer ├── MsgPackRequestView.cs ├── MsgPackResponseView.cs ├── MsgPackViewBase.cs ├── MsgPackViewer.Designer.cs ├── MsgPackViewer.cs ├── MsgPackViewer.csproj ├── MsgPackViewer.resx └── Properties │ └── AssemblyInfo.cs └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | [oO]bj/ 2 | [bB]in/ 3 | ClientBin/ 4 | deploy/ 5 | packages/ 6 | *.user 7 | *.suo 8 | *.cache 9 | _ReSharper.* 10 | *.resharper 11 | *.DotSettings 12 | Thumbs.db -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "MsgPackSlim"] 2 | path = MsgPackSlim 3 | url = https://github.com/jessemcdowell/MsgPackSlim 4 | -------------------------------------------------------------------------------- /FiddlerMsgPackViewer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MsgPackViewer", "MsgPackViewer\MsgPackViewer.csproj", "{DA080874-FDC8-4364-8D6C-AD90E5FF82A4}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DA080874-FDC8-4364-8D6C-AD90E5FF82A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {DA080874-FDC8-4364-8D6C-AD90E5FF82A4}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {DA080874-FDC8-4364-8D6C-AD90E5FF82A4}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {DA080874-FDC8-4364-8D6C-AD90E5FF82A4}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /MsgPackViewer/MsgPackRequestView.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | 3 | namespace MsgPackViewer 4 | { 5 | public class MsgPackRequestView : MsgPackViewBase, IRequestInspector2 6 | { 7 | public HTTPRequestHeaders headers { get; set; } 8 | 9 | protected override HTTPHeaders GetHeaders() 10 | { 11 | return headers; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MsgPackViewer/MsgPackResponseView.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | 3 | namespace MsgPackViewer 4 | { 5 | public class MsgPackResponseView : MsgPackViewBase, IResponseInspector2 6 | { 7 | public HTTPResponseHeaders headers { get; set; } 8 | 9 | protected override HTTPHeaders GetHeaders() 10 | { 11 | return headers; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MsgPackViewer/MsgPackViewBase.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | using Fiddler; 3 | 4 | namespace MsgPackViewer 5 | { 6 | public abstract class MsgPackViewBase : Inspector2 7 | { 8 | private readonly MsgPackViewer _viewer = new MsgPackViewer(); 9 | private byte[] _decodedBody; 10 | private byte[] _body; 11 | 12 | public override void AddToTab(TabPage o) 13 | { 14 | o.Text = "MsgPack"; 15 | o.Controls.Add(_viewer); 16 | _viewer.Dock = DockStyle.Fill; 17 | } 18 | 19 | public override int GetOrder() 20 | { 21 | return 1000; 22 | } 23 | 24 | public void Clear() 25 | { 26 | _body = null; 27 | _decodedBody = null; 28 | _viewer.Clear(); 29 | } 30 | 31 | public byte[] body 32 | { 33 | get { return _body; } 34 | set 35 | { 36 | _body = value; 37 | DisplayData(); 38 | } 39 | } 40 | 41 | private void DisplayData() 42 | { 43 | _decodedBody = _body; 44 | Utilities.utilDecodeHTTPBody(GetHeaders(), ref _decodedBody); 45 | 46 | _viewer.DisplayData(_decodedBody); 47 | } 48 | 49 | protected abstract HTTPHeaders GetHeaders(); 50 | 51 | public bool bDirty 52 | { 53 | get { return false; } 54 | } 55 | 56 | public bool bReadOnly 57 | { 58 | get { return true; } 59 | set { } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /MsgPackViewer/MsgPackViewer.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MsgPackViewer 2 | { 3 | partial class MsgPackViewer 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.tree = new System.Windows.Forms.TreeView(); 32 | this.SuspendLayout(); 33 | // 34 | // tree 35 | // 36 | this.tree.BackColor = System.Drawing.Color.AliceBlue; 37 | this.tree.BorderStyle = System.Windows.Forms.BorderStyle.None; 38 | this.tree.Dock = System.Windows.Forms.DockStyle.Fill; 39 | this.tree.LabelEdit = true; 40 | this.tree.Location = new System.Drawing.Point(0, 0); 41 | this.tree.Margin = new System.Windows.Forms.Padding(0); 42 | this.tree.Name = "tree"; 43 | this.tree.ShowNodeToolTips = true; 44 | this.tree.ShowRootLines = false; 45 | this.tree.Size = new System.Drawing.Size(570, 427); 46 | this.tree.TabIndex = 0; 47 | this.tree.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.tree_AfterLabelEdit); 48 | // 49 | // MsgPackViewer 50 | // 51 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 52 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 53 | this.Controls.Add(this.tree); 54 | this.Name = "MsgPackViewer"; 55 | this.Size = new System.Drawing.Size(570, 427); 56 | this.ResumeLayout(false); 57 | 58 | } 59 | 60 | #endregion 61 | 62 | private System.Windows.Forms.TreeView tree; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /MsgPackViewer/MsgPackViewer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Windows.Forms; 6 | using MsgPackSlim; 7 | using MsgPackSlim.Formats; 8 | 9 | namespace MsgPackViewer 10 | { 11 | public partial class MsgPackViewer : UserControl 12 | { 13 | public MsgPackViewer() 14 | { 15 | InitializeComponent(); 16 | } 17 | 18 | public void Clear() 19 | { 20 | tree.Nodes.Clear(); 21 | } 22 | 23 | public void DisplayData(byte[] data) 24 | { 25 | Clear(); 26 | 27 | TreeNode root = null; 28 | TreeNode parent = null; 29 | var remainingCountStack = new Stack(); 30 | var remainingCount = 1; 31 | 32 | using (var stream = new MemoryStream(data)) 33 | using (var reader = new MsgPackReader(stream)) 34 | { 35 | try 36 | { 37 | while (reader.ReadNext()) 38 | { 39 | var node = CreateNode(reader); 40 | if (parent != null) 41 | parent.Nodes.Add(node); 42 | else 43 | { 44 | root = node; 45 | parent = node; 46 | } 47 | remainingCount--; 48 | 49 | if (reader.IsArray || reader.IsMap) 50 | { 51 | remainingCountStack.Push(remainingCount); 52 | remainingCount = reader.ChildObjectCount; 53 | parent = node; 54 | } 55 | 56 | while ((remainingCount == 0) && (remainingCountStack.Count > 0)) 57 | { 58 | remainingCount = remainingCountStack.Pop(); 59 | parent = parent.Parent; 60 | } 61 | if ((remainingCount == 0) && (remainingCountStack.Count == 0)) 62 | break; 63 | } 64 | 65 | if (reader.ReadNext()) 66 | throw new Exception("content after the root node"); 67 | } 68 | catch (Exception ex) 69 | { 70 | var message = String.Format("Error at byte {0}: {1}", stream.Position, ex.Message); 71 | var node = CreateNode(message, ex.ToString()); 72 | if (root == null) 73 | root = node; 74 | else 75 | root.Nodes.Add(node); 76 | } 77 | } 78 | 79 | if (root != null) 80 | { 81 | tree.Nodes.Add(root); 82 | tree.ExpandAll(); 83 | tree.SelectedNode = root; 84 | } 85 | } 86 | 87 | private TreeNode CreateNode(string text, string toolTip) 88 | { 89 | return new TreeNode(text) 90 | { 91 | ToolTipText = toolTip 92 | }; 93 | } 94 | 95 | private TreeNode CreateNode(MsgPackReader reader) 96 | { 97 | var formatName = GetFormatName(reader.Format); 98 | 99 | var text = GetNodeText(reader); 100 | 101 | var tooltip = String.Format("{0} ({1:x2}) ({2} bytes)", formatName, reader.FormatByte, reader.TotalSize); 102 | if (reader.IsExtended) 103 | tooltip += String.Format(" (Extended Type {0})", reader.ExtendedType); 104 | else if ((reader.ContentSize > 0) && (reader.ContentSize <= 32) && !reader.IsBinary) 105 | tooltip += " " + GetHex(reader.ContentBytes); 106 | 107 | return CreateNode(text, tooltip); 108 | } 109 | 110 | private static string GetNodeText(MsgPackReader reader) 111 | { 112 | if (reader.IsArray) 113 | return String.Format("Array ({0} items)", reader.ChildObjectCount); 114 | if (reader.IsMap) 115 | return String.Format("Map ({0} items)", reader.ChildObjectCount/2); 116 | 117 | var value = reader.GetValue(); 118 | if (value == null) 119 | return "null"; 120 | 121 | var stringValue = value as string; 122 | if (stringValue != null) 123 | return "\"" + stringValue.Replace("\"", "\\\"").Replace("\0", "\\0") + "\""; 124 | 125 | var byteValue = value as byte[]; 126 | if (byteValue != null) 127 | return GetHex(byteValue); 128 | 129 | return value.ToString(); 130 | } 131 | 132 | private string GetFormatName(IMsgPackFormat format) 133 | { 134 | var name = format.GetType().Name; 135 | if (name.EndsWith("Format")) 136 | return name.Substring(0, name.Length - 6); 137 | return name; 138 | } 139 | 140 | private static string GetHex(byte[] data) 141 | { 142 | var output = new StringBuilder(data.Length*3 - 1); 143 | foreach (var b in data) 144 | { 145 | if (output.Length > 0) 146 | output.Append(' '); 147 | output.Append(b.ToString("x2")); 148 | } 149 | return output.ToString(); 150 | } 151 | 152 | private void tree_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) 153 | { 154 | e.CancelEdit = true; 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /MsgPackViewer/MsgPackViewer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DA080874-FDC8-4364-8D6C-AD90E5FF82A4} 8 | Library 9 | Properties 10 | MsgPackViewer 11 | MsgPackViewer 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 1685 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | true 35 | 1685 36 | 37 | 38 | 39 | ..\..\..\Program Files (x86)\Fiddler2Legacy\Fiddler.exe 40 | False 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | UserControl 53 | 54 | 55 | MsgPackViewer.cs 56 | 57 | 58 | 59 | 60 | 61 | MsgPackViewer.cs 62 | 63 | 64 | 65 | 66 | MsgPackSlim\%(Filename) 67 | 68 | 69 | 70 | 71 | copy "$(TargetDir)MsgPackViewer.*" "%25USERPROFILE%25\My Documents\Fiddler2\Inspectors" 72 | 73 | 74 | 81 | -------------------------------------------------------------------------------- /MsgPackViewer/MsgPackViewer.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /MsgPackViewer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MsgPackViewer")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("")] 8 | [assembly: AssemblyProduct("MsgPackViewer")] 9 | [assembly: AssemblyCopyright("Copyright © Jesse McDowell 2015")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | 15 | [assembly: AssemblyVersion("1.0.2.*")] 16 | [assembly: AssemblyFileVersion("1.0.2.0")] 17 | 18 | [assembly: Fiddler.RequiredVersion("2.5.0.0")] 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MsgPackViewer for Fiddler2 / Fiddler4 2 | 3 | # Dependencies 4 | 5 | This project is dependent on [Fiddler 2](http://www.telerik.com/fiddler). This project was last tested against Fiddler 2.5.0.0 and 4.5.0.0. 6 | 7 | 8 | # Author 9 | 10 | This project was created by Jesse McDowell. 11 | 12 | http://www.jessemcdowell.ca/ 13 | 14 | 15 | # License 16 | 17 | Copyright (c) 2015 Jesse McDowell. 18 | 19 | This program is free software: you can redistribute it and/or modify 20 | it under the terms of the GNU General Public License as published by 21 | the Free Software Foundation, either version 3 of the License, or 22 | (at your option) any later version. 23 | 24 | This program is distributed in the hope that it will be useful, 25 | but WITHOUT ANY WARRANTY; without even the implied warranty of 26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 | GNU General Public License for more details. 28 | 29 | You should have received a copy of the GNU General Public License 30 | along with this program. If not, see . 31 | --------------------------------------------------------------------------------