вторник, 4 февраля 2014 г.

nginx: limit_req для POST

Штатно нельзя поставить ограничение на конкретный метод типа POST, только через Ж, увы.
Если просто написать
        location /login/ {
                if ($request_method = POST) {
                        limit_req zone=login; #burst=1;
                }

то при nginx -t будет ошибка
nginx: [emerg] "limit_req" directive is not allowed here in /etc/nginx/nginx.conf:48

Вариант через error_page

     if( $request_method = "POST")
     {
         return 402;
     }
     error_page 402 = @post;
   }
   location @post
   {
      limit_req ...
   }

Вариант через map
http://nginx.org/ru/docs/http/ngx_http_map_module.html
Основан на том, что если $is_post пуст, то ограничение не применится.

limit_req_zone $is_post zone=login:1m rate=1r/s;

map $request_method $is_post {
    POST $binary_remote_addr;
}

server {
...
limit_req zone=login; 
}

как-то так (пока не тестировалось, вечером постараюсь).

4 комментария:

  1. Если почитать документацию, то всё окажется можно: "Ключом является любое непустое значение заданной переменной (пустые значения не учитываются).", а далее модуль map в помощь.

    ОтветитьУдалить
    Ответы
    1. Даже зная документацию, этот момент с пустым значением я не могу назвать логичным и красивым, да и конструкция по сложности будет не сильно отличаться от того, что есть выше. А по понятности - я бы даже назвал сложнее чем первый пример.
      Дополню примером с set/map.

      Удалить
    2. Считайте, что это штатный метод. Сложность видимо в том, что вы его не знали.

      А если объективно, то конструкция проста как пробка:
      1. Директива limit_req_zone устанавливает ключ по которому вычисляется ограничение, соответсвенно нет ключа на входе - нет и ограничения, логично и понятно.
      2. Конструкция map является обной из самых эффективных в nginx, как с точки зрения производительсности, так и с точки зрения элементарной логики работы.

      Удалить
    3. > Считайте, что это штатный метод.
      так укажите это в официальной документации! ну или хотя бы вики.

      1. В современном софте "нет ключа" == исключение или глюки. Опять же, очень стоит отразить это в документации.
      2. map - не спорю, инструмент мощный. Хотя документацию можно было бы тоже чуть расширить.

      Что мешало вообще сделать как вариант - чтобы работал метод в начале? Для этого никаких новых команд вводить не надо, просто чуть расширить возможности.

      Удалить