読者です 読者をやめる 読者になる 読者になる

みかづきメモ

学習したことのメモとか、日記とか、備忘録。

CefSharp で HTTP(S) 通信の中身をみたい

前からちまちまいじってる CefSharp の続きです。
私は CefSharp.WPF 以外は触ってないので、一応それでの話ということで。


も言ったように、 CefSharp は Chromium .NET でいじるやつです。
Chromium なので、 Developer Tools みたいなのも実装可能です。

そして、 Developer Tools には、 HTTPS 通信を含んだ、通信内容を見ることが可能です。
ということで、 CefSharp で HTTP(S) 通信を覗いてみます。

通信の中身をみるのは、 ResourceHandler を登録することで、行うことができます。

ということで、早速実装。 まずは、適当な場所に ChromiumWebBrowser を埋め込みます。

<UserControl x:Class="WpfApplication02.BrowserHost"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:behaviors="clr-namespace:WpfApplication02.Behaviors"
             xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             d:DesignHeight="300"
             d:DesignWidth="300"
             mc:Ignorable="d">
    <Grid>
        <cefSharp:ChromiumWebBrowser HorizontalAlignment="Center"
                                     VerticalAlignment="Center"
                                     RenderOptions.BitmapScalingMode="Linear">
                <i:Interaction.Behaviors>
                    <behaviors:CaptureHttpRequestBehavior />
                </i:Interaction.Behaviors>
            </cefSharp:ChromiumWebBrowser>
    </Grid>
</UserControl>

次に、 ResourceHandler は Binding できないので、 Behavior でくっつけてあげます。

internal class CaptureHttpRequestBehavior : Behavior<ChromiumWebBrowser>
{
    #region Overrides of Behavior

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.ResourceHandlerFactory = new HttpResourceHandlerFactory();
    }

    #endregion
}

で、 IResourceHandlerFactory を実装したやつ。

internal class HttpResourceHandlerFactory : IResourceHandlerFactory
{
    #region Implementation of IResourceHandlerFactory

    public IResourceHandler GetResourceHandler(IWebBrowser browserControl, IBrowser browser, IFrame frame,
                                               IRequest request)
    {
        return new HttpResourceHandler();
    }

    public bool HasHandlers => true;

    #endregion
}

GetResourceHandler にて null を返せばデフォルト動作となるので、
例えば特定のドメインだけ適用させるといったことも可能です。
するとしたらこんな感じ。

return request.Url.StartsWith("https://twitter.com") ? new HttpResourceHandler() : null;

Twitter へのアクセスの場合は適用させて、それ以外はスルーといったような。

最後に、 IResourceHandler

internal class HttpResourceHandler : ResourceHandler
{
    #region Overrides of ResourceHandler

    public override bool ProcessRequestAsync(IRequest request, ICallback callback)
    {
        // ここに
        return true;
    }

    #endregion
}

あとは、 ProcessRequestAsync にて、 HttpClient だとかで IRequest に設定されている
リクエストを実行し、レスポンスをいじるなりすれば OK です。

まぁ動作を見てみると、キャプチャと言うよりは、プロキシみたいな感じになっていますが、
こうすれば、 HTTP リクエストの中身も(結果的には)見れますよーということで。