web-dev-qa-db-fra.com

Route et réécriture haproxy en fonction du chemin URI

J'essaie de configurer un Haproxy pour charger les demandes d'équilibrage sur quelques backends identifiés par le chemin uri. Par exemple:

https://www.example.com/v1/catalog/foo/bar

Devrait conduire aux backends "catalog-v1".

La chose est que chaque application répond sur un chemin différent, donc je dois non seulement identifier l'application mais réécrire le chemin URL. Par exemple.

À

Je sais que je ne devrais pas utiliser Haproxy à des fins de réécriture mais pour l'instant c'est inévitable.

J'ai essayé la regex suivante qui fonctionnait sur regex101:

([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*)

Substitution:

\1/\3-\2/\4

Et enfin, voici le haproxy.config:

global
    daemon
    user root
    group root
    maxconn 256000
    log     127.0.0.1 local0
    log     127.0.0.1 local1 notice
    stats   socket /run/haproxy/stats.sock mode 777 level admin
defaults
    log      global
    option   dontlognull
    maxconn  4000
    retries  3
    timeout  connect 5s
    timeout  client  1m
    timeout  server  1m
    option   redispatch
    balance  roundrobin

listen stats :8088
    mode http
    stats enable
    stats uri /haproxy
    stats refresh 5s

backend catalog-v1
    mode http
    option httpchk GET /catalog-v1/ping
    http-check expect status 200
    reqrep ([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*)   \1/\3-\2/\4
    server 127.0.0.1:8280_catalog-v1-node01 127.0.0.1:8280 check inter 2s rise 3 fall 2

backend checkout-v1
    mode http
    option httpchk GET /checkout-v1/ping
    http-check expect status 200
    reqrep ([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*)   \1/\3-\2/\4
    server 127.0.0.1:8180_checkout-v1-node01 127.0.0.1:8180 check inter 2s rise 3 fall 2

frontend shared-frontend
    mode http
    bind localhost:80
    acl is-catalog-v1-path path_dir /v1/catalog
    acl is-checkout-v1-path path_dir /v1/checkout
    use_backend catalog-v1 if is-catalog-v1-path
    use_backend checkout-v1 if is-checkout-v1-path

Suis-je en train de manquer quelque chose?

Je lutte avec cela depuis un certain temps sans succès. Le back-end affiche "UP" dans la page de statistiques Haproxy mais à chaque fois que j'appelle l '"URL non réécrite", j'obtiens une erreur 400 Bad Request.

Merci d'avance pour votre aide!

13
leovrf

Si je vous comprends bien, remplacez l'exemple ci-dessous:

reqrep ^([^\ ]\*)\ /([-.0-9A-Za-z]\*)/([a-zA-Z]\*)/(.\*)  \1\ /\3-\2/\4

http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#reqrep

reqrep search string [{if | unless} cond]

Vous n'avez pas d'espace.

11
Rhim

La réponse ci-dessus est une solution unique qui n'explique pas la racine du problème. Le problème est que beaucoup supposent que nous analysons une URL complète ou uniquement le composant PATH, alors que nous analysons/réécrivons réellement les en-têtes HTTP.

Par exemple:

curl -iv https://stackoverflow.com/questions/24784517/haproxy-route-and-rewrite-based-on-uri-path
*   Trying 151.101.65.69...
> GET /questions/24784517/haproxy-route-and-rewrite-based-on-uri-path HTTP/1.1
> Host: stackoverflow.com
> User-Agent: curl/7.54.0
> Accept: */*

Le but est de réécrire GET /some_path HTTP/1.1 En GET /some_other_path HTTP/1.1

Je tiens à préciser que la solution ci-dessus fonctionne car elle prend en compte le verbe HTTP dans la correspondance et remplace. ^([^\ ]\*)\ (.*) pour capturer le verbe et l'utiliser dans le modèle de remplacement. \1 \2

6
Arron S