CoreWCF icon indicating copy to clipboard operation
CoreWCF copied to clipboard

[Bug]: NullReferenceException thrown when using invalid URL

Open bjornbouetsmith opened this issue 1 year ago • 7 comments

Duplicate ?

  • [X]Duplicate of #1331

Product version

1.5.1

Describe expected behavior

I have a net.tcp WCF Service bound to the following URL: net.tcp://localhost:1234/service/bootstrap2/0

If I call this service with a wcf client, but uses endpoint address:

net.tcp://localhost:1234/service/bootstrap2/1

I get a NullReferenceException logged in my log - instead of a more "correct" 404 not found.

The reason for client calling the "wrong" url - is because our client can also connect to a service running on netframework, where portsharing is enabled, so services on the same server share the port, but only differentiate on the last part of the url, i.e. one service binds to /0 the other binds to /1.

In net framework WCF, this never causes errors to be logged server side, and client just tries next number - with corewcf when a client tries a "wrong" url, the null reference exceptions is logged

Describe actual behavior

Null reference exception thrown instead of a more correct exception that should be captured by the framework and turned into a communication exception

Which binding

NetTcp

security

None

Which .NET version

.NET 6

Which os platform

Windows

Code snippet used to reproduce the issue

No real code example - but create a net.tcp service, bind to specific url - call service with a WCF client on correct port, but slightly different url.

I have verified the problem with the samples in:

https://github.com/CoreWCF/samples/tree/main/Scenarios/Getting-Started-with-CoreWCF

Start the net.tcp server - and use the NetCoreClient and change the url to end with /netTcp2

Stacktrace if any

00:18:36.358|3788037464|ERROR|119|Kestrel|Unhandled exception while processing 0HN132C763JHH.|System.NullReferenceException
Object reference not set to an instance of an object.
   at CoreWCF.Channels.Framing.FramingModeHandshakeMiddleware.OnConnectedCoreAsync(FramingConnection connection)
   at CoreWCF.Channels.Framing.FramingModeHandshakeMiddleware.OnConnectedAsync(FramingConnection connection)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.KestrelConnection`1.ExecuteAsync()

bjornbouetsmith avatar Feb 01 '24 11:02 bjornbouetsmith

I have pulled the code and it seems like adding:

 if (connection.ServiceDispatcher == null)
{
    await connection.SendFaultAsync(FramingEncodingString.EndpointNotFoundFault, Timeout.InfiniteTimeSpan/*GetRemainingTimeout()*/,
        ConnectionOrientedTransportDefaults.MaxViaSize + ConnectionOrientedTransportDefaults.MaxContentTypeSize);
    return;
}

just before:

if (reuseHandler == null)
{
    reuseHandler = connection.ServiceDispatcher.Binding.GetProperty<IConnectionReuseHandler>(new BindingParameterCollection());
}

Consequence would be that invalid requests would not reuse the connection I think?

And client gets a System.ServiceModel.EndpointNotFoundException, which is the same error as before - so from a client side it should be of no consequence, but from the server side it gets rid of an exception

bjornbouetsmith avatar Feb 02 '24 13:02 bjornbouetsmith

I can make a PR for this if you think its a good enough fix. The problem is that when a "wrong" url is used it seems like the ServiceDispatcher is not added to the connection because the url cannot be looked in the url map somewhere.

bjornbouetsmith avatar Feb 02 '24 18:02 bjornbouetsmith

@mconnew do you think a PR would be acceptable to fix this issue?

bjornbouetsmith avatar Feb 07 '24 09:02 bjornbouetsmith

Yes, please submit a PR, preferably with a test. A believe a test should be simple to write for this scenario.

mconnew avatar Feb 07 '24 12:02 mconnew

Will do - although I would love to assert that no "NullReferenceException" is logged server side - from a client side perspective this is a non breaking change, since before client got a EndpointNotFoundException and also does that now.

But I don't think the test framework is prepared for this, i.e. making assertions on what was logged or not.

Is this something that it would be okay if I added?

i.e. something similar to:

var provider = host.Services.GetService<ILoggerProvider>() as XunitLoggerProvider;
Assert.NotNull(provider);
Assert.Empty(provider.GetExceptionsLogged<NullReferenceException>());

To assert that no NullReferenceException was logged

bjornbouetsmith avatar Feb 07 '24 18:02 bjornbouetsmith

Created PR: https://github.com/CoreWCF/CoreWCF/pull/1335

bjornbouetsmith avatar Feb 07 '24 19:02 bjornbouetsmith

@mconnew How are chances that the PR will be reviewed anytime soon? I has been 3 weeks since I created the PR - I get that you most likely have a lot of stuff to look at, but it would be nice to get the process started.

bjornbouetsmith avatar Feb 25 '24 11:02 bjornbouetsmith