Connections, Sessions, Requests, Logs#
Connection processing mechanisms#
Angie supports various connection processing methods. The availability of a specific method depends on the platform being used. On platforms that support multiple methods, Angie typically selects the most efficient method automatically. However, if necessary, a connection processing method can be explicitly chosen using the use directive.
The following connection processing methods are available:
Method | Description |
|---|---|
| A standard method. The supporting module is built automatically on
platforms that do not have more efficient methods. The
|
| A standard method. The supporting module is built automatically on
platforms that do not have more efficient methods. The
|
| An efficient method available on FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0, and macOS. |
| An efficient method available on Linux 2.6+. |
| An efficient method available on Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+, and Tru64 UNIX 5.1A+. |
| The |
HTTP request processing#
An HTTP request goes through a series of phases, where a specific type of processing is performed at each phase.
| The initial phase. The RealIP module is invoked during this phase. |
| The phase where directives from the Rewrite
module, defined in a |
| A special phase where a location is selected based on the request URI. |
| Similar to the |
| A special phase where the request is redirected to a new location, as in
the |
| During this phase, standard Angie modules like Limit Req register their handlers. |
| The phase where the client's authorization to make the request is verified, typically by invoking standard Angie modules such as Auth Basic. |
| A special phase where the satisfy any directive is processed. |
| Standard module directives, such as try_files and mirror, register their handlers during this phase. |
| The phase where the response is usually generated. Multiple standard Angie modules register their handlers at this stage, including Index. The proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass and grpc_pass directives are also handled here. Handlers are called sequentially until one of them produces the output. |
| The final phase, where request logging is performed. Currently, only the Log module registers its handler at this stage for access logging. |
TCP/UDP session processing#
A TCP/UDP session from a client goes through a series of phases, where a specific type of processing is performed at each phase:
| The initial phase after accepting a client connection. The RealIP module is invoked at this phase. |
| A preliminary phase for checking access. The Set modules are invoked during this phase. |
| The phase for limiting client access before actual data processing. The Access module is invoked at this stage. |
| The phase where TLS/SSL termination occurs. The SSL module is invoked during this phase. |
| The phase for reading initial bytes of data into the preread buffer to allow modules such as SSL Preread to analyze the data before processing. |
| A mandatory phase where the data is actually processed, typically involving the Return module to send a response to the client. The proxy_pass directive is also handled here. |
| The final phase where the outcome of client session processing is recorded. The Log module is invoked at this phase. |
Selecting a server for a session#
Angie selects the server block for a session by the address and port
that accepted it, exactly as it does for HTTP connections; see
Selecting a server by address and port for the matching rules
and for the default server of a pair. TCP and UDP pairs of one port are
separate, each with a default server of its own: a server with
listen 9000 udp; never receives the TCP connections of port 9000.
Within the matched pair, a session takes its server name from SNI alone: either the SSL module terminates TLS and reads the name from the handshake, or the SSL Preread module reads it without terminating the connection. Angie then tests that name against the server_name entries of the servers that listen on the pair; a session with no SNI name, or with a name that matches none of them, is handled by the pair's default server.
Processing requests#
Virtual server selection#
Initially, a connection is created within the context of a default server. The server name can then be determined in the following stages of request processing, each of which is involved in the selection of server configuration:
During the SSL handshake, in advance, according to the SNI.
After processing the request line.
After processing the
Hostheader field.
If the server name is not determined after processing the request line or the
Host header field, Angie will use an empty name as the server name.
At each of these stages, different server configurations may be applied. Therefore, certain directives should be specified with caution:
In the case of the ssl_protocols directive, the protocol list is set by the OpenSSL library before the server configuration is applied according to the name requested through SNI. As a result, protocols should only be specified for the default server.
The client_header_buffer_size and merge_slashes directives are applied before reading the request line. Therefore, these directives use either the default server configuration or the server configuration chosen by SNI.
In the case of the ignore_invalid_headers, large_client_header_buffers, and underscores_in_headers directives, which are involved in processing request header fields, the server configuration additionally depends on whether it was updated according to the request line or the
Hostheader field.An error response is handled using the error_page directive in the server that is currently processing the request.
Name-based virtual servers#
Angie first determines which server should handle the request. Consider a simple configuration where all three virtual servers listen on port 80:
server {
listen 80;
server_name example.org www.example.org;
# ...
}
server {
listen 80;
server_name example.net www.example.net;
# ...
}
server {
listen 80;
server_name example.com www.example.com;
# ...
}
In this configuration, Angie determines which server should handle the
request based solely on the Host header field. If the value of this
header does not match any server name, Angie routes the request to the default
server for the *:80 pair. In the configuration above, the default
server is the first one — which is Angie's standard default behavior. It can
also be explicitly specified which server should be the default using the
default_server parameter in the listen directive:
server {
listen 80 default_server;
server_name example.net www.example.net;
# ...
}
Note
Note that the default server is a property of the address:port pair, not of the server name.
Internationalized names#
Internationalized domain names (IDNs) should be specified using an ASCII (Punycode) representation in the server_name directive:
server {
listen 80;
server_name xn--e1afmkfd.xn--80akhbyknj4f; # пример.испытание
# ...
}
Preventing requests with undefined server names#
If requests without the Host header field should not be allowed, a
server that simply drops such requests can be defined:
server {
listen 80;
server_name "";
return 444;
}
In this configuration, the server name is set to an empty string, which matches
requests without the Host header field. A special non-standard code 444
is then returned, which closes the connection.
Selecting a server by address and port#
Angie selects the server block for a connection in two steps: first by the address and port that accepted the connection, then by name.
The listen directives of the configuration define the address:port
pairs that Angie accepts connections on. Pairs on different ports, in different
address families, or on different transports never compete for a connection: a
quic listener is UDP, so it has a pair of its own even on a port that
also carries TCP listeners. When a connection arrives, Angie matches the
address that accepted it against the pairs of that port: an explicit address
wins, and *:port is the last resort. A server that listens on
*:port therefore has a pair of its own and does not stand in for the
servers on the explicit addresses of that port. The matched pair decides the
rest of the selection: which servers Angie tests by name, which of them is the
default, and which of the ssl, http2, quic, and
proxy_protocol parameters apply to the connection. A UNIX-domain socket
path is a pair in the same sense: it has a default server and a set of server
names of its own.
Angie then tests the Host header field against the server_name
entries of the servers whose listen directives name the matched pair;
servers listening on another address of the same port, *:port among
them, are never consulted. If no name matches, the pair's default server
handles the request: the first server in the configuration that names the pair,
unless another server names it with the default_server parameter. A
request that carries no host name is matched against the empty server name, as
described under Preventing requests with undefined server names; over HTTP/2 and HTTP/3 such a request is
rejected before a server is selected. Angie rejects a configuration in which
two servers claim the same pair as default, reporting
a duplicate default server for address:port.
On a TLS connection, Angie begins the handshake in the configuration of the pair's default server, so its ssl_certificate is the one offered unless the SNI name matches another server on the same pair; see Name-Based HTTPS Servers for serving several names on a single pair.
In the configuration below, four servers listen on port 80 — two on
198.51.100.1, one on 198.51.100.2, and one on *:80:
server {
listen 198.51.100.1:80;
server_name example.org www.example.org;
# ...
}
server {
listen 198.51.100.1:80;
server_name example.net www.example.net;
# ...
}
server {
listen 198.51.100.2:80;
server_name example.com www.example.com;
# ...
}
server {
listen 80;
server_name www.example.test;
# ...
}
A connection accepted on 198.51.100.1:80 matches that pair, so Angie tests the
Host header field against the first two servers only. A request for
www.example.test is therefore handled by the first of them, the default
server for 198.51.100.1:80, although the fourth server carries that name; the
same goes for www.example.com, which belongs to the pair
198.51.100.2:80. The fourth server handles only the connections accepted on
addresses of port 80 that no other listen directive names.
Every pair has a default server of its own, and default_server
designates it for the pair named by the same listen directive:
server {
listen 198.51.100.1:80;
server_name example.org www.example.org;
# ...
}
server {
listen 198.51.100.1:80 default_server;
server_name example.net www.example.net;
# ...
}
server {
listen 198.51.100.2:80 default_server;
server_name example.com www.example.com;
# ...
}
Adding listen 80 default_server; to a further server would set the
default for *:80 alone; the default for 198.51.100.1:80 would remain
the server that carries default_server there.
Choosing locations#
Consider a simple PHP website configuration:
server {
listen 80;
server_name example.org www.example.org;
root /data/www;
location / {
index index.html index.php;
}
location ~* \.(gif|jpg|png)$ {
expires 30d;
}
location ~ \.php$ {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Angie first searches for the most specific prefix location given by
literal strings, regardless of their listed order. In the configuration above,
the only prefix location is location /, which matches any request and
will be used as a last resort. Angie then checks locations defined by
regular expressions in the order they appear in the configuration file. The
first matching expression stops the search, and Angie will use that
location. If no regular expression matches a request, Angie will use
the most specific prefix location found earlier.
Note
Locations of all types test only the URI part of the request line, excluding arguments. This is because arguments in the query string can be specified in various ways, for example:
/index.php?user=john&page=1/index.php?page=1&user=john
Additionally, query strings may contain any number of parameters:
/index.php?page=1&something+else&user=john
Now let's look at how requests would be processed in the configuration above:
The request
/logo.gifis first matched by the prefixlocation /and then by the regular expression.(gif|jpg|png)$. Therefore, it is handled by the latter location. Using the directiveroot /data/www, the request is mapped to the file/data/www/logo.gif, and the file is sent to the client.The request
/index.phpis also initially matched by the prefixlocation /and then by the regular expression.(php)$. Consequently, it is handled by the latter location, and the request is passed to a FastCGI server listening onlocalhost:9000. The fastcgi_param directive sets the FastCGI parameterSCRIPT_FILENAMEto/data/www/index.php, and the FastCGI server executes the file. The variable $document_root is set to the value of therootdirective, and the variable $fastcgi_script_name is set to the request URI, i.e.,/index.php.The request
/about.htmlis matched only by the prefixlocation /, so it is handled in this location. Using the directiveroot /data/www, the request is mapped to the file/data/www/about.html, and the file is sent to the client.
Handling the request / is more complex. It is matched only by the prefix
location /, so it is handled by this location. The index directive then
tests for the existence of index files according to its parameters and the
root /data/www directive. If the file /data/www/index.html does
not exist but the file /data/www/index.php does, the directive performs
an internal redirect to /index.php, and Angie searches the locations
again as if the request had been sent by a client. As previously mentioned, the
redirected request will eventually be handled by the FastCGI server.
The examples above map a request to a file through the root directive, but the full mapping involves several directives acting together. Once a matching location is selected, Angie maps the normalized $uri of the request to a filesystem path: the root directive appends the whole URI to its value, whereas the alias directive replaces the matched location prefix. The try_files directive then probes for candidate files relative to that path; if none exist, its last parameter triggers an internal redirect, and Angie searches the locations again against the new $uri, just as with the index redirect above.
For the same request /images/top.gif, the two locations below resolve it
to the same file, /data/w3/images/top.gif:
location /images/ {
root /data/w3; # append: /data/w3 + /images/top.gif
}
location /images/ {
alias /data/w3/images/; # replace: /images/ -> /data/w3/images/, then top.gif
}
With alias, the matched prefix is removed by its length, so the trailing
slashes of the location and of the alias value must be consistent. Dropping the
trailing slash from the alias path above would instead yield
/data/w3/imagestop.gif.
Proxying and Load Balancing#
One common use of Angie is to set it up as a proxy server. In this role, Angie receives requests, forwards them to the proxied servers, retrieves responses from those servers, and sends the responses back to the clients.
A simple proxy server:
server {
location / {
proxy_pass http://backend:8080;
}
The proxy_pass directive instructs Angie to pass client requests to
the backend Angie can be used to route requests to FastCGI servers that run applications
built with various frameworks and programming languages, such as PHP. The most basic Angie configuration for working with a FastCGI server
involves using the fastcgi_pass directive instead of the
proxy_pass directive, along with fastcgi_param directives to set
parameters passed to the FastCGI server. Suppose the FastCGI server is
accessible on This configuration sets up a server that routes all requests, except those for
static images, to the proxied server operating on To upgrade a connection from HTTP/1.1 to WebSocket, the protocol switch mechanism
available in HTTP/1.1 is used. However, there is a subtlety: since the Angie implements a special mode of operation that allows setting up a tunnel
between a client and a proxied server if the proxied server returns a response
with code 101 (Switching Protocols), and the client requests a protocol switch
via the As mentioned, hop-by-hop headers, including A more sophisticated example demonstrates how the value of the
By default, the connection will be closed if the proxied server does not
transmit any data within 60 seconds. This timeout can be increased using the
proxy_read_timeout directive. Alternatively, the proxied server can be
configured to periodically send WebSocket ping frames to reset the timeout and
check if the connection is still active. Load balancing across multiple application instances is a widely used technique
to optimize resource utilization, maximize throughput, reduce latency, and
ensure fault-tolerant configurations. Angie can be used as a highly efficient HTTP load balancer to distribute
traffic to multiple application servers, thereby enhancing the performance,
scalability, and reliability of web applications. The simplest configuration for load balancing with Angie might look like
this: In the example above, three instances of the same application are running on
backend:8080 (the proxied server). There are many additional
directives available for further configuring a proxy
connection.FastCGI Proxying#
localhost:9000. In PHP, the SCRIPT_FILENAME
parameter is used to determine the script name, and the QUERY_STRING
parameter is used to pass request parameters. The resulting configuration would
be:server {
location / {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
localhost:9000 via the
FastCGI protocol.WebSocket Proxying#
Upgrade header is a hop-by-hop
header, it is
not passed from the client to the proxied server. With forward proxying, clients
may use the CONNECT method to circumvent this issue. This approach does not work
with reverse proxying, as clients are unaware of any proxy servers, and special
processing on the proxy server is required.Upgrade header in the request.Upgrade and
Connection, are not passed from the client to the proxied server.
Therefore, for the proxied server to be aware of the client's intention to
switch to the WebSocket protocol, these headers must be explicitly passed:location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Connection header field in a request to the proxied server depends on
the presence of the Upgrade field in the client request header:http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
...
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
Load Balancing#
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
srv1 through srv3. When a load balancing method is not
explicitly configured, it defaults to round-robin. Other supported load
balancing mechanisms include: weight, least_conn, and
ip_hash. The reverse proxy implementation in Angie also supports
in-band (or passive) server health probes. These are configured using the
max_fails and fail_timeout directives
within the server block in the upstream context.
Logging#
Note
In addition to the options listed here, you can also enable the debugging log.
Syslog#
The error_log and access_log directives support logging to
syslog. The following parameters are used to configure logging to
syslog:
| Specifies the address of a |
| Sets the facility for |
| Defines the severity level of |
| Sets the tag for |
| Disables the addition of the |
Example syslog configuration:
error_log syslog:server=192.168.1.1 debug;
access_log syslog:server=unix:/var/log/angie.sock,nohostname;
access_log syslog:server=[2001:db8::1]:12345,facility=local7,tag=angie,severity=info combined;