A variation on the earlier Common Gateway Interface (CGI), FastCGI's main objective is to reduce the overhead related to interfacing between the Web server and CGI programs, thus allowing a server to handle more Web page requests per unit of time.

HAProxy Enterprise can send HTTP requests to Responder FastCGI applications. To do so, you configure the following:

  • Servers to use the FastCGI protocol (using the keyword proto fcgi on the server line)

  • A FastCGI application that the backend server uses to manage these servers (using the keyword use-fcgi-app in the proxy section). You can define several FastCGI applications, but the backend can only use one at a time.

HAProxy implements all the features of the FastCGI specification for the Responder application. In particular, it can multiplex several requests on a simple connection.

Set up FastCGI

To set up FastCGI, you edit the following sections in the HAProxy configuration file:

Fcgi-app section

In the Fcgi-app section of the HAProxy configuration file, define the following directives:

Directive

Description

fcgi-app <name>

Declares a FastCGI application called <name>. To be valid, you must define at least the document root.

acl <aclname> <criterion> [flags] [operator] <value> ...

Declares or completes an access list. See the "acl" keyword and ACL usage for details. ACLs defined for a FastCGI application are private; no other application or proxy can use them.

In the same way, FastCGI applications cannot use any ACLs defined in any other section. Pre-defined ACLs are available.

docroot <path>

Defines the document root on the remote host. The parameter <path> serves to build the default value of FastCGI parameters SCRIPT_FILENAME and PATH_TRANSLATED. It is a mandatory setting.

index <script-name>

Defines the script name to append after a URI that ends with a slash ("/") to set the default value for the FastCGI parameter SCRIPT_NAME. It is an optional setting.

index index.php

log-stderr global, log-stderr <address> [len <length>] [format <format>] [sample <ranges>:<smp_size>] <facility> [<level> [<minlevel>]]

Enables logging of STDERR messages that the FastCGI application reports. See the "log" keyword for details.

It is an optional setting. By default, HAProxy ignores STDERR messages.

pass-header <name> [ { if | unless } <condition> ]

Specifies the name of a request header to pass to the FastCGI application.

Optionally, you can follow it with an ACL-based condition, in which case the FastCGI application evaluates it only if the condition is true.

Most request headers are already available to the FastCGI application with the prefix "HTTP". Thus, you only need this directive to pass headers that are purposefully omitted. Currently, the headers "Authorization", "Proxy-Authorization", and hop-by-hop headers are omitted.

Note that the headers "Content-type" and "Content-length" never pass to the FastCGI application because they are already converted into parameters.

path-info <regex>

Defines a regular expression to extract the script-name and the path-info from the URI. Thus, <regex> must have two captures: the first to capture the script name, and the second to capture the path- info.

It is an optional setting. If not defined, it does not perform matching on the URI, and does not fill the FastCGI parameters PATH_INFO and PATH_TRANSLATED.

path-info ^(/.+\.php)(/.*)?$

option get-values, no option get-values

Enables or disables the retrieval of variables related to connection management.

HAproxy can send the record FCGI_GET_VALUES upon connection establishment to retrieve the value for the following variables:

  • FCGI_MAX_REQS: The maximum number of concurrent requests this application can accept.

  • FCGI_MPXS_CONNS: "0" if this application does not multiplex connections; "1" otherwise.

    Some FastCGI applications do not support this feature. Others close the connection immediately after sending their response. So, by default, this option is disabled.

    Note

    The maximum number of concurrent requests that a FastCGI application accepts is a connection variable. It only limits the number of streams per connection. If you must limit the global load on the application, you must set the server parameters "maxconn" and "pool-max-conn". Also, if an application does not support connection multiplexing, then the maximum number of concurrent requests automatically sets to 1.

option keep-conn, no option keep-conn

Tells the FastCGI application whether or not to keep the connection open after it sends a response. If disabled, the FastCGI application closes the connection after responding to this request. Default: enabled

option max-reqs <reqs>

Defines the maximum number of concurrent requests this application can accept. If the FastCGI application retrieves the variable FCGI_MAX_REQS during connection establishment, it can override this option. Furthermore, if the application does not do multiplexing, it will ignore this option. Default: 1

option mpxs-conns, no option mpxs-conns

Enables or disables the support of connection multiplexing. If the FastCGI application retrieves the variable FCGI_MPXS_CONNS during connection establishment, it can override this option. Default: disabled.

set-param <name> <fmt> [ { if | unless } <condition> ]

Sets a FastCGI parameter to pass to this application. Its value, defined by <fmt>, must follow the log-format rules. Optionally, you can follow it with an ACL-based condition, in which case the FastCGI application evaluates it only if the condition is true.

With this directive, it is possible to overwrite the value of default FastCGI parameters. If the value evaluates to an empty string, it ignores the rule. The FastCGI application evaluates these directives in their declaration order.

# PHP only, required if PHP was built with --enable-force-cgi-redirect
set-param REDIRECT_STATUS 200

set-param PHP_AUTH_DIGEST %[req.hdr(Authorization)]

Proxy section

