luvit / lit

Toolkit for developing, sharing, and running luvit/lua programs and libraries.
http://lit.luvit.io/
Apache License 2.0
245 stars 58 forks source link

Fix coro-http server to close the socket when done #289

Closed creationix closed 3 years ago

creationix commented 3 years ago

A simple server to reproduce this is:

require('coro-http').createServer("127.0.0.1", 8080, function(req)
    p(req)
    return {
        code = 200,
        reason = "OK",
        {"Content-Length", "6"},
        -- Also test with this uncommented, but it should work with both.
        -- {"Connection", "close"},
    }, "hello\n"
end)
p 'http://localhost:8080/'

In another terminal, watch the sockets:

while true; do clear && netstat -an | grep 8080 && sleep 1; done

Initially you should only the listening socket:

tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN     

And in another, hit the server using curl:

curl -v http://localhost:8080/test

When you have Connection: closed commented out, curl should report the server supports http keepalive:

...
* Connection #0 to host localhost left intact

And when you uncomment it, it should change to:

...
* Closing connection 0

But in all cases, the only sockets should be the LISTEN for the server and then TIME_WAIT lines for the past properly closed requests. (These eventually timeout, you can ignore them. They prevent the kernel from reusing the same socket pair too soon)

Before this fix, you would see the leak with lots of connections with FIN_WAIT2 in the client side sockets and CLOSE_WAIT on the server side. The FIN_WAIT2 sockets will eventually timeout and go away, but the CLOSE_WAIT sockets leak and hang around till the server dies.

creationix commented 3 years ago

Fixes #274