次の方法で共有


カスタム プラグインを作成する

この記事では、開発プロキシ用のカスタム プラグインを作成する方法について説明します。 開発プロキシ用のプラグインを作成することで、その機能を拡張し、ニーズに合わせてカスタム機能を追加できます。

前提条件

カスタム プラグインの作成を開始する前に、次の前提条件があることを確認してください。

新しいプラグインを作成する

次の手順に従って新しいプロジェクトを作成します。

  1. dotnet new classlib コマンドを使用して、新しいクラス ライブラリ プロジェクトを作成します。

    dotnet new classlib -n MyCustomPlugin
    
  2. Visual Studio Code で新しく作成したプロジェクトを開きます。

    code MyCustomPlugin
    
  3. 開発プロキシ抽象化 DLL (DevProxy.Abstractions.dll) をプロジェクト フォルダーに追加します。

  4. プロジェクト DevProxy.Abstractions.dll ファイルへの参照としてDevProxyCustomPlugin.csprojを追加します。

    <ItemGroup>
      <Reference Include="DevProxy.Abstractions">
        <HintPath>.\DevProxy.Abstractions.dll</HintPath>
        <Private>false</Private>
        <ExcludeAssets>runtime</ExcludeAssets>
      </Reference>
    </ItemGroup>
    
  5. プロジェクトに必要な NuGet パッケージを追加します。

    dotnet add package Microsoft.Extensions.Configuration
    dotnet add package Microsoft.Extensions.Configuration.Binder
    dotnet add package Microsoft.Extensions.Logging.Abstractions
    dotnet add package Unobtanium.Web.Proxy
    
  6. ExcludeAssets ファイルのPackageReferenceごとにDevProxyCustomPlugin.csproj タグを追加して、依存関係 DLL をビルド出力から除外します。

    <ExcludeAssets>runtime</ExcludeAssets>
    
  7. BaseProxy クラスから継承する新しいクラスを作成します。

    using DevProxy.Abstractions.Plugins;
    using DevProxy.Abstractions.Proxy;
    using Microsoft.Extensions.Logging;
    
    namespace MyCustomPlugin;
    
    public sealed class CatchApiCallsPlugin(
        ILogger<CatchApiCallsPlugin> logger,
        ISet<UrlToWatch> urlsToWatch) : BasePlugin(logger, urlsToWatch)
    {
        public override string Name => nameof(CatchApiCallsPlugin);
    
        public override Task BeforeRequestAsync(ProxyRequestArgs e)
        {
            Logger.LogTrace("{Method} called", nameof(BeforeRequestAsync));
    
            ArgumentNullException.ThrowIfNull(e);
    
            if (!e.HasRequestUrlMatch(UrlsToWatch))
            {
                Logger.LogRequest("URL not matched", MessageType.Skipped, new(e.Session));
                return Task.CompletedTask;
            }
    
            var headers = e.Session.HttpClient.Request.Headers;
            var header = headers.Where(h => h.Name == "Authorization").FirstOrDefault();
            if (header is null)
            {
                Logger.LogRequest($"Does not contain the Authorization header", MessageType.Warning, new LoggingContext(e.Session));
                return Task.CompletedTask;
            }
    
            Logger.LogTrace("Left {Name}", nameof(BeforeRequestAsync));
            return Task.CompletedTask;
        }
    }
    
  8. プロジェクトをビルドする。

    dotnet build
    

カスタム プラグインを使用する

カスタム プラグインを使用するには、それを開発プロキシ構成ファイルに追加する必要があります。

  1. devproxyrc.json ファイルに新しいプラグイン構成を追加します。

    {
      "plugins": [{
        "name": "CatchApiCallsPlugin",
        "enabled": true,
        "pluginPath": "./bin/Debug/net9.0/MyCustomPlugin.dll",
      }]
    }
    
  2. 開発プロキシを実行します。

    devproxy
    

この例のプラグインは、必要な Authorization ヘッダーについて、一致するすべての URL をチェックします。 ヘッダーが存在しない場合は、警告メッセージが表示されます。

プラグインへのカスタム構成の追加 (省略可能)

カスタム構成を追加することで、プラグインのロジックを拡張できます。

  1. BasePlugin<TConfiguration> クラスから継承します。 開発プロキシは、実行時に Configuration プロパティを介して解析されたプラグイン構成を公開します。

    using DevProxy.Abstractions.Plugins;
    using DevProxy.Abstractions.Proxy;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    
    namespace MyCustomPlugin;
    
    public sealed class CatchApiCallsConfiguration
    {
        public string? RequiredHeader { get; set; }
    }
    
    public sealed class CatchApiCallsPlugin(
        ILogger<CatchApiCallsPlugin> logger,
        ISet<UrlToWatch> urlsToWatch,
        IProxyConfiguration proxyConfiguration,
        IConfigurationSection pluginConfigurationSection) :
        BasePlugin<CatchApiCallsConfiguration>(
            logger,
            urlsToWatch,
            proxyConfiguration,
            pluginConfigurationSection)
    {
        public override string Name => nameof(CatchApiCallsPlugin);
    
        public override Task BeforeRequestAsync(ProxyRequestArgs e)
        {
            Logger.LogTrace("{Method} called", nameof(BeforeRequestAsync));
    
            ArgumentNullException.ThrowIfNull(e);
    
            if (!e.HasRequestUrlMatch(UrlsToWatch))
            {
                Logger.LogRequest("URL not matched", MessageType.Skipped, new(e.Session));
                return Task.CompletedTask;
            }
    
            // Start using your custom configuration
            var requiredHeader = Configuration.RequiredHeader ?? string.Empty;
            if (string.IsNullOrEmpty(requiredHeader))
            {
                // Required header is not set, so we don't need to do anything
                Logger.LogRequest("Required header not set", MessageType.Skipped, new LoggingContext(e.Session));
                return Task.CompletedTask;
            }
    
            var headers = e.Session.HttpClient.Request.Headers;
            var header = headers.Where(h => h.Name == requiredHeader).FirstOrDefault();
            if (header is null)
            {
                Logger.LogRequest($"Does not contain the {requiredHeader} header", MessageType.Warning, new LoggingContext(e.Session));
                return Task.CompletedTask;
            }
    
            Logger.LogTrace("Left {Name}", nameof(BeforeRequestAsync));
            return Task.CompletedTask;
        }
    }
    
  2. プロジェクトをビルドする。

    dotnet build
    
  3. devproxyrc.json ファイルを更新して、新しい構成を含めます。

    {
      "plugins": [{
        "name": "CatchApiCallsPlugin",
        "enabled": true,
        "pluginPath": "./bin/Debug/net9.0/MyCustomPlugin.dll",
        "configSection": "catchApiCalls"
      }],
      "catchApiCalls": {
        "requiredHeader": "Authorization" // Example configuration
      }
    }
    
  4. 開発プロキシを実行します。

    devproxy