htaccess Rewrite rule for anything after the domain - regex

I've got a one page website that just has a switch that replaces some content with a local town names.
The normal domain.com will go to index.php, but I want anything after the domain to be passed in the GET query.
So domain.com/nottingham would go to index.php?town=nottingham
I have around 300 town names, so I dont ant to hardcode them all so I'm trying to get the $1 to pass the value and it doesn't seem to work.
I've got the following in my .htaccess
RewriteEngine On
RewriteRule ^([a-zA-Z0-9])$ /index.php?town=$1 [NC,L]
ErrorDocument 404 /index.php
But when I try domain.com/townname I get "Warning: Undefined array key "town" in..." So I assume thats missing my rewriterule and gonig to the 404.

You forgot to include a quantifier in your pattern - [a-zA-Z0-9] means allow for one character out of this character group. And since you anchored your pattern at the start and end, it would match when you requested domain.com/t, but not with any path component longer than that.
Add the + quantifier after the character group, to say "a character matching this group, one or more times":
RewriteRule ^([a-zA-Z0-9]+)$ /index.php?town=$1 [NC,L]

Related

Simplifying redirect in htaccess

I have redirects:
RewriteRule ^(.*)/thema(.*)$ https://www.newurl.com [R=301,L]
RewriteRule ^(.*)/stichpunkt(.*)$ https://newurl.com [R=301,L]
RewriteRule ^(.*)/author(.*)$ https://www.newurl.com [R=301,L]
RewriteRule ^(.*)/2023(.*)$ https://www.newurl.com [R=301,L]
is there a way to simplify these into one line?
I need to disable category, tag, author and date archives in Wordpress
This should really be done in WordPress itself. Otherwise WP is still going to generate and publish these URLs (eg. Sitemap, RSS feed, etc.).
Otherwise, if .htaccess is your only option then you should serve a 404, rather than redirect to the homepage. Whilst a redirect to the homepage is likely to be treated as a soft-404 by Google (and possibly other search engines) it runs the risk of being indexed under these "archive" URLs (and accessible with a site: search).
For example, at the top of the root .htaccess file (before any existing WP directives):
# Whatever your custom 404 page is (could be WordPress)
ErrorDocument 404 /404.php
# Force a 404 for "category, tag, author and date archives
RewriteRule (^|/)(thema|author|stichpunkt|2\d{3})(/|$) - [R=404]
2\d{4} matches any 4 digit year (in the 2000's).
The regex matches any of those "words" only when they occur as a whole path segement (not partial matches).
R=404 - This is not a "redirect" (despite the use of the R flag). The 404 error document is served via an internal subrequest and a 404 HTTP response code is set on the initial response. If these URLs have previously been indexed then consider changing this to a "410 Gone" instead, ie. R=410 or simply G (shorthand flag).
You can use a simple alternation with |:
RewriteRule ^.*/(thema|author|stichpunkt|2023) https://www.newurl.com [R=301,L]
You don't need to capture parts that you don't need to refer back to, so I removed the () around the .*. Around the alternation they are still needed so even if you are not interested in capturing that part, otherwise it would not be clear where the first value starts and the last one ends.
And you don't need to match .*$ either, you can just leave of the $ that anchors this pattern at the end.

Using htaccess to redirect anything after a parameter - regex

Id like to have the following URL(s) redirect to the same URL just without the ?
For example:
https://www.example.com/this-is-static?numbersletterssymbols
goes to
https://www.example.com/this-is-static
"numbersletterssymbols" can be anything
Id like this to be a 301 , using htaccess ( apache )
I came across the following, however, the variable seems to be in parentheses
RewriteCond %{QUERY_STRING} ^product=(.*)$
RewriteRule ^test.php$ %1/? [R=301,L]
Any insight is appreciated
To remove the query string (any query string) from any URL you could do the following using mod_rewrite, near the top of your .htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} .
RewriteRule ^ %{REQUEST_URI} [QSD,R=301,L]
The condition (RewriteCond directive) simply asserts that there is a query string consisting of at least 1 character (determined by the regex . - a single dot).
The QSD (Query String Discard) flag removes the original query string from the redirected response. The QSD flag requires Apache 2.4 (which you are most probably using). The method used on earlier versions of Apache, as in your example, is to append a ? to the susbstitution string (essentially an empty query string).
Note that you should test first with a 302 (temporary) redirect to avoid potential caching issues.
however, the variable seems to be in parentheses
The parentheses in the regex simply creates a "capturing group" which can be referenced later with a backreference. eg. In your example, the value of the product URL parameter is referenced in the RewriteRule substitution string using the %1 backreference in order to redirect to the value of the URL parameter. This is very different to what you are trying to do and is arguably a security issue. eg. It would redirect a request for /test.php?product=https://malicious.com to https://malicious.com/, allowing a potential hacker to relay traffic via your site.
UPDATE: is it possible to make this work only for when the URL begins with "this-is-static" (for example)
Yes, the RewriteRule pattern (1st argument) matches the URL-path, less the slash prefix. For example:
RewriteCond %{QUERY_STRING} .
RewriteRule ^this-is-static %{REQUEST_URI} [QSD,R=301,L]
Matches all URLs that start with /this-is-static.

