haproxy/doc/design-thoughts/config-language.txt

263 lines
9.3 KiB
Plaintext
Raw Normal View History

Pr<EFBFBD>voir des commandes en plusieurs mots cl<63>s.
Par exemple :
timeout connection XXX
connection scale XXX
On doit aussi accepter les pr<70>fixes :
tim co XXX
co sca XXX
Pr<EFBFBD>voir de ranger les combinaisons dans un tableau. On doit m<>me
pouvoir effectuer un mapping simplifiant le parseur.
Pour les filtres :
<direction> <where> <what> <operator> <pattern> <action> [ <args>* ]
<direction> = [ req | rsp ]
<where> = [ in | out ]
<what> = [ line | LINE | METH | URI | h(hdr) | H(hdr) | c(cookie) | C(cookie) ]
<operator> = [ == | =~ | =* | =^ | =/ | != | !~ | !* | !^ | !/ ]
<pattern> = "<string>"
<action> = [ allow | permit | deny | delete | replace | switch | add | set | redir ]
<args> = optionnal action args
exemples:
req in URI =^ "/images" switch images
req in h(host) =* ".mydomain.com" switch mydomain
req in h(host) =~ "localhost(.*)" replace "www\1"
alternative :
<direction> <where> <action> [not] <what> [<operator> <pattern> [ <args>* ]]
req in switch URI =^ "/images" images
req in switch h(host) =* ".mydomain.com" mydomain
req in replace h(host) =~ "localhost(.*)" "www\1"
req in delete h(Connection)
req in deny not line =~ "((GET|HEAD|POST|OPTIONS) /)|(OPTIONS *)"
req out set h(Connection) "close"
req out add line "Server: truc"
<direction> <action> <where> [not] <what> [<operator> <pattern> [ <args>* ]] ';' <action2> <what2>
req in switch URI =^ "/images/" images ; replace "/"
req in switch h(host) =* ".mydomain.com" mydomain
req in replace h(host) =~ "localhost(.*)" "www\1"
req in delete h(Connection)
req in deny not line =~ "((GET|HEAD|POST|OPTIONS) /)|(OPTIONS *)"
req out set h(Connection) "close"
req out add line == "Server: truc"
Extension avec des ACL :
req in acl(meth_valid) METH =~ "(GET|POST|HEAD|OPTIONS)"
req in acl(meth_options) METH == "OPTIONS"
req in acl(uri_slash) URI =^ "/"
req in acl(uri_star) URI == "*"
req in deny acl !(meth_options && uri_star || meth_valid && uri_slash)
Peut-<2D>tre plus simplement :
acl meth_valid METH =~ "(GET|POST|HEAD|OPTIONS)"
acl meth_options METH == "OPTIONS"
acl uri_slash URI =^ "/"
acl uri_star URI == "*"
req in deny not acl(meth_options uri_star, meth_valid uri_slash)
req in switch URI =^ "/images/" images ; replace "/"
req in switch h(host) =* ".mydomain.com" mydomain
req in replace h(host) =~ "localhost(.*)" "www\1"
req in delete h(Connection)
req in deny not line =~ "((GET|HEAD|POST|OPTIONS) /)|(OPTIONS *)"
req out set h(Connection) "close"
req out add line == "Server: truc"
Pr<EFBFBD>voir le cas du "if" pour ex<65>cuter plusieurs actions :
req in if URI =^ "/images/" then replace "/" ; switch images
Utiliser les noms en majuscules/minuscules pour indiquer si on veut prendre
en compte la casse ou non :
if uri =^ "/watch/" setbe watch rebase "/watch/" "/"
if uri =* ".jpg" setbe images
if uri =~ ".*dll.*" deny
if HOST =* ".mydomain.com" setbe mydomain
etc...
Another solution would be to have a dedicated keyword to URI remapping. It
would both rewrite the URI and optionally switch to another backend.
uriremap "/watch/" "/" watch
uriremap "/chat/" "/" chat
uriremap "/event/" "/event/" event
Or better :
uriremap "/watch/" watch "/"
uriremap "/chat/" chat "/"
uriremap "/event/" event
For the URI, using a regex is sometimes useful (eg: providing a set of possible prefixes.
Sinon, peut-<2D>tre que le "switch" peut prendre un param<61>tre de mapping pour la partie match<63>e :
req in switch URI =^ "/images/" images:"/"
2007/03/31 - Besoins plus pr<70>cis.
1) aucune extension de branchement ou autre dans les "listen", c'est trop complexe.
Distinguer les donn<6E>es entrantes (in) et sortantes (out).
Le frontend ne voit que les requetes entrantes et les r<>ponses sortantes.
Le backend voir les requ<71>tes in/out et les r<>ponses in/out.
Le frontend permet les branchements d'ensembles de filtres de requ<71>tes vers
d'autres. Le frontend et les ensembles de filtres de requ<71>tes peuvent brancher
vers un backend.
-----------+--------+----------+----------+---------+----------+
\ Where | | | | | |
\______ | Listen | Frontend | ReqRules | Backend | RspRules |
\| | | | | |
Capability | | | | | |
-----------+--------+----------+----------+---------+----------+
Frontend | X | X | | | |
-----------+--------+----------+----------+---------+----------+
FiltReqIn | X | X | X | X | |
-----------+--------+----------+----------+---------+----------+
JumpFiltReq| X | X | X | | | \
-----------+--------+----------+----------+---------+----------+ > = ReqJump
SetBackend | X | X | X | | | /
-----------+--------+----------+----------+---------+----------+
FiltReqOut | | | | X | |
-----------+--------+----------+----------+---------+----------+
FiltRspIn | X | | | X | X |
-----------+--------+----------+----------+---------+----------+
JumpFiltRsp| | | | X | X |
-----------+--------+----------+----------+---------+----------+
FiltRspOut | | X | | X | X |
-----------+--------+----------+----------+---------+----------+
Backend | X | | | X | |
-----------+--------+----------+----------+---------+----------+
En conclusion
-------------
Il y a au moins besoin de distinguer 8 fonctionnalit<69>s de base :
- capacit<69> <20> recevoir des connexions (frontend)
- capacit<69> <20> filtrer les requ<71>tes entrantes
- capacit<69> <20> brancher vers un backend ou un ensemble de r<>gles de requ<71>tes
- capacit<69> <20> filtrer les requ<71>tes sortantes
- capacit<69> <20> filtrer les r<>ponses entrantes
- capacit<69> <20> brancher vers un autre ensemble de r<>gles de r<>ponses
- capacit<69> <20> filtrer la r<>ponse sortante
- capacit<69> <20> g<>rer des serveurs (backend)
Remarque
--------
- on a souvent besoin de pouvoir appliquer un petit traitement sur un ensemble
host/uri/autre. Le petit traitement peut consister en quelques filtres ainsi
qu'une r<><72>criture du couple (host,uri).
Proposition : ACL
Syntaxe :
---------
acl <name> <what> <operator> <value> ...
Ceci cr<63>era une acl r<>f<EFBFBD>renc<6E>e sous le nom <name> qui sera valid<69>e si
l'application d'au moins une des valeurs <value> avec l'op<6F>rateur <operator>
sur le sujet <what> est valid<69>e.
Op<EFBFBD>rateurs :
------------
Toujours 2 caract<63>res :
[=!][~=*^%/.]
Premier caract<63>re :
'=' : OK si test valide
'!' : OK si test <20>chou<6F>.
Second caract<63>re :
'~' : compare avec une regex
'=' : compare cha<68>ne <20> cha<68>ne
'*' : compare la fin de la cha<68>ne (ex: =* ".mydomain.com")
'^' : compare le d<>but de la cha<68>ne (ex: =^ "/images/")
'%' : recherche une sous-cha<68>ne
'/' : compare avec un mot entier en acceptant le '/' comme d<>limiteur
'.' : compare avec un mot entier en acceptant el '.' comme d<>limiteur
Ensuite on ex<65>cute une action de mani<6E>re conditionnelle si l'ensemble des ACLs
mentionn<EFBFBD>es sont valid<69>es (ou invalid<69>es pour celles pr<70>c<EFBFBD>d<EFBFBD>es d'un "!") :
<what> <where> <action> on [!]<aclname> ...
Exemple :
---------
acl www_pub host =. www www01 dev preprod
acl imghost host =. images
acl imgdir uri =/ img
acl imagedir uri =/ images
acl msie h(user-agent) =% "MSIE"
set_host "images" on www_pub imgdir
remap_uri "/img" "/" on www_pub imgdir
remap_uri "/images" "/" on www_pub imagedir
setbe images on imghost
reqdel "Cookie" on all
Actions possibles :
req {in|out} {append|delete|rem|add|set|rep|mapuri|rewrite|reqline|deny|allow|setbe|tarpit}
resp {in|out} {append|delete|rem|add|set|rep|maploc|rewrite|stsline|deny|allow}
req in append <line>
req in delete <line_regex>
req in rem <header>
req in add <header> <new_value>
req in set <header> <new_value>
req in rep <header> <old_value> <new_value>
req in mapuri <old_uri_prefix> <new_uri_prefix>
req in rewrite <old_uri_regex> <new_uri>
req in reqline <old_req_regex> <new_req>
req in deny
req in allow
req in tarpit
req in setbe <backend>
resp out maploc <old_location_prefix> <new_loc_prefix>
resp out stsline <old_sts_regex> <new_sts_regex>
Les cha<68>nes doivent <20>tre d<>limit<69>es par un m<>me caract<63>re au d<>but et <20> la fin,
qui doit <20>tre <20>chapp<70> s'il est pr<70>sent dans la cha<68>ne. Tout ce qui se trouve
entre le caract<63>re de fin et les premiers espace est consid<69>r<EFBFBD> comme des
options pass<73>es au traitement. Par exemple :
req in rep host /www/i /www/
req in rep connection /keep-alive/i "close"
Il serait pratique de pouvoir effectuer un remap en m<>me temps qu'un setbe.
Captures: les s<>parer en in/out. Les rendre conditionnelles ?