Обработка http-ответа с LUA в HAProxy - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь определить хук LUA в HAProxy, чтобы я мог выполнить действие (уничтожить контейнер, обрабатывающий запрос), как только получу ответ. Моя проблема здесь связана с буфером HAProxy. Я пробовал разные реализации, и это самая близкая к работе (хотя в половине случаев клиент не отправляет все данные обратно):

function hook(txn)
  local in_len = txn.res:get_in_len()
  while in_len > 0 do
    txn.res:forward(in_len)
    local out_len = txn.res:get_out_len()
    while out_len ~= 0 do
      core.yield()
      out_len = txn.res:get_out_len()
    end
    in_len = txn.res:get_in_len()
  end
  os.execute("docker rm -f server_" .. txn.sf:srv_id())
end

core.register_action("hook", { "http-res" }, hook)

Моя самая большая проблема в том, что нет заголовка Content-length, поэтому я не знаю, когда обработал всю информацию и когда закончил. Кроме того, мне не удалось заставить get и настроить методы для работы, так как каждый раз, когда я вызываю get , я получаю точно такую ​​же информацию.

Это конфигурация HAProxy:

backend my-backend
  balance roundrobin
  http-response lua.hook
  server server_1 192.168.1.3:80 check

Как правильно обработать всю информацию перед тем, как убить внутренний сервер?

1 Ответ

0 голосов
/ 14 ноября 2018

Когда вы используете функцию forward в «txn.res: forward (in_len)», вы перемещаете данные из входной части буфера http-ответа в вывод один.
Затем вы используете yield , который возвращает обработку обратно в HAProxy, и именно тогда возникает проблема. HAProxy не смог проанализировать заголовки (они были перемещены непосредственно в выходной буфер) и будет считать ответ недействительным.
Поэтому я думаю, что вы всегда получаете только первый буфер до HAProxy

Если вы измените сценарий и используете его в контексте TCP, HAProxy не нужно будет проверять правильность ответа HTTP, и он будет работать правильно. В контексте TCP ваш сценарий можно даже упростить, чтобы он выглядел так:

function hook(txn) 
    local in_len = txn.res:get_in_len() 
    while in_len > 0 do 
            core.yield() 
            in_len = txn.res:get_in_len() 
    end 
    os.execute("docker rm -f server_" .. txn.sf:srv_id())
end 
core.register_action("hook", { "tcp-res" }, hook) 

Также вам нужно знать, что не рекомендуется использовать os.execute (), потому что он будет блокировать HAProxy до тех пор, пока выполнение не будет завершено. Подробнее об этом здесь в разделе «Неблокируемый дизайн». Поэтому лучше выбрать другой вариант, например, использовать API для отправки действия в контейнер.

...