Apache mod_rewrite manipulate captured variable - apache

I want to translate the following URL:
http://my.domain.net/locations
to
http://my.domain.net/location_list.php
My current rewrite rule looks like this:
RewriteRule ^(locations)$ /$1_list.php
But that mean that my file must be named locations_list.php. So ideally I would like to remove the 's' from my variable $1, is this possible? I'm having problems finding any examples.

Just remove the s:
RewriteRule ^(location)$ /$1_list.php
or make it optional
RewriteRule ^(locations?)$ /$1_list.php
or make it so it's not captured
RewriteRule ^(location)s$ /$1_list.php

Related

Apache Mod_Rewrite Question Mark

I need to redirect an incoming request with the following URL:
http://mywebsite.com/abc/mapserv.exe?map=123
to
http://mywebsite.com/abc/mapserv.exe?map=C:\Mapserver\ms4w\Apache\htdocs\Mapfiles\123.map
I already managed to do simple mod_rewrites but the question mark is killing this one all the time. I am not able to adapt common Query String examples to my case so I need help with this exact case.
As though you did not show your try, you could test this:
RewriteEngine On
RewriteCond %{QUERY_STRING} map=([0-9]+)$
RewriteRule . %{REQUEST_URI}?map=C:\\Mapserver\\ms4w\\Apache\\htdocs\\Mapfiles\\%1.map [NE,L]
Rewrite flags used:
NE: Not Escape,
L: Last instruction to run.
I was still having trouble with the .exe url since it is not accessible if you dont deliver the parameters right when you send the request. And then the redirect wont fire. So I made a dummy mapserver.php file which allows setting a parameter like so:
http://mywebsite.com/abc/mapserver.php?map=123
After hours of trying I ended up with the following RewriteRule:
RewriteCond %{QUERY_STRING} ^map=(.*)$
RewriteRule ^mapserver.php?$ /cgi-bin/mapserv.exe?map=C://Mapserver//ms4w//Apache//htdocs//Mapfiles//%1.map

How to allow special characters in Rewrite_Map?

Here is the config I am using
RewriteEngine on
RewriteMap shortlinks txt:/var/www/html/s.overhash.net/public_html/shortlinks.txt
RewriteRule ^/(.+)$ ${shortlinks:$1} [R=temp,L]
My txt document looks something like this:
9H40o https://osyrisrblx.github.io/playground/#code/HYUw7gBAggTjCGBPAPMArgWwEYhgPgAoBKAOhhABM0BjEAggB3IDcAaCatOEYAFyIC8eJiGYBqAZ258iQA
However, upon going to my site (http://s.overhash.net/9H40o), it replaces the # with %23, making the URL this:
https://osyrisrblx.github.io/playground/%23code/HYUw7gBAggTjCGBPAPMArgWwEYhgPgAoBKAOhhABM0BjEAggB3IDcAaCatOEYAFyIC8eJiGYBqAZ258iQA
(which isn't valid)
How would I go about ensuring the # remains?
It's not a rewrite map issue, it's the way rewrite rules work.
By default, special chars will be escaped.
Use the NE flag in your rewriterule if you don't want that to happen:
RewriteRule ^/(.+)$ ${shortlinks:$1} [NE,R=temp,L]
More details on https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_ne

mod_rewrite regex to match root level whole name page

I'm want to rewrite many pages following the simple schema:
old_page.php to content/new-page.php
I got a problem when apple.php must be rewritten to fruits/red-apple.php because I get into a rewriting loop, so i have to match domain/apple.php
I'm not sure if I can set up RewriteRule or I'll also need rewriteCond ..
You should show us what you're working with, but it sounds like your patterns are simply missing start and end of string anchors. E.g.:
RewriteBase /
RewriteRule ^apple\.php$ fruits/red-apple.php [NS,L]
You may be better off using RewriteMap if you have a lot of rules.

Apache mod rewrite .htaccess to get params

How can i catch the prams after file name with extension like service.php/view1
for ex:
service.php/newview1
I want to get it like
service.php?view=newview1
how do i write mod-rewrite for this
I tried like
RewriteRule ^services.php/?([a-zA-Z_]+)$ /services.php?category=$1
its not matching the service.php/newview1
When the replacement URI contains a query string, the default behavior
of RewriteRule is to discard the existing query string, and replace it
with the newly generated one. Using the [QSA] flag causes the query
strings to be combined.
You need to add [QSA] flag to end of your current line
Try adding this regex:
([a-zA-Z0-9-_]+) as this also matches any integers and hyphens also.
RewriteRule ^services.php/?([a-zA-Z0-9-_]+)$ /services.php?category=$1 [QSA,L]
I also put the [L] flag so it stop processing further rules.

Apache RewriteRule with RewriteMap

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?
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
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]
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]