Prvoir des commandes en plusieurs mots cls.
Par exemple :

  timeout connection XXX
  connection scale XXX

On doit aussi accepter les prfixes :

  tim co XXX
  co sca XXX

Prvoir de ranger les combinaisons dans un tableau. On doit mme
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"

Prvoir le cas du "if" pour excuter 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 paramtre de mapping pour la partie matche :

        req in  switch   URI     =^ "/images/" images:"/"


2007/03/31 - Besoins plus prcis.

1) aucune extension de branchement ou autre dans les "listen", c'est trop complexe.

Distinguer les donnes entrantes (in) et sortantes (out).

Le frontend ne voit que les requetes entrantes et les rponses sortantes.
Le backend voir les requtes in/out et les rponses in/out.
Le frontend permet les branchements d'ensembles de filtres de requtes vers
d'autres. Le frontend et les ensembles de filtres de requtes 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 fonctionnalits de base :
 - capacit  recevoir des connexions (frontend)
 - capacit  filtrer les requtes entrantes
 - capacit  brancher vers un backend ou un ensemble de rgles de requtes
 - capacit  filtrer les requtes sortantes
 - capacit  filtrer les rponses entrantes
 - capacit  brancher vers un autre ensemble de rgles de rponses
 - capacit  filtrer la rponse sortante
 - capacit  grer 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 rcriture du couple (host,uri).


Proposition : ACL

Syntaxe :
---------

   acl <name> <what> <operator> <value> ...

Ceci crera une acl rfrence sous le nom <name> qui sera valide si
l'application d'au moins une des valeurs <value> avec l'oprateur <operator>
sur le sujet <what> est valide.

Oprateurs :
------------

Toujours 2 caractres :

  [=!][~=*^%/.]

Premier caractre :  
   '=' : OK si test valide
   '!' : OK si test chou.

Second caractre :
   '~' : compare avec une regex
   '=' : compare chane  chane
   '*' : compare la fin de la chane (ex: =* ".mydomain.com")
   '^' : compare le dbut de la chane (ex: =^ "/images/")
   '%' : recherche une sous-chane
   '/' : compare avec un mot entier en acceptant le '/' comme dlimiteur
   '.' : compare avec un mot entier en acceptant el '.' comme dlimiteur

Ensuite on excute une action de manire conditionnelle si l'ensemble des ACLs
mentionnes sont valides (ou invalides pour celles prcdes 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 chanes doivent tre dlimites par un mme caractre au dbut et  la fin,
qui doit tre chapp s'il est prsent dans la chane. Tout ce qui se trouve
entre le caractre de fin et les premiers espace est considr comme des
options passes 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 mme temps qu'un setbe.

Captures: les sparer en in/out. Les rendre conditionnelles ?
