ngx-php — это расширение модуля высокопроизводительного веб-сервера nginx, которое реализует встраивание скриптов PHP7 и PHP8 для обработки локаций и переменных nginx.
ngx-php черпает идеи из дизайна ngx_lua и стремится предоставить неблокирующие веб-сервисы с существенным преимуществом производительности по сравнению с php-cgi, mod_php, php-fpm и hhvm.
ngx-php не стремится заменять что-либо, а просто предлагает решение.
Есть старая версия ngx_php5, которая отражает некоторые мои прошлые практики программирования и также имеет ценность.
$ wget 'http://php.net/distributions/php-7.3.10.tar.gz'
$ tar xf php-7.3.10.tar.gz
$ cd php-7.3.10
$ ./configure --prefix=/путь/к/php --enable-embed
$ make && make install
$ git clone https://github.com/rryqszq4/ngx-php.git
$ wget 'http://nginx.org/download/nginx-1.12.2.tar.gz'
$ tar -zxvf nginx-1.12.2.tar.gz
$ cd nginx-1.12.2
$ export PHP_CONFIG=/путь/к/php/bin/php-config
$ export PHP_BIN=/путь/к/php/bin
$ export PHP_INC=/путь/к/php/include/php
$ export PHP_LIB=/путь/к/php/lib
$ ./configure --user=www --group=www \
$ --prefix=/путь/к/nginx \
$ --with-ld-opt="-Wl,-rpath,$PHP_LIB" \
$ --add-module=/путь/к/ngx-php/third_party/ngx_devel_kit \
$ --add-module=/путь/к/ngx-php
$ make && make install
yum -y install https://extras.getpagespeed.com/release-el7-latest.rpm
yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm yum-utils
yum-config-manager --enable remi-php73
yum install nginx-module-php7
Редактирование nginx.conf
и загрузка необходимых модулей в начале файла:
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_php_module.so;
apt-get update -yqq && apt-get install -yqq software-properties-common
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php
apt-get update -yqq
apt-get install -yqq wget git unzip libxml2-dev cmake make systemtap-sdt-dev \
zlib1g-dev libpcre3-dev libargon2-0-dev libsodium-dev libkrb5-dev \
php7.4-cli php7.4-dev libphp7.4-embed php7.4-mysql
```git clone https://github.com/rryqszq4/ngx-php.git
wget 'http://nginx.org/download/nginx-1.18.0.tar.gz'
tar -zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
export PHP_LIB=/usr/lib
./configure --user=www --group=www \
--prefix=/путь/к/nginx \
--with-ld-opt="-Wl,-rpath,$PHP_LIB" \
--add-module=/путь/к/ngx-php/third_party/ngx_devel_kit \
--add-module=/путь/к/ngx-php
make && make install
https://github.com/rryqszq4/ngx-php/blob/master/docs/zh-cn/osx_install.md
$ docker build -t nginx-php7 .
$ : "app.conf: Создайте конфигурацию nginx"
$ docker run -p 80:80 -v $PWD/app.conf:/etc/nginx/conf.d/default.conf nginx-php7
worker_processes auto;
events {
worker_connections 102400;
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
client_max_body_size 64k;
client_body_buffer_size 64k;
php_ini_path /usr/local/php/etc/php.ini;
server {
listen 80;
server_name localhost;
default_type 'application/json; charset=UTF-8';
location /php {
content_by_php_block {
echo "hello ngx-php";
}
}
location = /ngx_request {
content_by_php_block {
echo ngx_request_document_uri();
}
}
# curl /ngx_get?a=1&b=2
location = /ngx_get {
content_by_php_block {
echo "ngx_query_args()\n";
var_dump(ngx_query_args());
}
}
# curl -d 'a=1&b=2' /ngx_post
location = /ngx_post {
content_by_php_block {
echo "ngx_post_args()\n";
var_dump(ngx_post_args());
}
}
location = /ngx_sleep {
content_by_php_block {
echo "ngx_sleep начало\n";
yield ngx_sleep(1);
echo "ngx_sleep конец\n";
}
}
location = /ngx_socket2 {
default_type 'application/json;charset=UTF-8';
content_by_php_block {
$fd = ngx_socket_create();
``````markdown
yield ngx_socket_connect($fd, "httpbin.org", 80);
$send_buf = "GET /get HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\n\r\n";
yield ngx_socket_send($fd, $send_buf, strlen($send_buf));
$recv_buf = "";
yield ngx_socket_recv($fd, $recv_buf);
var_dump($recv_buf);
yield ngx_socket_close($fd);
}
}
location = /ngx_var {
set $a 1234567890;
content_by_php_block {
$a = ngx_var_get("a");
var_dump($a);
}
}
# установка типа содержимого заголовков ответа
location = /ngx_header {
content_by_php_block {
ngx_header_set("Content-Type", "text/html; charset=UTF-8");
}
}
}
``` # запустить PHP-файл
location = /php {
content_by_php_block {
include "название_php_файла.php";
}
}
# запустить любой PHP-файл в корне
location = / {
content_by_php_block {
include ngx_var_get("uri");
}
}
}
}
```Тестирование
-------------
Используем модуль [Test::Nginx](https://github.com/openresty/test-nginx) для тестирования, поиска и выявления проблем в ngx-php.
```sh
Ngx-php test ...
nginx version: nginx/1.22.1
built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
configure arguments: --prefix=/home/runner/work/ngx-php/ngx-php/nginx --with-ld-opt=-Wl,-rpath,/usr/lib --add-module=./third_party/ngx_devel_kit --add-module=./home/runner/work/ngx-php/ngx-php
t/001-hello.t ... ok
t/002-ini.t ... ok
t/003-error.t ... ok
t/004-ngx_request.t ... ok
t/005-ngx_log.t ... ok
t/006-ngx_sleep.t ... ok
t/007-ngx_socket.t ... ok
t/008-ngx_exit.t ... ok
t/009-ngx_query_args.t ... ok
t/010-ngx_post_args.t ... ok
t/011-ngx_constants.t ... ok
t/012-function.t ... ok
t/013-class.t ... ok
t/014-ngx_var.t ... ok
t/015-ngx_header.t ... ok
t/016-rewrite_by_php.t ... ok
t/017-ngx_redirect.t ... ok
t/018-ngx_mysql.t ... skipped: fix later
t/019-php_set.t ... ok
t/020-ngx_cookie.t ... ok
t/021-content_by_php_block.t ... ok
t/022-init_worker_by_php_block.t ... ok
t/023-ngx_redis.t ... ok
t/024-ngx_request_body.t ... ok
t/025-opcache.t ... ok
Все тесты прошли успешно.
Файлов=25, Тестов=92, 16 секунд работы (0.08 usr 0.04 sys + 4.56 cusr 0.93 csys = 5.61 CPU)
Результат: PASS
Синтаксис: php_ini_path
<путь к файлу php.ini>
Контекст: http
Фаза: загрузка-конфига
Эта директива позволяет загружать официальный конфигурационный файл php.ini, который будет использоваться последующими скриптами PHP.
Синтаксис: init_worker_by_php
<PHP скрипт код>
Контекст: http
Фаза: начало-работника
Синтаксис: init_worker_by_php_block
{PHP скрипт код}
Контекст: http
Фаза: начало-работника
Синтаксис: rewrite_by_php
<PHP скрипт код>
Контекст: http, сервер, локация, условие локации
Фаза: перезапись
В фазе перезаписи Nginx можно выполнять встроенный PHP код.
Синтаксис: rewrite_by_php_block
{PHP скрипт код}
Контекст: локация, условие локации
Фаза: перезапись
В фазе перезаписи Nginx можно выполнять встроенный PHP код.
Синтаксис: access_by_php
<PHP скрипт код>
Контекст: http, сервер, локация, условие локации
Фаза: доступ
В фазе доступа Nginx можно выполнять встроенный PHP код.
Синтаксис: access_by_php_block
{PHP скрипт код}
Контекст: локация, условие локации
Фаза: доступ
В фазе доступа Nginx можно выполнять встроенный PHP код.
Синтаксис: content_by_php
<PHP скрипт код>
Контекст: http, сервер, локация, условие локации
Фаза: контент
синтаксис: content_by_php_block
{PHP скрипт код}
контекст: локация, условие локации
фаза: контент
В фазе контента Nginx может выполнять встроенный PHP код.
синтаксис: log_by_php
<PHP скрипт код>
контекст: http, сервер, локация, условие локации
фаза: журнал
синтаксис: log_by_php_block
{PHP скрипт код}
контекст: локация, условие локации
фаза: журнал
синтаксис: header_filter_by_php
<PHP скрипт код>
контекст: http, сервер, локация, условие локации
фаза: фильтрация заголовков выходных данных
синтаксис: header_filter_by_php_block
{PHP скрипт код}
контекст: локация, условие локации
фаза: фильтрация заголовков выходных данных
синтаксис: body_filter_by_php
<PHP скрипт код>
контекст: http, сервер, локация, условие локации
фаза: фильтрация содержимого выходных данных
синтаксис: body_filter_by_php_block
{PHP скрипт код}
контекст: локация, условие локации
фаза: фильтрация содержимого выходных данных
синтаксис: php_keepalive
<размер>
по умолчанию: 0
http, сервер
API Nginx для PHPсинтаксис: ngx_exit(int $status) : void
Параметры:
status: int
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Завершение текущего запроса и возврат HTTP-кодом состояния.
Синтаксис: ngx_query_args(void) : array
или ngx::query_args(void) : array
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Связанный массив переменных, переданных текущему скрипту через параметры URL (также известные как строка запроса).
Вместо официальной константы PHP $_GET.
Синтаксис: ngx_post_args(void) : array
или ngx::post_args(void) : array
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Связанный массив переменных, переданных текущему скрипту через метод HTTP POST
при использовании application/x-www-form-urlencoded или multipart/form-data в качестве HTTP Content-Type в запросе.
Вместо официальной константы PHP $_POST.
Синтаксис: ngx_log_error(int $level, string $log_message) : void
или ngx_log::error(int $level, string $log_message) : void
Параметры:
level: int
log_message: string
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Синтаксис: ngx_request_method(void) : string
или ngx_request::method(void): string
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Какой метод запроса был использован для доступа к странице, такой как 'GET', 'POST', 'PUT', 'DELETE' и так далее.
Синтаксис: ngx_request_document_root(void) : string
или ngx_request::document_root(void): string
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Каталог корневого документа, под которым выполняется текущий скрипт, как определено в конфигурационном файле сервера.
Синтаксис: ngx_request_document_uri(void) : string
или ngx_request::document_uri(void) : string
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Синтаксис: ngx_request_script_name(void) : string
или ngx_request::script_name(void) : string
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Содержит полный путь и имя текущего скрипта. Это полезно для страниц, которые должны указывать на сами себя.
Константа __FILE__
содержит полный путь и имя текущего (включенного) файла.
Синтаксис: ngx_request_script_filename(void) : string
или ngx_request::script_filename(void) : string
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Абсолютный путь к имени текущего исполняющегося скрипта.
Синтаксис: ngx_request_query_string(void) : string
или ngx_request::query_string(void) : string
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Строка запроса, если таковая имеется, через которую была доступна данная страница.
Синтаксис: ngx_request_uri(void) : string
или ngx_request::uri(void) : string
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
URI, который был указан для доступа к данной странице, например, '/index.html'.
синтаксис: ngx_request_server_protocol(void) : string
или ngx_request::server_protocol(void) : string
параметры:
void
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Название и версия протокола, через который была запрошена данная страница, например, 'HTTP/1.0'.
синтаксис: ngx_request_remote_addr(void) : string
или ngx_request::remote_addr(void) : string
параметры:
void
контекст: rewrite_by_php*, access_by_php*, content_by_php*
IP-адрес, с которого просматривает текущую страницу пользователь.
синтаксис: ngx_request_server_addr(void) : string
или ngx_request::server_addr(void) : string
параметры:
void
контекст: rewrite_by_php*, access_by_php*, content_by_php*
IP-адрес сервера, под которым выполняется текущий скрипт.
синтаксис: ngx_request_remote_port(void) : int
или ngx_request::remote_port(void) : int
параметры:
void
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Порт, используемый на машине пользователя для связи с веб-сервером.
синтаксис: ngx_request_server_port(void) : int
или ngx_request::server_port(void) : int
параметры:
void
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Синтаксис: ngx_request_server_name(void) : string
или ngx_request::server_name(void) : string
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Имя хоста сервера, под которым выполняется текущий скрипт. Если скрипт запущен на виртуальном хосте, это будет значением, определённым для этого виртуального хоста.
Синтаксис: ngx_request_headers(void): array
или ngx_request::headers(void) : array
Параметры:
void
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Получение полной информации о заголовках HTTP-запроса.
Синтаксис: ngx_var_get(string $key) : string
или ngx_var::get(string $key) : string
Параметры:
key: string
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Получение переменных из конфигурации Nginx.
Синтаксис: ngx_var_set(string $key, string $value) : void
или ngx_var::set(string $key, string $value) : void
Параметры:
key: string
value: string
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Установка переменных в конфигурации Nginx.
Синтаксис: ngx_header_set(string $key, string $value) : bool
Параметры:
key: string
value: string
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Установка информации о заголовках HTTP-ответа.
Синтаксис: ngx_header_get(string $key) : string
Параметры:
key: string
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Получение информации о заголовке HTTP-ответа.
Синтаксис: ngx_header_gets(void) : array
параметры:
void
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Получает полную информацию заголовков HTTP-ответа.
синтаксис: ngx_redirect(string $uri, int $status) : bool
параметры:
uri: string
status: int
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Устанавливает переадресацию ответа.
синтаксис: ngx_cookie_get_all(void) : string
параметры:
void
контекст: rewrite_by_php*, access_by_php*, content_by_php*
синтаксис: ngx_cookie_get(string $key) : string
параметры:
key: string
контекст: rewrite_by_php*, access_by_php*, content_by_php*
синтаксис: ngx_cookie_set(string $data) : bool
параметры:
data: string
контекст: rewrite_by_php*, access_by_php*, content_by_php*
синтаксис: yield ngx_sleep(int seconds)
параметры:
seconds: int
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Задерживает выполнение программы на указанное количество секунд.
синтаксис: yield ngx_msleep(int milliseconds)
параметры:
milliseconds: int
контекст: rewrite_by_php*, access_by_php*, content_by_php*
синтаксис: ngx_socket_create(int $domain, int $type, int $protocol) : resource
параметры:
domain: int
type: int
protocol: int
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Создает и возвращает ресурс сокета, также известный как конечная точка связи. Обычная сетевая связь состоит из двух сокетов, один выполняет роль клиента, а другой — сервера.
синтаксис: ngx_socket_iskeepalive(void) : bool
параметры:
void
контекст: rewrite_by_php*, access_by_php*, content_by_php*
синтаксис: ( yield ngx_socket_connect(resource $socket, string $address, int $port) ) : bool
параметры:
socket: resource
address: string
port: int
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Инициализирует соединение с адресом, используя ресурс сокета socket, который должен быть действительным ресурсом сокета, созданным с помощью ngx_socket_create().
синтаксис: ( yield ngx_socket_close(resource $socket) ) : bool
параметры:
socket: resource
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Функция ngx_socket_close() закрывает ресурс сокета, указанный параметром socket. Эта функция предназначена только для работы с сокетами и не может использоваться для других типов ресурсов.
синтаксис: ( yield ngx_socket_send(resource $socket, string $buf, int $len) ) : int
параметры:
socket: resource
buf: string
len: int
контекст: rewrite_by_php*, access_by_php*, content_by_php*
Синтаксис: ( yield ngx_socket_recv(resource $socket, string &$buf, int $len) ) : int
Параметры:
socket: resource
buf: string
len: int
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Функция ngx_socket_recv() получает $len байтов данных в $buf из сокета $socket. ngx_socket_recv() может использоваться для получения данных от подключенного сокета.
$buf передается по ссылке, поэтому он должен быть указан как переменная в списке аргументов.
Данные, считанные из сокета с помощью ngx_socket_recv(), будут возвращены в $buf.
Синтаксис: ( yield ngx_socket_recvpage(resource $socket, string &$buf, int &$rc) ) : int
Параметры:
socket: resource
buf: string
rc: int
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Синтаксис: ngx_socket_recvsync(ресурс $socket, строка &$buf, целое $len) : целое
Параметры:
socket: ресурс
buf: строка
len: целое
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Синтаксис: ngx_socket_clear(ресурс $socket) : логическое
Параметры:
socket: ресурс
Контекст: rewrite_by_php*, access_by_php*, content_by_php*
Закрывает ресурс сокета и является блокирующим, но обеспечивает высокую производительность.
название | значение |
---|---|
NGINX_VAR | NGINX |
NGINX_VERSION | 1.12.2 |
NGX_HTTP_PHP_MODULE_VERSION | 0.0.21 |
NGX_HTTP_PHP_MODULE_NAME | ngx_php |
название | значение |
---|---|
NGX_OK | 0 |
NGX_ERROR | -1 |
NGX_AGAIN | -2 |
NGX_BUSY | -3 |
NGX_DONE | -4 |
NGX_DECLINED | -5 |
NGX_ABORT | -6Константы состояния для PHP |
Название | Значение |
---|---|
NGX_LOG_STDERR | 0 |
NGX_LOG_EMERG | 1 |
NGX_LOG_ALERT | 2 |
NGX_LOG_CRIT | 3 |
NGX_LOG_ERR | 4 |
NGX_LOG_WARN | 5 |
NGX_LOG_NOTICE | 6 |
NGX_LOG_INFO | 7 |
NGX_LOG_DEBUG | 8 |
Название | Значение |
---|---|
NGX_HTTP_CONTINUE | 100 |
NGX_HTTP_SWITCHING_PROTOCOLS | 101 |
NGX_HTTP_PROCESSING | 102 |
NGX_HTTP_OK | 200 |
NGX_HTTP_CREATED | 201 |
NGX_HTTP_ACCEPTED | 202 |
NGX_HTTP_NO_CONTENT | 204 |
NGX_HTTP_PARTIAL_CONTENT | 206 |
NGX_HTTP_SPECIAL_RESPONSE | 300 |
NGX_HTTP_MOVED_PERMANENTLY | 301 |
NGX_HTTP_MOVED_TEMPORARILY | 302 |
NGX_HTTP_SEE_OTHER | 303 |
NGX_HTTP_NOT_MODIFIED | 304 |
NGX_HTTP_TEMPORARY_REDIRECT | 307 |
NGX_HTTP_PERMANENT_REDIRECT | 308 |
NGX_HTTP_BAD_REQUEST | 400 |
NGX_HTTP_UNAUTHORIZED | 401 |
NGX_HTTP_FORBIDDEN | 403 |
NGX_HTTP_NOT_FOUND | 404 |
NGX_HTTP_NOT_ALLOWED | 405 |
NGX_HTTP_REQUEST_TIME_OUT | 408 |
NGX_HTTP_CONFLICT | 409 |
NGX_HTTP_LENGTH_REQUIRED | 411 |
NGX_HTTP_PRECONDITION_FAILED | 412 |
NGX_HTTP_REQUEST_ENTITY_TOO_LARGE | 413 |
NGX_HTTP_REQUEST_URI_TOO_LARGE | 414 |
NGX_HTTP_UNSUPPORTED_MEDIA_TYPE | 415 |
NGX_HTTP_RANGE_NOT_SATISFIABLE | 416 |
NGX_HTTP_CLOSE | 444 |
NGX_HTTP_NGINX_CODES | 494 |
NGX_HTTP_REQUEST_HEADER_TOO_LARGE | 494 |
NGX_HTTPS_CERT_ERROR | 495 |
NGX_HTTPS_NO_CERT | 496 |
NGX_HTTP_TO_HTTPS | 497 |
NGX_HTTP_CLIENT_CLOSED_REQUEST | 499 |
NGX_HTTP_INTERNAL_SERVER_ERROR | 500 |
NGX_HTTP_NOT_IMPLEMENTED | 501 |
NGX_HTTP_BAD_GATEWAY | 502 |
NGX_HTTP_SERVICE_UNAVAILABLE | 503 |
NGX_HTTP_GATEWAY_TIME_OUT | 504 |
NGX_HTTP_INSUFFICIENT_STORAGE | 507 |
Авторское право © 2016-2020, rryqszq4 <rryqszq@gmail.com>
Все права защищены.
```Разрешается копировать и использовать данный программный продукт в виде исходного кода или бинарной формы с изменениями или без, при условии выполнения следующих условий:
* При распространении исходного кода должна быть сохранена вышеуказанная информация об авторском праве, этот список условий и нижеуказанный отказ от ответственности.
* При распространении в форме исполняемых файлов должна быть воспроизведена вышеуказанная информация об авторском праве, этот список условий и нижеуказанный отказ от ответственности в документации и/или других материалах, предоставляемых вместе с распределением.
Этот программный продукт предоставляется «как есть» авторами и участниками проекта без каких-либо гарантий, явных или подразумеваемых, включая, но не ограничиваясь, гарантии MERCHANTABILITY и FITNESS FOR A PARTICULAR PURPOSE.
НИ В КАКОМ СЛУЧАЕ АВТОРОВ ИЛИ УЧАСТНИКОВ ПРОЕКТА НЕ ОБЯЗАНЫ ПОЧИНЯТЬ, СЛЕДУЮЩИМ ЗАКОННЫМ СПОСОБОМ ИЛИ ДРУГИМ ТИПОМ ОТВЕТСТВЕННОСТИ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЯ, ГАРАНТИЯМИ БЕЗОПАСНОСТИ И ПРИВЫКАТЕЛЬНОСТИ) ВОЗНИКШИХ ПОСЛЕ ИСПОЛЬЗОВАНИЯ ЭТОГО ПРОГРАММНОГО ПРОДУКТА, ДАЖЕ ЕСЛИ БЫЛО Учреждено знание возможности таких убытков.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )