Модификация HTTP-трафика с помощью FiddlerScript и .NET-плагинов к Fiddler

в 10:38, , рубрики: .net, fiddler, Блог компании Инфопульс Украина, отладка, Тестирование веб-сервисов, Хабрахабр API, метки:

На Хабре уже неоднократно рассказывали о таком мощном и удобном средстве мониторинга HTTP-трафика, как Fiddler. Все имеющиеся статьи, однако, рассказывают о встроенных фичах программы, не акцентируя внимания на возможностях её расширения, которых существует целых две: с помощью встроенного языка FiddlerScript и с помощью написания .NET-плагинов. В этой статье мы рассмотрим и то, и другое, а чтобы было интереснее — используем их для решения вполне практической задачи, о которой я писал в своей прошлой статье (подмене битых ссылок на картинки в статьях на Хабре на рабочие).

Итак, давайте вспомним для начала, чем закончилась прошлая статья: мы получили список нерабочих ссылок на картинки и соответствующих им рабочих ссылок на веб-архиве. Теперь нужно отдать их браузеру и для этого мы напишем расширения к Fiddler (одно на FiddlerScript и одно на .NET). Обратите внимание на удобства полученного решения: да, нам нужно будет запустить Fiddler, но зато битые ссылки будут подменяться на рабочие независимо от домена статьи (хабр, гиктаймс или мегамозг), независимо от используемого браузера (лишь бы имел поддержку прокси) и даже мобильные устройства можно будет настроить на использование установленного на компьютере Fiddler в качестве прокси.

FiddlerScript

FiddlerScript — это встроенный в Fiddler язык программирования, основанный на JScript.NET, позволяющий анализировать и изменять входящий и исходящий траффик, расширять функциональность самого Fiddler, модифицировать его интерфейс.
Пара ссылок по теме:

Писать код нужно в файл, который открывается по клику в меню на Rules->Customize Rules. Если вдруг запорете его — просто удалите, Fiddler пересоздаст его из резервной копии.

Простейшая подмена одной ссылки на другую на FiddlerScript будет выглядеть как добавление в обработчик OnBeforeRequest вот такого кода:

static function OnBeforeRequest(oSession: Session) {
...
if (oSession.url=="www.example.com/bad_url.jpg") {
      oSession.url = "www.example.com/good_url.jpg";
    }
}

Нам нужно подменить 13863 ссылки. Писать такое лес «ифов» — малопродуктивно. Вспомним, что FiddlerScript основан на JScript.NET, JScript.NET — это .NET, а в .NET есть весьма производительные структуры данных для хранения набора строк и быстрого поиска по нему, в основе которого лежат хеш-таблицы. Да-да, я о StringDictionary.

Возьмём наши исходные данные и парой нехитрых операций по автозамене в любом текстовом редакторе с поддержкой регулярных выражений приведём его к виду:

myDict.Add("img224.imageshack.us/img224/410/yandexmoney7mg.gif", "web.archive.org/web/20060723135036/http://img224.imageshack.us:80/img224/410/yandexmoney7mg.gif");
myDict.Add("blaugh.com/wp-content/themes/blaugh/images/cartoon-gd_01.gif", "web.archive.org/web/20070703010741/http://blaugh.com/wp-content/themes/blaugh/images/cartoon-gd_01.gif");
myDict.Add("blaugh.com/cartoons/060712_google_life.gif", "web.archive.org/web/20120112151300/http://blaugh.com/cartoons/060712_google_life.gif");
...

