nickel-org / nickel.rs

An expressjs inspired web framework for Rust

Home Page:http://nickel-org.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Broken keep-alive results in hanging server

kpcyrd opened this issue · comments

I wrote my first nickel webapp yesterday (and I really loved it!). After putting all my code together with the frontend code I wrote (which is also served by nickel), I started to run into issues.

I opened my application in firefox and after the static assets got loaded, the server was hanging for the api request. After requests started to hang, other requests I did with curl were also hanging.

I noticed the time the server was hanging was sort of consistent, at around ~75-76s, after Sergio on irc pointed out it might be a keep-alive issue I digged through the source and found this line:

keep_alive_timeout: Some(Duration::from_secs(75))

which was really close to the delay I was experiencing. I didn't have issues (at all) when curling all my routes individually, so I wrote this piece of middleware that adds Connection: close to all responses:

fn no_keepalive<'mw>(_: &mut Request, mut res: Response<'mw>) -> MiddlewareResult<'mw> {
    // this is a workaround for broken keep-alive (people on irc say it's in hyper)
    res.set(Connection::close());
    res.next_middleware()
}

After that, my application loads nicely in firefox. My application is probably still prone to DoS from malicious clients that don't respect this header and I'd prefer to get rid of my workaround.

If you pass None to nickel.keep_alive_timeout method, there will be no keep alives, which will address the thread exhaustion problem, at the cost of a performance hit. This trade off should be resolved once async support lands.

This seems to be related to #308 and hyperium/hyper#368.

@jolhoeft I've added this to my code and I can confirm it works nicely. Thanks!

server.keep_alive_timeout(None);
server.listen("127.0.0.1:6767").unwrap();

Hyper 0.11 has just been released with async support. I've created #402 to track upgrading. Since there is a viable work around, I am resolving this issue.

I'm playing with nickel. My application sends a lot of images to the client using send_file and I got this error after the server hangs for more than 1 minute:

Error: Failed to send file: Broken pipe (os error 32)

Setting server.keep_alive_timeout(None); as mentioned above solved the problem for me too.
Hope it helps if someone looking for solution to the same error as mine.