Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

HttpRecorder.DevProxy

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

httprecorder.devproxy - nuget Package Compare versions

Comparing version
0.2.0
to
0.0.2
services/metadata/...cc2b3a09f0bd4c629fbfbbceb55fa285.psmdcp

Sorry, the diff of this file is not supported yet

+8
-7

@@ -5,11 +5,13 @@ <?xml version="1.0" encoding="utf-8"?>

<id>HttpRecorder.DevProxy</id>
<version>0.2.0</version>
<authors>Max Golovanov</authors>
<version>0.0.2</version>
<authors>maxgolov</authors>
<license type="expression">MIT</license>
<licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
<readme>README.md</readme>
<projectUrl>https://github.com/maxgolov/HttpRecorderNext</projectUrl>
<description>Dev Proxy plugin for recording HTTP traffic to HAR files using HttpRecorder library. Features streaming HAR file writes with real-time flush and session-based recording.</description>
<tags>devproxy plugin har http recording testing proxy</tags>
<repository type="git" url="https://github.com/maxgolov/HttpRecorderNext" commit="ea772f3677aff9c048ecd074c7661b2ecded7b92" />
<projectUrl>https://github.com/maxgolov/HttpRecorder</projectUrl>
<description>Dev Proxy plugin to record HTTP traffic to HAR (HTTP Archive) files for testing and analysis. Integrates with the HttpRecorder library to capture, replay, and anonymize HTTP interactions.</description>
<releaseNotes>See https://github.com/maxgolov/HttpRecorder/blob/main/CHANGELOG.md</releaseNotes>
<copyright>Copyright (c) 2024 maxgolov</copyright>
<tags>dev-proxy har http recording testing proxy devproxy microsoft</tags>
<repository type="git" url="https://github.com/maxgolov/HttpRecorder" commit="ea772f3677aff9c048ecd074c7661b2ecded7b92" />
<dependencies>

@@ -19,3 +21,2 @@ <group targetFramework="net9.0">

<dependency id="Microsoft.Extensions.Logging.Abstractions" version="9.0.0" exclude="Build,Analyzers" />
<dependency id="Unobtanium.Web.Proxy" version="0.1.5" exclude="Build,Analyzers" />
</group>

@@ -22,0 +23,0 @@ </dependencies>

+175
-225

@@ -1,299 +0,249 @@

