htaccess 规则仅对某些捕获组进行编码

htaccess 规则仅对某些捕获组进行编码

我目前的规则是

RewriteRule ^data/(v[0-9]\.[0-9]\.?[0-9]?)/.*$ http://35.231.131.100:5000/cocoon_$1?subject=https://w3id.org/cocoon/$0 [L,NE,QSA,R=308]

它将转换

https://w3id.org/cocoon/data/v1.0.1/2019-03-07/CloudStorageTransactionsPriceSpecification/Azure/managed_disk/transactions-ssd

http://35.231.131.100:5000/cocoon_v1.0.1?subject=https://w3id.org/cocoon/data/v1.0.1/2019-03-07/CloudStorageTransactionsPriceSpecification/Azure/managed_disk/transactions-ssd

但对于另一个示例原始 URL

https://w3id.org/cocoon/data/v1.0.1/Measurement/DownlinkSpeed-1-128-KB/StorageService/Gcloud/150.203.213.249/lat=-35.271475/long=149.121434/2019-02-26T07%3A14%3A19.932Z/australia-southeast1

我需要对查询字符串进行编码subject=,即

http://35.231.131.100:5000/cocoon_v1.0.1?subject=https%3A%2F%2Fw3id.org%2Fcocoon%2Fdata%2Fv1.0.1%2FMeasurement%2FDownlinkSpeed-1-128-KB%2FStorageService%2FGcloud%2F150.203.213.249%2Flat%3D-35.271475%2Flong%3D149.121434%2F2019-02-26T07%253A14%253A19.932Z%2Faustralia-southeast1

我目前正在使用NE标志,以避免转义$1,即v1.0.1

我该如何对该https://w3id.org/cocoon/$0部分进行编码?

:这一切背后的一些原因: URL 中的日期时间部分导致页面停止工作,单独对其进行编码%3A不起作用,因此我对整个subject=部分进行了编码。


编辑

建议的规则怀特先生,不太管用。

RewriteCond %{THE_REQUEST} [a-z]{3,5}\s.*?/(data/(v[0-9]\.[0-9]\.?[0-9]?)/.*)\s [NC]
RewriteRule ^data/(v[0-9]\.[0-9]\.?[0-9]?)/.* http://35.231.131.100:5000/cocoon_$1?subject=https\%3A\%2F\%2Fw3id.org\%2Fcocoon\%2F%1 [L,NE,QSA,R=308]

我测试过

curl http://localhost/cocoon/data/v1.0.1/Measurement/DownlinkSpeed-1-128Gcloud/150.203.213.249/lat=-35.271475/long=149.121434/2019-02-26T07%3A14%3A19.932Z/australia-southeast1

它会重定向到 http://35.231.131.100:5000/cocoon_v1.0.1?subject=https%3A%2F%2Fw3id.org%2Fcocoon%2Fdata/v1.0.1/Measurement/DownlinkSpeed-1-128-KB/StorageService/Gcloud/150.203.213.249/lat=-35.271475/long=149.121434/2019-02-26T07%3A14%3A19.932Z/australia-southeast1

我的 Linked Data Fragments 服务器无法识别此内容。未/编码。我认为subject不采用部分编码字符串。:必须对它进行编码,因此整个主题字符串必须采用编码选项。

对于B标志,我用 进行了测试B=/,似乎所有内容都被编码了两次?.%252e/%252f

谢谢你指出我无意中加的尾点,我其实想要v[0-9]\.[0-9](?:\.[0-9])?

我也尝试了N标志,但无法正确显示。它变成了无限循环。

RewriteRule ^data/(v[0-9]\.[0-9]\.?[0-9]?)/([^/]+)/(.*) data/$1/$2\%2F$3 [N=20]
RewriteRule ^data/(v[0-9]\.[0-9]\.?[0-9]?)/.* http://35.231.131.100:5000/cocoon_$1?subject=https\%3A\%2F\%2Fw3id.org\%2Fcocoon\%2Fdata\%2F$1\%2F$3[L,NE,QSA,R=308]

我想[^/]+匹配任何非 / 的内容,因此我可以将版本号后的所有斜线替换为编码值,并添加\以转义%2F

答案1

您可以使用该B标志来转义反向引用。但是,默认情况下,这也会转义反向引用v1.0.1中的点$1,除非您在标志本身中明确说明应转义的字符B,例如B=:(需要 Apache 2.4.26+)。

或者,如果实际问题“是:URL 的日期时间部分”,并且这已经在请求的 URL 中正确编码(如在您的示例中所示),那么您可以从THE_REQUEST服务器变量中获取已编码的 URL 部分,而不是与 URL 路径匹配的 URL 部分RewriteRule 图案. 使用获取 URL 部分时出现的“问题”RewriteRule 图案是这已经被 URL 解码了(因此才使用B如上所述的标志)。

你可以手动如果您希望对其进行编码,请对查询字符串的第一个(常量)部分进行编码(即https://w3id.org/cocoon/) 。https%3A%2F%2Fw3id.org%2Fcocoon%2F

请尝试以下操作:

RewriteCond %{THE_REQUEST} [a-z]{3,5}\s.*?/(data/(v[0-9]\.[0-9]\.?[0-9]?)/.*)\s [NC]
RewriteRule ^data/(v[0-9]\.[0-9]\.?[0-9]?)/.* http://35.231.131.100:5000/cocoon_$1?subject=https\%3A\%2F\%2Fw3id.org\%2Fcocoon\%2F%1 [L,NE,QSA,R=308]

补充笔记:

  • %% 编码字符的文字代换字符串经过反斜杠转义,以免被视为对前一个字符串的(无效)反向引用条件模式(否则它们将被视为反向引用没有什么)。

  • 确保在测试之前已清除浏览器缓存,并在将其更改为永久重定向之前使用临时(302 或 307)重定向进行测试。


在旁边:获取版本号的正则表达式允许在第二个(“次要”)数字后面有一个尾随点,例如v1.0.- 这是故意的吗?

相关内容