HTTP pipelining - concurrent responses per connection

2.7k views Asked by At

I was just reading this Wikipedia article on HTTP pipelining and from the diagram it appears that responses can be sent concurrently on one connection. Am I misinterpreting the diagram or is this allowed?

Section 8.1.2.2 of RFC 2616 states:

A server MUST send its responses to those requests in the same order that the requests were received.

Whilst that stops short of explicitly ruling out concurrent responses, it does not mention a need to ensure that responses must not only start in the correct order with relation to requests, but also finish in the correct order.

I also cannot imagine the practicalities of dealing with concurrent responses - how would the client know to which response the received data applies?

Therefore my interpretation of the RFC is that whilst additional requests can be made whilst the response to the first request is being processed, it is not allowedfor the client to send concurrent requests or the server to send concurrent responses on the same connection.

Is this correct? I've attached a diagram below to illustrate my interpretation.

It would prevent the problems I mentioned from occurring, but it does not appear to completely align with the diagram in Wikipedia.

HTTP pipelining

1

There are 1 answers

1
PoByBolek On BEST ANSWER

Short answer: Yes, clients and servers can send requests and responses concurrently.

However, a server cannot send multiple responses to one request, i.e. the request response pattern still applies. RFC 2616 (and the Wikipedia article you are refering to) simply state that a client does not need to wait for the server's response to send an additional request on the same connection. So the requests in your diagram look good :).

But the server doesn't have to wait for each of its responses to finish before it can start transmission of the next response. It can just send the responses to the client as it receives the client's requests. (Which results in the diagram shown in the Wikipedia article.)

How does the client know to which request a response applies?

Well, let's ignore that whole network delay stuff for a minute here and assume that pipelined request or response messages arrive at once but only after all of them have been sent.

  1. The client sends its requests in a certain order (without waiting for responses inbetween requests).
  2. The server receives the requests in the same order (TCP guarantees that) all at once.
  3. The server takes the first request message, processes it, and stores the response in a queue.
  4. The server takes the second request message, processes it, and stores the response in a queue.
  5. (You get the idea...)
  6. The server sends the contents of that queue to the client. The responses are stored in order so the response to the first request is at the beginning of that queue followed by the response to the second request and so on...
  7. The client receives the responses in the same order (TCP guarantees that) and associates the first response with the first request it made and so on.

This still works even if we don't assume that we receive all the messages at once because TCP guarantees that the data that was sent is received in the same order.

We could also ignore the network completely and just look at the messages that are transferred between server and client.

Client -> Server

GET /request1.html HTTP/1.1
Host: example.com
...

GET /request2.html HTTP/1.1
Host: example.com
...

GET /request3.html HTTP/1.1
Host: example.com
...

Server -> Client

HTTP/1.1 200 OK
Content-Length: 234
...

HTTP/1.1 200 OK
Content-Length: 123
...

HTTP/1.1 200 OK
Content-Length: 345
...

The great thing about TCP is that this particular stream of messages always looks the same. You can send all of the requests first and then receive the responses; you can send request 1 first, receive the first response, send the remaining requests, and receive the remaining responses; you can send the first and part of the second request, receive part of the first response, send the remaining requests, receive the remaining responses; etc. Because TCP guarantees to keep the order of the transmitted messages, we can always associate the first request with the first response and so on.

I hope this answers your question...