Reading multiple HTTP request (tokio rs)


#1

Hi guys, i am trying to understand how does tcp reads multiple http requests which are send at around the same time (in Tokio).

I have two different ideas how it works and i am not sure which one of them is right would appreciate your help :slight_smile:

Suppose we use tokio’s socket.read_buf for example this way:

match self.socket.read_buf(&mut self.buffer) {
       Ok(Async::Ready(0)) => {
          // end connection
        }
        Ok(Async::Ready(_)) => {
          // we will read till the end of the request (or all requests)
          continue;
        }
       Ok(Async::NotReady) => { 
           // some logic on NotReady
       }
      Err(e) => {
         // ignore for now
      }
}

What will happened if client decides to send 2+ large http requests to the server?

Would it be like:

client sends 2 larger http requests (from the same connection)
server receives first part of first request
server receives second part of first request
server triggers Async::NotReady
servers receives first part of second request
servers receives second part of second request
server triggers Async::NotReady

Or would it be like:

client sends 2 larger requests (from the same connection)
server receives first part of first request
server receives second part of first request
servers receives first part of second request
servers receives second part of second request
server triggers Async::NotReady

(Second one is different as it removes (server triggers Async::NotReady) in between)


#2

There are two parts to the answer: one depends on the HTTP protocol, and one is more general.

For HTTP, pipelining requests like this is only supposed to be allowed with certain versions and negotiated parameters, although these are common, if they’re not in use it’s entirely likely for the connection to stall and go idle between the two requests.

More generally, though, you can expect the connection to stall and go idle at any time - even during the body of a single request. Perhaps there is some network congestion, or the server is simply reading data faster than the client can upload it. So you can get Async::NotReady any time the TCP input buffer is empty, and you shouldn’t ascribe any particular protocol interpretation to it.

Async IO exposes you to these events and pauses (rather than blocking and waiting for more data to arrive) precisely so that you can choose to do something else in the meantime.