Как nginx обрабатывает запрос
- Как предотвратить обработку запросов с неопределенными именами сервера
- Смешанные основанные на имени и IP-адресах виртуальные серверы
- Простая настройка сайта PHP
Виртуальные серверы, основанные на имени
nginx сначала определяет, какой сервер должен обработать запрос. Начнём с простой конфигурации, где все три виртуальных сервера слушают порт *: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;
...
}
В этой конфигурации nginx проверяет только поле заголовка запроса «Host», чтобы определить, на какой сервер следует направить запрос. Если его значение не совпадает с именем ни одного сервера или запрос вообще не содержит этого поля заголовка, nginx направить запрос на сервер по умолчанию для этого порта. В вышеприведенной конфигурации сервер по умолчанию — это первый сервер — это стандартное поведение nginx по умолчанию. Также можно явно указать, какой сервер должен быть сервером по умолчанию, с помощью параметра default_server в директиве listen:
server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
Параметрdefault_serverдоступен начиная с версии 0.8.21. В более ранних версиях вместо него нужно использовать параметрdefault.
Обратите внимание, что сервер по умолчанию является свойством порта прослушивания, а не имени сервера. Подробнее об этом позже.
Как предотвратить обработку запросов с неопределенными именами сервера
Если запросы без поля заголовка «Host» не должны обрабатываться, можно определить сервер, который просто отбрасывает такие запросы:
server {
listen 80;
server_name "";
return 444;
}
Здесь имя сервера установлено на пустую строку, которая будет соответствовать запросам без поля «Host», и возвращается специальный код nginx 444, который закрывает соединение.
Начиная с версии 0.8.48, это значение по умолчанию для имени сервера, поэтому параметр server_name "" можно опустить. В более ранних версиях в качестве имени сервера по умолчанию использовалось имя машины.
Смешанные основанные на имени и IP-адресах виртуальные серверы
Рассмотрим более сложную конфигурацию, где некоторые виртуальные серверы слушают на разных адресах:
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;
...
}
В этой конфигурации nginx сначала проверяет IP-адрес и порт запроса на соответствие директивам listen блоков server. Затем он проверяет поле заголовка «Host» запроса на соответствие записям server_name блоков server, которые соответствуют IP-адресу и порту. Если имя сервера не найдено, запрос будет обработан сервером по умолчанию. Например, запрос на www.example.com, полученный на порту 192.168.1.1:80, будет обработан сервером по умолчанию для порта 192.168.1.1:80, то есть первым сервером, так как www.example.com для этого порта не определено.
Как уже говорилось, сервер по умолчанию — это свойство порта прослушивания, и для разных портов могут быть определены разные серверы по умолчанию:
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;
...
}
Простая настройка сайта PHP
Теперь рассмотрим, как nginx выбирает местоположение для обработки запроса для типичного простого сайта PHP:
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 сначала ищет самое конкретное местоположение, заданное буквальными строками независимо от перечисленного порядка. В указанной конфигурации единственное местоположение с буквальной строкой — «/», и так как оно соответствует любому запросу, оно будет использовано в последнюю очередь. Затем nginx проверяет местоположения, заданные с помощью регулярного выражения, в порядке их перечисления в файле конфигурации. Первое соответствующее выражение останавливает поиск, и nginx будет использовать это местоположение. Если ни одно регулярное выражение не соответствует запросу, nginx использует самое конкретное найденное ранее местоположение.
Обратите внимание, что местоположения всех типов проверяют только часть URI строки запроса без аргументов. Это делается, потому что аргументы в строке запроса могут быть заданы несколькими способами, например:
/index.php?user=john&page=1 /index.php?page=1&user=john
Кроме того, любой может запросить что угодно в строке запроса:
/index.php?page=1&something+else&user=john
Теперь рассмотрим, как будут обрабатываться запросы в указанной конфигурации:
- Запрос “
/logo.gif” сначала сопоставляется с местоположением «/», а затем с регулярным выражением «\.(gif|jpg|png)$», поэтому он обрабатывается последним местоположением. Используя директиву «root /data/www», запрос отображается на файл/data/www/logo.gif, и файл отправляется клиенту. - Запрос “
/index.php” также сначала сопоставляется с местоположением «/», а затем с регулярным выражением «\.(php)$». Поэтому он обрабатывается последним местоположением, и запрос передаётся на сервер FastCGI, прослушивающий на localhost:9000. Директива fastcgi_param устанавливает параметр FastCGISCRIPT_FILENAMEв значение “/data/www/index.php”, и сервер FastCGI выполняет файл. Переменная$document_rootравна значению директивы root, а переменная$fastcgi_script_nameравна значению URI запроса, т.е. «/index.php». - Запрос “
/about.html” сопоставляется только с местоположением «/», поэтому он обрабатывается в этом местоположении. Используя директиву «root /data/www», запрос отображается на файл/data/www/about.html, и файл отправляется клиенту. - Обработка запроса “
/” более сложная. Он сопоставляется только с местоположением «/», поэтому он обрабатывается в этом местоположении. Затем директива index проверяет наличие файлов индексов в соответствии с её параметрами и директивой «root /data/www». Если файл/data/www/index.htmlне существует, а файл/data/www/index.phpсуществует, то директива делает внутренний редирект на “/index.php”, и nginx снова ищет местоположения, как если бы запрос был отправлен клиентом. Как мы видели ранее, перенаправленный запрос в конечном итоге будет обработан сервером FastCGI.
| написано Игорем Сысоевым отредактировано Брайаном Мерсером |
© 2002-2021 Igor Sysoev
© 2011-2024 Nginx, Inc.
Licensed under the BSD License.
https://nginx.org/en/docs/http/request_processing.html