Compartir a través de


Creación de un complemento personalizado

De un vistazo
Objetivo: Crear un complemento de proxy Dev personalizado
Tiempo: 30 minutos
Complementos: Complemento personalizado
Prerequisites:Set up Dev Proxy, .NET 10 SDK

En este artículo, aprenderá a crear un complemento personalizado para el proxy de desarrollo. Al crear complementos para el proxy de desarrollo, puede ampliar su funcionalidad y agregar características personalizadas para satisfacer sus necesidades.

Complementos HTTP frente a complementos stdio

Dev Proxy admite dos tipos de complementos en función del tráfico que quiera interceptar:

  • Los complementos HTTP interceptan las solicitudes y respuestas HTTP(S) entre la aplicación y las API. Heredan de y invalidan métodos como y . Use complementos HTTP cuando quiera simular errores de API, agregar respuestas simuladas, validar encabezados de solicitud o inspeccionar y modificar el tráfico HTTP.

  • Los complementos stdio interceptan los mensajes enviados a través de la entrada y salida estándar (stdin, stdout, stderr) entre un proceso primario y un proceso secundario. Implementan la interfaz (que también implementa) e invalidan métodos como , y . Use complementos stdio al trabajar con herramientas que se comunican a través de stdio, como servidores de Protocolo de contexto de modelo (MCP).

Una sola clase de complemento puede controlar el tráfico HTTP y stdio invalidando métodos de ambos conjuntos.

Requisitos previos

Antes de empezar a crear un complemento personalizado, asegúrese de que tiene los siguientes requisitos previos:

Creación de un complemento

Siga los pasos siguientes para crear un proyecto:

  1. Cree un nuevo proyecto de biblioteca de clases mediante el comando .

    dotnet new classlib -n MyCustomPlugin
    
  2. Abra el proyecto recién creado en Visual Studio Code.

    code MyCustomPlugin
    
  3. Agregue la DLL de Abstracciones del Proxy de Desarrollo a la carpeta del proyecto.

  4. Agregue el elemento como referencia en el archivo de su proyecto.

    <ItemGroup>
      <Reference Include="DevProxy.Abstractions">
        <HintPath>.\DevProxy.Abstractions.dll</HintPath>
        <Private>false</Private>
        <ExcludeAssets>runtime</ExcludeAssets>
      </Reference>
    </ItemGroup>
    
  5. Agregue los paquetes NuGet necesarios para el proyecto.

    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. Excluya las bibliotecas de vínculos dinámicos de dependencias (DLL) de la salida de compilación agregando una etiqueta por en el archivo.

    <ExcludeAssets>runtime</ExcludeAssets>
    
  7. Cree una nueva clase que herede de la clase .

    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, CancellationToken cancellationToken)
        {
            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. Construya su proyecto.

    dotnet build
    

Uso del complemento personalizado

Para usar el complemento personalizado, debe agregarlo al archivo de configuración del proxy de desarrollo:

  1. Agregue la nueva configuración del complemento en el archivo.

    Archivo: devproxyrc.json

    {
      "plugins": [{
        "name": "CatchApiCallsPlugin",
        "enabled": true,
        "pluginPath": "./bin/Debug/net10.0/MyCustomPlugin.dll",
      }]
    }
    
  2. Ejecute el proxy de desarrollo.

    devproxy
    

El complemento de ejemplo comprueba todas las direcciones URL coincidentes para el encabezado necesario . Si el encabezado no está presente, se muestra un mensaje de advertencia.

Adición de una configuración personalizada al complemento (opcional)

Puede ampliar la lógica del complemento agregando una configuración personalizada:

  1. Hereda de la clase . El proxy de desarrollo expone la configuración del complemento interpretada a través de la propiedad en tiempo de ejecución.

    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(
        HttpClient httpClient,
        ILogger<CatchApiCallsPlugin> logger,
        ISet<UrlToWatch> urlsToWatch,
        IProxyConfiguration proxyConfiguration,
        IConfigurationSection pluginConfigurationSection) :
        BasePlugin<CatchApiCallsConfiguration>(
            httpClient,
            logger,
            urlsToWatch,
            proxyConfiguration,
            pluginConfigurationSection)
    {
        public override string Name => nameof(CatchApiCallsPlugin);
    
        public override Task BeforeRequestAsync(ProxyRequestArgs e, CancellationToken cancellationToken)
        {
            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. Genere su proyecto.

    dotnet build
    
  3. Actualice el archivo para incluir la nueva configuración.

    Archivo: devproxyrc.json

    {
      "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.1.0/rc.schema.json",
      "plugins": [{
        "name": "CatchApiCallsPlugin",
        "enabled": true,
        "pluginPath": "./bin/Debug/net10.0/MyCustomPlugin.dll",
        "configSection": "catchApiCalls"
      }],
      "catchApiCalls": {
        "requiredHeader": "Authorization"
      }
    }
    
  4. Ejecute el proxy de desarrollo.

    devproxy
    

Consulte también

  • Arquitectura del complemento
  • Usar configuraciones preestablecidas
  • Configuración del proxy de desarrollo