HTTP: The Definitive Guide
8.6 Relays
HTTP relays are simple HTTP proxies that do not fully adhere to the HTTP specifications. Relays process enough HTTP to establish connections, then blindly forward bytes.
Because HTTP is complicated, it's sometimes useful to implement bare-bones proxies that just blindly forward traffic, without performing all of the header and method logic. Because blind relays are easy to implement, they sometimes are used to provide simple filtering, diagnostics, or content transformation. But they should be deployed with great caution, because of the serious potential for interoperability problems.
One of the more common (and infamous) problems with some implementations of simple blind relays relates to their potential to cause keep- alive connections to hang, because they don't properly process the Connection header. This situation is depicted in Figure 8-14 .
Figure 8-14. Simple blind relays can hang if they are single-tasking and don't support the Connection header
Here's what's going on in this figure:
In Figure 8-14 a, a web client sends a message to the relay, including the Connection: Keep-Alive header, requesting a keep-alive connection if possible. The client waits for a response to learn if its request for a keep-alive channel was granted.
The relay gets the HTTP request, but it doesn't understand the Connection header, so it passes the message verbatim down the chain to the server ( Figure 8-14 b). However, the Connection header is a hop-by-hop header; it applies only to a single transport link and shouldn't be passed down the chain. Bad things are about to start happening!
In Figure 8-14 b, the relayed HTTP request arrives at the web server. When the web server receives the proxied Connection: Keep-Alive header, it mistakenly concludes that the relay (which looks like any other client to the server) wants to speak keep-alive! That's fine with the web serverit agrees to speak keep-alive and sends a Connection: Keep-Alive response header back in Figure 8-14 c. So, at this point, the web server thinks it is speaking keep-alive with the relay, and it will adhere to rules of keep-alive. But the relay doesn't know anything about keep-alive.
In Figure 8-14 d, the relay forwards the web server's response message back to the client, passing along the Connection: Keep-Alive header from the web server. The client sees this header and assumes the relay has agreed to speak keep-alive. At this point, both the client and server believe they are speaking keep-alive, but the relay to which they are talking doesn't know the first thing about keep-alive.
Because the relay doesn't know anything about keepalive, it forwards all the data it receives back to the client, waiting for the origin server to close the connection. But the origin server will not close the connection, because it believes the relay asked the server to keep the connection open ! So, the relay will hang waiting for the connection to close.
When the client gets the response message back in Figure 8-14 d, it moves right along to the next request, sending another request to the relay on the keep-alive connection ( Figure 8-14 e). Simple relays usually never expect another request on the same connection. The browser just spins , making no progress.
There are ways to make relays slightly smarter , to remove these risks, but any simplification of proxies runs the risk of interoperation problems. If you are building simple HTTP relays for a particular purpose, be cautious how you use them. For any wide-scale deployment, you should strongly consider using a real, HTTP-compliant proxy server instead.
For more information about relays and connection management, see Section 4.5.6 .