---
title: "10. FastCGI Applications"
linkTitle: "10. FastCGI"
weight: 210
description: "FastCGI application setup, parameters, examples, and limitations"
icon: fa-solid fa-bolt
module: [HAPROXY]
categories: [Reference]
aliases:
- /haproxy/configuration/fastcgi/
- /docs/haproxy/configuration/fastcgi/
- /haproxy/fastcgi/
upstream_link: "https://docs.haproxy.org/3.4/configuration.html"
upstream_name: "HAProxy 3.4 Configuration Manual"
upstream_ref: "v3.4.4, chapter 10"
---
HAProxy is able to send HTTP requests to Responder FastCGI applications. This feature was added in
HAProxy 2.1. To do so, servers must be configured to use the FastCGI protocol (using the keyword
"proto fcgi" on the server line) and a FastCGI application must be configured and used by the
backend managing these servers (using the keyword "use-fcgi-app" into the proxy section). Several
FastCGI applications may be defined, but only one can be used at a time by a backend.
HAProxy implements all features of the FastCGI specification for Responder application. Especially
it is able to multiplex several requests on a simple connection.
## 10.1. Setup {#section-10-1}
### 10.1.1. Fcgi-app section {#section-10-1-1}
**`fcgi-app `**
```haproxy
fcgi-app
```
Declare a FastCGI application named ``. To be valid, at least the document root must be
defined.
**`acl [flags] [operator] ...`**
```haproxy
acl [flags] [operator] ...
```
Declare or complete an access list.
See "acl" keyword in [section 4.2](/docs/haproxy/proxies/#section-4-2) and [section 7](/docs/haproxy/acls-and-samples/) about ACL usage for details. ACLs defined for a
FastCGI application are private. They cannot be used by any other application or by any proxy. In
the same way, ACLs defined in any other section are not usable by a FastCGI application. However,
Pre-defined ACLs are available.
**`docroot `**
```haproxy
docroot
```
Define the document root on the remote host. `` will be used to build the default value of
FastCGI parameters SCRIPT_FILENAME and PATH_TRANSLATED. It is a mandatory setting.
**`index `**
```haproxy
index
```
Define the script name that will be appended after an URI that ends with a slash ("/") to set the
default value of the FastCGI parameter SCRIPT_NAME. It is an optional setting.
Example:
```text
index index.php
```
**`log-stderr global`**
```haproxy
log-stderr global
log-stderr [len ] [format ]
[sample :] [ []]
```
Enable logging of STDERR messages reported by the FastCGI application.
See "log" keyword in [section 4.2](/docs/haproxy/proxies/#section-4-2) for details. It is an optional setting. By default STDERR messages
are ignored.
**`pass-header [ { if | unless } ]`**
```haproxy
pass-header [ { if | unless } ]
```
Specify the name of a request header which will be passed to the FastCGI application. It may
optionally be followed by an ACL-based condition, in which case it will only be evaluated if the
condition is true.
Most request headers are already available to the FastCGI application, prefixed with "HTTP\_". Thus,
this directive is only required 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" are never passed to the FastCGI
application because they are already converted into parameters.
**`path-info `**
```haproxy
path-info
```
Define a regular expression to extract the script-name and the path-info from the URL-decoded path.
Thus, `` may have two captures: the first one to capture the script name and the second one
to capture the path-info. The first one is mandatory, the second one is optional. This way, it is
possible to extract the script-name from the path ignoring the path-info. It is an optional setting.
If it is not defined, no matching is performed on the path. and the FastCGI parameters PATH_INFO and
PATH_TRANSLATED are not filled.
For security reason, when this regular expression is defined, the newline and the null characters
are forbidden from the path, once URL-decoded. The reason to such limitation is because otherwise
the matching always fails (due to a limitation one the way regular expression are executed in
HAProxy). So if one of these two characters is found in the URL-decoded path, an error is returned
to the client. The principle of least astonishment is applied here.
Example:
```text
path-info ^(/.+\.php)(/.*)?$ # both script-name and path-info may be set
path-info ^(/.+\.php) # the path-info is ignored
```
**`option get-values`**
```haproxy
option get-values
no option get-values
```
Enable or disable the retrieve of variables about connection management.
HAProxy is able to send the record FCGI_GET_VALUES on connection establishment to retrieve the value
for following variables:
* FCGI_MAX_REQS The maximum number of concurrent requests this
application will accept.
* FCGI_MPXS_CONNS "0" if this application does not multiplex connections,
"1" otherwise.
Some FastCGI applications does not support this feature. Some others close the connection
immediately after sending their response. So, by default, this option is disabled.
Note that the maximum number of concurrent requests accepted by a FastCGI application is a
connection variable. It only limits the number of streams per connection. If the global load must be
limited on the application, the server parameters "maxconn" and "pool-max-conn" must be set. In
addition, if an application does not support connection multiplexing, the maximum number of
concurrent requests is automatically set to 1.
**`option keep-conn`**
```haproxy
option keep-conn
no option keep-conn
```
Instruct the FastCGI application to keep the connection open or not after sending a response.
If disabled, the FastCGI application closes the connection after responding to this request. By
default, this option is enabled.
**`option max-reqs `**
```haproxy
option max-reqs
```
Define the maximum number of concurrent requests this application will accept.
This option may be overwritten if the variable FCGI_MAX_REQS is retrieved during connection
establishment. Furthermore, if the application does not support connection multiplexing, this option
will be ignored. By default set to 1.
**`option mpxs-conns`**
```haproxy
option mpxs-conns
no option mpxs-conns
```
Enable or disable the support of connection multiplexing.
This option may be overwritten if the variable FCGI_MPXS_CONNS is retrieved during connection
establishment. It is disabled by default.
**`set-param [ { if | unless } ]`**
```haproxy
set-param [ { if | unless } ]
```
Set a FastCGI parameter that should be passed to this application. Its value, defined by ``
must follows the Custom log format rules (see [section 8.2.6](/docs/haproxy/configuration-logging/#section-8-2-6) "Custom Log format"). It may optionally
be followed by an ACL-based condition, in which case it will only be evaluated if the condition is
true.
With this directive, it is possible to overwrite the value of default FastCGI parameters. If the
value is evaluated to an empty string, the rule is ignored. These directives are evaluated in their
declaration order.
Example:
```shell
# 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)]
```
### 10.1.2. Proxy section {#section-10-1-2}
use-fcgi-app `` Define the FastCGI application to use for the backend.
Arguments:
```text
is the name of the FastCGI application to use.
```
This keyword is only available for HTTP proxies with the backend capability and with at least one
FastCGI server. However, FastCGI servers can be mixed with HTTP servers. But except there is a good
reason to do so, it is not recommended (see [section 10.3](/docs/haproxy/fastcgi/#section-10-3) about the limitations for details). Only
one application may be defined at a time per backend.
Note that, once a FastCGI application is referenced for a backend, depending on the configuration
some processing may be done even if the request is not sent to a FastCGI server. Rules to set
parameters or pass headers to an application are evaluated.
### 10.1.3. Example {#section-10-1-3}
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)(/.*)?$
## 10.2. Default parameters {#section-10-2}
A Responder FastCGI application has the same purpose as a CGI/1.1 program. In the CGI/1.1
specification (RFC3875), several variables must be passed to the script. So HAProxy set them and
some others commonly used by FastCGI applications. All these variables may be overwritten, with
caution though.
```text
+-------------------+-----------------------------------------------------+
| AUTH_TYPE | Identifies the mechanism, if any, used by HAProxy |
| | to authenticate the user. Concretely, only the |
| | BASIC authentication mechanism is supported. |
| | |
+-------------------+-----------------------------------------------------+
| CONTENT_LENGTH | Contains the size of the message-body attached to |
| | the request. It means only requests with a known |
| | size are considered as valid and sent to the |
| | application. |
| | |
+-------------------+-----------------------------------------------------+
| CONTENT_TYPE | Contains the type of the message-body attached to |
| | the request. It may not be set. |
| | |
+-------------------+-----------------------------------------------------+
| DOCUMENT_ROOT | Contains the document root on the remote host under |
| | which the script should be executed, as defined in |
| | the application's configuration. |
| | |
+-------------------+-----------------------------------------------------+
| GATEWAY_INTERFACE | Contains the dialect of CGI being used by HAProxy |
| | to communicate with the FastCGI application. |
| | Concretely, it is set to "CGI/1.1". |
| | |
+-------------------+-----------------------------------------------------+
| PATH_INFO | Contains the portion of the URI path hierarchy |
| | following the part that identifies the script |
| | itself. To be set, the directive "path-info" must |
| | be defined. |
| | |
+-------------------+-----------------------------------------------------+
| PATH_TRANSLATED | If PATH_INFO is set, it is its translated version. |
| | It is the concatenation of DOCUMENT_ROOT and |
| | PATH_INFO. If PATH_INFO is not set, this parameters |
| | is not set too. |
| | |
+-------------------+-----------------------------------------------------+
| QUERY_STRING | Contains the request's query string. It may not be |
| | set. |
| | |
+-------------------+-----------------------------------------------------+
| REMOTE_ADDR | Contains the network address of the client sending |
| | the request. |
| | |
+-------------------+-----------------------------------------------------+
| REMOTE_USER | Contains the user identification string supplied by |
| | client as part of user authentication. |
| | |
+-------------------+-----------------------------------------------------+
| REQUEST_METHOD | Contains the method which should be used by the |
| | script to process the request. |
| | |
+-------------------+-----------------------------------------------------+
| REQUEST_URI | Contains the request's 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 the directive |
| | "path-info" is defined, it is the first part of the |
| | URI path hierarchy, ending with the script name. |
| | Otherwise, it is the entire URI path. |
| | |
+-------------------+-----------------------------------------------------+
| SERVER_NAME | Contains the name of the server host to which the |
| | client request is directed. It is the value of the |
| | header "Host", if defined. Otherwise, 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 the client |
| | connected to. |
| | |
+-------------------+-----------------------------------------------------+
| SERVER_PROTOCOL | Contains the request's protocol. |
| | |
+-------------------+-----------------------------------------------------+
| SERVER_SOFTWARE | Contains the string "HAProxy" followed by the |
| | current HAProxy version. |
| | |
+-------------------+-----------------------------------------------------+
| HTTPS | Set to a non-empty value ("on") if the script was |
| | queried through the HTTPS protocol. |
| | |
+-------------------+-----------------------------------------------------+
```
## 10.3. Limitations {#section-10-3}
The current implementation have some limitations. The first one is about the way some request
headers are hidden to the FastCGI applications. This happens during the headers analysis, on the
backend side, before the connection establishment. At this stage, HAProxy know the backend is using
a FastCGI application but it don't know if the request will be routed to a FastCGI server or not.
But to hide request headers, it simply removes them from the HTX message. So, if the request is
finally routed to an HTTP server, it never see these headers. For this reason, it is not recommended
to mix FastCGI servers and HTTP servers under the same backend.
Similarly, the rules "set-param" and "pass-header" are evaluated during the request headers
analysis. So the evaluation is always performed, even if the requests is finally forwarded to an
HTTP server.
About the rules "set-param", when a rule is applied, a pseudo header is added into the HTX message.
So, the same way than for HTTP header rewrites, it may fail if the buffer is full. The rules
"set-param" will compete with "http-request" ones.
Finally, all FastCGI params and HTTP headers are sent into a unique record FCGI_PARAM. Encoding of
this record must be done in one pass, otherwise a processing error is returned. It means the record
FCGI_PARAM, once encoded, must not exceeds the size of a buffer. However, there is no reserve to
respect here.