RewriteRule to remove superfluous single "?" in URL

I am using IBM HTTP server configuration file to rewrite a URL redirected from CDN.
For some reason the URL comes with a superfluous single question mark even when there are no any query string. For example:
/index.html?
I'm in the process of making the 301 redirect for this. I want to remove the single "?" from the url but keep it if there is any query string.
Here's what I tried but it doesn't work:
RewriteRule ^/index.html? http://localhost/index.html [L,R=301]
update:
I tried this rule with correct regular expression but it never be triggered either.
RewriteRule ^/index.html\?$ http://localhost/index.html [L,R=301]
I tried to write another rule to rewrite "index.html" to "test.html" and I input "index.html?" in browser, it redirected me to "test.html?" but not "index.html".
You need to use a trick since RewriteRule implicitly matches against just the path component of the URL. The trick is looking at the unparsed original request line:
RewriteEngine ON
# literal ? followed by un-encoded space.
RewriteCond %{THE_REQUEST} "\? "
# Ironically the ? here means drop any query string.
RewriteRule ^/index.html /index.html? [R=301]
Question-mark is a Regular Expression special character, which means "the preceding character is optional". Your rule is actually matching index.htm or index.html.
Instead, try putting the question-mark in a "character class". This seems to be working for me:
RewriteRule ^/index.html[?]$ http://localhost/index.html [L,R=301]
($ to signify end-of-string, like ^ signifies start-of-string)
See http://publib.boulder.ibm.com/httpserv/manual60/mod/mod_rewrite.html (for your version of Apache, which is not the latest)
Note from our earlier attempts, escaping the question-mark doesn't seem to work.
Also, I'd push the CDN on why that question-mark is being sent. This doesn't seem a normal pattern.

How to rewrite this URL to a redirect page?

