Конфигурирование цепочек#

Механизм работы#

Механизм цепочек действий выглядит следующим образом:

  1. Каждая объявленная цепочка есть дерево действий, в общем случае независимая друг от друга.

  2. Выполнение каждой цепочки инициируется последовательно, однако, в общем случае не гарантируется, что запуск следующей цепочки произойдет до окончания предыдущей.

  3. Цепочки гарантировано будут выполнены последовательно только в том случае, если не существует ни одного отложенного (асинхронного) действия ни в одной из них. В настоящий момент единственное определенное асинхронное действие - AntivirusFileChecker.

  4. Основной смысл объединения действий в одну цепочку заключается в возможности, инициализируя корневое действие одним сообщением, выполнять цепочку преобразований и проверок над ним и получающихся в результате преобразований над ним данных.

  5. Если результат выполнения действий не зависит друг от друга, то их не следует размещать в одной цепочке.

  6. Если в цепочке находится действие, принимающее на вход сообщение, то данное сообщение должно быть определено либо как сообщение, которым инициализировалась цепочка, либо как сообщение, которое создано предыдущим действием.

  7. Действия манипулятора с переменными могут располагаться в любом месте цепочки, однако при этом следует учитывать, что требования в п. 6 должны выполняться.

Конфигурирование цепочек#

Для описания цепочек используются следующие конструкции:

profile: test_chain
system:
  conn_count: 4096
  optional:
    log_level: debug
  wrk_count: 1
version: 2.0.3
service:
  service_http_proxy:
    chains:
      request_chains:
      - actions:
        - action: RootAction
          actions:
          - action: ChildAction
        message: $message_to_proceed
        phase: rewrite
      request_chain_properties:
        error_state_code: 500
        failed_check_state_code: 403
        max_buffer_size: 16k
        max_inmemory_size: 1M
      response_chains:
      - actions:
        - action: RootAction
          actions:
          - action: ChildAction
        message: $message_to_proceed
      response_chain_properties:
        error_state_code: 500
        failed_check_state_code: 403
        max_buffer_size: 16k
        max_inmemory_size: 1M
        skip_on_error_stage_before: on
        use_post_processor: True
        resp_gen_modify: on

Рассмотрим структуру и назначение элементов.

Элемент chains объявляется внутри элементов - сервисов и является корневым для все цепочек действий. В зависимости от того, к какому объекту, request или response, применяется цепочка действий, объявляется секция request_chains или response_chains, при этом обе секции могут быть объявлены одновременно. В каждой из этих секций может быть объявлен список цепочек, каждый элемент из которых имеет следующие параметры:

Параметр

Возможные значения

Обязательность

Описание

action

Одно из перечисленных действий выше

да

Действие, которое является корневым в данной цепочке (с которого начинается обработка)

actions

Список дочерних действий, каждый элемент которого также является действием

нет

Действия, которые будут выполнены после выполнения корневого действия. Максимальный уровень вложенности в настоящий момент = 10

message

Сообщение, которое поступает на вход корневому действию. Может быть либо выражением из переменных nginx, либо использовать значения $clj_request_body - для тела запроса, либо $clj_response_body (может быть использовано только для response_chains)

нет

Обязательно для тех действий, у которых в таблице выше заполнен вход. Важно! Контроль того, определен message или нет, осуществляется только в runtime - если на вход действию придет незаполненное сообщение, то будет сгенерирована ошибка

phase

Фаза обработки, одно из значений - rewrite/access

нет

Используется только для request_chains, по умолчанию - access. Задавать этот параметр нужно только в том случае, когда какие-либо параметры заполняются на определенной фазе, либо используются значения переменных, заполняемые на определенной фазе, обычно нативными модулями

И для цепочки обработки запросов, и для цепочки обработки ответов могут быть заданы дополнительные параметры.

Для request_chains в секции request_chain_properties:

Параметр

Возможные значения

Обязательность

Описание

error_state_code

http-статус ответа

нет

http статус ответа, который будет возвращаться в случае ошибки - по умолчанию -500

failed_check_state_code

http-статус ответа

нет

http статус ответа, который будет возвращаться в случае блокировки запроса/ответа проверяющим действием, по умолчанию - 403

max_buffer_size

1; Kb; Mb

нет

Объем памяти для внутренней буферизации (служебное значение, менять не рекомендуется)

max_inmemory_size

kb/Mb

нет

Максимальный размер памяти, который одномоментно может взять из памяти любое действие - по умолчанию 1Mb

skip_on_error_stage_before

on/off

нет

Определяет, выполнять ли цепочку действий, если цепочка на фазе запроса завершилась с ошибкой или блокировкой запроса

use_post_processor

true/false

нет

Определяет, использовать ли пост-обработку для генерации ответа

resp_gen_modify

on/off

нет

Включение переопределения тела ответа для ответов с backend (успешно прошедших проверку и не с ошибочным статусом)

Переменные#

  1. Для получения информации о результате выполнения цепочек определены следующие переменные:

    • сlj_request_chain_result

      Результат выполнения цепочки действий над запросом.

      Возможные варианты:

      • complete, deny, error;

      • complete - выполнено без ошибок;

      • deny - заблокировано;

      • error -ошибка.

    • clj_error_action

      Действие, вызвавшее блокировку/ошибку - начиная с версии 2.2.

    • clj_processing_phase

      Фаза выполнения цепочки, request или response.

    • clj_response_chain_result

      Результат выполнения цепочки действий над ответом.

      Возможные варианты:

      • complete, deny, error;

      • complete - выполнено без ошибок;

      • deny - заблокировано;

      • error -ошибка.

  2. При описании цепочек, если предполагается заполнять какие-либо переменные, отличные от встроенных, то необходимо объявлять их либо с префиксом clj_ либо объявлять их в конфигурации с использованием директивы set_varialble в секции optional сервиса.

  3. Переменные для доступа к содержимому данных запроса ответа:

    • clj_message_mime_typ

      MIME-тип текущего сообщения.

    • сlj_request_body

      Тело запроса.

    • сlj_request_body

      Тело ответа.

Конфигурирование действий#

Рассмотрим определение действия:

- action: AnyAction
    conditions:
      {список условий}
    params:
      {список параметров}
    {actions:}

Определение каждого действия состоит собственно из названия действия (элемент из перечисленных действий), условий, при которых данное действие выполняется (conditions) - безотносительно того, какое это действие, данный элемент используется универсально (при этом может отсутствовать, если действие должно выполняться всегда, если до него дошла очередь) , секции специфичных параметров действия - params (какие параметры должны задаваться определяется реализацией действий) и список дочерних действий, каждый из которых рекурсивно имеет такую же структуру.

Каждое условие состоит из трех элементов:

  • var - переменная или выражение из переменных

  • val - значение с которым будет сравниваться значение var. В качестве val может использоваться:

    • константа;

    • переменная, их сочетания или сочетания с константами;

    • данные из файла.

  • operator - операция сравнения, одно из значений:

    • "=" - равенство (при сравнении строк используется посимвольное сравнение);

    • ">" - больше, для числовых значений;

    • "<" - меньше, для числовых значений;

    • ">=" - больше или равно, для числовых значений;

    • "<=" - меньше или равно, для числовых значений;

    • "IN" - вхождение в перечисление;

    • "NOT IN" - отсутствие вхождения;

    • "!=" - неравенство значений;

    • "~" - регулярное выражение с учетом регистра символов;

    • "~*" - регулярное выражение без учета регистра символов;

    • "!~" - негативное регулярное выражение с учетом регистра символов;

    • "!~*" - негативное регулярное выражение без учета регистра символов.