I need to develop a plugin that can write into the WP htaccess file and "simulate" subdomains.
I have a new WP installation with basic htaccess on example.com
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Is there a way via htaccess that if I go to about.example.com I see the page example.com/about, without changing the URL (meaning that I still see about.example.com in the browser address bar)?
And also, is it possible that if I go to about.example.com/category1 I see the page example.com/about/category1?
I tried using the following code by adding it to the end of the htaccess, but it doesn't work:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?example.com.com$
RewriteRule ^(/)?$ about [L]
You should be able to do that using the following rule in your .htaccess:
RewirieEngine On
RewriteCond %{HTTP_HOST} ^about.example.com [OR]
RewriteCond %{HTTP_HOST} ^www.about.example.com
RewriteRule ^(.*) http://example.com/about/$1 [P]
What this does is check for the address about.example.com, if the condition is met it should redirect to example.com/about/.... but keeping the original address.
The [P] flag causes the request to be handled by mod_proxy, and handled via a proxy request.
However, keep in mind that using mod_proxy can cause security issues:
Take care when constructing the target URL of the rule, considering
the security impact from allowing the client influence over the set of
URLs to which your server will act as a proxy. Ensure that the scheme
and hostname part of the URL is either fixed, or does not allow the
client undue influence.
Normally using .htaccess you cannot go from one domain to another domain keeping the original URL. It can be a security nightmare as mentioned above. However, since this is a subdomain it should work.
Make sure you clear your cache before testing this.
Alternative
You can use ProxyPass - which would be a more secure option. You can find more information on how to use this via the Apache Documentation via this link. But this would need to done on a level higher than .htaccess. Through the config files.
I hope this helps.
Related
How to redirect all urls with .php? to only .php ?
I´m using
RewriteEngine On
RewriteRule ^(.+\.php)/.*$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?secure/(.*) https://example.org$1 [R,L]
How can i prevent somone using urls that doesn´t exist on my server?
It´s all about blocking everything that comes after .php like ?123456789
Why should it be an issue if someone adds a query string to a URL? Unless your php scripts react to that, of course, but that is something you can control, can't you?
Nevertheless it certainly is possible to drop such query strings if you want to:
RewriteEngine on
RewriteCond %{QUERY_STRING} !^$
RewriteRule \.php$ %{REQUEST_URI} [QSD,R=301,L]
For this to work the apache rewrite module needs to be loaded into the http server, obviously.
It is a good diea to start with a R=302 temporary redirection first. And to only change that to a R=301 permanent redirection once everything works as desired. That prevents nasty caching issues for your users.
You should prefer to implement such rules in the actual http server's host configuration. If you have no access to that you can also use a distributed configuration file (".htaccess"), but that comes with a few disadvantages. And has to be enabled first.
On my test server with Apache and php7.1 I can work with an URL like example.com/news/id/title
and it redirects me to
example.com/news.php
but the url is still the same and I can use the Parameters after the slashes.
Now I work on a live hosting and its not working anymore.
I tried to redirect with htaccess and it works for
example.com/news to redirect to example.com/news.php
but if I put anything after that i get an 404 error.
How can I redirect the requests from
/news/id/ to news.php where I want to read out the id?
And why did that work natively on my test server?
Thousand thanks for any hint.
My actual .htaccess:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^news/(.*) /news.php/$1 [R=301,NC,L]
Sounds like you may have a conflict with MultiViews (part of mod_negotiation). You need to make sure MultiViews is disabled at the top of your .htaccess file:
Options -MultiViews
If MultiViews is enabled and you make a request for /news/id/ then mod_negotiation makes an internal subrequest for /news.php (without any additional path-info) before mod_rewrite is able to rewrite the request.
why did that work natively on my testserver?
MultiViews is disabled by default on Apache, however, a number of shared web hosts do enable it for some reason. It makes extensionless URLs "magically" work without doing anything, however, this potentially creates duplicate content (bad for SEO) and causes no end of unexpected conflicts with mod_rewrite, such as this.
UPDATE: Change your directives to something like the following instead:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^news/(.*) /news.php/$1 [L]
This internally rewrites (as opposed to _externally redirects_) all requests that start /news/to/news.php/- whereis passed as _path-info_ to/news.php`. (I assume that passing the URL-path as path-info is the intention? You could instead use the query string or not pass anything in the directive and simply examine the requested URL in PHP? - but this might require marginally more processing in PHP.)
There's no need to check that the target file exists, since it's hardcoded in this example.
Removal of the R flag results in the internal rewrite.
You will need to clear your browser cache since the 301 (permanent) redirect will have been cached by the browser.
If you need a more generic solution that rewrites /<action>/<data> to /<action>.php/<data> then write it like this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/]+)/(.*) /$1.php/$1 [L]
Again, no need to check that the request does not map to a file before checking that it does map to a file when .php is appended.
Note that this is not using a TestString of the form %{REQUEST_FILENAME}.php (as you had initially), as this can result in a rewrite loop (500 error) for certain requests. See my answer to the following question on ServerFault that explains this further: https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error
So, I've this problem:
Base Website located at http://example.com/
Second Website located at http://example.com/web2/
People making various requests to the second website like
http://example.com/myWeb/pg1 and http://example.com/web2/pg2
Recently and due to some other issues I need to have a custom new path for the second website but also keep the first one working.
The ideia is to allow users to access the second website over the two following addresses:
http://example.com/web2/
http://example.com/alternative-url-web2/
The folder /web2/ actually exists on the server, but how can I simulate the folder /alternative-url-web2/ and "redirect" the requests to /web2/?
Please note I don't want the URL on the browser to change, this must be a "silent redirect". And I also make sure that all other requests like http://example.com/other are not redirected by the second website.
Thank you.
Update:
According to #anubhava I could simply solve this issue by adding in my .htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^alternative-url-web2(/.*|)$ /web2$1 [L,NC]
This is probably working fine but I noticed the following:
http://ex.com/alternative-url-web2 is redirected to http://ex.com/web2/ (changing browser URL);
http://ex.com/alternative-url-web2/ is redirected to http://ex.com/(changing browser URL);
http://ex.com/alternative-url-web2/someRequest works fine and does NOT change the browser URL;
http://ex.com/alternative-url-web2/index.php works fine and does NOT change the browser URL;
Site Note:
At /web2/ there's an .htaccess that might be cause the wired redirect behavior above... So here is the file contents:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(data/|js/|styles/|install/|favicon\.ico|crossdomain\.xml|robots\.txt) - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</IfModule>
Can the internal RewriteRule to index.php be causing all this? If yes, how can I fix it?
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteRule ^alternative-url-web2(/.*|)$ /web2$1 [L,NC]
Alternate code:
RewriteRule ^alternative-url-web2/?$ /web2/ [L,NC]
RewriteRule ^alternative-url-web2/(.+)$ /web2/$1 [L,NC]
This is a pretty simple rewrite. In the htaccess file in your document root, just add the following:
RewriteEngine On
RewriteRule ^alternative-url-web2/?(.*)$ /web2/$1 [L]
Unlike a redirect, which makes the browser/client send a new request for a new URL (thus changing what's in the browser's location bar), a rewrite happens entirely on the server's side.
By the way, in order to follow the trail of htaccess redirects, you could add something like this to each of them:
Header add X-Remark-Rewrite "/path.to/htaccess"
You can inspect these in the response in the developer tools.
User clicks link (from their email): http://www.site.com/edit/wih293f73y
Browser window opens and gets them to the correct page.
But now the browser's address bar shows: http://www.site.com/editor.php?editCode=wih293f73y
Extra info:
My rewrite rule is:RewriteRule ^edit/([A-Za-z0-9-]+)/?$ editor.php?editCode=$1 [NC,L]
This problem ONLY occurs when the user has clicked a link. It works perfectly when you just type the pretty url into the address bar.
This problem ONLY occurs for links that include the www. - the link http://site.com/edit/wih293f73y works like a charm.
My .htaccess file includes the following code (from HTML5 boilerplate, which I wasn't aware of previously):
# Rewrite www.example.com → example.com
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
</IfModule>
If it's important, this occurs after my other rewrite rules.
I just took a look and it is apparent that your www rules is causing this. Question is do you want it be fixed? If you do then move this rule on top of all other rules and your problem should be fixed.
Move this to top of all other rules
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
You can use use the redirect directive
redirect 301 ^edit/([A-Za-z0-9-]+)/?$ editor.php?editCode=$1
There are some pros and cons to this strategy. The pros being;
It's super fast. You don't even need to load up your application for this to work.
It's minimal code.
Redirects are an intrinsic part of Apache (or any http server) and aren't going anywhere soon.
The cons being;
It's not part of your application proper. Should you decide to change logic or URLs, you'll have to change this, too.
It's slower, as you need to invoke php, as opposed to just having Apache issue the redirect.
I've searched and found a lot of questions on this site and elsewhere that are very similar, but I've tried implementing and modifying all the suggestions I've found and none of it works. I realize this is a very basic question an I am extremely frustrated because nothing I'm trying is working.
With that having been said... I am trying to organize my content pages within kurtiskronk.com/pages/... (e.g. kurtiskronk.com/pages/about.php)
What I want to do is make it so that I can simply link to kurtiskronk.com/about ... So how do I go about stripping "pages/" and ".php"? I don't have a ton of content pages, so it's not a big deal if I have to specify for each page, though something dynamic would be handy.
NOTES: I am using Rackspace Cloud hosting, and WordPress is installed in /blog. My phpinfo() can be seen at http://kurtiskronk.com/pages/phpinfo.php
This is my existing .htaccess file (in the root)
php_value register_globals "on"
Options +FollowSymLinks
RewriteEngine On
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
RewriteBase /
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [L]
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
# PHP - MAIL
php_value mail.force_extra_parameters -kurtis#kurtiskronk.com
I tested and the rewrite works with the line below (/about as URL brings up file /pages/about.php), but then the homepage gives a 500 Internal Server Error:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
So I'm still sort of in the same boat as before, and as a follow-up, possibly more difficult question, if you go to http://kurtiskronk.com/weddings I am using SlideShowPro (flash) w/ SSP Director (self-hosted) as the back-end for it. When it pulls up a new image, it adds the following after /weddings ... "#id=album-152&num=content-9698"
There are four sections of the portfolio
# Homepage (kurtiskronk.com) id=album-148 ($id is constant for this section)
# Weddings (/weddings) id=album-152 ($id is constant for this section)
# Portraits (/portraits) id=album-151 ($id is constant for this section)
# Commercial (/commercial) id=album-150 ($id is constant for this section)
Assuming we get kurtiskronk.com/weddings to rewrite successfully without breaking anything, how would we make the total URL something cleaner kurtiskronk.com/weddings/9698 since the $num is the only thing that will change within a given section?
Kurtis, thanks for the extra information. It's a lot easier to give a specific answer to this.
My first comment is that you need to separate out in your thinking URI space -- that is what URIs you want your users to type into their browser -- and filesystem space -- what physical files you want to map to. Some of your mappings are URI->URI and some are URI->FS
For example you want to issue a permanent redirect of www.kurtiskronk.com/* to kurtiskronk.com/*. Assuming that you only server the base and www subdomains from this tree, then this cond/rule pair should come first, so that you can assume that all other rules only refer to kurtiskronk.com.
Next, you need to review the RewiteBase documentation. .htaccess files are processed in what Apache calls a Per-Directory context and this directive tells the rewrite engine what to assume as the URI base which got to this directory and .htaccess file. From what I gather, your blog is installed in docroot/blog (in the filesystem, and that you want to get to directory by typing in http://kurtiskronk.com/blog/ but that this .htaccess file is for the root folder -- that is the base should be (this goes before the www mapping rule)
DirectorySlash On
DirectoryIndex index.php
RewriteBase /
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
You can add some field dumps look for REDIRECT_* in the Server or Environment table in the phpinfo O/P to see if these are sensible. For example:
RewriteWrite ^(.*)$ - \
[E=TESTDR:%{DOCUMENT_ROOT}/pages/$1.php,E=TESTPDR:%{DOCUMENT_ROOT}/pages/$1.php]
Your next rule is that if the file exists in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [NS,L]
[Note that some shared service sites don't set up DOCUMENT_ROOT properly for the rewrite engine so you may need to run a variableinfo script (<?php phpinfo(INFO_ENVIRONMENT | INFO_VARIABLES); to see if it sets up alternatives. On your site you have to use %{ENV:PHP_DOCUMENT_ROOT} instead.]
Your next rule is that if the file exists, but with the extension .php in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [NS,L]
Now redirect any blog references to the blog subdirectory unless the URI maps to a real file (e.g. the blog stylesheets and your uploads.)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
A complication here is that WP may be using a poorly documented Apache feature call Path Info that is a script can act as a pseudo directory so http://kurtiskronk.com/blog/tag/downtown/ is redirected to docroot/blog/index.php/tag/downtown/ which is then executed by `docroot/blog/index.php using /tag/downtown/ as the PATH_INFO. But this is one for Wordpress experts to comment on. If this last rule doesn't work then try:
RewriteRule ^blog/(.*) blog/index.php/$1 [L]
PS. I like your site. I wish I was that young again :(
Postscript
When you say "it doesn't work", what doesn't with this .htaccess?
http://kurtiskronk.com/phpinfo,
http://kurtiskronk.com/phpinfo.php,
http://kurtiskronk.comblog/tag/downtown/
It's just that these rules work for these tests (with domain swapped) on mine. (One way is to move or copy the above variableinfo.php to the various subdirectories. If necessary temporarily rename the index.php to index.php.keep, say, and copy the variableinfo.php to the index.php file. You can now enter the various URI test patterns and see what is happening. Look for the REDIRECT_* fields in the phpinfo output, and the SCRIPT_NAME will tell you which is being executed. You can add more {E=...] flags to examine the various pattern results. (Remember that these only get assigned if the rule is a match.
Lastly note the changes above especially the additional NS flags. For some reason mod_rewrite was going directly into a subquery which was resulting in redirect: being dumped into the file pattern. I've had a look at the Apache code and this is a internal botch to flag that further redirection needs to take place (which then replaces this or backs out). However this open bug indicates that this backout can be missed in sub-queries and maybe that's what is happening here. Certainly adding the NS flas cured the problem on my test environment.
PS. Note the added explicit DirectoryIndex directive and also that whilst http://kurtiskronk.com will run the root index.php, the explicit /index.php version will run the one in pages, because that's what your rules say.
Here is a simple solution. You can use it apache conf file(s) or in .htaccess (easier to set up when you're trying).
mod_rewrite has to be enabled.
For example, use .htaccess in your DocumentRoot with:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
It will redirect /about to /pages/about.php, and any other page.
The "RewriteCond" part is to authorize access to an existing file (eg: if you had an "about" file at the root of your site, then it will be served, instead of redirecting to /pages/about.php).
Options +FollowSymLinks
RewriteEngine On
RewriteRule /([0-9]+)$ /pages/$1.php [L]
Put something like this in your .htaccess file. I guess that is what you want.
Juest a redirect from a simple url to a longer url.