Coverity sees in the following code that the messageHandler going out of scope, leaks the resource it refers to.
"System.Net.Http" Version="4.3.4" .net 6.0
Could you please suggest what I can do here?
1. "new System.Net.Http.HttpClientHandler(){UseCookies = false}" creates a new resource.
2. Assigning: "messageHandler" = resource returned from "new System.Net.Http.HttpClientHandler(){UseCookies = false}".
var messageHandler = config.MessageHandler ?? new HttpClientHandler() { UseCookies = false };
3. Condition "config.UseOAuth", taking false branch.
if (config.UseOAuth)
{
ā¦
4. Resource "messageHandler" is not closed or saved in "HttpClient".
var client = new HttpClient(messageHandler, messageHandler != config.MessageHandler) { BaseAddress = new Uri(config.Url) };
5. Condition "!config.UseOAuth", taking true branch.
if (!config.UseOAuth)
{
//add request headers
}
6. Variable "messageHandler" going out of scope leaks the resource it refers to.
return RestService.For<AClass>(client, AClass.RefitSettings);
});
}
Thank you!
It looks like Coverity lack some information how HttpClient
looks inside.
It says: 4. Resource "messageHandler" is not closed or saved in "HttpClient".
Internally HttpClient
is forwarding your messageHandler
to it's one base class called HttpMessageInvoker
, then store it in variable _handler
and there we can find Dispose
method
protected virtual void Dispose(bool disposing)
{
if (disposing && !_disposed)
{
_disposed = true;
if (_disposeHandler)
{
_handler.Dispose();
}
}
}
So messageHandler
is saved inside HttpClient
In .NET 6 you don't need to reference package System.Net.Http
at all as it's available without anything with version 6.0.0
Note: What I wrote here is based on version 6.0.0
I see other issue, if this code is called multiple times and if HttpClient
takes argument messageHandler
from config.MessageHandler
, then if one of those HttpClient
get disposed other one will contained disposed object, so when you are creating HttpClient
you have pass false
as second argument if it's config.MessageHandler
, or just use messageHandler != config.MessageHandler
var client = new HttpClient(messageHandler, messageHandler != config.MessageHandler) { BaseAddress = new Uri(config.Url) };