[2.1.1-scala] adjusting http keep alive

1,211 views
Skip to first unread message

Michael Allman

unread,
May 9, 2013, 1:02:22 AM5/9/13
to play-fr...@googlegroups.com
Hello,

After a fairly thorough search through the play framework source code, I cannot find any way to disable http keepalive in a play app. It seems that the only way play will close a connection after sending its response is if the client sends a "Connection: close" request header. Am I wrong about this? I would like to be able to send a "Connection: close" response header and close the tcp connection to the client immediate following certain client requests.

Cheers,

Michael

Alexandru Nedelcu

unread,
May 9, 2013, 2:07:51 AM5/9/13
to play-fr...@googlegroups.com
I think that what you say is accurate. I also had this behaviour on top of plain Java servlets with Jetty, in order to close the connection, you need to set a "Connection: close" header to force closing it.

Considering that you only want this behaviour for certain requests, in Play I think it would be best if you use Action composition.
Take a look at this article: http://www.playframework.com/documentation/2.1.1/ScalaActionsComposition

If you want an example, I have something similar. For certain responses, I need to add CORS-related headers to the responses (for cross domain requests) and I ended up with something like this:
https://gist.github.com/alexandru/5545852




--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Alexandru Nedelcu
http://bionicspirit.com

Alexandru Nedelcu

unread,
May 9, 2013, 2:10:52 AM5/9/13
to play-fr...@googlegroups.com
Btw, I misunderstood what you said.

"Connection: close" works both ways. If you specify "Connection: close" in the response, then the connection should be closed.

Michael Allman

unread,
May 9, 2013, 3:21:46 AM5/9/13
to play-fr...@googlegroups.com
Hi Alexandru,

Thank you for your suggestions. I can send the response header, but that doesn't mean the client will close the connection. Perhaps it should, but I'd like a firmer guarantee. For example, in a DDOS situation you certainly couldn't expect an attacker to politely respect a server's request to back off. ;) I'd like the server to proactively manage its network resources in a defensive way when under a heavy load.

We've actually run into the problem of TCP port exhaustion running a play app in an ordinary production scenario. The server holds the connections open too long and the kernel runs out of ports to allocate. The server is "running", but the response time balloons from milliseconds to tens of seconds for the simplest requests. This isn't a limitation of the hardware or the kernel. We have no trouble if we put a reverse proxy in front of our play server and configure the proxy to disable persistent connections. This configuration actually suits our production traffic pattern quite well, so if it's something that play supported we could make excellent use of it.

There are probably other good reasons to put a proxy in front of a play app, but it was performing brilliantly until we ran into this issue. Now I'm curious to see what it could do without this limitation. I'd love to hack in a change and take it for a spin, but I've got other things I have to put ahead on my task list.

If anyone else has encountered and worked around the same issue, please share. :)

Cheers,

Michael


You received this message because you are subscribed to a topic in the Google Groups "play-framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/d5jv4XRXnPg/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to play-framewor...@googlegroups.com.

Alexandru Nedelcu

unread,
May 9, 2013, 6:41:35 AM5/9/13
to play-fr...@googlegroups.com
On Thu, May 9, 2013 at 10:21 AM, Michael Allman <mic...@eclipse.io> wrote:
I can send the response header, but that doesn't mean the client will close the connection.  

I've ran into this issue with Jetty for a non-Play2 app and Jetty does close the connection when you specify that header in the response.
Unfortunately, I just did a test with Play2.1 and it doesn't seem to close the connection by specifying that header, but maybe I did something wrong.

Doing the test is easy. Start your server then connect with "telnet" to it, like:

    telnet localhost 9000

Then simulate a request by inputting:

   GET / HTTP/1.1
   Host: some.hostname.com
   Connection: keep-alive
   <blank line>

And yeah, unfortunately Play2.1 doesn't close the connection. It eventually times it out, if no progress has been made for some time though. I don't know if or how you can configure the timeout.

However, even if the connection is closed, if the clients are misbehaving, like in the case of a DDOS attack, the issue is kind of complex. That's because closing a TCP connection implies a negotiation between the 2 parties. So if the client refuses to close the connection, you'll have connections in TIME_WAIT or CLOSE_WAIT states. Closed connections eventually time out, but it might take some time to do that.

Read this answer on SO_LINGER for instance: http://stackoverflow.com/a/13088864/3280

Alexandru Nedelcu

unread,
May 9, 2013, 7:00:16 AM5/9/13
to play-fr...@googlegroups.com
Btw, if I'm right, then this is a bug.

I opened an issue at: https://github.com/playframework/Play20/issues/1103

Michael Allman

unread,
May 9, 2013, 1:30:58 PM5/9/13
to play-fr...@googlegroups.com
Thanks for filing the bug. Let's see where it goes.

Cheers,

Michael

Reply all
Reply to author
Forward
0 new messages