Unable to transform Response Header "Set-Cookie" with ITransformProvider
- Dominant language
- C#
- Stars
- 9.6k
- Forks
- 933
- Avg merge
- 12d 18h
- Merged PRs (30d)
- 2
Description
### Describe the bug
My application needs to transform the Cookie Path from the original Server to match the transformed Path. For that I build a custom ITransformProvider
```c#
public class ReverseCookieTransform : ITransformProvider
{
public const string SourceCookiePath = "SourceCookiePath";
public const string DestinationCookiePath = "DestinationCookiePath";
private const string HeaderSetCookie = "Set-Cookie";
public void ValidateRoute(TransformRouteValidationContext context)
{
if (!TryGetSourceCookiePath(context.Route, out var sourceCookiePath))
return;
if (string.IsNullOrEmpty(sourceCookiePath))
context.Errors.Add(new ArgumentException($"A non-empty {SourceCookiePath} value is required"));
if (TryGetDestinationCookiePath(context.Route, out var destinationCookiePath))
{
if (string.IsNullOrEmpty(destinationCookiePath))
context.Errors.Add(new ArgumentException($"A non-empty {DestinationCookiePath} value is required"));
}
else
{
context.Errors.Add(new ArgumentException($"{DestinationCookiePath} is required when {SourceCookiePath} is set."));
}
}
public void ValidateCluster(TransformClusterValidationContext context) { }
public void Apply(TransformBuilderContext context)
{
if (!TryGetSourceCookiePath(context.Route, out var sourceCookiePath))
return;
if (!TryGetDestinationCookiePath(context.Route, out var destinationCookiePath))
return;
context.AddResponseTransform(ctx =>
{
var headers = ctx.ProxyResponse.Headers;
if (!headers.TryGetValues(HeaderSetCookie, out var values))
return default;
headers.Remove(HeaderSetCookie);
foreach (var cookie in SetCookieHeaderValue.ParseList(values.ToList()))
{
if (cookie.Path.HasValue && cookie.Path.StartsWith(sourceCookiePath, StringComparison.OrdinalIgnoreCase))
cookie.Path = destinationCookiePath + cookie.Path.Substring(sourceCookiePath.Length);
headers.TryAddWithoutValidation(HeaderSetCookie, cookie.ToString());
}
return default;
});
}
private static bool TryGetSourceCookiePath(ProxyRoute route, out string sourceCookiePath)
{
sourceCookiePath = null;
return route.Metadata?.TryGetValue(SourceCookiePath, out sourceCookiePath) ?? false;
}
private static bool TryGetDestinationCookiePath(ProxyRoute route, out string destinationCookiePath)
{
destinationCookiePath = null;
return route.Metadata?.TryGetValue(DestinationCookiePath, out destinationCookiePath) ?? false;
}
}
}
```
I included the YARP sources for debugging. When I check the `destinationResponse.Headers` within `HttpProxy.cs` I see that the header Set-Cookie headers are replaced as wanted, but those headers are not send to the browser; the original headers are send. It looks like my header transformation was applied to late.
Is there a better way to do it?
### Further technical details
- Windows 10
- Visual Studio 2019 with IISExpress
- Yarp.ReverseProxy 1.0.0-preview.11.21223.5
Contributor guide
Assessment
This issue has not been assessed yet.