| 1993 | |
| 1994 | |
| 1995 | Future<Nothing> serve( |
| 1996 | network::Socket socket, |
| 1997 | std::function<Future<Response>(const Request&)>&& f) |
| 1998 | { |
| 1999 | // HTTP serving is implemented by running two loops, a "receive" |
| 2000 | // loop and a "send" loop. The receive loop passes the pipeline of |
| 2001 | // request/responses via a `Queue` to the send loop that is |
| 2002 | // responsible for sending the response back to the client. A `None` |
| 2003 | // passed on the queue signifies that receiving has completed. |
| 2004 | // |
| 2005 | // TODO(benh): Replace this with something like `Stream` that can |
| 2006 | // give us completion semantics without having to encode them with |
| 2007 | // an `Option` like we do here. |
| 2008 | Queue<Option<Item>> pipeline; |
| 2009 | |
| 2010 | Future<Nothing> receiving = |
| 2011 | receive(socket, std::move(f), pipeline) |
| 2012 | .onAny([=]() mutable { |
| 2013 | // Either: |
| 2014 | // |
| 2015 | // (1) An EOF was received. |
| 2016 | // (2) A failure occurred while receiving. |
| 2017 | // (3) Receiving was discarded (likely because serving was |
| 2018 | // discarded). |
| 2019 | // |
| 2020 | // In all cases the best course of action is to signify that |
| 2021 | // no more items will be enqueued on the `pipeline` and in |
| 2022 | // the case of (2) or (3) shutdown the read end of the |
| 2023 | // socket so the client recognizes it can't send any more |
| 2024 | // requests. |
| 2025 | // |
| 2026 | // Note that we don't look at the return value of |
| 2027 | // `Socket::shutdown` because the socket might already be |
| 2028 | // shutdown! |
| 2029 | pipeline.put(None()); |
| 2030 | socket.shutdown(network::Socket::Shutdown::READ); |
| 2031 | }); |
| 2032 | |
| 2033 | Future<Nothing> sending = |
| 2034 | send(socket, pipeline) |
| 2035 | .onAny([=]() mutable { |
| 2036 | // Either: |
| 2037 | // |
| 2038 | // (1) HTTP connection is not meant to be persistent or |
| 2039 | // there are no more items expected in the pipeline. |
| 2040 | // (2) A failure occurred while sending. |
| 2041 | // (3) Sending was discarded (likely because serving was |
| 2042 | // discarded). |
| 2043 | // |
| 2044 | // In all cases the best course of action is to shutdown the |
| 2045 | // socket which will also force receiving to complete. |
| 2046 | // |
| 2047 | // Note that we don't look at the return value of |
| 2048 | // `Socket::shutdown` because the socket might already be |
| 2049 | // shutdown! |
| 2050 | // |
| 2051 | // CAREFUL! We can't shutdown with Shutdown::READ_WRITE |
| 2052 | // because on OSX if the socket is already shutdown with READ |