Udostępnij za pośrednictwem


Tworzenie wtyczki niestandardowej

Na pierwszy rzut oka
Celem: Zbudować niestandardową wtyczkę Dev Proxy
Czas: 30 minut
Wtyczki: Wtyczka niestandardowa
Prerequisites:Set up Dev Proxy, .NET 10 SDK

Z tego artykułu dowiesz się, jak utworzyć niestandardową wtyczkę dla serwera proxy deweloperów. Tworząc wtyczki dla Dev Proxy, możesz rozszerzyć jego funkcjonalność i dodać funkcje niestandardowe, aby dostosować do swoich potrzeb.

Wtyczki HTTP a wtyczki stdio

Serwer proxy deweloperów obsługuje dwa typy wtyczek w zależności od ruchu, który chcesz przechwycić:

  • Wtyczki HTTP przechwytują żądania i odpowiedzi HTTP(S) między Twoją aplikacją a interfejsami API. Dziedziczą one metody, takie jak i , i zastępują . Użyj wtyczek HTTP, jeśli chcesz symulować błędy interfejsu API, dodawać pozorne odpowiedzi, weryfikować nagłówki żądań lub w inny sposób sprawdzać i modyfikować ruch HTTP.

  • Wtyczki Stdio przechwytują komunikaty wysyłane za pośrednictwem standardowego wejścia/wyjścia (stdin, stdout, stderr) między procesem nadrzędnym a procesem podrzędnym. Implementują interfejs (który również coś implementuje) i zastępują takie metody, jak , , i . Użyj wtyczek stdio podczas pracy z narzędziami komunikującymi się za pośrednictwem stdio, takich jak serwery protokołu MCP (Model Context Protocol).

Pojedyncza klasa wtyczki może obsługiwać zarówno ruch HTTP, jak i stdio, przesłaniając metody z obu zestawów.

Wymagania wstępne

Przed rozpoczęciem tworzenia wtyczki niestandardowej upewnij się, że masz następujące wymagania wstępne:

Tworzenie nowej wtyczki

Wykonaj następne kroki, aby utworzyć nowy projekt:

  1. Utwórz nowy projekt biblioteki klas przy użyciu polecenia .

    dotnet new classlib -n MyCustomPlugin
    
  2. Otwórz nowo utworzony projekt w Visual Studio Code.

    code MyCustomPlugin
    
  3. Dodaj bibliotekę DLL abstrakcji dev proxy () do folderu projektu.

  4. Dodaj jako odwołanie do pliku projektu .

    <ItemGroup>
      <Reference Include="DevProxy.Abstractions">
        <HintPath>.\DevProxy.Abstractions.dll</HintPath>
        <Private>false</Private>
        <ExcludeAssets>runtime</ExcludeAssets>
      </Reference>
    </ItemGroup>
    
  5. Dodaj pakiety NuGet wymagane dla projektu.

    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. Wyklucz biblioteki linków dynamicznych zależności (DLL) z danych wyjściowych kompilacji, dodając tag na w pliku.

    <ExcludeAssets>runtime</ExcludeAssets>
    
  7. Utwórz nową klasę dziedziczącą z klasy .

    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. Skompiluj projekt.

    dotnet build
    

Użyj swojej wtyczki niestandardowej

Aby użyć niestandardowej wtyczki, należy dodać ją do pliku konfiguracji serwera proxy deweloperów:

  1. Dodaj nową konfigurację wtyczki w pliku .

    Plik: devproxyrc.json

    {
      "plugins": [{
        "name": "CatchApiCallsPlugin",
        "enabled": true,
        "pluginPath": "./bin/Debug/net10.0/MyCustomPlugin.dll",
      }]
    }
    
  2. Uruchom serwer proxy deweloperów.

    devproxy
    

Przykładowa wtyczka sprawdza wszystkie pasujące adresy URL wymaganego nagłówka. Jeśli nagłówek nie jest obecny, zostanie wyświetlony komunikat ostrzegawczy.

Dodawanie konfiguracji niestandardowej do wtyczki (opcjonalnie)

Logikę wtyczki można rozszerzyć, dodając konfigurację niestandardową:

  1. Dziedzicz z klasy . Dev Proxy udostępnia w czasie działania składnię konfiguracji wtyczki poprzez właściwość .

    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. Skompiluj projekt.

    dotnet build
    
  3. Zaktualizuj plik, aby uwzględnić nową konfigurację.

    Plik: devproxyrc.json

    {
      "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.2.0/rc.schema.json",
      "plugins": [{
        "name": "CatchApiCallsPlugin",
        "enabled": true,
        "pluginPath": "./bin/Debug/net10.0/MyCustomPlugin.dll",
        "configSection": "catchApiCalls"
      }],
      "catchApiCalls": {
        "requiredHeader": "Authorization"
      }
    }
    
  4. Uruchom serwer proxy deweloperów.

    devproxy
    

Zobacz także

  • Architektura wtyczki
  • Używanie wstępnie ustawionych konfiguracji
  • Konfigurowanie serwera proxy deweloperskiego