備忘録

備忘録

C# FiddlerCoreのサンプル

Ⅰ. はじめに

FiddlerCoreを使いHTTP, HTTPS, WebSocketのプロキシサーバーを作る場合のサンプルです。
Windowsのみで動作します。

※2017/12/16追記
FiddlerCoreの.NET Standard 2.0対応版(現時点でベータ版)がリリースされていました。
これによりクロスプラットフォームでFiddlerCoreを利用する事ができます。
https://www.telerik.com/fiddler/fiddlercore

また、Titanium Web Proxy を利用するという方法もあります。
C#でTitanium-Web-Proxyを利用してProxyサーバを構築する方法

Ⅱ. サンプルプログラム

using Fiddler;
using System;

namespace HttpProxyServer
{
  class Program
  {
    static void Main(string[] args)
    {
      FiddlerApplication.OnWebSocketMessage += FiddlerApplication_OnWebSocketMessage;
      FiddlerApplication.BeforeRequest += FiddlerApplication_BeforeRequest;
      FiddlerApplication.BeforeResponse += FiddlerApplication_BeforeResponse;
      CONFIG.IgnoreServerCertErrors = true;

      // ルート証明書を指定する
      // Fiddler の Quick Exec で about:config と入力し、表示される値を使う。
      // FiddlerApplication.Prefs.SetStringPref("fiddler.certmaker.bc.key", "INPUT YOUR fiddler.certmaker.bc.key");
      // FiddlerApplication.Prefs.SetStringPref("fiddler.certmaker.bc.cert", "INPUT YOUR fiddler.certmaker.bc.cert");

      // ルート証明書を出力する
      // CertMaker.createRootCert();
      // var rootCert = CertMaker.GetRootCertificate();
      // var rootCertBytes = rootCert.Export(X509ContentType.Cert);
      // File.WriteAllBytes("FiddlerCoreRoot.cer", rootCertBytes);

      var startupSettings =
         new FiddlerCoreStartupSettingsBuilder()
           .ListenOnPort(8080)
           //.RegisterAsSystemProxy()
           .DecryptSSL()
           .AllowRemoteClients()
           //.ChainToUpstreamGateway()
           //.MonitorAllConnections()
           //.HookUsingPACFile()
           //.CaptureLocalhostTraffic()
           //.CaptureFTP()
           .OptimizeThreadPool()
           //.SetUpstreamGatewayTo("http=CorpProxy:80;https=SecureProxy:443;ftp=ftpGW:20")
           .Build();
      FiddlerApplication.Startup(startupSettings);

      Console.WriteLine("listening");
      Console.ReadLine();
    }

    private static void FiddlerApplication_BeforeResponse(Session oSession)
    {
      // GZipやchunked transferされた場合、
      // oSession.ResponseBodyが期待通りにならないので、
      // oSession.utilDecodeResponse(); を呼んでデコードする。
      oSession.utilDecodeResponse();
      Console.WriteLine("BeforeResponse");
      Console.WriteLine($"{oSession.fullUrl}");
      var bytes = oSession.ResponseBody;
    }

    private static void FiddlerApplication_BeforeRequest(Session oSession)
    {
      // レスポンスデータを書き換えるためにはtrueにする必要がある
      oSession.bBufferResponse = true;
      // 上位プロキシを設定する
      //oSession["X-OverrideGateway"] = "10.226.0.9:3128";
      Console.WriteLine("BeforeRequest");
      Console.WriteLine($"{oSession.fullUrl}");
      var bytes = oSession.RequestBody;
    }

    private static void FiddlerApplication_OnWebSocketMessage(object sender, WebSocketMessageEventArgs e)
    {
      Console.WriteLine($"OnWebSocketMessage: {e.oWSM.PayloadAsString()}");
      var bytes = e.oWSM.PayloadAsBytes();
    }
  }
}