Инициализировать словарь нужнов всего однажды (например, в обработчике OnBoot, а использовать при поиске его мы можем в каждом вызове OnBeforeRequest:

static var myDict: StringDictionary = null;

static function OnBoot() {
	myDict = new StringDictionary();
	myDict.Add("img224.imageshack.us/img224/410/yandexmoney7mg.gif", "web.archive.org/web/20060723135036/http://img224.imageshack.us:80/img224/410/yandexmoney7mg.gif");
	myDict.Add("blaugh.com/wp-content/themes/blaugh/images/cartoon-gd_01.gif", "http://web.archive.org/web/20070703010741/http://blaugh.com/wp-content/themes/blaugh/images/cartoon-gd_01.gif");
	myDict.Add("blaugh.com/cartoons/060712_google_life.gif", "http://web.archive.org/web/20120112151300/http://blaugh.com/cartoons/060712_google_life.gif");
	....
    }

...

static function OnBeforeRequest(oSession: Session) {
...
	if (null != myDict && myDict.ContainsKey(oSession.url)) {
	    oSession.url = myDict[oSession.url];
	}
}

Сохраняем, проверяем открытием статьи с битой ссылкой на картинку, видим картинку, которая без этой подмены была недоступна — ура, всё работает!

Код полностью

Написание .NET-плагина к Fiddler

Если вам не сильно понравилось писать код на странном языке JScript.NET в странном редакторе и запускать его странным способом копипасты в конфиг-файл, ожидая при этом по 30 сек, пока распарсится и скомпилируеся написанный нами скрипт — к вашим услугам вся мощь C#, .NET, Visual Studio и прочих радостей жизни!

Коротко о создании проекта:
1. Запускаем Visual Studio, создаём новый .NET-проект типа «Библиотека классов».
2. Если пишете под Fiddler 4 — выбирайте в свойствах проекта .NET версии 4, если под Fiddler 2 — .NET версии 3.5
3. Добавляйте в зависимости сам Fiddler (экзешник Fiddler.exe, лежащий в своей папке в Program Files).
4. В коде нужно указать, какую минимальную версию Fiddler вы поддерживаете:

using Fiddler;

// Extension requires Fiddler 2.2.8.6+ because it uses types introduced in v2.2.8...
[assembly: Fiddler.RequiredVersion("2.2.8.6")]

5. Вам нужно написать класс, реализовывающий интерфейс IAutoTamper. События у него, в общем-то те же, что и были в нашем коде на FiddlerScript, поэтому вот он схематически:

using System;
using Fiddler;
using System.Collections.Specialized;

[assembly: Fiddler.RequiredVersion("2.3.5.0")]

public class HabraFixer : IAutoTamper    // Ensure class is public, or Fiddler won't see it!
{
    public HabraFixer()
    {
    }

    public void OnLoad()
    {
        myDict = new StringDictionary();
        myDict.Add("img224.imageshack.us/img224/410/yandexmoney7mg.gif", "web.archive.org/web/20060723135036/http://img224.imageshack.us:80/img224/410/yandexmoney7mg.gif");
        myDict.Add("blaugh.com/wp-content/themes/blaugh/images/cartoon-gd_01.gif", "web.archive.org/web/20070703010741/http://blaugh.com/wp-content/themes/blaugh/images/cartoon-gd_01.gif");
        myDict.Add("blaugh.com/cartoons/060712_google_life.gif", "web.archive.org/web/20120112151300/http://blaugh.com/cartoons/060712_google_life.gif");
        ...
    }
    
    public void OnBeforeUnload() { }

    public void AutoTamperRequestBefore(Session oSession)
    {
        if (null != myDict && myDict.ContainsKey(oSession.url)) {
    	    oSession.url = myDict[oSession.url];
    	}
    }
    public void AutoTamperRequestAfter(Session oSession) { }
    public void AutoTamperResponseBefore(Session oSession) { }
    public void AutoTamperResponseAfter(Session oSession) { }
    public void OnBeforeReturningError(Session oSession) { }

    private StringDictionary myDict;
}

Полный код

Билдим, подкладываем сборку в %Program Files%Fiddler2Scripts (для всех пользователей) или в %USERPROFILE%My DocumentsFiddler2Scripts (только для текущего), запускаем Fiddler, проверяем — всё работает!

Вот так мы научились писать расширения для Fiddler.

Автор: tangro

Источник

Поделиться