In the proxy section of the HAProxy configuration file, set up the following directives:

Directive

Description

use-fcgi-app <name>

Defines the name of the FastCGI application to use for the backend.

This keyword is only available for HTTP proxies with backend capability and at least one FastCGI server. However, you can mix FastCGI servers with HTTP servers, although we do not recommend doing this unless there is a good reason to do so (see Limitations below for details). You can define only one application at a time for each backend.

Note

Once you reference a FastCGI application for a backend, depending on the configuration, some processing may take place even if the request does not go to a FastCGI server. The backend evaluates rules to set parameters or pass headers to an application.

Example of a FastCGI configuration

The following example is a typical configuration to assist you in setting up your FastCGI application:

frontend front-http
   mode http
   bind *:80
   bind *:

   use_backend back-dynamic if { path_reg ^/.+\.php(/.*)?$ }
   default_backend back-static

backend back-static
   mode http
   server www A.B.C.D:80

backend back-dynamic
   mode http
   use-fcgi-app php-fpm
   server php-fpm A.B.C.D:9000 proto fcgi

fcgi-app php-fpm
   log-stderr global
   option keep-conn

   docroot /var/www/my-app
   index index.php
   path-info ^(/.+\.php)(/.*)?$

Default parameters

A Responder FastCGI application has the same purpose as a CGI/1.1 program.

In the CGI/1.1 specification (RFC3875), several variables must pass to the script. HAProxy sets these variables as well as certain others that FastCGI applications commonly use.

You can overwrite all these variables with extreme caution.

Parameter

Description

AUTH_TYPE

Identifies the mechanism, if any, that HAProxy uses to authenticate the user. Concretely, we only support the BASIC authentication mechanism.

CONTENT_LENTH

Contains the size of the message-body attached to the request. This means that it only considers requests with a known size as valid to send to the application.

CONTENT_TYPE

Contains the type of the message-body attached to the request. Set this parameter only if there is a content-type header in the request or if you explicitly set it in the application configuration using the set-param directive.

DOCUMENT_ROOT

Contains the document root on the remote host under which to execute the script as defined in the application configuration.

GATEWAY_INTERFACE

Contains the dialect of CGI that HAProxy uees to communicate with the FastCGI application. Concretely, it is set to "CGI/1.1".

PATH_INFO

Contains the portion of the URI path hierarchy that follows the part that identifies the script itself. To set it, you define the directive path-info.

PATH_TRANSLATED

If you set PATH_INFO, this parameter is its translated version. It is the concatenation of DOCUMENT_ROOT and PATH_INFO. If PATH_INFO is not set, this parameter is also not set.

QUERY_STRING

Contains the query string of the request. Set this parameter only if there is a query-string type header in the request or if you explicitly set it in the application configuration using the set-param directive.

REMOTE_ADDR

Contains the network address of the client sending the request.

REMOTE_USER

Contains the user identification string that the client supplied as part of user authentication.

REQUEST_METHOD

Contains the method that the script must use to process the request.

REQUEST_URI

Contains the request URI.

SCRIPT_FILENAME

Contains the absolute pathname of the script. It is the concatenation of DOCUMENT_ROOT and SCRIPT_NAME.

SCRIPT_NAME

Contains the name of the script. If you define the directive path-info, this is the first part of the URI path hierarchy, and ends with the script name. Otherwise, it is the entire URI path.

SERVER_NAME

Contains the name of the server host where to direct the client request. It is the value of the header "Host" (if available). Otherwise, it is the destination address of the connection on the client side.

SERVER_PORT

Contains the destination TCP port of the connection on the client side, which is the port where the client connects.

SERVER_PROTOCOL

Contains the request protocol.

HTTPS

Sets to a non-empty value ("on") if the script executed through the HTTPS protocol.

Limitations

The current implementation has the following limitations:

  • HAProxy hides certain request headers from FastCGI applications. This happens on the backend side during the header analysis, before the connection establishes.

    At this stage, HAProxy knows that the backend uses a FastCGI application, but it does not know whether the request will go to a FastCGI server or not.

    So in order to hide request headers, it simply removes them from the HTX message. Hence, when the request finally gets to an HTTP server, it never sees these headers.

    For this reason, we do not recommended that you mix FastCGI servers and HTTP servers under the same backend.

  • Similarly, HAProxy evaluates the rules "set-param" and "pass-header" during the request headers analysis. HAProxy always carries out these evaluations, even if the requests finally go to an HTTP server.

  • Regarding the rules "set-param": when HAProxy applies a rule, it adds a pseudo header to the HTX message.

    Thus, similar to HTTP header rewrites, it may fail if the buffer is full. The "set-param" rules will compete with the "http-request" rules.

  • Finally, all FastCGI parameters and HTTP headers go into a unique record FCGI_PARAM.

    Encoding of this record must happen in one pass; otherwise, HAProxy returns a processing error.

    This means that the record FCGI_PARAM, once encoded, must not exceed the size of the buffer. However, you can use the entire reserved buffer space intended for rewriting an HTTP message here. (See "tune.maxrewrite" parameter in the global section for information about the reserved space.)