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 classlibcommand.dotnet new classlib -n MyCustomPluginOpen the newly created project in Visual Studio Code.
code MyCustomPluginAdd the Dev Proxy Abstractions DLL (
DevProxy.Abstractions.dll) to the project folder.Add the
DevProxy.Abstractions.dllas a reference to your projectDevProxyCustomPlugin.csprojfile.<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.ProxyExclude the dependency DLLs from the build output by adding a
ExcludeAssetstag perPackageReferencein theDevProxyCustomPlugin.csprojfile.<ExcludeAssets>runtime</ExcludeAssets>Create a new class that inherits from the
BaseProxyclass.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.jsonfile.{ "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 theConfigurationproperty.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 buildUpdate your
devproxyrc.jsonfile 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