Определение виртуального сервера по имени
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 ""
является стандартной и может явно не указываться.
В более ранних версиях в качестве стандартного имени сервера
выступало имя машины (hostname).
Определение виртуального сервера по имени и 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 выбирает location
для обработки запроса на примере обычного простого 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 вначале ищет среди всех префиксных location’ов, заданных строками,
максимально совпадающий.
В вышеприведённой конфигурации
указан только один префиксный location “/”, и поскольку
он подходит под любой запрос, он и будет использован, если других
совпадений не будет найдено.
Затем nginx проверяет location’ы, заданные регулярными выражениями, в
порядке их следования в конфигурационном файле.
При первом же совпадении поиск прекращается и nginx использует
совпавший location.
Если запросу не соответствует ни одно из регулярных выражений,
nginx использует максимально совпавший префиксный location,
найденный ранее.
Следует иметь в виду, что location’ы всех типов сопоставляются только с
URI-частью строки запроса без аргументов.
Так делается потому, что аргументы в строке запроса могут быть
заданы различными способами, например:
/index.php?user=john&page=1
/index.php?page=1&user=john
Кроме того, в строке запроса можно запросить что угодно:
/index.php?page=1&something+else&user=john
Теперь посмотрим, как бы обрабатывались запросы
в вышеприведённой конфигурации:
-
Запросу “
/logo.gif” во-первых соответствует префиксный
location “/”, а во-вторых — регулярное выражение
“\.(gif|jpg|png)$”,
поэтому он обрабатывается location’ом регулярного выражения.
Согласно директиве “root /data/www” запрос
отображается в файл /data/www/logo.gif, который
и посылается клиенту.
-
Запросу “
/index.php” также во-первых соответствует префиксный
location “/”, а во-вторых — регулярное выражение
“\.(php)$”.
Следовательно, он обрабатывается location’ом регулярного выражения
и запрос передаётся FastCGI-серверу, слушающему на localhost:9000.
Директива
fastcgi_param
устанавливает FastCGI-параметр
SCRIPT_FILENAME в “/data/www/index.php”,
и сервер FastCGI выполняет указанный файл.
Переменная $document_root равна
значению директивы
root,
а переменная $fastcgi_script_name равна
URI запроса, т.е. “/index.php”.
-
Запросу “
/about.html” соответствует только префиксный
location “/”, поэтому запрос обрабатывается в нём.
Согласно директиве “root /data/www” запрос
отображается в файл /data/www/about.html, который
и посылается клиенту.
-
Обработка запроса “
/” более сложная.
Ему соответствует только префиксный location “/”,
поэтому запрос обрабатывается в нём.
Затем директива
index
проверяет существование индексных файлов согласно своих параметров
и директиве “root /data/www”.
Если файл /data/www/index.html не существует,
а файл /data/www/index.php существует, то
директива делает внутреннее перенаправление на “/index.php”
и nginx снова сопоставляет его с location’ами,
как если бы такой запрос был послан клиентом.
Как мы видели ранее, перенаправленный запрос будет в конечном итоге
обработан сервером FastCGI.
автор: Игорь Сысоев редактор: Brian Mercer
|
|