How nginx processes a requestnginx如何处理请求

How to prevent processing requests with undefined server names如何防止使用未定义的服务器名称处理请求
Mixed name-based and IP-based virtual servers混合基于名称和基于IP的虚拟服务器
A simple PHP site configuration一个简单的PHP站点配置

Name-based virtual servers基于名称的虚拟服务器

nginx first decides which server should process the request. nginx首先决定哪个服务器应该处理请求。Let’s start with a simple configuration where all three virtual servers listen on port *:80:让我们从一个简单的配置开始,其中所有三个虚拟服务器都在端口*: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 nginx tests only the request’s header field “Host” to determine which server the request should be routed to. 在此配置中,nginx仅测试请求的标题字段“Host”,以确定请求应路由到哪个服务器。If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port. 如果其值与任何服务器名称不匹配,或者请求根本不包含此标头字段,则nginx将将请求路由到此端口的默认服务器。In the configuration above, the default server is the first one — which is nginx’s standard default behaviour. 在上面的配置中,默认服务器是第一个——这是nginx的标准默认行为。It can also be set explicitly which server should be default, with the default_server parameter in the listen directive:还可以使用listen指令中的default_server参数明确设置默认服务器:

server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ... }
The default_server parameter has been available since version 0.8.21. In earlier versions the default parameter should be used instead.

Note that the default server is a property of the listen port and not of the server name. 请注意,默认服务器是侦听端口的属性,而不是服务器名称的属性。More about this later.稍后将对此进行详细介绍。

How to prevent processing requests with undefined server names如何防止处理具有未定义服务器名称的请求

If requests without the “Host” header field should not be allowed, a server that just drops the requests can be defined:如果不允许没有“主机”头字段的请求,则可以定义只丢弃请求的服务器:

server {
    listen      80;
    server_name "";
    return      444;
}

Here, the server name is set to an empty string that will match requests without the “Host” header field, and a special nginx’s non-standard code 444 is returned that closes the connection.

Since version 0.8.48, this is the default setting for the server name, so the server_name "" can be omitted. In earlier versions, the machine’s hostname was used as a default server name.

Mixed name-based and IP-based virtual servers

Let’s look at a more complex configuration where some virtual servers listen on different addresses:

server {
    listen      192.168.1.1:80;
    server_name example.org www.example.org;
    ... }

server {
    listen      192.168.1.1:80;
    server_name example.net www.example.net;
    ... }

server {
    listen      192.168.1.2:80;
    server_name example.com www.example.com;
    ... }

In this configuration, nginx first tests the IP address and port of the request against the listen directives of the server blocks. It then tests the “Host” header field of the request against the server_name entries of the server blocks that matched the IP address and port. If the server name is not found, the request will be processed by the default server. For example, a request for www.example.com received on the 192.168.1.1:80 port will be handled by the default server of the 192.168.1.1:80 port, i.e., by the first server, since there is no www.example.com defined for this port.

As already stated, a default server is a property of the listen port, and different default servers may be defined for different ports:

server {
    listen      192.168.1.1:80;
    server_name example.org www.example.org;
    ... }

server {
    listen      192.168.1.1:80 default_server;
    server_name example.net www.example.net;
    ... }

server {
    listen      192.168.1.2:80 default_server;
    server_name example.com www.example.com;
    ... }

A simple PHP site configuration

Now let’s look at how nginx chooses a location to process a request for a typical, simple PHP site:

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;
    }
}

nginx first searches for the most specific prefix location given by literal strings regardless of the listed order. In the configuration above the only prefix location is “/” and since it matches any request it will be used as a last resort. Then nginx checks locations given by regular expression in the order listed in the configuration file. The first matching expression stops the search and nginx will use this location. If no regular expression matches a request, then nginx uses the most specific prefix location found earlier.

Note that locations of all types test only a URI part of request line without arguments. This is done because arguments in the query string may be given in several ways, for example:

/index.php?user=john&page=1 /index.php?page=1&user=john

Besides, anyone may request anything in the query string:

/index.php?page=1&something+else&user=john

Now let’s look at how requests would be processed in the configuration above:

written by Igor Sysoev
edited by Brian Mercer