我正在尝试通过在POSTpath的节点上强制进行URL编码来纠正URL参数问题,这种情况经常发生。 在这个时候,最好是在代理层修复这个问题,直到开发出更好的解决scheme。但是Haproxy给了我这个问题,我还要提一下,我现在被Haproxy v1.5所困住了(从我可以告诉,也离开使用Lua列表的选项..引入v1.6?)。
这是一个例子是这样的..
我通常以这种forms得到POST请求
http(s)://sub.domain.com/context/{context}/staticPath/location/{location}/material/{material}
所以,在实践中可能看起来更像这样。
http://sub.domain.com/context/smith/staticePath/location/columbus/material/abc/123
从另一端需要以下
http://sub.domain.com/context/smith/staticePath/location/columbus/material/abc%2F123
问题是,abc / 123是一个单一的材料,需要看起来更像“abc%2F123”,其中“/”斜线正在改变实际的path。
我试图在代理中捕捉到这一点,我可以得到正则expression式来捕获我所需要的,但似乎每当我尝试在捕获组中有一个“斜杠”/ /和/或试图把斜杠放回到取代部分它打破了重写。
下面是我尝试过的一些例子,同时请记住,我打算扩大抓取以抓取整个url,但正在简化尝试解决这些问题,同时我也试图从这个记忆中讲述一些故事点,所以请原谅,如果下面没有死..我尝试了许多,很多组合试图想出一个可行的战略。
通过这种方式..
reqrep (\w+\s?)\/(material)\/(\w+\s?)\/(.*) \1\2\3%2f\4
我可以让捕获组再次将URL重新组合起来,但path节点之间没有path定界符(“/”)。
像这样,它不会取代,它只会发送原始path。
reqrep (\w+\s?)\/(material)\/(\w+\s?)\/(.*) \1\/\2\/\3%2f\4
采取这样的策略…
reqrep (\w+\s?)(\/)(material)(\/)(\w+\s?)\/(.*) \1\2\3\4\5%2f\6
我尝试的另一个策略是在捕获组中保留“/”,以便它们可以在replace中出现,而不在捕获组中留下不需要的“斜线”,如下所示。
reqrep (\w+\s?)(\/material\/)(\w+\s?)\/(.*) \1\2\3%2f\4
我也读了一下,看到一些正则expression式有空格,replace有一些间距的例子。我可以通过在replace中使用一些间距来closures,但是在最终的结果中留下不希望的空格。
也..
如果我逃脱一个空间,然后加一个斜线,似乎更接近..前。 \1\ /\2但是,我会得到像(例如) location /material..东西,像上面提到的添加空间。
我注意到的模式是,当我试图在正则expression式中添加斜杠到捕获组时,它会弄乱replace,使我猜测像..这样的事情是否由于它们在捕获组中而不能逃脱? 而且,为什么我不能把它们放回文字replace? 这是我想象我可能已经偶然发现了一个错误的地步..但也意识到我可以搞砸了。 使用Nginx开发了一个解决scheme,但是如果能够让Haproxy做到这一点,在我们需要的前面站立一个实例也不是最实际的,主要是因为我们已经使用Haproxy来做相当多的其他东西已经。
我真的更喜欢用另一种方式来解决这个问题,但是现在使用代理似乎是我最好的select之一。 我也没有奢望强迫发起人给予更好的path。
我在评论中提出的这个build议看起来几乎是正确的:
reqrep ^([^\ :]+)(\ ?/.+/material/)(.+)/(.+)(\ .+)$ \1\2\3\4%2f\5
实际上我把%2f放在%2f的错误的一边。 我也错误地在第二个捕获组的开始的空间可选,这不会打破正则expression式,但在技术上是不正确的。
这是正确的forms:
reqrep ^([^\ :]+)(\ /.+/material/)(.+)/(.+)(\ .+)$ \1\2\3%2f\4\5
这就是reqrep的问题 – 直接调整HTTP请求的第一行。 强大,但乏味。
打破这个:
总是把你的模式锚定到行首。
([^\ :]+)这是HTTP动词( GET , POST等)。 它不得包含空格,不能冒号。 这是捕获组1。
(\ /.+/material/)动词后面必须跟一个空格,前面的斜杠(正斜杠不需要HAProxy正则expression式中的反斜杠转义),一个或多个字符,然后/ material / …这是捕获第2组
(.+)我们想要在/被分割的第一部分是捕获组3,实际上,这将被更准确地写入([^/]+)尽pipe大多数潜在的不匹配都会被我们需要的空间阻止在下面的组5中。
/我们想要消除的斜线
(.+) /是捕获组4后的URL部分
(\ .+)一个空格,后跟一个或多个字符,它将在请求行的末尾捕获HTTP/1.x作为捕获组5。
$锚定到行的末尾。
然后把他们都放回去。
\1\2\3%2f\4\5
HAProxy 1.6通过内置的Lua解释器以及一个名为regsub()的转换器(虽然它非常简单,只是replace,没有捕获组,但对于分割string很好)以及用户定义的variables您可以在处理请求时“隐藏”小块数据块。 它也允许你使用http-request set-path并且有一个path读取和写入path与URL的其余部分隔离,而不用直接用正则expression式调整HTTP请求缓冲区。 大部分或全部这些东西都不在1.5。