Поделиться через


Создание настраиваемого подключаемого модуля

Из этой статьи вы узнаете, как создать пользовательский подключаемый модуль для прокси-сервера разработки. Создавая подключаемые модули для прокси-сервера разработки, вы можете расширить функциональные возможности и добавить пользовательские функции в соответствии с вашими потребностями.

Необходимые компоненты

Прежде чем приступить к созданию пользовательского подключаемого модуля, убедитесь, что у вас есть следующие предварительные требования:

Создание подключаемого модуля

Выполните следующие действия, чтобы создать новый проект:

  1. Создайте проект библиотеки классов с помощью dotnet new classlib команды.

    dotnet new classlib -n MyCustomPlugin
    
  2. Откройте созданный проект в Visual Studio Code.

    code MyCustomPlugin
    
  3. Добавьте библиотеку DLL абстракции прокси-сервера разработки (dev-proxy-abstractions.dll) в папку проекта.

  4. dev-proxy-abstractions.dll Добавьте ссылку на файл проектаDevProxyCustomPlugin.csproj.

    <ItemGroup>
      <Reference Include="dev-proxy-abstractions">
        <HintPath>.\dev-proxy-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. Исключите библиотеки DLL зависимостей из выходных данных сборки, добавив ExcludeAssets тег в PackageReference DevProxyCustomPlugin.csproj файл.

    <ExcludeAssets>runtime</ExcludeAssets>
    
  7. Создайте новый класс, реализующий BaseProxyPlugin интерфейс.

    using Microsoft.DevProxy.Abstractions;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    
    namespace MyCustomPlugin;
    
    public class CatchApiCalls(IPluginEvents pluginEvents, IProxyContext context, ILogger logger, ISet<UrlToWatch> UrlsToWatch, IConfigurationSection? configSection = null) : BaseProxyPlugin(pluginEvents, context, logger, UrlsToWatch, configSection)
    {
      public override string Name => nameof(CatchApiCalls);
    
      public override async Task RegisterAsync()
      {
        await base.RegisterAsync();
    
        PluginEvents.BeforeRequest += BeforeRequestAsync;
      }
    
      private Task BeforeRequestAsync(object sender, ProxyRequestArgs e)
      {
        if (UrlsToWatch is null ||
          !e.HasRequestUrlMatch(UrlsToWatch))
        {
          // No match for the URL, so we don't need to do anything
          Logger.LogRequest("URL not matched", MessageType.Skipped, new LoggingContext(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;
        }
    
        return Task.CompletedTask;
      }
    }
    
  8. Выполните сборку проекта.

    dotnet build
    

Использование пользовательского подключаемого модуля

Чтобы использовать настраиваемый подключаемый модуль, необходимо добавить его в файл конфигурации прокси-сервера разработки:

  1. Добавьте новую конфигурацию подключаемого devproxyrc.json модуля в файл.

    {
      "plugins": [{
        "name": "CatchApiCalls",
        "enabled": true,
        "pluginPath": "./bin/Debug/net8.0/MyCustomPlugin.dll",
      }]
    }
    
  2. Запустите прокси-сервер разработки.

    devproxy
    

Пример подключаемого модуля проверяет все соответствующие URL-адреса для требуемого заголовка авторизации. Если заголовок отсутствует, отображается предупреждение.

Добавление настраиваемой конфигурации в подключаемый модуль (необязательно)

Вы можете расширить логику подключаемого модуля, добавив настраиваемую конфигурацию:

  1. Добавьте новый _configuration объект и привязать его к методу Register .

    using Microsoft.DevProxy.Abstractions;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    
    namespace MyCustomPlugin;
    
    public class CatchApiCallsConfiguration
    {
      public string? RequiredHeader { get; set; }
    }
    
    public class CatchApiCalls(IPluginEvents pluginEvents, IProxyContext context, ILogger logger, ISet<UrlToWatch> UrlsToWatch, IConfigurationSection? configSection = null) : BaseProxyPlugin(pluginEvents, context, logger, UrlsToWatch, configSection)
    {
      public override string Name => nameof(CatchApiCalls);
    
      // Define you custom configuration
      private readonly CatchApiCallsConfiguration _configuration = new();
    
      public override async Task RegisterAsync()
      {
        await base.RegisterAsync();
    
        // Bind your plugin configuration
        configSection?.Bind(_configuration);
    
        // Register your event handlers
        PluginEvents.BeforeRequest += BeforeRequestAsync;
      }
    
      private Task BeforeRequestAsync(object sender, ProxyRequestArgs e)
      {
        if (UrlsToWatch is null ||
          !e.HasRequestUrlMatch(UrlsToWatch))
        {
          // No match for the URL, so we don't need to do anything
          Logger.LogRequest("URL not matched", MessageType.Skipped, new LoggingContext(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;
        }
    
        return Task.CompletedTask;
      }
    }
    
  2. Выполните сборку проекта.

    dotnet build
    
  3. Обновите devproxyrc.json файл, чтобы включить новую конфигурацию.

    {
      "plugins": [{
        "name": "CatchApiCalls",
        "enabled": true,
        "pluginPath": "./bin/Debug/net8.0/MyCustomPlugin.dll",
        "configSection": "catchApiCalls"
      }],
      "catchApiCalls": {
        "requiredHeader": "Authorization" // Example configuration
      }
    }
    
  4. Запустите прокси-сервер разработки.

    devproxy