HTTP Location Header Rewrite - 将逻辑从 IIS 代理移动到 IBM datapower
HTTP Location Header Rewrite - moving logic from IIS proxy to IBM datapower
我们正在将 Location Header Rewrite 逻辑从 IIS 反向代理移动到 IBM dataPower XI52。我知道我们在 DP 上有 header 重写功能,但我无法理解我们如何在 DP 上实现以下场景,你能拜托吗引导我?我可以知道R:1、R:2 和R:3 在这里指的是什么吗?
IIS 反向代理上的 Location HeaderRewrite 传出规则:
<rule name="Change Location Header" enabled="true">
<match serverVariable="RESPONSE_LOCATION" pattern="^http(s)?://([^/]+)/(.*)" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="true">
<add input="{RESPONSE_STATUS}" pattern="^301" />
<add input="{RESPONSE_STATUS}" pattern="^302" />
</conditions>
<action type="Rewrite" value="http{R:1}://{R:2}/{R:3}" />
</rule>
我可以知道我们如何在 DP 上实现相同的功能吗?
我尝试使用下面的 xslt,但得到空的 LocationHeader_output 值,我这里做错了吗?
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:re="http://exslt.org/regular-expressions"
extension-element-prefixes="dp re"
exclude-result-prefixes="dp">
<xsl:template match="*">
<xsl:choose>
<xsl:when test="dp:responding()">
<xsl:variable name="code">
<xsl:choose>
<xsl:when test="dp:http-response-header('x-dp-response-code') != ''">
<xsl:value-of select="substring(dp:http-response-header('x-dp-response-code'), 1, 3)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring(dp:variable('var://service/error-headers'), 10, 3)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$code = '301' or $code = '302'">
<xsl:variable name="location" select="dp:http-response-header('Location')"/>
<xsl:variable name="location_final">
<xsl:value-of select="re:replace($location, '^http(s)?://([^/]+)/(.*)', 'g', 'http{}://{}/{}')" />
</xsl:variable>
<dp:set-http-response-header name="'Location'" value="$location_final" />
</xsl:if>
<!-- the following prevent DataPower from overriding the response code coming back from Server-->
<dp:set-response-header name="'x-dp-response-code'" value="'-1'"/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
它在 IBM DataPower 中使用以下 xslt 时有效
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:re="http://exslt.org/regular-expressions"
extension-element-prefixes="dp re"
exclude-result-prefixes="dp">
<xsl:template match="/">
<xsl:variable name="code">
<xsl:choose>
<xsl:when test="dp:http-response-header('x-dp-response-code') != ''">
<xsl:value-of select="substring(dp:http-response-header('x-dp-response-code'), 1, 3)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring(dp:variable('var://service/error-headers'), 10, 3)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:message dp:priority="info">
HTTP response Code:<xsl:value-of select="$code"/>
</xsl:message>
<xsl:if test="$code = '301' or $code = '302'">
<xsl:variable name="location" select="dp:http-response-header('Location')"/>
<xsl:variable name="location_final">
<xsl:value-of select="re:replace($location, '^http(s)?://([^/]+)/(.*)', 'g', 'http:///')" />
</xsl:variable>
<dp:set-http-response-header name="'Location'" value="$location_final" />
<xsl:message dp:priority="info">
Response Location_beforeModify:<xsl:value-of select="$location"/>
Response Location_AfterModify:<xsl:value-of select="$location_final"/>
<!-- Response test Regex:<xsl:value-of select="re:replace('https://demo.cloudimg.io/s/width/300/sample.li/boat.jpg', '^http(s)?://([^/]+)/(.*)', 'g', 'http:///')" /> -->
</xsl:message>
</xsl:if>
<!-- the following prevent DataPower from overriding the response code coming back from Server-->
<dp:set-response-header name="'x-dp-response-code'" value="'-1'"/>
</xsl:template>
以下代码片段对我来说效果很好。
<xsl:variable name="locationHeader" select="dp:http-response-header('Location')"/>
<xsl:if test="starts-with($locationHeader, 'http://') or starts-with($locationHeader, 'https://')">
<xsl:choose>
<xsl:when test="starts-with(dp:variable('var://service/URL-in'), 'https')">
<dp:set-http-response-header name="'Location'" value="concat('https://', dp:variable('var://service/local-service-address'), '/', substring-after(substring-after($locationHeader, '://'), '/'))"/>
</xsl:when>
<xsl:when test="starts-with(dp:variable('var://service/URL-in'), 'http')">
<dp:set-http-response-header name="'Location'" value="concat('http://', dp:variable('var://service/local-service-address'), '/', substring-after(substring-after($locationHeader, '://'), '/'))"/>
</xsl:when>
</xsl:choose>
</xsl:if>
我们正在将 Location Header Rewrite 逻辑从 IIS 反向代理移动到 IBM dataPower XI52。我知道我们在 DP 上有 header 重写功能,但我无法理解我们如何在 DP 上实现以下场景,你能拜托吗引导我?我可以知道R:1、R:2 和R:3 在这里指的是什么吗? IIS 反向代理上的 Location HeaderRewrite 传出规则:
<rule name="Change Location Header" enabled="true">
<match serverVariable="RESPONSE_LOCATION" pattern="^http(s)?://([^/]+)/(.*)" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="true">
<add input="{RESPONSE_STATUS}" pattern="^301" />
<add input="{RESPONSE_STATUS}" pattern="^302" />
</conditions>
<action type="Rewrite" value="http{R:1}://{R:2}/{R:3}" />
</rule>
我可以知道我们如何在 DP 上实现相同的功能吗?
我尝试使用下面的 xslt,但得到空的 LocationHeader_output 值,我这里做错了吗?
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:re="http://exslt.org/regular-expressions"
extension-element-prefixes="dp re"
exclude-result-prefixes="dp">
<xsl:template match="*">
<xsl:choose>
<xsl:when test="dp:responding()">
<xsl:variable name="code">
<xsl:choose>
<xsl:when test="dp:http-response-header('x-dp-response-code') != ''">
<xsl:value-of select="substring(dp:http-response-header('x-dp-response-code'), 1, 3)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring(dp:variable('var://service/error-headers'), 10, 3)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$code = '301' or $code = '302'">
<xsl:variable name="location" select="dp:http-response-header('Location')"/>
<xsl:variable name="location_final">
<xsl:value-of select="re:replace($location, '^http(s)?://([^/]+)/(.*)', 'g', 'http{}://{}/{}')" />
</xsl:variable>
<dp:set-http-response-header name="'Location'" value="$location_final" />
</xsl:if>
<!-- the following prevent DataPower from overriding the response code coming back from Server-->
<dp:set-response-header name="'x-dp-response-code'" value="'-1'"/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
它在 IBM DataPower 中使用以下 xslt 时有效
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:re="http://exslt.org/regular-expressions"
extension-element-prefixes="dp re"
exclude-result-prefixes="dp">
<xsl:template match="/">
<xsl:variable name="code">
<xsl:choose>
<xsl:when test="dp:http-response-header('x-dp-response-code') != ''">
<xsl:value-of select="substring(dp:http-response-header('x-dp-response-code'), 1, 3)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring(dp:variable('var://service/error-headers'), 10, 3)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:message dp:priority="info">
HTTP response Code:<xsl:value-of select="$code"/>
</xsl:message>
<xsl:if test="$code = '301' or $code = '302'">
<xsl:variable name="location" select="dp:http-response-header('Location')"/>
<xsl:variable name="location_final">
<xsl:value-of select="re:replace($location, '^http(s)?://([^/]+)/(.*)', 'g', 'http:///')" />
</xsl:variable>
<dp:set-http-response-header name="'Location'" value="$location_final" />
<xsl:message dp:priority="info">
Response Location_beforeModify:<xsl:value-of select="$location"/>
Response Location_AfterModify:<xsl:value-of select="$location_final"/>
<!-- Response test Regex:<xsl:value-of select="re:replace('https://demo.cloudimg.io/s/width/300/sample.li/boat.jpg', '^http(s)?://([^/]+)/(.*)', 'g', 'http:///')" /> -->
</xsl:message>
</xsl:if>
<!-- the following prevent DataPower from overriding the response code coming back from Server-->
<dp:set-response-header name="'x-dp-response-code'" value="'-1'"/>
</xsl:template>
以下代码片段对我来说效果很好。
<xsl:variable name="locationHeader" select="dp:http-response-header('Location')"/>
<xsl:if test="starts-with($locationHeader, 'http://') or starts-with($locationHeader, 'https://')">
<xsl:choose>
<xsl:when test="starts-with(dp:variable('var://service/URL-in'), 'https')">
<dp:set-http-response-header name="'Location'" value="concat('https://', dp:variable('var://service/local-service-address'), '/', substring-after(substring-after($locationHeader, '://'), '/'))"/>
</xsl:when>
<xsl:when test="starts-with(dp:variable('var://service/URL-in'), 'http')">
<dp:set-http-response-header name="'Location'" value="concat('http://', dp:variable('var://service/local-service-address'), '/', substring-after(substring-after($locationHeader, '://'), '/'))"/>
</xsl:when>
</xsl:choose>
</xsl:if>