我目前的规则是
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
我的 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.
- 这是故意的吗?