It appears (other sources linked at the bottom of this post) that the networking code of Apple exhibits a bug in the following circumstances:
- a client application on macOS or iOS makes a POST request over HTTPS
- the server response includes the headers (shown below) to indicate its intention to keep the connection open, to serve future requests that may arrive in the near future.
The mentioned headers in the server response that trigger the bug are the following (the actual values for timeout
and max
parameters don’t matter):
Connection: Keep-Alive
Keep-Alive = timeout=5, max=100
They are perfectly legit and they cause no issues on Windows or with GET requests on macOS.
The timeout
parameter in particular, informs the client that the current TCP connection can be reused for further requests for 5 more seconds.
After that time, the server will close the connection on its side, so the expected behavior for the client is to establish a new connection if it intends to make another request past that timeout.
In the case of Apple, and in the circumstances stated above (POST over HTTPS), what happens instead is that the client ignores that timeout indication, and even for a request that comes, for example, 10 seconds later, it attempts to reuse the connection well past the intended 5 seconds.
The result is that the buggy client gets disappointed when it finds that the connection has been closed by the server, and it produces the following error, printed by a DBG
in didFailWithError()
, in juce_mac_Network.mm
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost."
Inspired by some of the workarounds found online for the same problem, I can confirm that immediately repeating the same request results in a success on the second attempt.
The attached patch for juce_mac_Network.mm does implement such workaround for this specific error condition.
EDIT: it is intended for the “master” branch, on which I am, not “develop”
patch.txt (2.6 KB)
It does so by adding a member to URLConnectionState
to capture the resulting error code in case of a failure, and if that error code indicates the “lost connection” condition, then the connection attempt in createConnection()
is repeated (only once).
For people interested in this problem, these are the descriptions given by other (non-JUCE) developers struggling with it: