Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Django throttling

Anna | 16.06.2014 | нет комментариев
Как-то раз пришлось применять чужое django-app, в котором было много форм, способов и каждого остального. И, что само собой разумеется, автор решил не заморачиваться и не делать никакой охраны от спамеров, либо от любителей понажимать F5 на тяжелой форме. Переписывать и форкать у меня мечты не было, следственно решил написать middleware, режущий кислород нехорошим людям.

Функционал
  • maintenance режим, разрешает выключать view в целом, либо отдельные http способы
  • всеобщии fallback-таймауты сайта, для PATCH, POST и т.д.
  • локальные таймауты для view в целом, либо для отдельных http-способов

Проще показать пример конфига:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 'callable:helpers.trash.my_callback',
    'congestion': 'forum.views.congestion',

    'django.contrib.admin.options.change_view': {
        'post': False,
        'all': None,
        'uri': '/admin/forum/post/23/',
    },
}

Остальные примеры с описаниеми под катом.

Установка

git clone http://github.com/night-crawler/django-throttling.git
cd django-throttling
python setup.py install
Global throttling

Конфиг состоит из сегментов, самая верхняя — fallback, используется для каждого сайта в целом, в случае, если не нашлось больше детализированного правила.

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 10000,
    'congestion': 'forum.views.congestion',
}

В этом примере для запросов всех типов установлено лимитация в 1 запрос в секунду, post — запрос раз в 10 секунд.
congestion может быть uri, либо вьюхой. В данном случае будет вызвана вьюха, живущая по соседству:

def congestion(request, congestion_bundle):
    user = request.user
    progress = int(float(congestion_bundle['delta']) / congestion_bundle['timeout'] * 100)
    c = Context({'user': user, 'congestion_bundle': congestion_bundle, 'progress': progress})
    return render_to_response(get_theme_template(user, 'congestion.html'), c,
        context_instance=RequestContext(request)
    )

Это дозволит сказать юзеру, что он шалит и, к примеру, должен подождать N секунд. Вьюху дозволено снабдить скриптом с прогрессбаром, тот, что механически зарелоадит форму. В congestion_bundleпередается подлинная вьюха и каждый комплект ее доводов, чтобы дозволено было сказать юзеру что-то больше детальное.

Дозволено отключить POST на каждому сайте. Тогда юзер увидит HttpResponseBadRequest:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': False,
    'congestion': 'forum.views.congestion',
}

А дозволено отключить POST вот так, тогда юзер будет отправляться в корень:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': '/',
    'congestion': 'forum.views.congestion',
}

Если простого редиректа неудовлетворительно, то дозволено сделать свой обработчик для maintenance-mode:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 'forum.views.maintenance',
    'congestion': 'forum.views.congestion',
}

# forum.views.maintenance
def maintenance(request, maintenance_bundle):
    return HttpPreResponse(maintenance_bundle)

Может быть так, что необходимо блокировать вьюху только в определенных случаях, скажем, для блокирования одного топика в форуме, либо для еще какого-то частного случая. Тогда дозволено написать кастомный обработчик для правила:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 'callable:helpers.trash.my_callback', # обратите внимание на callable:
    'congestion': 'forum.views.congestion',
}

# helpers.trash.my_callback'
def my_callback(request, view_func, view_args, view_kwargs):
    return 'some_strange_key_123', 10000

Он должен возвращать кортеж из наименования ключа и таймаута. Таймаутом может вновь быть int(), False, view, либо uri.

Local throttling

В основном имеет аналогичный синтаксис. Отличается только наличием опционального ключа ‘uri’, тот, что разрешает натравливать throttle check только на него.

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 'callable:helpers.trash.my_callback',
    'congestion': 'forum.views.congestion',

    'django.contrib.admin.options.change_view': {
        'post': False,
        'all': None,
        'uri': '/admin/forum/post/23/',
        # 'post': 'callable:helpers.trash.my_callback',
        # 'all': 4000,
    },
}

Пупутно есть несколько настроек:

  1. DJANGO_THROTTLING_ENABLED: включает троттлинг, по умолчанию отключен.
  2. DJANGO_THROTTLING_CACHE_EXPIRE: определяет сколько хранятся ключи в кэше. По умолчанию 60*60.
  3. DJANGO_THROTTLING_CACHE_PREFIX: кэш-префикс, по умолчанию «THROTTLING»
  4. THROTTLING_CACHE_KEY_PATTERNS: здесь хранятся паттерны для генерации ключа. Каждого есть 4 разновидности: view_method, view, site_method, site. Дозволено переопределить.

На github’е есть изложение на «английском».

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB