.htaccess issue with ExpressionEngine and YOURLS - regex

I have a primary site running ExpressionEngine and I am trying to get YOURLS running in a subfolder called "work", ie: http://foo.com/work/ for short urls and EE is running at the root, ie: http://foo.com/. Please note there is no 'www'.
The problem I am having is that when I use a short URL and a user adds "www" to the URI, such as http://www.foo.com/work/123 I get a redirect chain that looks like this:
http://www.foo.com/work/123 302 redirects to
http://www.foo.com/work 301 redirects to
http://www.foo.com/work/ which returns 200
Everything works fine if you omit the 'www' from the URI. YOURLS is set up to use the non-www but the worry is that some users might habitually type the 'www' as these URIs are being placed on printed ads.
The root .htaccess file looks like this:
SetOutputFilter DEFLATE
DirectoryIndex index.php index.html
# BEGIN ExpressionEngine Rewrite
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www.foo.com [NC]
RewriteRule ^(.*)$ http://foo.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteRule ^(.*)$ /index.php?$1 [NC,L]
</IfModule>
# END ExpressionEngine Rewrite
The /work/ (YOURLS) .htaccess looks like this:
# BEGIN YOURLS
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /work/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /work/yourls-loader.php [L]
</IfModule>
# END YOURLS
How can I get the 'www' URIs to work like the non-www URIs do without completely hosing EE? :)

I faced a similar issue. Some end users or people publishing the short urls tend to append them with www while the short url was bought with the intention of using it without www.
I also installed the YOURLS redirect index plugin to forward homepage visitors to our regular homepage.
So I had a few different types of urls:
short domain homepage, should lead to the regular https homepage
short domain YOURLS admin panel, should lead to the https admin panel
short domain shortened urls, should lead to the long url
I wanted all urls to work with or without www and make sure http was forwarded to https.
My solution was to start .htaccess with these lines:
# Force HTTPS (because of passwords via /admin) and use clean domain (non www)
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www.examp.le [NC]
RewriteRule ^(.*)$ https://examp.le/$1 [L,R=301]

Related

Redirect specific url to homepage

I am building a React (frontend) with Wordpress (Backend - REST API) website. My domain is example.com which is going to have my React app (frontend) and on example.com/backend I have the Wordpress installation.
My problem is: I want to redirect example.com/backend and everything on to example.com except example.com/backend/wp-admin (so i can login). Is that do-able?
In a sentence: Can u redirect example.com/backend but have example.com/backend/wp-admin working (not redirecting)?
I tried lots of reggex in my .htaccess but none would do the trick.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^fanismahmalat.com/backend$ [NC]
RewriteCond %{REQUEST_URI} !^(.)?wp-login.php(.)$
RewriteCond %{REQUEST_URI} !^(.)?wp-admin$
RewriteRule ^(.)$ https://example.com/ [R=301,L]
One way to exclude a URL is to have a rule before the "real" redirect, e.g.
RewriteRule ^backend/wp-admin - [L]
RewriteRule ^backend/ https://example.com [R,L]
The first rule will handle the wp-admin case. The second rule will catch anything else starting with backend/.
Another solution would be to exclude the specific URL from being rewritten
RewriteCond %{REQUEST_URI} !^/backend/wp-admin
RewriteRule ^backend/ https://example.com [R,L]
When the .htaccess file is in the backend sub-folder, the rules are almost the same, but the RewriteRule pattern does not include the backend prefix
RewriteCond %{REQUEST_URI} !^/backend/wp-admin
RewriteRule ^ https://example.com [R,L]
or
RewriteRule ^wp-admin - [L]
RewriteRule ^ https://example.com [R,L]

Rewriting URL and hiding Subpage Name

I have a rewrite in my .htaccess file that sends people from example.com to example.com/home
RewriteEngine On
RewriteBase /
RewriteRule ^$ home [L,R=301]
How do I do this but then strip the string "home" from the url bar so that it appears to be example.com? I'm not interested in any subdirectories after home as the rest of the site lives in the root.
Full Context
# Perch Runway
<IfModule mod_rewrite.c>
# Turn on RewriteEngine
RewriteEngine On
# When user goes to the home page send to .com/home and strip /home
RewriteBase /
RewriteRule ^$ home [L,R=301]
# Cache Busting
RewriteRule (assets[/])([^.]*).min.+.(css|js)$ $1$2.min.$3
# Perch Runway
RewriteCond %{REQUEST_URI} !^/login
RewriteCond %{REQUEST_URI} !(/sub-directory-one|/sub-directory-two) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /login/core/runway/start.php [L]
</IfModule>
Use below rule,
RewriteEngine On
RewriteBase /
RewriteRule !home /home%{REQUEST_URI} [L]
When you use the R|redirect flag, Apache sends a redirect status to the client. The client then requests the new URL (e.g. http://www.example.com/home) and displays the new URL.
To avoid this behaviour, you do not send a redirect (e.g. R), but silently rewrite internally to the new URL. This way Apache sends the contents of the target without notifying the client.
To just rewrite internally from / to /home, keep the existing rule, but remove the R flag
RewriteRule ^$ /home [L]

.htaccess restrict subdomain by IP - Wordpress Multisite

I'd like to redirect traffic away from a subdomain install of Wordpress Multisite unless it's coming from a specific IP address/range, and without affecting the root domain traffic. Is this possible?
Conceptually, I've been thinking something like this:
# IF we're dealing with the subdomain
RewriteCond %{HTTP_HOST} subdomain\.example\.com [NC]
# AND the user is NOT from our allowed IP
RewriteCond %{REMOTE_ADDR} !111\.222\.333\.444
# THEN redirect them to the root domain
RewriteRule ^(.*)$ http://example.com/$1 [L,R=302]
In other words, restrict access to the subdomain from all traffic that doesn't originate from a defined IP address. I've literally just learned regex and .htaccess for this, so apologies in advance for anything that's glaringly wrong.
The reason I'm not doing this with directory specific .htaccess is that I'm working with a subdomain install of Wordpress Multisite, so there are no directories. It's all in the URL.
Some possible complications that come from Wordpress itself:
Ideally these rules should be added in such a way that they aren't overwritten every time the permalink cache is refreshed in WP.
I'm not sure what RewriteBase / evaluates to, or how it's affecting URIs (if that's the correct acronym) in my file.
EDIT:
Per #Prix feedback, here is the complete .htaccess file I'm working with:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} subdomain\.example\.com [NC]
RewriteCond %{REMOTE_ADDR} !111\.222\.333\.444
RewriteRule ^(.*)$ http://example.com/$1 [L,R=302]
RewriteRule ^index\.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]
</IfModule>
# END WordPress
This is Wordpress' Multisite default rules, with my own additions included immediately after RewriteBase /. I incorporated #hjpotter92's suggestion.
The desired affect it to redirect all traffic from subdomain.example.com to example.com, unless it's coming from a specific IP address. This is for a client who's essentially using part of their Wordpress Multisite as a company extranet.
The rule looks fine yes, the only thing I would change is this:
RewriteRule ^(.*)$ http://example.com/$1 [L,R=302]
Into this
RewriteRule ^ http://example.com/ [L,R=302]
As you don't want a 404 on the redirect aside from that given the subdomain share the same DocumentRoot, then yes, it should work as I have tested it myself.
And I hope at this line:
RewriteCond %{HTTP_HOST} subdomain\.example\.com [NC]
You're not adding noise to it like http:// or anything other than the qualified domain name, such as for example intranet\.mydomainname\.com no slash, no http, etc.

301 redirect to new domain and redirect individual old pages at the same time

I hope you can help me with this 301 issue.
Introduction
I've just published a re-design of a website with new clean urls. The old webpage had urls like this: www.domain.dk/Default.aspx?ID=66. And the new website urls look like this: www.domain.com/contact
So I wan't to redirect all these old urls to the new ones, and therefor i'm not keeping the old urls and no general rule can be applied.
That's just simple 301 redirects, but at the same time the old domain points to a new domain, and this is where things get dirty, I think. The old domain was www.domain.dk, but i wan't to 301 all traffic to the new domain www.domain.com and at the same time I wan't to make all the individual 301 redirects.
The problem
When I click on the link www.domain.dk/Default.aspx?ID=66 in Google I get this URL in my browser: www.domain.comindex.php/?ID=66.
On other links I get www.domain.comdefault.aspx/?ID=2
So the redirecting to the new domain works fine? But the individual redirects doesn't apply at all.
The code
This code is pasted as is from my .htaccess file on the server running apache.
The first bit is auto-generated by Concrete5 CMS to make pretty URLs.
# -- concrete5 urls start --
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
</IfModule>
# -- concrete5 urls end --
This is the code I found to 301 redirect all traffic to urls that is not using www.esvagt.com to www.esvagt.com
## --- 301 Redirects --- ##
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com$1 [R=301,L]
This is just one of the manual 301 redirects.
## General - Redirects ##
redirect 301 /Default.aspx?ID=66 http://www.domain.com/contact/contact-us
Thanks in advance. If you need more information I'll gladly provide that.
I have zero knowledge about writing code in .htaccess, so I'm pretty clueless. I hope you can help. :)
Avoid mixing mod_rewrite and mod_alias rules.
Ordering of rules is also very important so have 301 rules first and then have your catch all controller rule
Use this code for 301 redirect:
## --- 301 Redirects --- ##
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.dk$ [NC]
RewriteRule ^ http://www.domain.com%{REQUEST_URI} [R=301,L]
## General - Redirects ##
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+Default\.aspx\?ID=66[&\s] [NC]
RewriteRule ^ http://www.domain.com/contact/contact-us? [R=301,L]
# -- concrete5 urls start --
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
</IfModule>
# -- concrete5 urls end --
RewriteRule www.domain.dk/Default.aspx?ID=66 domain.com/contact/contact-us [R=301,L]
If you want to redirect all posts automatically:
RewriteRule /Artical.aspx?ID=(.+?) domain.com/article-title-$1.html [R=301,L]
or
RewriteRule /Artical.aspx?ID=(.+?) domain.com/Post.aspx?ID=$1 [R=301,L]
Then the dynamic url Artical.aspx?ID=20 will be redirect to http://www.domain.com/article-title-30.html,
I successfully apply this method for my blog http://downloadapp.info

htaccess: redirect old domain and all pages to a new domain

I know that there is a lot of examples on Stackoverflow but I still miss something.
I'm trying to redirect http://old.domain.com/fr/ to http://brand.new-domain.com/fr/ with the following rules, but that doesn't work:
# Enable Rewrite Engine
RewriteEngine On
RewriteBase /
# Add a trailing slash to paths without an extension
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule ^(.*)$ $1/ [L,R=301]
# Redirect domain
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} ^old.domain.com [OR]
RewriteCond %{HTTP_HOST} ^other-old.domain.com [NC]
RewriteRule ^(.*)$ http://brand.new-domain.com/$1 [r=301,L]
# Remove index.php
# Uses the "exclude method"
# http://expressionengine.com/wiki/Remove_index.php_From_URLs/#Exclude_List_Method
# This method seems to work best for us, you might also use the include method.
# http://expressionengine.com/wiki/Remove_index.php_From_URLs/#Include_List_Method
# Exclude root files
RewriteCond $1 !^(index\.php) [NC]
# Exclude EE folders
RewriteCond $1 !^(assets|ee-admin|images|templates|themes|fr|nl)/ [NC]
# Exclude user created folders
RewriteCond $1 !^(assets|css|img|js|swf|uploads)/ [NC]
# Exlude favico, robots, ipad icon
RewriteCond $1 !^(favicon\.ico|robots\.txt|pple-touch-icon\.png) [NC]
# Remove index.php
RewriteCond %{QUERY_STRING} !^(ACT=.*)$ [NC]
RewriteCond %{QUERY_STRING} !^(URL=.*)$ [NC]
RewriteRule ^(.*)$ /index.php?/$1 [L]
It correctly redirect when I call the root URL, but not when I call a page. What am I doing wrong?
Thanks in advance!
Pv
When writing mod_rewrite rules, the rules get applied in the order that they appear.
To redirect an old domain to a new domain, you'll want that rule to be first in your .htaccess or httpd.conf file — all other rules should appear after it.
If you only want to redirect a certain directory, the following rule will do so, while allowing the rest of the site to function normally:
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect Only Matching Directories
RewriteCond %{REQUEST_URI} ^/(fr|fr/.*)$
RewriteRule ^(.*)$ http://brand.new-domain.com/fr/$1 [R=301,L]
</IfModule>
If you want to redirect the entire site, the following rule will do so:
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect Entire Site to New Domain
RewriteCond %{HTTP_HOST} ^old.domain.com$ [OR]
RewriteCond %{HTTP_HOST} ^other-old.domain.com$ [NC]
RewriteRule ^(.*)$ http://brand.new-domain.com/$1 [R=301,L]
</IfModule>
If you care about letting crawlers know your content has moved and want to make the transition as seamless as possible, be sure to keep the 301 Redirect flag in the RewriteRule.
This will ensure that users and search engines are directed to the correct page.
While we're on the subject, as part of the EE 2.2 release, EllisLab now "officially" offers limited technical support for removing index.php from ExpressionEngine URLs.
Simply add or update your code to the following, making sure to consider any rules you may already have in place:
<IfModule mod_rewrite.c>
RewriteEngine On
# Removes index.php
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
# If 404s, "No Input File" or every URL returns the same thing
# make it /index.php?/$1 above (add the question mark)
</IfModule>
Try to use the following ruke as the first one:
# Redirect domain
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} ^old.domain.com [OR]
RewriteCond %{HTTP_HOST} ^other-old.domain.com [NC]
RewriteRule ^(.*)$ http://brand.new-domain.com/$1 [R=301,L]
Also mind the upper case R with is the short form for the lower case redirect.
Have you tried using mod_alias simple redirect instructions (a core module that you have), before trying the hacky-mod-rewrite thing?
I would do a VirtualHost with ServerName old.domain.com and in this VH I would add this rule:
Redirect /fr http://brand.new-domain.com/fr
from doc:
Then any request beginning with URL-Path will return a redirect request to the client at the location of the target URL. Additional path information beyond the matched URL-Path will be appended to the target URL.
So get a separate VirtualHost for brand.new-domain.com (with ServerName brand.new-domain.com) and in this one do not set the Redirect Rule.
If you still want to handle the 2 domains in the same VirtualHost then you'll have to use mod-rewrite as even RedirectMatch cannot check the request domain on the query.