Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In this article, you learn how to create a custom plugin for the Dev Proxy. By creating plugins for Dev Proxy, you can extend its functionality and add custom features to fit your needs.
Prerequisites
Before you start creating a custom plugin, make sure you have the following prerequisites:
- .NET v9 Core SDK
- The latest version of the Dev Proxy Abstractions DLL, which you can find on the Dev Proxy GitHub releases page
Create a new plugin
Follow the next steps to create a new project:
Create a new class library project using the
dotnet new classlib
command.dotnet new classlib -n MyCustomPlugin
Open the newly created project in Visual Studio Code.
code MyCustomPlugin
Add the Dev Proxy Abstractions DLL (
DevProxy.Abstractions.dll
) to the project folder.Add the
DevProxy.Abstractions.dll
as a reference to your projectDevProxyCustomPlugin.csproj
file.<ItemGroup> <Reference Include="DevProxy.Abstractions"> <HintPath>.\DevProxy.Abstractions.dll</HintPath> <Private>false</Private> <ExcludeAssets>runtime</ExcludeAssets> </Reference> </ItemGroup>
Add the NuGet packages required for your project.
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
Exclude the dependency DLLs from the build output by adding a
ExcludeAssets
tag perPackageReference
in theDevProxyCustomPlugin.csproj
file.<ExcludeAssets>runtime</ExcludeAssets>
Create a new class that inherits from the
BaseProxy
class.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; } }
Build your project.
dotnet build
Use your custom plugin
To use your custom plugin, you need to add it to the Dev Proxy configuration file:
Add the new plugin configuration in the
devproxyrc.json
file.{ "plugins": [{ "name": "CatchApiCallsPlugin", "enabled": true, "pluginPath": "./bin/Debug/net9.0/MyCustomPlugin.dll", }] }
Run the Dev Proxy.
devproxy
The example plugin checks all matching URLs for the required Authorization
header. If the header isn't present, it shows a warning message.
Adding custom configuration to your plugin (optional)
You can extend your plugin's logic by adding custom configuration:
Inherit from the
BasePlugin<TConfiguration>
class. Dev Proxy exposes at runtime parsed plugin configuration through theConfiguration
property.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; } }
Build your project.
dotnet build
Update your
devproxyrc.json
file to include the new configuration.{ "plugins": [{ "name": "CatchApiCallsPlugin", "enabled": true, "pluginPath": "./bin/Debug/net9.0/MyCustomPlugin.dll", "configSection": "catchApiCalls" }], "catchApiCalls": { "requiredHeader": "Authorization" // Example configuration } }
Run the Dev Proxy.
devproxy