Appendix B of the FastCGI specification gives an example of multiplexing, where the unindented lines are the sent by the client (e.g. Nginx), and the indented lines are sent by the FastCGI server:
{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 1, ""}
{FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_STDIN, 1, ""}
{FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n"}
{FCGI_PARAMS, 2, ""}
{FCGI_STDIN, 2, ""}
{FCGI_STDOUT, 2, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}
{FCGI_STDOUT, 2, ""}
{FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}
{FCGI_STDOUT, 1, "<html>\n<head> ... "}
{FCGI_STDOUT, 1, ""}
{FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
From my understanding, in a non-multiplexed version of the above, the FastCGI client (e.g. Nginx) will send request 1 before sending anything to do with request 2:
(Figure 2):
{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 1, ""}
{FCGI_STDIN, 1, ""}
{FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n"}
{FCGI_STDOUT, 1, "<html>\n<head> ... "}
{FCGI_STDOUT, 1, ""}
{FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
{FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 2, ""}
{FCGI_STDIN, 2, ""}
{FCGI_STDOUT, 2, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}
{FCGI_STDOUT, 2, ""}
{FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}
Is my understanding correct?
I read in a few places that Nginx does not support multiplexing for FastCGI:
However, that appears to be contradicted by multi threaded FastCGI App, where it is mentioned that Nginx does not wait for a response from the first request before sending the second request, like this:
(Figure 3):
{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 1, ""}
{FCGI_STDIN, 1, ""}
{FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 2, ""}
{FCGI_STDIN, 2, ""}
I am confused at this point, because from my understanding, a non-multiplexed version should only handle one request at a time (i.e. receive the request, and send a response for that request before handling the next request). What exactly is the meaning of multiplexing? In particular:
Does non-multiplexing allow new requests to be accepted before a response is given for an old request? (e.g. referring to the snippet below, see the acceptance of request B before response A is given).
(Figure 4):
{Request A} {Request B} {Response A} {Request C} {Response C} {Response B}
Does non-multiplexing allow responses to be given in a different order from the requests? (e.g. request order: A, B, C; response order: A, C, B).
Does multiplexing mean that parts of a request can be intermingled with parts of other requests and responses? e.g.
(Figure 5):
{Small part of request A} {Small part of request B} {Small part of request A} {Small part of request B} {Small part of response A} {Small part of request B} {Small part of response B} ...
Note that I am new to networking and FastCGI.