.htaccess RedirectMatch conditional regex fails - regex

Good evening dear fellow coders,
I am trying to handle urls without file extensions that are more readable to average internet users using a .htaccess redirect, like http://example.com/file to http://example.com/file.php (with or without query)
Unfortunately I am not able to use mod_rewrite, but although redirect does work, it seems not to be able to handle my request properly.
To handle any given URL I tried using
RedirectMatch ^/(?(?=.*\.php(?i).*)|(\w+)(.*)) /$1.php$2
And
RedirectMatch ^/.*\.php(?i).*|(\w+)(.*) /$1.php$2
As well as using $2 and $3, assuming the behaviour might extract the first pattern contrary to every knowledge.
It should extract characters and numbers for $1 and everything else for $2 (starting with ? for queries etc.) unless it contains the file extension .php.
Validating the regex with https://regex101.com/r/zF2bV9/2 everything should work fine, but implementing one of these lines to the .htaccess the filename will replace any given file with ".php" (as in http://example.com/.php) and obviously produce an error of a non-existing file.
What am I missing about the code or the redirect functionality?

You can try something like:
RedirectMatch ^/([^.]+)$ /$1.php
This matches the URL providing there is not already a dot (ie. .php) in the URL. And so prevents a redirect loop.
As mentioned in comments, you don't need to do anything specific with the query string, providing you want it passed through to the destination unaltered. The query string is not present in the URL-path that the RedirectMatch directive matches against anyway. So, any manipulation of the query string would require mod_rewrite.

Related

URLs rewrite - Removing unwanted characters and slashes

I need to rewrite URL's using .htaccess to redirect all users from old sitemap to the new URL's. The old URLs looks like this:
http://example.com/a/v/c/document_title1.php
http://example.com/fr/x/1/o/document_title2.php
http://example.com/de/a/a/2/document_title3.php
http://example.com/eng/6/z/z/document_title4.php
I need to keep first directory and then remove all sub-directories, including slashes and characters (letters and numbers between /) so the new URLs will look like this:
http://example.com/document_title1.php
http://example.com/fr/document_title1.php
http://example.com/de/document_title2.php
http://example.com/eng/document_title3.php
I tried various online generators and always got 500 error. Is this something I can do?
You can use this substitution
Pattern: (?<=http://example\.com/)(fr/|de/|eng/)?.*(?=document_title\d\.php)
Replace with: $1
This will almost definitely need to include some tweaks, but I'm working with what I was given. In this section (fr/|de/|eng/)? you'll need to add | for each possible language extension.

regex - Match # part of the url on the server

I'm trying to write a regex to match parts of urls and use a SEO redirection wordpress plugin to create a 301 redirect on the matching results.
if, for example, I write these URLs:
https://www.test.com/my-site
https://www.test.com/my-site/
I want to be redirect to:
https://www.test.com/your-site/
but if the urls are followed by an hash (#) like the one below:
https://www.test.com/my-site/#/..
Do not redirect.
I have played around for a bit with regExr and this is as far as I could get:
regexr.com/3scpb
But when try to implement it inside the plugin the redirect doesn't work.
What am i doing wrong here?
Is it better to do it straight inside the .htaccess file?
would it be better and more robust/reliable that way?
Thanks
The hash is never sent by the browser.
The hash is used internally by the browser to see which fragment of the document is focused on. This is called fragment identifier. This means your server will never see the # coming up. You cannot prevent this behavior.

htaccess - rewrite url with two rules

Okay, I am having a little trouble with .htaccess as I am a beginner with it. This is what I am trying to accomplish.
URL DESIRED: example.com/package/forest/
What I have now:
RewriteRule ^package/forest/$
/deep/file/do_stuff.php?action=package&location=forest [R=301,QSA,L]
This is working as intended, when you go to example.com/package/forest you get the page that is produced by do_stuff.php. The hard part that I can't get, is what if I want to send extra GET variables to the do_stuff page but keep the same URL.
STARTING URL: example.com/package/forest/list/5/2015-10-03
STILL DESIRED URL: example.com/package/forest
The difference being, I want the rewrite or redirect, not sure the term, to be
/deep/file/do_stuff.php?action=package&location=forest&pictures=5&date=2015-10-03
this time.
Not sure how to stack the rules so that I end up with the same URL whether they pass extra variables or not.
RewriteRule ^package/forest/list/(\d)/(\d{4}-\d{2}-\d{2})$ package/forest/deep/file/do_stuff.php?action=package&location=forest&pictures=$1&date=$2
The regex captures two groups, one with a single digit and one with the date. These are used later as $1 and $2.
Unfortunately I cannot test it as I am using nginx, so I am not 100% sure if I'm right.
I thought about whether the uri was going to get rewritten again after the first rewrite because "package/forest/" would still match, but the dollar sign at the end of the string should prevent any uri longer than that from matching.
For the same reason you don't have to worry about stacking; the first rule will only apply to short uri's ending with "forest/", the second only to those with a date in the end.
On the other hand I am wondering, why you are using the QSA flag. A uri containing a query will never match because of the trailing dollar sign.

.htaccess Negated Lookahead Regex malformed

The following is a segment from my .htaccess file.
I want the following behaviour from Apache (currently the site is at localhost, but that shouldn't matter, right?):
If the requested resource is anything else other than
{site_url}/core
or
{site_url}/login
like
{site_url}/pseudo/path/name
the resource served must be
{site_url}/site/pseudo/path/name
Otherwise the URL served must be {site_url}/core or {site_url}/login, i.e. whatever was requested.
The .htaccess file is:
<IfModule mod_alias.c>
AliasMatch ^/(?!core|login)(/?.*)$ /site/$2
Header add X-Enabled mod_alias
</IfModule>
But this doesn't seem to be working and returns an error. I am not very familiar with Regular Expressions and am trying to learn these. So what I have inferred from this expressions is:
If the expression after '/' , i.e. URI after site_url does not match core or login (?!core|login)) , and is followed by anything, inclusive of a sub-folder (/?.*)$ Optional slash, and anything following it, set the alias to /site/(anything that was matched in second parentheses).
The module is working, which I've checked using only the Header add part, the problem is the regex.
Please help.
Leave off the ^ at the beginning. The regex you have would match /pseudo/path/name but not {site_url}/pseudo/path/name, because you're telling it that the text must begin with a /.
Also, be careful, because your regex is excluding things like {site_url}/corel. That's probably not going to be a problem unless you have other directories beginning with core, but if you really want to make it match anything other than {site_url}/core or {site_url}/login, use this regex:
/(?!core$|login$)(/?.*)$

Extract multiple (and potentially unlimited) params from an URL for .htaccess redirect

I am writing a mod_rewrite redirect that essentially grabs all the different parameters from an old URL format and pass them all concatenated as one argument to the new url.
Eg.:
Old URL: /rss.php/searchtype/basic/yearfrom/PARAM1/colour/PARAM2/yearto/PARAM3/ .. and so on.
New URL: /search/keywords/PARAM1+PARAM2+PARAM3
So basically I need to be able to match the start of the string, but after that match the VALUE of any argueent passed and then append them to the end of the new URL with a space between them.
You want to extract the params, no problem.
But once they're extracted, the problem is that you want to concatenate them without yearfrom (and so on)...
I don't think this is possible, and what I'm pretty sure is not possible, is that you want to replace chars (replace / by +).
This is an answer even though it may disappoint you (sorry).
You can use RewriteMap with an external program to do this. See Apache Docs and this RewriteMap example from Rick Bowen