# HttpRecorder Dev Proxy Extension
# HttpRecorder.Next
This directory contains a Microsoft Dev Proxy plugin that integrates HttpRecorder to capture HTTP traffic and save it as HAR (HTTP Archive) files.
.NET HttpClient integration tests made easy.
## Overview
HttpRecorder is an `HttpMessageHandler` that can record and replay HTTP interactions through the standard `HttpClient` . This allows the creation of HTTP integration tests that are fast, repeatable and reliable.
The HttpRecorder Dev Proxy plugin allows you to:
- Intercept HTTP requests and responses passing through Dev Proxy
- Record them using the HttpRecorder library
- Save interactions as HAR files for later replay or analysis
- Anonymize sensitive data like authorization headers
- Filter which URLs to record
Interactions are recorded using the [HTTP Archive format standard](https://en.wikipedia.org/wiki/.har), so that they are easily manipulated by your favorite tool of choice.
## Project Structure
> **Note:** This is a modernized fork of the [original HttpRecorder by nventive](https://github.com/nventive/HttpRecorder), maintained by **Max Golovanov** ([max.golovanov+github@gmail.com](mailto:max.golovanov+github@gmail.com)). This fork features .NET 8 and .NET 9 support, updated dependencies, modern APIs, and compatibility fixes for the latest .NET ecosystem.
```
DevProxyExtension/
├── HttpRecorder.DevProxy/
│ ├── HttpRecorderPlugin.cs # Main plugin implementation
│ ├── HttpRecorderPluginConfiguration.cs # Plugin configuration class
│ ├── BasePlugin.cs # Base class stub (replace with DevProxy.Abstractions)
│ └── HttpRecorder.DevProxy.csproj # Project file
├── README.md # This file
└── devproxyrc.example.json # Example Dev Proxy configuration
```
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
[![.NET 8](https://img.shields.io/badge/.NET-8.0-blue.svg)](https://dotnet.microsoft.com/download/dotnet/8.0)
[![.NET 9](https://img.shields.io/badge/.NET-9.0-blue.svg)](https://dotnet.microsoft.com/download/dotnet/9.0)
![Nuget](https://img.shields.io/nuget/v/HttpRecorder.Next.svg)
![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)
## Prerequisites
## Getting Started
1. **Microsoft Dev Proxy** - Install using winget (recommended):
```powershell
# Stable version
winget install DevProxy.DevProxy --silent
# OR Beta version (for latest preview features)
winget install DevProxy.DevProxy.Beta --silent
```
**Important**: After installation, restart your command prompt to refresh the PATH environment variable.
Alternative: Manual installation from [Microsoft Dev Proxy Documentation](https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/)
Install the package:
2. **.NET 9.0 SDK** - Required for building the plugin
### First Time Setup
When you start Dev Proxy for the first time:
1. **Trust the certificate**: Dev Proxy installs a certificate named "Dev Proxy CA". Select **Yes** to confirm installation.
2. **Allow firewall access**: Windows Firewall will show a warning. Select **Allow access** to permit traffic through the firewall.
Dev Proxy will display:
```
info Dev Proxy API listening on http://localhost:8897...
info Dev Proxy Listening on 127.0.0.1:8000...
dotnet add package HttpRecorder.Next
Hotkeys: issue (w)eb request, (r)ecord, (s)top recording, (c)lear screen
Press CTRL+C to stop Dev Proxy
```
# or, using Package Manager
**Important**: Always stop Dev Proxy using **Ctrl+C** to safely unregister it as the system proxy. Closing the terminal without stopping Dev Proxy may cause connection issues.
## Building the Plugin
```powershell
# From the DevProxyExtension directory
cd HttpRecorder.DevProxy
dotnet build
# The plugin DLL will be at:
# bin/Debug/net9.0/HttpRecorder.DevProxy.dll
Install-Package HttpRecorder.Next
```
## Configuration
Here is an example of an integration tests using **HttpRecorder** (the `HttpRecorderDelegatingHandler`):
### Dev Proxy Configuration
```csharp
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using HttpRecorder;
using Xunit;
Create or update your `devproxyrc.json` file:
```json
namespace Sample
{
"plugins": [
public class SampleIntegrationTests
{
"name": "HttpRecorderPlugin",
"enabled": true,
"pluginPath": "./DevProxyExtension/HttpRecorder.DevProxy/bin/Debug/net9.0/HttpRecorder.DevProxy.dll",
"configSection": "httpRecorder"
}
],
"urlsToWatch": [
"https://api.example.com/*",
"https://graph.microsoft.com/*"
],
"httpRecorder": {
"outputDirectory": "./recordings",
"mode": "Record",
"includeBodies": true,
"anonymizeSensitiveData": true,
"sensitiveHeaders": [
"Authorization",
"Cookie",
"Set-Cookie",
"X-API-Key",
"X-Auth-Token"
]
}
}
```
[Fact]
public async Task ItShould()
{
// Initialize the HttpClient with the recorded file
// stored in a fixture repository.
var client = CreateHttpClient();
### Configuration Options
// Performs HttpClient operations.
// The interaction is recorded if there are no record,
// or replayed if there are
// (without actually hitting the target API).
// Fixture is recorded in the SampleIntegrationTestsFixtures\ItShould.har file.
var response = await client.GetAsync("api/user");
- **outputDirectory**: Directory where HAR files will be saved (default: `./recordings`)
- **mode**: Recording mode - currently supports "Record" (default)
- **includeBodies**: Whether to include request/response bodies (default: `true`)
- **anonymizeSensitiveData**: Redact sensitive headers (default: `true`)
- **sensitiveHeaders**: Array of header names to anonymize
// Performs assertions.
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
## Running Dev Proxy with the Plugin
private HttpClient CreateHttpClient(
[CallerMemberName] string testName = "",
[CallerFilePath] string filePath = "")
{
// The location of the file where the interaction is recorded.
// We use the C# CallerMemberName/CallerFilePath attributes to
// automatically set an appropriate path based on the test case.
var interactionFilePath = Path.Join(
Path.GetDirectoryName(filePath),
$"{Path.GetFileNameWithoutExtension(filePath)}Fixtures",
testName);
```powershell
# Start Dev Proxy with your configuration
devproxy --config-file devproxyrc.json
# Or if devproxyrc.json is in the current directory
devproxy
# For beta version
devproxy-beta --config-file devproxyrc.json
// Initialize the HttpClient with HttpRecorderDelegatingHandler, which
// records and replays the interactions.
// Do not forget to set the InnerHandler property.
return new HttpClient(
new HttpRecorderDelegatingHandler(interactionFilePath) { InnerHandler = new HttpClientHandler() })
{
BaseAddress = new Uri("https://reqres.in/"),
};
}
}
}
```
### Verifying Dev Proxy is Working
## Features
Before using the plugin, confirm Dev Proxy is intercepting requests:
### Record mode
```powershell
# Test with Invoke-WebRequest (PowerShell)
Invoke-WebRequest -Uri https://jsonplaceholder.typicode.com/posts
The `HttpRecorderDelegatingHandler` can be run in different modes:
# Or with curl
curl -ikx http://localhost:8000 https://jsonplaceholder.typicode.com/posts
```
- Auto: Default mode - replay the interactions if the recording exists, otherwise record it.
- Record: Always record the interaction, even if a record is present.
- Replay: Always replay the interaction, throw if there is no recording.
- Passthrough: Always passes the request/response down the line, without any interaction
You should see output in the Dev Proxy terminal like:
```
req ╭ GET https://jsonplaceholder.typicode.com/posts
time │ 1/31/2025 12:12:14 PM +00:00
api ╰ Passed through
```
Just use the appropriate mode in the `HttpRecorderDelegatingHandler` constructor.
## How It Works
The mode can also be overridden using the environment variable `HTTP_RECORDER_MODE`.
If this is set to any valid `HttpRecorderMode` value, it will override the mode set in the code,
except if this mode is `HttpRecorderMode.Passthrough`.
This is useful when running in a CI environment and you want to make sure that no
request goes out and all interactions are properly committed to the codebase.
1. **Request Interception**: When Dev Proxy intercepts an HTTP request matching `urlsToWatch`, the `BeforeRequestAsync` method is called
2. **Request Recording**: The plugin creates an `Interaction` object and stores request details (URL, method, headers, body)
3. **Response Interception**: When the response arrives, `AfterResponseAsync` is called
4. **Response Recording**: The plugin updates the interaction with response details (status code, headers, body, timing)
5. **HAR Export**: The complete interaction is saved as a HAR file using `HttpArchiveInteractionRepository`
### Customize the matching behavior
## HAR File Output
By default, matching of the recorded requests is done by comparing the HTTP Method and complete Request URI. The first request that match is used and will not be returned again in the current run.
Each recorded interaction is saved as a separate HAR file:
If needed, the matching behavior can be customized using the `RulesMatcher`:
```
recordings/
├── 20251104_143022_1_api_example_com_users.har
├── 20251104_143023_2_api_example_com_orders.har
└── ...
```
```csharp
using HttpRecorder.Matchers;
Filenames include:
- Timestamp (yyyyMMdd_HHmmss)
- Interaction ID
- Sanitized URL path
// Will match requests once in order, without comparing requests.
var matcher = RulesMatcher.MatchOnce;
## Integration with Dev Proxy Abstractions
// Will match requests once only by comparing HTTP methods.
matcher = RulesMatcher.MatchOnce.ByHttpMethod();
**Note**: The current implementation includes a stub `BasePlugin.cs` class. For production use:
// Will match requests multiple times by comparing HTTP methods,
// request uri (excluding the query string) and the X-API-Key header.
matcher = RulesMatcher.MatchMultiple
.ByHttpMethod()
.ByRequestUri(UriPartial.Path)
.ByHeader("X-API-Key");
1. Install Dev Proxy and locate `DevProxy.Abstractions.dll`
2. Add it as a reference in the `.csproj` file:
// Custom matching rule using the provided incoming request
// and a recorded interaction message.
matcher = RulesMatcher.MatchOnce.By((request, message) => ...);
```xml
<ItemGroup>
<Reference Include="DevProxy.Abstractions">
<HintPath>path/to/DevProxy.Abstractions.dll</HintPath>
</Reference>
</ItemGroup>
var client = new HttpClient(new HttpRecorderDelegatingHandler("...", matcher: matcher));
```
3. Remove the stub `BasePlugin.cs` file
4. Update imports to use `DevProxy.Abstractions` namespace
Additional customization can be done by providing a custom `IRequestMatcher` implementation.
## Use Cases
### Anonymize the records
- **API Testing**: Record API interactions for test fixtures
- **Documentation**: Generate HAR files to document API behavior
- **Debugging**: Capture full request/response cycles for troubleshooting
- **Replay**: Save production traffic for replay in test environments
- **Analysis**: Analyze API performance and payloads
Sometimes, there are portions of the requests / responses that you don't want recorded
(e.g. because of API keys you do not want to commit to the source code repo...).
## Example Workflow
In this case, you can use the `RulesInteractionAnonymizer` to perform the substitution.
```powershell
# 1. Build the plugin
cd DevProxyExtension/HttpRecorder.DevProxy
dotnet build
```csharp
using HttpRecorder.Anonymizers;
# 2. Configure Dev Proxy (edit devproxyrc.json)
var anonymizer = RulesInteractionAnonymizer.Default
.AnonymizeRequestQueryStringParameter("queryStringParam")
.AnonymizeRequestHeader("requestHeader");
# 3. Start Dev Proxy
devproxy
var client = new HttpClient(new HttpRecorderDelegatingHandler("...", anonymizer: anonymizer));
```
# 4. Configure your application to use the proxy
$env:HTTP_PROXY = "http://localhost:8000"
$env:HTTPS_PROXY = "http://localhost:8000"
Additional customization can be done by providing a custom `IInteractionAnonymizer`
implementation.
# 5. Run your application
# HTTP traffic will be recorded to ./recordings/
### HttpClientFactory
# 6. Stop Dev Proxy (Ctrl+C)
The component comes with extension methods for the HttpClientFactory:
# 7. Review HAR files
ls ./recordings/*.har
```csharp
services
.AddHttpClient("TheClient")
.AddHttpRecorder(interactionName);
```
## Viewing HAR Files
### Recorder Context
HAR files can be viewed in:
- Chrome DevTools (Network tab → Import HAR)
- Firefox DevTools (Network tab → Import HAR)
- [HAR Viewer](http://www.softwareishard.com/har/viewer/)
- [Charles Proxy](https://www.charlesproxy.com/)
- [Fiddler](https://www.telerik.com/fiddler)
It is sometime helpful to be able to decoralate the injection of the `HttpRecorderDelegatingHandler`
and the Test case setup.
## Advanced Usage
This is especially useful in the context of ASP.NET Core Integration tests.
### Custom Anonymization Rules
It is possible to add the `HttpRecorderDelegatingHandler` globally to all `HttpClient` managed by the `IHttpClientFactory`,
and then to customize the recording in the test case by using the `HttpRecorderContext`.
Extend the plugin to add custom anonymization logic:
Here is how to do it:
```csharp
private void AnonymizeSensitiveHeaders(Dictionary<string, string> headers)
// When registering the services, do the following:
services.AddHttpRecorderContextSupport();
// This can be done in the ConfigureWebHost method of the WebApplicationFactory for example.
// It will inject the HttpRecorderDelegatingHandler in all HttpClients.
// Then, write your test cases using the following pattern:
[Fact]
public async Task ItShould()
{
// Existing logic...
// Custom: Anonymize API keys in query strings
if (headers.ContainsKey("X-Custom-Header"))
{
headers["X-Custom-Header"] = MaskApiKey(headers["X-Custom-Header"]);
}
using var context = new HttpRecorderContext(); // Notice the using pattern here.
// .. Perform test case. Interactions are recorded and replay as expected :-)
}
```
### Filtering Requests
Modify `BeforeRequestAsync` to add custom filtering:
```csharp
public override Task BeforeRequestAsync(ProxyRequestArgs e)
// Additional configuration per HttpClient can be setup as well:
[Fact]
public async Task ItShould()
{
// Only record POST/PUT requests
if (e.Session.HttpClient.Request.Method != "POST" &&
e.Session.HttpClient.Request.Method != "PUT")
{
return Task.CompletedTask;
}
// Continue with recording...
using var context = new HttpRecorderContext((sp, builder) =>
{
return builder.Name switch // The builder name here is the name of the HttpClient.
{
nameof(TypedClient) => new HttpRecorderConfiguration
{
Matcher = RulesMatcher.MatchMultiple,
},
nameof(DisabledClient) => new HttpRecorderConfiguration
{
Enabled = false,
},
_ => null // Default configuration.
};
});
// .. Perform test case.
}
```
## Troubleshooting
### Record interaction in external tools
### Plugin Not Loading
- Verify the `pluginPath` in `devproxyrc.json` is correct
- Check that the DLL was built successfully
- Ensure .NET 9.0 runtime is installed
Interaction files can be recorded using your favorite tool (e.g. [Fiddler](https://www.telerik.com/fiddler), Google Chrome Inspector, ...).
### No HAR Files Generated
- Check the `outputDirectory` has write permissions
- Verify `urlsToWatch` patterns match your requests
- Check Dev Proxy console for error messages
You only have to export it using the HAR/HTTP Archive format. They can then be used as-is as a test fixture that will be loaded by the `HttpRecorderDelegatingHandler`.
### Missing Request/Response Bodies
- Set `includeBodies: true` in configuration
- Some content types may not be captured (binary, streaming)
### Customize the storage
## Contributing
Reading/writing the interaction can be customized by providing a custom `IInteractionRepository` implementation.
This plugin is part of the HttpRecorder.Next project. See the main README for contribution guidelines.
## Changelog
Please consult the [CHANGELOG](CHANGELOG.md) for more information about version
history.
## License
MIT License - see LICENSE file in the project root.
This project is licensed under the Apache 2.0 license - see the
[LICENSE](LICENSE) file for details.
## References
## Contributing
- [Microsoft Dev Proxy Documentation](https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/)
- [Creating Custom Dev Proxy Plugins](https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/how-to/create-custom-plugin)
- [HAR Specification](http://www.softwareishard.com/blog/har-12-spec/)
- [HttpRecorder.Next Repository](https://github.com/maxgolov/HttpRecorderNext)
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the process for
contributing to this project.
Be mindful of our [Code of Conduct](CODE_OF_CONDUCT.md).
## Acknowledgments
- https://github.com/vcr/vcr
- https://github.com/nock/nock
- https://github.com/mleech/scotch
- https://github.com/nventive/HttpRecorder

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet