swifter icon indicating copy to clipboard operation
swifter copied to clipboard

Connection: Keep-Alive not properly terminating connections.

Open apocolipse opened this issue 6 years ago • 0 comments

Description

When requests are sent with Connection: Keep-Alive, they can be kept indefinitely if the client exhibits unusual circumstances.

To recreate:

Server

Simple server running on linux server with arbitrary endpoint (/ hello world)

Client

iOS Client with button(s) to hit the endpoint with URLSession (Note: URLSession has known issues with keep-alive as well).

    var request = URLRequest(url: URL(string: "http://testserver.local:3000/")!)
    let task = URLSession.shared.dataTask(with: request)
    task.resume()

Press button multiple times, close app, reopen app, repeat multiple times.

Server

Observe output of [ps|top|htop], over time the number of threads listed grows (presumably) due to threads waiting on dead connections.

Alternatives tested

Switching to an HTTP library that's not backed on NSURLSession (thus doesn't automatically overwrite intentional Connection: close headers), like Just, and repeating the same behavior with Connection: close, the number of threads reported by [ps|top|htop] only grows as requests comes in and appropriately levels back off (to 2 threads on my specific linux device).

Proposed Solutions

  • Adding this known caveat to documentation
  • Adding a server option to ignore keep-alive headers and always close sockets
  • Adding timeouts to the socket class as well as configurable timeouts on the server.

The last and obviously best option is however the most complicated as it requires adding a lot to the socket class itself. I'd propose simply adding a separate socket class, i.e. IBM's BlueSocket, which is very lightweight and also feature complete by itself (and can support SSL easily), however that adds a dependency which I'm not a fan of. A compromise is redesigning the existing socket class basing it off of BlueSocket, there's room to take only whats needed from there for proper timeouts without adding extra stuff for unix sockets, etc.

apocolipse avatar May 28 '19 07:05 apocolipse