| 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 ? |