Как добавить заголовки ответа с HAproxy 1.6 на основе запроса URI?

9

Я использую HAproxy 1.6 в качестве балансировщика нагрузки перед серверами Tomcat.

Мне нужно добавить заголовки ответа на основе запроса URI.

Например, я хотел бы добавить заголовок ответа, Cache-Control public,max-age="600"когда URI запроса есть, /apiно не когда URI запроса является чем-то другим.

  • Моей первой попыткой было использование acl на основе пути для добавления заголовков в http-response:

    acl api path_reg ^/api/(.*)$
    http-response add-header Cache-Control public,max-age="600" if api
    

    Когда я запускаю haproxy с -d, у меня появляется предупреждение о том, что path_reg(или path) несовместимо с http-response:

    Dec  6 15:22:29 ip-10-30-0-196 haproxy-systemd-wrapper[315]: 
    [WARNING] 340/152229 (2035) : parsing 
    [/etc/haproxy/haproxy.cfg:78] : acl 'api' will never match because 
    it only involves keywords that are incompatible with 'backend 
    http-response header rule'
    
  • Я попытался добавить заголовок http-requestвместо http-response:

    acl api path_reg ^/api/(.*)$
    http-request add-header Cache-Control public,max-age="600" if api
    

    Это сработало, но мне нужно в ответе

  • Я также пытался использовать переменные haproxy:

    http-request set-var(txn.path) path
    acl path_acl %[var(txn.path)] -m ^/api/(.*)$
    http-response add-header Cache-Control public,max-age="600" if path_acl
    

    Но при попытке HAproxy событие не запускается, и у меня появляется следующая ошибка:

    [ALERT] 340/162647 (2241) : parsing [/etc/haproxy/haproxy.cfg:48] 
    : error detected while parsing ACL 'path_acl' : unknown fetch 
    method '%[var' in ACL expression '%[var(txn.path)]'.
    

Как я могу использовать путь запроса в ACL, чтобы установить заголовок ответа?

jmlrt
источник

Ответы:

9

Попробуй это:

http-response set-header Cache-Control no-cache,\ max-age=600 if { capture.req.uri -m beg /api/ }

capture.req.uriсохраняется, пока ответ не будет обработан, в отличие от pathэтого.

Несколько заметок:

В этом примере используется анонимный ACL. Вы также можете сделать это с именованным ACL, но это займет 2 строки.

Я не знаю, почему вы должны указывать значение максимального возраста.

Вы, вероятно, не хотите add-header, вы хотите set-header, что гарантирует, что, если один уже присутствует, он будет удален.

acl path_acl %[var(txn.path)] -m ^/api/(.*)$наверное правильно написано как acl path_acl var(txn.path) -m ^/api/(.*)$. HAProxy немного привередлив, когда он ожидает, %[ ]а когда нет. Я уверен, что есть образец, но мне не ясно, что это такое.

Майкл - sqlbot
источник
1
Благодарю за ваш ответ. Оба метода с использованием capture.req.uriи переменные при удалении %[ ]в acl̀работают. Вы также правы насчет кавычек вокруг max-ageзначения и set-headerвместо add-header.
JMLRT
1
Обратите внимание, что внутренне я делаю нечто похожее, если серверная часть не предоставляет Cache-Controlответ: я добавляю Cache-Control-Authority: implicit, gatewayзаголовок, чтобы дать разработчику / средству устранения неполадок / тестировщику предупреждение, что я, прокси-сервер, предоставляю этот заголовок, а не приложение , но приложение может отключить меня, просто предоставив свой собственный заголовок. Обратите внимание, что этот заголовок не является стандартным - я просто придумал его, чтобы помочь другим членам команды понять, что я предоставляю это встроенное, а не приложение. Прокси настолько безаварийны, что имеют плохую привычку забывать, что они вообще на пути.
Майкл - sqlbot