Управление nginx
nginx -s stop (выйти немедленно)
nginx -s quit (выйти обычным образом)
nginx -s reopen (переоткрыть log файлы)
nginx -s reload (перезагрузить конфигурацию)
killall nginx (убить все сервера nginx)
nginx -t (протестировать конфигурацию)
Настройка nginx
Файл nginx/conf/nginx.conf
nginx.conf: (основной файл конфигурации сервера)
# это комментарий
user dima rabota; (имя системного пользователя и имя его грыппы под правами которого запущен сервер)
worker_processes 4; (число процессов сервера)
worker_priority 0; (приоритет процессов сервера над другими процессами в операционной системе)
log_not_found on; (записывать лог, если страница не найдена)
events {
worker_connections 1024; (число возможных одновременных соединений с сервером)
accept_mutex on;
accept_mutex_delay 500ms;
multi_accept off;
}
include mime.types (список расширений и ассоциаций файлов с ними)
include fastcgi.conf (настройки FastCGI)
include proxy.conf (настройки для proxy)
include sites.conf (настройки сайтов, то есть Virtual Hosts. Можно создать для них отдельный файл и подключать их через инклюд)
include other_settings.conf (включение сюда настроек из другого файла. обычный инклюд)
include sites/*.conf (включение всех файлов из папки)
--------------------------------------------------------------------
other_settings.conf:
error_log logs/error.log (определение папки для записи логов сервера)
pid logs/inginx.pid (определение папки для записи pid - идентификатора процесса сервера)
--------------------------------------------------------------------
Директивы, как в Apache, только вместо треугольных скобок <Directory >...</Directory>, скобки http {...}, как в JavaScript.
Таким образом
Apache - это HTML-тэги
Enginx - это JavaScript-объекты (хэш-массивы)
http {
server {
listen 80; (порт 80)
server_name example.com; (доменное имя)
access_log /var/log/nginx/example.com.log; (папка записи логов сервера для этого сайта)
location ^~ /admin/ { (при переходе по URL /admin/ Из папки домашеного пользователя взять файл index.php)
index.php;
access_log off; (лог по этому адресу не записывать)
access_log log/main.log; (записывать логи для URL /admin/ в эту папку)
log_format main '$pid - $nginx_version - $remote_addr'; (записывать логи в таком формате)
log_not_found on; (записывать лог, если страница не найдена)
}
}
}
--------------------------------------------------------------------
Правила для реврайта адресов
rewrite ^/(.*)\.(png|jpg|gif)$ /image.php? file=$1&format=$2 last;
--------------------------------------------------------------------
Определение размера передачи данных
client_max_body_size 2M;
или
client_max_body_size 2048k;
--------------------------------------------------------------------
Установка времени ожидания таймаута
client_body_timeout 3m;
client_body_timeout 180s;
client_body_timeout 180;
--------------------------------------------------------------------
Пример создания тестового сервера
http {
include mime.types;
defautl_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost; (http://localhost/)
location / {
root html; (главное расширение файла)
index index.html index.htm; (главная индексная страница. Могла бы быть и index index.php)
}
error_page 500 502 503 504 /50x.html
location = /50x.html {
root html;
}
}
}
--------------------------------------------------------------------
Базовая конфигурация сервера под сайт.
Структура всегда такая: http / server / location
http - размещаются директивы общие для всех сайтов HTTP
server - прописывается IP, PORT, HOST-доменный адрес сайта
location - настройки для конкретного URL сайта
Пример
http {
gzip on;
server {
listen 80;
server_name localhost;
location /main/ {
...
}
location /downloads/ {
gzip off;
...
}
}
}
Варианты записи директив.
Прослушивать переход по IP-адресу и порту
listen 192.168.1.1:80;
listen 127.0.0.1;
listen 80 default;
listen 443 ssl;
Доменное имя сайта
server_name www.website.com;
server_name www.site1.com site2.com site3.com;
server_name *.website.com;
server_name .website.com;
server_name *.website.*;
server_name ~^\.example\.com$;
Пути до файлов
root /home/website.com/public_html; (корневая директория сайта)
Установка alias соотвествия URL с папкой, где лежат файлы
http {
server {
server_name localhost;
root /var/www/website.com/html; (основная папка, где хранятся файлы сайта)
location /admin/ {
alias /var/www/locked/; (при переходе URL /admin/ взять файлы из папки /var/www/locked/)
}
}
}
Вывод страницы об ошибке
error_page 404 /not_found.html;
error_page 500 501 502 503 504 /server_error.html;
error_page 403 http://website.com/;
error_page 404 @notfound; # перейти на named location block
error_page 404 =200 /index.html; # в случае ошибки 404 сделать редирект на файл index.html с 200 OK response code
Определение главной страницы сайта index
index index.php index.html index.htm;
index index.php index2.php /catchall.php;
Обслуживание запросов бразера.
keepalive_requests 100; (число поддержания одновременных запросов со стороны браузера)
Таймаут запросов
keepalive_timeout 75; (время удержания подключения)
keepalive_timeout 75 60;
Установка MimeTypes
include mime.types;
types {
mimetype1 extension1;
mimetype2 extension2 [extension3…];
[…]
}
Пример 1
http {
include mime.types;
[…]
location /downloads/ {
types { } # удалить все MIME types
default_type application/octet-stream; (установить тип MimeType по умолчанию)
}
[…]
}
Пример 2
http {
include mime.types;
[…]
location /downloads/ {
types {
text/html html;
image/gif gif;
image/jpeg jpg;
}
default_type text/plain; (установить тип MimeType по умолчанию)
}
[…]
}
Ограничить тип подключения, выбрав GET или POST
location /admin/ {
limit_except GET { (ограничить подключение только типом GET)
allow 192.168.1.0/24; (разрешить подключение только с этого IP-адреса)
deny all; (всем остальным запретить)
}
}
limit_except METHOD1 [METHOD2…] {
allow | deny | auth_basic | auth_basic_user_file | proxy_pass | perl;
}
Включить бэйсик авторизэйшон
location /admin/ {
allow 192.168.1.0/24;
deny all;
auth_basic "Authentication required"; (включить базовую авторизацию)
auth_basic_user_file conf/htpasswd; (логин и пароль сверять с файлом из этой папки)
}
Разрешить переход по этому адресу только с локального компьютера
server {
server_name .website.com;
location /admin/ {(на этот адрес можно перейти только с локального компьютера, на котором установлен сервер. Все остальные браузеры получат страницу 404 Not found)
internal;
}
}
Объединять двойные // в один /
merge_slashes off;
Пример
было http://website.com//documents/
стало http://website.com/documents/
Включить правильное отображение страниц с ошибкой 400 и выше в Internet Explorer
msie_padding on;
Уустановка правильного обновления Refresh страницы для Internet Explorer
msie_refresh on;
Разрешить использовать символ _ в серверных заголовках
underscores_in_headers on;
Запустить особый сценарий после выполнения запроса сервером.
location /payment/ {
post_action /scripts/done.php; (запустить это сценарий на сервере после отсылки страницы браузеру)
}
Переменные, хранящие заголовки Request
$http_host - доменное имя из адресной строки (URL сайта)
$http_user_agent - ,hfepth gjkmpjdfntkz
$http_referer - URL-страницы с которой переше пользователь
$http_via - перечень proxy-серверов, которые использовал пользователе\ь
$http_x_forwarded_for - Ip-адрес клиента, если клиент прячется за proxy
$http_cookie - значение куки в браузере пользователя
$http_... - любые другие установленные значения, которые можно получить
Переменные, хранящие заголовки Response
$sent_http_content_type - указан тип MimeType контента
$sent_http_content_length - указана величина body
$sent_http_content_location - указан location ресурса
$sent_http_last_modified - дата модификации контента
$sent_http_connection - поддерживается соединение keep-alive или оно закрыто closed
$sent_http_keep_alive - сколько времени будет поддерживаться соединение keep alive
$sent_http_transfer_encoding - кодировка тела ответа (например оно заархивировано gzip)
$sent_http_cache_control - должен ли браузер кэшировать страницу на своей стороне или нет
$sent_http_... - любые другие установленные значения, которые можно получить
Некоторые другие переменные, генерируемые Nginx
$content_length - длина ответа
$content_type - тип содержимого ответа
$cookie_XXX - выбрать куки с именем XXX
$document_root - адрес корневой папки сайта
$document_uri - текущий URL запроса
$host - доменное имя сайта в URL
$hostname - системное имя компьютера, на котором установлен сервер
$nginx_version - версия сервера
$pid - pid сервера
$query_string - строка запроса в URL после знака ? (тоже самое, что и $args)
$remote_addr - IP-адрес браузера клиента
$remote_port - порт браузера клиента
$remote_user - имя клиента, если он авторизован
$realpath_root - document root в запросе request клиента
$request_body - тело ответа клиенту
$request_method - тип запроса GET или POST
$scheme - схема http или https
$server_addr - IP-адрес компьютера, на котором установлен сервер
$server_name - имя компьютера, на котором установлен сервер
$server_port - порт, на котором установлен сервер
$server_protocol - используемый HTTP-протокол HTTP/1.0 или HTTP/1.1
$uri - тоже самое, что и $document_uri
--------------------------------------------------------------------
Способы задания Location
http {
server {
server_name website.com;
location /abcd {
...
}
location ~ ^/abcd$ {
...
}
location ~* ^/abcd$ {
...
}
location /files/ {
...
}
location = /files/ {
...
}
location /doc {
# requests beginning with "/doc"
}
location ~* ^/document$ {
# requests exactly matching "/document"
}
location /document {
# requests beginning with "/document"
}
location ~* ^/document$ {
# requests exactly matching "/document"
}
location ^~ /doc {
# requests beginning with "/doc"
}
location ~* ^/document$ {
# requests exactly matching "/document"
}
}
}
--------------------------------------------------------------------
Переписывание адресов через регулярные выражения модуля Rewrite
rewrite "hel{2,}o" /hello.php;
rewrite 'hel{2,}o' /hello.php;
--------------------------------------------------------------------
захват значений из URL-адреса размещенных внутри скобок в переменные nginx
PATTERN ^(hello|hi) (sir|mister)$
STRING hello sir
VARIABLES $1 = hello $2 = sir
PATTERN ^(.*)$
STRING nginx rocks
VARIABLES $1 = nginx rocks
PATTERN ^(.{1,3})([0-9]{1,4})([?!]{1,2})$
STRING abc1234!?
VARIABLES $1 = abc $2 = 1234 $3 = !?
Пример
server {
server_name website.com;
location ~* ^/(downloads|files)/(.*)$ {
add_header Capture1 $1;
add_header Capture2 $2;
}
}
--------------------------------------------------------------------
Вывод страниц с сообщениемя об ошибках
server {
server_name website.com;
error_page 403 /errors/forbidden.html; (при ошибке 403 взять страницу из этой папки)
error_page 404 /errors/not_found.html; (при ошибке 404 взять страницу из этой папки)
}
server {
server_name website.com; (доменное имя сайта)
root /var/www/vhosts/website.com/httpdocs/; (корневая папка, где лежат файлы сайта)
error_page 404 /errors/404.html; (при ошибке 404 взять страницу из этой папки)
location /errors/ {
alias /var/www/common/errors/; (при переходе по адресу /errors/ взять файлы из этой папки)
internal; (страница по адресу /errors/ доступна только с локального компьютера, на котором установлен сервер)
}
}
--------------------------------------------------------------------
Переписывание URL-адреса Rewrite при переходе на страницу
server {
server_name website.com;
root /var/www/vhosts/website.com/httpdocs/;
location /storage/ {
internal;
alias /var/www/storage/;
}
location /documents/ { (при переходе на страницу переписывание адреса с documents на storage)
rewrite ^/documents/(.*)$ /storage/$1; (производится редирект на другой адрес)
}
}
Бесконечный цикл перехода
server {
server_name website.com;
location /documents/ {
rewrite ^(.*)$ /documents/$1;
}
}
--------------------------------------------------------------------
Включение Server Side Includes
<html>
<head>
<!--# include file="header.html" -->
</head>
<body>
<!--# include file="body.html" -->
<!--# include virtual="/footer.php?id=123" -->
</body>
</html>
Разрешить SSI
server {
server_name website.com;
location ~* \.shtml$ {
ssi on; (разрешить инклюды для этого адреса)
}
}
Команды SSI
<!--# include file="header.html" -->
<!--# include virtual="/sources/header.php?id=123" -->
<!--# include virtual="header.php" wait="yes" -->
<!--# set var="MY_VARIABLE" value="hello" -->
<!--# echo var="MY_VARIABLE" -->
<!--# set var="MY_VARIABLE" value="$MY_VARIABLE there" -->
<!--# echo var="MY_VARIABLE" -->
<!--# if expr="expression1" -->
...
<!--# elif expr="expression2" -->
...
<!--# else -->
...
<!--# endif -->
<!--# config errmsg="Something terrible happened" -->
<!--# config timefmt="%A, %d-%b-%Y %H:%M:%S %Z" -->
--------------------------------------------------------------------
Условная обработка запросов GET и POST на стороне сервера
server {
if ($request_method = GET) {
...
}
if ($request_method = POST) {
...
}
if ($uri ~ /search/) {
...
}
}
--------------------------------------------------------------------
Частые правила переписывания URL страниц
Поиск для сайта
Input URI http://website.com/search/some-search-keywords
Rewritten URI http://website.com/search.php?q=some-search-keywords
Rewrite rule rewrite ^/search/(.*)$ /search.php?q=$1?;
Просмотр профиля пользователя
Input URI http://website.com/user/31/James
Rewritten URI http://website.com/user.php?id=31&name=James
Rewrite rule rewrite ^/user/([0-9]+)/(.+)$ /user.php?id=$1&name=$2?;
Передача нескольких параметров в URL
Input URI http://website.com/index.php/param1/param2/param3
Rewritten URI http://website.com/index.php?p1=param1&p2=param2&p3=param3
Rewrite rule rewrite ^/index.php/(.*)/(.*)/(.*)$ /index.php?p1=$1&p2=$2&p3=$3?;
Как на Wikipedia
Input URI http://website.com/wiki/Some_keyword
Rewritten URI http://website.com/wiki/index.php?title=Some_keyword
Rewrite rule rewrite ^/wiki/(.*)$ /wiki/index.php?title=$1?;
Показать статью на новостном сайте
Input URI http://website.com/33526/us-economy-strengthens
Rewritten URI http://website.com/article.php?id=33526
Rewrite rule rewrite ^/([0-9]+)/.*$ /article.php?id=$1?;
Форум
Input URI http://website.com/topic-1234-50-some-keywords.html
Rewritten URI http://website.com/viewtopic.php?topic=1234&start=50
Rewrite rule rewrite ^/topic-([0-9]+)-([0-9]+)-(.*)\.html$ /viewtopic.php?topic=$1&start=$2?;
--------------------------------------------------------------------
Задание главной страницы сайта
index index.php index.html index.htm;
index index.php index2.php /catchall.php;
--------------------------------------------------------------------
Включение автоиндексации файлов в папках сайта, если нет индексного файла
http {
server {
location / {
autoindex on;
}
}
}
--------------------------------------------------------------------
Включение базовой авторизации Basic Authtorization
location /admin/ {
auth_basic "Admin control panel";
auth_basic_user_file access/password_file;
}
--------------------------------------------------------------------
Разрешение доступак к странице только с определенного IP-адреса
location {
allow 127.0.0.1; # allow local IP address
deny all; # deny all other IP addresses
}
--------------------------------------------------------------------
Размещение empty gif по адресу, указанному в location
location = /empty.gif {
empty_gif;
}
--------------------------------------------------------------------
Обработка адресов для FLV
location ~* \.flv {
flv;
}
--------------------------------------------------------------------
Добавление HTTP заголовков
add_before_body file_uri;
add_after_body file_uri;
--------------------------------------------------------------------
Memcached
Memcached - это фоновое приложение, которе может быть подсоединено через соекты. Основное его назначение это кэширование данных в пямяти по принципу ключ-значение.
Модуль Nginx Memcached предлагает директивы для доступа к фоновум демону Memcached.
memcached_pass localhost:8888 (задает хост и порт на котором работает программа Memcached)
memcached_connect_timeout 5000;
memcached_send_timeout 5,000;
Пример
server {
server_name example.com;
location / {
set $memcached_key $uri;
memcached_pass 127.0.0.1:8888;
error_page 404 @notcached;
}
location @notcached {
internal;
# Если файл не найден то переадресовать на proxy-сервер
proxy_pass 127.0.0.1:8080;
}
}
Пример Memcached
server {
server_name www.example1.com;
location / {
set $memcached_key $uri;
memcached_pass 127.0.0.1:11211;
default_type text/html;
error_page 404 @fallback;
}
location @fallback {
proxy_pass http://backend;
}
}
--------------------------------------------------------------------
Возможно также:
Обработка картинок средствами сервера nginx
Обработка XSLT средствами сервера nginx
--------------------------------------------------------------------
Установка Real IP
real_ip_header X-Forwarded-For;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 127.0.0.1;
--------------------------------------------------------------------
Включение SSL-шифрования
server {
listen 443;
server_name secure.website.com;
ssl on;
ssl_certificate /path/to/combined.crt;
ssl_certificate_key /path/to/secure.website.com.key;
...
}
Пример
http {
...
ssl_certificate common.crt;
ssl_certificate_key common.key;
server {
listen 80;
server_name www.example1.com;
location / {
...
}
}
server {
listen 443 default ssl;
server_name payment.example1.com;
location / {
...
}
}
server {
listen 80;
listen 443;
server_name static.example1.com;
location / {
root /var/www/www.example1.com/static;
}
}
--------------------------------------------------------------------
Установка Secure link
location /downloads/ {
secure_link_secret "secret";
if ($secure_link = "") {
return 403;
}
rewrite ^ /downloads/$secure_link break;
}
--------------------------------------------------------------------
Включение FastCGI для подключения языка программирования к серверу PHP, Python. Ruby
fastcgi_pass localhost:9000;
fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/tmp/fastcgi.socket;
# используем upstream block
upstream fastcgi {
server 127.0.0.1:9000;
server 127.0.0.1:9001;
}
location ~* \.php$ {
fastcgi_pass fastcgi;
}
PHP и fastCGI
server {
listen 80;
server_name www.example1.com;
root /var/www/www.example1.com;
index index.php index.html index.htm;
try_files $uri $uri/ /index.php;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
--------------------------------------------------------------------
Использование Upstream nginx в качестве proxy-сервера между браузером и backend-компьютером Apache, на котором выполняется серверный сценарий на языке программирования
upstream phpfpm {
server 192.168.0.50:9000;
server 192.168.0.51:9000;
server 192.168.0.52:9000;
}
server {
server_name website.com;
location ~* \.php$ {
fastcgi_pass phpfpm;
...
}
}
Установка приоритета выбора серверов
Балансировщик нагрузки
upstream php {
server 192.168.0.1:9000 weight=2;
server 192.168.0.2:9000;
}
upstream phpbackend {
server localhost:9000 weight=5;
server 192.168.0.1 max_fails=5 fail_timeout=60s;
server unix:/tmp/backend backup;
}
--------------------------------------------------------------------
Использование PHP с nginx и FastCGI
server {
server_name .website.com; (доменное имя сайта)
listen 80; (порт 80)
root /home/website/www; (корневая папка, откуда берутся файлы сайта)
index index.php; (имя индексного файла)
location ~* \.php$ { (для всех запросов, оканчивающихся на php запускается серверный сценарий на PHP)
fastcgi_pass 127.0.0.1:9000; (обработчик скрипотв PHP размещается на порту 9000)
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include fastcgi_params; (включить еще какие-либо настройки)
}
}
--------------------------------------------------------------------
Использование Django с nginx и FastCGI
Необходимо установить Python-Flup и стартовать FastCGI процесс
[root@website.com www]# python manage.py runfcgi method=prefork host=127.0.0.1 port=9000 pidfile=/var/run/ django.pid
Далее настроить конфигурацию nginx
http {
server {
server_name .website.com;
listen 80;
root /home/website/www;
index index.html;
location / {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include fastcgi_params;
}
}
}
Django Python и uWSGI
Установить модуль для nginx
http://projects.unbit.it/downloads/uwsgi-0.9.6.5.tar.gz
django_wsgi.py
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'testapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
В консоли запускаем
uwsgi --socket 127.0.0.1:3031 --pythonpath /var/www/ --pythonpath /var/www/testapp/ -w django_wsgi -M -T -d server.log –L
настройки nginx
server {
listen 80;
server_name www.example1.com;
location / {
root /var/www/testapp;
index index.php index.html index.htm;
}
location / {
uwsgi_pass 127.0.0.1:3031;
include uwsgi_params;
}
}
дополнительно можно написать сценарий django_usgi2.py:
import web
urls = (
'/(.*)', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self, name):
if not name:
name = 'World'
return 'Hello, ' + name + '!'
application = app.wsgifunc()
Запустим из консоли
uwsgi -s /tmp/web.py.socket -w django_usgi2.py
Modifying FCGI
Изменим FastCGI timeouts
server {
listen 80;
server_name www.example1.com;
root /var/www/www.example1.com;
index index.php index.html index.htm;
fastcgi_read_timeout 120;
fastcgi_write_timeout 120;
try_files $uri $uri/ /index.php;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
--------------------------------------------------------------------
использование nginx совместно с apache
Nginx в качестве reverse proxy
Переадресация запроса с nginx на Apache
proxy_pass http://localhost:8080;
proxy_pass http://127.0.0.1:8080;
proxy_pass http://unix:/tmp/nginx.sock;
proxy_pass https://192.168.0.1;
proxy_pass http://localhost:8080/uri/;
proxy_pass http://unix:/tmp/nginx.sock:/uri/;
proxy_pass http://$server_name:8080;
# Используем upstream block
upstream backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
location ~* \.php$ {
proxy_pass http://backend;
}
Proxy redirect
proxy_redirect off;
proxy_redirect default;
proxy_redirect http://localhost:8080/ http://example.com/;
proxy_redirect http://localhost:8080/wiki/ /w/;
proxy_redirect http://localhost:8080/ http://$host/;
Пример проксирования на другой сервер
server {
listen 80;
server_name example1.com;
access_log /var/www/example1.com/log/nginx.access.log;
error_log /var/www/example1.com/log/nginx_error.log debug;
location / {
include proxy.conf;
proxy_pass http://127.0.0.1:8080;
}
}
Проксирование на несколько серверов и балансировка нагрузки
upstream backend {
server backend1.example1.com weight=5;
server backend2.example1.com max_fails=3 fail_timeout=30s;
server backend3.example1.com;
}
server {
listen 80;
server_name example1.com;
access_log /var/www/example1.com/log/nginx.access.log;
error_log /var/www/example1.com/log/nginx_error.log debug;
location / {
include proxy.conf;
proxy_pass http://backend;
}
}
Конфигурирование Apache для проксирования с nginx
<VirtualHost A.B.C.D:8080>
ServerName example.com:8080
ServerAlias www.example.com
...
Order deny,allow
allow from 127.0.0.1
allow from 192.168.0.1
deny all
</VirtualHost>
Конфигурирование nginx для проксирования на Apache
upstream apache {
server 192.168.0.1:80;
server 192.168.0.2:80;
server 192.168.0.3:80 weight=2;
server 192.168.0.4:80 backup;
}
server {
server_name .example.com;
root /home/example.com/www;
...
location / {
proxy_pass http://apache;
}
}
Разделение ститчного и динамичного контента при проксировании
server {
server_name .example.com;
root /home/example.com/www;
...
location ~* \.php$ {
# Передача на Apache всех запросов, оканчивающихся на .php
proxy_pass http://127.0.0.1:8080;
}
location / {
# Опции для отдачи статичных файлов: css, kavascript, images, html
# например cache control, alias и так далее
expires 30d;
}
}
Комментариев нет:
Отправить комментарий