共用方式為


建立自定義外掛程式

在本文中,您將瞭解如何為 Dev Proxy 建立自定義插件。 藉由建立開發 Proxy 的外掛程式,您可以擴充其功能,並新增自定義功能以符合您的需求。

必要條件

開始建立自定義外掛程式之前,請確定您具備下列必要條件:

建立新的外掛程式

請遵循後續步驟來建立新的專案:

  1. 使用 dotnet new classlib 命令建立新的類別庫專案。

    dotnet new classlib -n MyCustomPlugin
    
  2. 在 Visual Studio Code 中開啟新建立的專案。

    code MyCustomPlugin
    
  3. 將 Dev Proxy 抽象 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檔案中,以從建置輸出中排除相依性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
    

使用您的自定義外掛程式

若要使用您的自定義外掛程式,您必須將它新增至 Dev Proxy 組態檔:

  1. devproxyrc.json檔案中新增外掛程式的設定。

    {
      "plugins": [{
        "name": "CatchApiCallsPlugin",
        "enabled": true,
        "pluginPath": "./bin/Debug/net9.0/MyCustomPlugin.dll",
      }]
    }
    
  2. 執行開發代理伺服器。

    devproxy
    

此範例外掛程式會檢查所有相符 URL 是否有符合要求的 Authorization 標頭。 如果標頭不存在,它會顯示警告訊息。

將自訂元件新增至您的外掛程式 (選擇性)

您可以藉由新增自訂元件來擴充外掛程式的邏輯:

  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