Skip to content
This repository has been archived by the owner on May 8, 2021. It is now read-only.

Commit

Permalink
updated example extension
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholascloud committed Jan 21, 2013
1 parent 92f386b commit 76a848d
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 30 deletions.
103 changes: 97 additions & 6 deletions stlaltdotnet/full-frontal-fiddler/DotNet-Extensions.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# .NET Extensions
# .NET extensions

- Fiddler2 loads .NET 2.0/3.5 assemblies only (there is a .NET 4.0 version of Fiddler in beta)
- users must have the appropriate .NET runtime installed (2.0 or 3.5)
Expand All @@ -8,15 +8,106 @@
- set preference `fiddler.debug.extensions.verbose` to write log messages and warnings to the log tab
- globally available extensions installed to: `%Program Files%\Fiddler2\Scripts`
- user extensions installed to: `%USERPROFILE%\My Documents\Fiddler2\Scripts`
- http://fiddler2.com/Fiddler/dev/IFiddlerExtension.asp

## Extension interfaces

### IFiddlerExtension

### Extensions
Basic interface required to load an extension on startup.

### Importer/Exporter Extensions
- `OnLoad()`: UI is fully available
- `OnBeforeUnload()`: application is shutting down

### Author extensions
### IAutoTamper : IFiddlerExtension

http://getfiddler.com/addons
Methods called for each HTTP(S) request/response. Methods are called on background threads, which has implications for UI components.

- JavaScript formatter
- `AutoTamperRequestBefore(Session)`: before the user can edit a request with inspectors
- `AutoTamperRequestAfter(Session)`: after the user can edit a request, and before the request is actually sent
- `AutoTamperResponseBefore(Session)`: before the user can edit a response with inspectors (unless streaming)
- `AutoTamperResponseAfter(Session)`: after the user can edit a response (unless streaming)
- `OnBeforeReturningError(Session)`: when fiddler returns a self-generated HTTP error (e.g., DNS lookup failure)

### IAutoTamper2 : IAutoTamper

Allows extensions to optionally "peek" at response headers before anything handles the response.

- `OnPeekAtResponseHeaders(Session)`: when the response headers become available

### IAutoTamper3 : IAutoTamper2

Allows extensions to "peek" at request headers before anything handles the request.

- `OnPeekAtRequestHeaders(Session)`: when the request headers become available

### IHandleExecAction

An extension that can handle commands entered into the QuickExec field.

- OnExecAction(String)


## Extension preferences

Preferences can be set manually in the QuickExec bar:

`prefs set [name] [value]`

They can also be set by invoking the preferences dialog from the QuickExec bar:

`about:config`

The `FiddlerApplication.Prefs` object implements `IFiddlerPreferences` and allows you to manipulate preferences programatically.

- `Get[Bool|String|Int32]Pref(name, default)`
- `Set[Bool|String|Int32]Pref(name, value)`
- `RemovePref(name)`
- `AddWatcher(filter, handler)`
- `RemoveWatcher(watcher)`
- `[name]` (get/set by indexer)

__NOTE__: Extensions must invoke `RemoveWatcher` when disposed in order to get garbage collected.


## Fiddler objects

Fiddler exposes several useful objects that extensions can access.

### FiddlerApplication.UI

- manipulate sessions in the session (select, unselect, remove) list
- change layout options
- toggle capturing
- set status text / show alert
- copy sessions and session information (e.g., headers, URL, etc.)
- persist session(s) to archive
- etc.

### FiddlerApplication.Log

- log a simple string to the Log inspector (`LogString()`)
- log a formatted string to the Log inspector (`LogFormat()`)

### FiddlerApplication.Prefs

- get/set/remove preferences
- attach/remove preference "watchers" that will be triggered when preferences change

### Session

- manipulate request (`oRequest`), including headers, URL, query string, and HTTP method
- manipulate response (`oResponse`) including headers and response code
- manipulate flags (used by extensions and UI components)
- abort
- query client information (IP address, port, etc.)
- query destination information (IP address, port, host)
- determine if the session is using HTTPS
- examine a number of time spans (`Timers`) that measure the duration of certain parts of the request
- etc.


## Other types of extensions

- importer/exporter extensions
- inspectors (UI)
1 change: 0 additions & 1 deletion stlaltdotnet/full-frontal-fiddler/Fiddler-Core.md

This file was deleted.

3 changes: 3 additions & 0 deletions stlaltdotnet/full-frontal-fiddler/Inspectors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Inspectors

p. 234
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Log.cs" />
<Compile Include="Prefs.cs" />
<Compile Include="TraceFile.cs" />
<Compile Include="TraceRouteTamper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;