I am using Microsoft-IIS/7.5 on a hosted server (Hostek.com)
I have an existing site with 2,820 indexed links in Google. You can see the results by searching Google with this: site:flyingpiston.com Most of the pages use a section, makerid, or bikeid to get the right information. Most of the links look like this:
flyingpiston.com/?BikeID=1068
flyingpiston.com/?MakerID=1441
flyingpiston.com/?Section=Maker&MakerID=1441
flyingpiston.com/?Section=Bike&BikeID=1234
On the new site, I am doing URL rewriting using .htaccess. The new URLs will look like this:
flyingpiston.com/bike/1068/
flyingpiston.com/maker/1123/
Basically, I just want to use my htaccess file to direct any request with a "?" question mark in it directly a coldfusion page called redirect.cfm. On this page, I will use ColdFusion to write a custom 301 redirect. Here's what ColdFusion's redirect looks like:
<cfheader statuscode="301" statustext="Moved Permanently">
<cfheader name="Location" value="http://www.newurl/bike/1233/">
<cfabort>
So, what does my htaccess file need to look like if I want to push everything with a question mark to a particular page? Here's what I have tried, but it's not working.
RewriteEngine on
RewriteRule ^? /redirect.cfm [NS,L]
Update. Using the advice from below, I am using this rule:
RewriteRule \? /redirect/redirect.cfm [NS,L]
To try to push this request
http://flyingpiston2012-com.securec37.ezhostingserver.com/?bikeid=1235
To this page:
http://flyingpiston2012-com.securec37.ezhostingserver.com/redirect/redirect.cfm
There's a couple of reasons what you're trying isn't working.
The first one is that RewriteRule uses a regex, and ? is a regex metacharacter, which therefore needs be escaped with a backslash (\?) to tell it to match the literal question mark character.
However, the second part of the problem is that the regex for RewriteRule is only tested against the filename part of the URL - it specifically excludes the query string.
In order to match against the query string you need to use the RewriteCond directive, placed on the line before the rule (but applied in between the RewriteRule matching and replacing), acting as an additional filter. The useful bit is that you can specify which part of the URL to match against (as well as having the option for using non-regex tests).
Bearing all this in mind, the simplest way to match/rewrite a request with a query string is:
RewriteCond %{QUERY_STRING} .
RewriteRule .* /redirect/redirect.cfm
The %{QUERY_STRING} is what the regex is tested against (everything in CF's CGI scope can be used here, and some other stuff too - see the Server Variables box in the docs).
The single . just says "make sure the matched item has any single character"
At the moment, this rule will preserve the existing query string - if you want to discard it, you can place a ? onto the end of the replacement URL. (If you need to use a query string on the URL and not discard the old version, use the [QSA] flag.)
In the opposite direction, you're losing the filename part of the URL - to preserve this, you probably want to append it onto the replacement as PATH_INFO, using the automatic whole-match capture $0.
These two things together provides:
RewriteCond %{QUERY_STRING} .
RewriteRule .* /redirect/redirect.cfm/$0?
One final thing is that you'll want to guard against infinite loops - the above rule strips the query string so it will always fail the RewriteCond, but better to be safe (especially if you might need to add a query string), which you can do with an extra RewriteCond:
RewriteCond %{QUERY_STRING} .
RewriteCond %{REQUEST_URI} !/redirect/redirect\.cfm
RewriteRule .* /redirect/redirect.cfm/$0?
Multiple RewriteCond are combined as ANDs, and the ! negates the match.
You can of course add whatever flags are required to the RewriteRule to have it behave as desired.

.htaccess regex, redirect to new folders

I'm trying to redirect some old files/folders that used to follow this pattern:
foldername/filename.extension
foldername has:
(2010 or 2011)(text A-Z a-z 0-9 _ or -)
filename has:
(text A-Z a-z 0-9 _ or -).extension
Ex: 2011aug_SomeNameHere/image.jpg
The new folder tree organizes the files by year (so everything is one level deeper):
2010/foldername/filename.extension
and
2011/foldername/filename.extension
Ex: 2011/2011aug_SomeNameHere/image.jpg
And I have the following for my rewriterule:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^http://(www\.)?domain.com/path/to/+(2010|2011)+([A-Za-z\_\-])+/([A-Za-z0-9\_\-]\.([A-Za-z]))$ http://domain.com/path/to/$1/$1$2/$3 [L,R=301]
</IfModule>
In Firefox I'm getting a redirect to:
domain.com/path/to/2011aug_SomeNameHere/image.jpg/2011aug_SomeNameHere/image.jpg/2011aug_SomeNameHere/image.jpg...
In Chrome I'm getting a 404 error with the url at:
domain.com/path/to/2011aug_SomeNameHere/image.jpg
Does anyone have any ideas/tips?
Try this:
RewriteRule ^path/to/(2010|2011)([A-Za-z\_\-]+)/([A-Za-z0-9\_\-]+\.[A-Za-z]+)$ /path/to/$1/$1$2/$3 [L,R=301]
It is not required to use have the domain in your rewrite unless you are handling multiple domains with one rewrite. Your first group being $1 would have been your (www.) if you went to your domain with www infront. I suggest you look up your use of +'s and groups to understand more of the regex. Having your +'s outside the groups allows for matching of the same group more than once. In your case you want to match all of it in one group. You also had a nested group for your file extension match where it wasn't need.