I have a project in which I need to sign gRPC messages on the fly. Unfortunately, there is no way to do so as of now. CallCredentials doesn't provide any meaningful information about the data being transferred and Intercepting a message just allows me to add metadata which is far from ideal. This is all on the client-side by the way. Have no problem with the server-side for checking the signature.
However, a good place to add a filter and do these sorts of things is via the GrpcChannelOptions.HttpHandler property. However, the default value of this property is a new instance of SocketsHttpHandler which supports and implemented a ton of feature I can not simply replace with own implementation and really like to have. Especially the new KeepAlivePing properties introduced with Net5.
Unfortunately, this class is sealed and therefore I can not extend its functionality, and to add insult to the injury, I can not even wrap it up in another class since the SocketsHttpHandler.Send() and SocketsHttpHandler.SendAsync() are both protected internal meaning that only the net core itself is allowed to access those since the class is sealed.
I really don't see why this is the case. This class can and should be at least inheritable.
namespace System.Net.Http
{
[UnsupportedOSPlatform("browser")]
- public sealed class SocketsHttpHandler : HttpMessageHandler {
+ public class SocketsHttpHandler : HttpMessageHandler {
}
``` C#
public class ExampleHttpHandler : SocketsHttpHandler
{
public ExampleHttpHandler()
{
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return await base.SendAsync(request, cancellationToken);
}
}
```
I am not aware of any risk associated with this change.
Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.
Issue Details
I have a project in which I need to sign gRPC messages on the fly. Unfortunately, there is no way to do so as of now. CallCredentials doesn't provide any meaningful information about the data being transferred and Intercepting a message just allows me to add metadata which is far from ideal. This is all on the client-side by the way. Have no problem with the server-side for checking the signature.
However, a good place to add a filter and do these sorts of things is via the GrpcChannelOptions.HttpHandler property. However, the default value of this property is a new instance of SocketsHttpHandler which supports and implemented a ton of feature I can not simply replace with own implementation and really like to have. Especially the new KeepAlivePing properties introduced with Net5.
Unfortunately, this class is sealed and therefore I can not extend its functionality, and to add insult to the injury, I can not even wrap it up in another class since the SocketsHttpHandler.Send() and SocketsHttpHandler.SendAsync() are both protected internal meaning that only the net core itself is allowed to access those since the class is sealed.
I really don't see why this is the case. This class can and should be at least inheritable.
namespace System.Net.Http
{
[UnsupportedOSPlatform("browser")]
- public sealed class SocketsHttpHandler : HttpMessageHandler {
+ public class SocketsHttpHandler : HttpMessageHandler {
}
``` C#
public class ExampleHttpHandler : SocketsHttpHandler
{
public ExampleHttpHandler()
{
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return await base.SendAsync(request, cancellationToken);
}
}
```
I am not aware of any risk associated with this change.
| Author: | falahati |
|---|---|
| Assignees: | - |
| Labels: | `api-suggestion`, `area-System.Net.Http`, `untriaged` |
| Milestone: | - |
If you don't need to modify any behaviors of SocketsHttpHandler, you can just wrap it with your own DelegatingHandler-derived type; there's no need to derive from SocketsHttpHandler.
If you do need to modify behaviors, how will unsealing help?
@stefannikolei
Thanks for the suggestion. Was not aware of the fact that DelegatingHandler and SocketsHttpHandler both share the same parent. This solved my problem:
```C#
public class Example : DelegatingHandler
{
public Example(HttpMessageHandler handler)
{
InnerHandler = handler;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// do things
return base.SendAsync(request, cancellationToken);
}
}
```
Sorry for the issue.
Glad it worked for you.