mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-15 16:04:37 +00:00
263 lines
9.3 KiB
Plaintext
263 lines
9.3 KiB
Plaintext
Prévoir des commandes en plusieurs mots clés.
|
|
Par exemple :
|
|
|
|
timeout connection XXX
|
|
connection scale XXX
|
|
|
|
On doit aussi accepter les préfixes :
|
|
|
|
tim co XXX
|
|
co sca XXX
|
|
|
|
Pré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-ê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évoir le cas du "if" pour exé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-être que le "switch" peut prendre un paramètre de mapping pour la partie matchée :
|
|
|
|
req in switch URI =^ "/images/" images:"/"
|
|
|
|
|
|
2007/03/31 - Besoins plus précis.
|
|
|
|
1) aucune extension de branchement ou autre dans les "listen", c'est trop complexe.
|
|
|
|
Distinguer les données entrantes (in) et sortantes (out).
|
|
|
|
Le frontend ne voit que les requetes entrantes et les réponses sortantes.
|
|
Le backend voir les requêtes in/out et les réponses in/out.
|
|
Le frontend permet les branchements d'ensembles de filtres de requêtes vers
|
|
d'autres. Le frontend et les ensembles de filtres de requê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és de base :
|
|
- capacité à recevoir des connexions (frontend)
|
|
- capacité à filtrer les requêtes entrantes
|
|
- capacité à brancher vers un backend ou un ensemble de règles de requêtes
|
|
- capacité à filtrer les requêtes sortantes
|
|
- capacité à filtrer les réponses entrantes
|
|
- capacité à brancher vers un autre ensemble de règles de réponses
|
|
- capacité à filtrer la réponse sortante
|
|
- capacité à 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éécriture du couple (host,uri).
|
|
|
|
|
|
Proposition : ACL
|
|
|
|
Syntaxe :
|
|
---------
|
|
|
|
acl <name> <what> <operator> <value> ...
|
|
|
|
Ceci créera une acl référencée sous le nom <name> qui sera validée si
|
|
l'application d'au moins une des valeurs <value> avec l'opérateur <operator>
|
|
sur le sujet <what> est validée.
|
|
|
|
Opérateurs :
|
|
------------
|
|
|
|
Toujours 2 caractères :
|
|
|
|
[=!][~=*^%/.]
|
|
|
|
Premier caractère :
|
|
'=' : OK si test valide
|
|
'!' : OK si test échoué.
|
|
|
|
Second caractère :
|
|
'~' : compare avec une regex
|
|
'=' : compare chaîne à chaîne
|
|
'*' : compare la fin de la chaîne (ex: =* ".mydomain.com")
|
|
'^' : compare le début de la chaîne (ex: =^ "/images/")
|
|
'%' : recherche une sous-chaî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écute une action de manière conditionnelle si l'ensemble des ACLs
|
|
mentionnées sont validées (ou invalidées pour celles précédé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înes doivent être délimitées par un même caractère au début et à la fin,
|
|
qui doit être échappé s'il est présent dans la chaîne. Tout ce qui se trouve
|
|
entre le caractère de fin et les premiers espace est considéré comme des
|
|
options passé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 ?
|