Apache RewriteRule with RewriteMap

帅比萌擦擦* 提交于 2019-12-10 22:19:15

问题


I've got a RewriteMap that looks like this:

Guide           1
Mini-Guide      2
White Paper     3

and I'm including it into Apache via

RewriteMap legacy txt:/var/www/site/var/rewrite_map.txt

I want to create a RewriteRule that will allow only values from the left side of said RewriteMap to be in this position;

RewriteRule ^/section/downloads/(${legacy})/(.*)$ /blah.php?subsection=${legacy:%1}&title=$2

I know I can use ${legacy} on the right side, but can I use it on the left, and if so, how?


回答1:


In your map file, the left side is the key and the right side is the value. When you create a rule for matching against a map, you input the key and it outputs the value.

Change your RewriteRule to this:

# Put these on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
            /blah.php?subsection=${legacy:$1}&title=$2

The first grouping captures the string in the incoming URL. The $1 in the replacement applies it to the named map. To make a default value, change ${legacy:$1} to ${legacy:$1|Unknown}.

Finally, if you only want the rule to work on values that are in the map file, add a RewriteCond:

RewriteCond ${legacy:$1|Unknown} !Unknown
# Put these on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
            /blah.php?subsection=${legacy:$1}&title=$2

The condition says if the map does not return the default value (Unknown), then run the next rule. Otherwise, skip the rule and move on.

Apache RewriteMap




回答2:


another variant:

# %1 will be the subpattern number1 afterwards
RewriteCond %{REQUEST_URI} ^/section/downloads/(.*)
# check if there is no mapping for %1
RewriteCond ${legacy:%1} !^$
# if there is rewrite it
RewriteRule ^/(.*) /blah.php?subsection=${legacy:%1}&title=$2 [R]



回答3:


You said, you want to only allow values found in the map. This isn't possible unless you specify an additional restriction in regex for the capture group. There's no way to do it with the map itself. There's no "map.keys" syntax, as far as I know, that you can apply in the left hand side, the pattern.

BUT,
You can specify a default value if the captured value is not found. This way:

## all on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
        /blah.php?subsection=${legacy:$1|defaultValue}&title=$2

Replace "defaultValue" with whatever you like. For example 0 (zero), or "notfound", if the given arg is not found in the map.

You can then either rewrite the result of that, with another rule, or just allow it to flow through and provide a "404" message at the URL with the default value.

If you choose to use another rule, then it would look like this:

## all on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
        /blah.php?subsection=${legacy:$1|notFoundMarker}&title=$2

## This rule fires if the lookupKey was not found in the map in the prior rule.
RewriteRule ^/blah.php?subsection=notFoundMarker  /404.php   [L]


来源:https://stackoverflow.com/questions/1909438/apache-rewriterule-with-rewritemap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!