0

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.

Flux
  • 9,805
  • 5
  • 46
  • 92

1 Answers1

0

Without multiplexing, nginx simply makes a new connection to the fastcgi listen socket when it gets a new request. Multiple requests are handled in parallel, in whatever order, but each connection only carries data for one request at a time. This is exactly the same way things are done with HTTP/1, and with many other protocols.

hobbs
  • 223,387
  • 19
  • 210
  • 288
  • So multiplexing = a connection between nginx and FastCGI handles multiple requests. No multiplexing = nginx makes a new connection to FastCGI for every request. Is my understanding correct? – Flux Oct 24 '21 at 05:15
  • @Flux not necessarily. A connection can handle more than one request *in sequence* without multiplexing, but not more than one request *in parallel*. – hobbs Oct 24 '21 at 15:16
  • Thank you for the explanation. So figures 2 and 3 are possible without multiplexing, and figure 5 is only possible with multiplexing. What about figure 4? Can the responses be given is a different order than the requests? – Flux Oct 25 '21 at 00:30