namespace AltNetFiddler {
internal static class Prefs {
internal const String PREFIX = "altnetfiddler.traceroutetamper";
internal const String SHOW_OUTPUT = "altnetfiddler.traceroutetamper.showoutput";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@

namespace AltNetFiddler {
internal class TraceFile {
private readonly IDictionary<Guid, string> _traces;

public TraceFile(IDictionary<Guid, String> traces) {
_traces = traces;
}

private readonly IDictionary<Guid, string> _traces;
private String _cache = String.Empty;

public override string ToString() {
var b = new StringBuilder();
foreach (var kvp in _traces) {
b.AppendLine(kvp.Key.ToString())
.AppendLine(kvp.Value)
.AppendLine(String.Empty)
.AppendLine(String.Empty);
if (_cache == String.Empty) {
var b = new StringBuilder();
foreach (var kvp in _traces) {
b.AppendLine(kvp.Key.ToString())
.AppendLine(kvp.Value)
.AppendLine(String.Empty)
.AppendLine(String.Empty);
}
_cache = b.ToString();
}
return b.ToString();
return _cache;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,37 @@
using Fiddler;

namespace AltNetFiddler {
public class TraceRouteTamper : IAutoTamper {
public class TraceRouteTamper : IAutoTamper, IDisposable {
private const Int32 MAX_MS = 50;
private Log _log = new Log("TraceRouteTamper");
private static readonly Log _log = new Log("TraceRouteTamper");
private readonly PreferenceBag.PrefWatcher _prefWatcher;

//thread safe
private readonly Object _lock = new Object();
private readonly Dictionary<Guid, String> _traceResults = new Dictionary<Guid, String>();
private readonly String _traceResultsOutputFile = String.Empty;
private bool _showOutput = false;

public TraceRouteTamper() {
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

lock (_lock) {
_traceResultsOutputFile = Path.Combine(dir, "AltNetFiddler.txt");
//set up default preferences
_showOutput = FiddlerApplication.Prefs.GetBoolPref(Prefs.SHOW_OUTPUT, false);
}

//watch for preference changes
_prefWatcher = FiddlerApplication.Prefs.AddWatcher(Prefs.PREFIX, OnPreferencesChange);
}

private void OnPreferencesChange(Object sender, PrefChangeEventArgs args) {
if (args.PrefName == Prefs.SHOW_OUTPUT) {
lock (_lock) {
_showOutput = args.ValueBool;
}
_log.Info("preference " + args.PrefName + " changed to " + args.ValueBool);
}
}

/// <summary>
Expand All @@ -37,7 +54,7 @@ public void AutoTamperResponseBefore(Session oSession) {
String host = oSession.oRequest.host;

ThreadPool.QueueUserWorkItem(state => {
var trace = new TraceRoute((String) state, 20);
var trace = new TraceRoute((String) state, 10);
try {
String result = trace.Execute();
UpdateTraceResults(result);
Expand All @@ -50,19 +67,28 @@ public void AutoTamperResponseBefore(Session oSession) {
private void UpdateTraceResults(String results) {
lock (_lock) {
_traceResults.Add(Guid.NewGuid(), results);
if (_traceResults.Keys.Count > 5) {
try {
var file = new TraceFile(_traceResults);
using (var stream = File.CreateText(_traceResultsOutputFile)) {
stream.Write(file.ToString());
}
_log.Info("[UpdateTraceResults] output written to " + _traceResultsOutputFile);
} catch (Exception ex) {
_log.Error("[UpdateTraceResults] " + ex.Message);
} finally {
_traceResults.Clear();

if (_traceResults.Keys.Count <= 5) {
return;
}

var file = new TraceFile(_traceResults);

try {
using (var stream = File.CreateText(_traceResultsOutputFile)) {
stream.Write(file.ToString());
}
_log.Info("[UpdateTraceResults] output written to " + _traceResultsOutputFile);
} catch (Exception ex) {
_log.Error("[UpdateTraceResults] " + ex.Message);
} finally {
_traceResults.Clear();
}

if (_showOutput) {
_log.Info(file.ToString());
}

}
}

Expand Down Expand Up @@ -105,5 +131,21 @@ public void AutoTamperResponseAfter(Session oSession) {
/// </summary>
public void OnBeforeReturningError(Session oSession) {
}

private bool _isDisposed = false;

public void Dispose() {
Dispose(true);
}

private void Dispose(bool disposing) {
if (disposing) {
if (_isDisposed) {
return;
}
FiddlerApplication.Prefs.RemoveWatcher(_prefWatcher);
_isDisposed = true;
}
}
}
}

0 comments on commit 76a848d

Please sign in to comment.