Модификации HTTP-трафика с помощью FiddlerScript и .NET-плагинов к Fiddler
На Хабре уже неоднократнорассказывали о таком мощном и удобном средстве мониторинга 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.53. Добавляйте в зависимости сам 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%\Fiddler2\Scripts (для всех пользователей) или в %USERPROFILE%\My Documents\Fiddler2\Scripts (только для текущего), запускаем Fiddler, проверяем — всё работает!
Вот так мы научились писать расширения для Fiddler.