WebInputStream not cleaning up correctly on Windows?

I’m working on something that talks to a server and just noticed something odd when testing it on Windows.

It’s nothing complicated, it’s basically just two requests that I send and then evaluate the response. Like this:

if(some_condition)
{
  auto url = URL()
    .withNewDomainAndPath(config.getBaseURL() + config.licenseCheckEndpoint)
    .withParameter("payload", JSON::toString(payload));
            
  WebInputStream wis(url, true);
  wis.withExtraHeaders(someHeader);

  if(wis.getStatusCode() == 200)
  {
    auto responseBody = wis.readEntireStreamAsString();
    // do something based on the response
  }
}

Works like a charm on macOS, and also on Windows, but with a hidden twist.

The server is currently a Django server, and when the plugin runs I see the requests in the log output. Everything works, suspiciously a little slower than on mac though. But when I then close the plugin (or Standalone version, doesn’t matter) an error message "Broken Pipe from (‘127.0.0.1’, 60821) appears in Django’s output.

So it seems that the connection might not be closed correctly. WebInputStream doesn’t have any functions to explicitly close the connection, right? It should clean up after itself with the destructor. But it might not do so.

Happens with both JUCE 7.0.12 and the current juce8 preview branch.

Anybody else seeing similar problems?

How far away is this port # from the one you are connecting to? Is it possible that some bug in the Headers is leaving Windows waiting to parse a missing header token while having your download socket assigned anyway?

I ran into a bug with this a while back which I think was fixed with a slight header tweak, but I will have to dig through the details. The part that made me think about this in your case was this:

  wis.withExtraHeaders(someHeader);

Huh, that’s a good spot, but doesn’t seem to be it though. Even when I only do the simplest of GET requests without anything else I get the same problem:

WebInputStream wis( URL("http://localhost:8000"), false);
auto response = wis.readEntireStreamAsString();
DBG(response);

When I don’t read from the stream and only get the response headers, the broken pipe message doesn’t appear.

Googling a bit for “Django broken pipe” it seems like there is or has been an issue in Django’s debug server causing this, and it’s probably nothing to worry about. So might be false alarm. But feels a bit uncomfortable.