Maintaining the query string with mod_rewrite - apache

I've correctly configured my website to re-route every piece of traffic from
mywonderfulwebsite.com/folder1/whatever-url.php
to
http://folder1.mywonderfulwebsite.com/whatever-url-as-above.php
Question is: many times, an external website links the page with GET parameters, for example
mywonderfulwebsite.com/folder1/whatever-url.php*?trackingToken=1*
So, question is how to make the mod_rewrite pass in the GET parameters to the "rewrited" url, like this:
folder1.mywonderfulwebsite.com/whatever-url-as-above.php*?trackingToken=1*
Currently, I'm doing the following:
<VirtualHost *>
ServerName mywonderfulwebsite.com
ServerAlias www.mywonderfulwebsite.com
DocumentRoot /var/www/mywonderfulwebsite/
DirectoryIndex index.html
<Directory />
allow from all
Options +FollowSymlinks -Indexes
</Directory>
RewriteEngine On
RewriteRule ^/folder1/(.*)?$ http://folder1.mywonderfulwebsite.com/$1&%{QUERY_STRING} [L,R=301]
</VirtualHost>
This piece of htaccess is awful: for example, trying to access this url:
www.mywonderfulwebsite.com/folder1/atextfile.txt
Redirects to
folder1.mywonderfulwebsite.com/atextfile.txt&
In fact, the mod_rewrite appends the trailing &
How do I fix this issue? How to correctly redirecting to the correct ( also with GET parameters ) url?
Many thanks

Just add the [QSA] flag to your other flags to have the [Q]uery [S]tring [A]ppended automatically.
[L,R=301,QSA]

Related

mod_rewrite entire website to front page ONLY of new website

Now I've written dozens of redirects in my time, some with tricky regex, some more tame, but today, the very simplest redirect is stumping me on a CentOS server, running Apache 2.2.3.
All I'd like to do is redirect every single request on an old domain, regardless of path and query string, to the front page only of a new site. This is why, for example, a mod_alias Redirect directive isn't appropriate, since it appends the path to the new address.
In an Apache conf file, where the virtual server is defined, I now have
<VirtualHost THE.IP.ADDRESS:80>
DocumentRoot "/var/www/html/SITE_ROOT"
ServerName OLD_DOMAIN.com
<Directory "/var/www/html/SITE_ROOT">
Options FollowSymLinks
RewriteEngine On
RewriteRule ^$ https://NEW_DOMAIN [R=301,L]
AllowOverride None
</Directory>
</VirtualHost>
While the redirect to https://NEW_DOMAIN occurs as expected, the path of the original request is always appended, leading to 404 errors on the new site.
For example, visiting http://OLD_DOMAIN.com/asdf
redirects to https://NEW_DOMAIN.com/asdf
...when I'd actually want to arrive at https://NEW_DOMAIN.com/
Why is the path being appended, even though I'm not collecting a pattern match, and am not specifying such a match in the destination?
There are plenty of answers like this on SO already:
Apache redirect to a clean URL
https://stackoverflow.com/a/11590814/1738274
But I can't find a discrepancy comparing these solutions against my own configuration. Any ideas?
RewriteRule ^(.*)$ https://NEW_DOMAIN [R=301,NC,L] should work. I have tested with various URLs and it always redirects to https://NEW_DOMAIN
My config structure looks a bit different:
<VirtualHost *:80>
ServerName OLD_DOMAIN.com
DocumentRoot "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs"
<IfModule mod_rewrite.c>
RewriteEngine on
Options FollowSymLinks
RewriteRule ^(.*)$ https://NEW_DOMAIN [R=301,NC,L]
.......
.......

Set urls for redirect to a specific url without rewrite

I'm building a webscheduler that have a multitenant structure, what I'm trying to do is assign a custom url that point to my application to each buyer.
So essentially when a user buy a license from me, I'll create a custom url on my webserver like this:
http://webserver/foo.scheduler.com/login
where foo is the name of the user that has buyed the license, and scheduler is a default part of the url, another example with more buyers:
http://webserver/foo.scheduler.com/login
http://webserver/foo2.scheduler.com/login
http://webserver/foo3.scheduler.com/login
essentially there are three buyers (my customers), each custom endpoint allow me to identify the correct database credentials, 'cause in my logic each tenant have a specific db, for more data organization.
Actually my application is located to this endpoint:
http://webserver/scheduler
I want to know if is possible point all custom urls to http://webserver/scheduler, without rewrite the url in the browser, so for example when the user go to http://webserver/foo.scheduler.com/login in the true is http://webserver/scheduler/login, but the user still continue to see http://webserver/foo.scheduler.com/login.
How can do this? In my .htaccess, available inside the root of the application folder I've this content:
RewriteEngine On
RewriteBase /webscheduler/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
this allow me to rewrite the base path to the index, and shunt the trace to the specific controller.
Happy to help you with this.
Get a valid SSL certificate for *.scheduler.com. You are going to need that if you're going to get this to work. Are you sure you want to use HTTPS? Your other URL is not HTTPS. Then you will need to set up your virtual host for *.scheduler.com to work properly with that certificate. Only having:
<VirtualHost *:443>
ServerAlias *.scheduler.com
DocumentRoot "/var/www/html/progetti/scheduler"
</VirtualHost>
Is not going to be anything like enough. You need all the mod_ssl stuff setting up in there as you have with the other virtual host. You could just use that default HTTPS host instead of adding another one, and modify it.
The first thing to do is get your hosting working for https://*.scheduler.com/ and then just point it at the right place.
What do you mean your endpoint is http://webserver/scheduler? This is not a valid domain name. Please clarify what you mean by that and I will update my answer with more information. Is the code on the same server?
--
Update
So to do this without SSL, add the following to your "000-default.conf", after what is currently there:
<VirtualHost *:80>
ServerAdmin localhost#gmail.com
ServerName www.scheduler.com
ServerAlias *.scheduler.com
UseCanonicalName off
DocumentRoot /var/www/html/progetti/scheduler
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/html/progetti/scheduler>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
--
Update
To make http://webserver/foo.scheduler.com work and serve /scheduler, add this to the VirtualHost that was already there. Not the new one added above, the original one at the top.
RewriteEngine on
RewriteRule ^(/[^./]+\.scheduler\.com)(?:$|/(.*)$) /scheduler/$2
Let me know any problems. If you would prefer to put it in your .htaccess it will need updating.
Note: I'm taking literally your statements that the app is using http:// and the clients will use https:// URLs. Also I'm assuming that the clients are hitting the same server as the one that hosts the app.
Probably the simplest way to do this is to configure one VirtualHost for your actual application and a separate one for the other URLs.
So assuming your application lives in /var/www/html/scheduler, then your existing VirtualHost looks like:
<VirtualHost *:80>
ServerName webserver
DocumentRoot "/var/www/html"
</VirtualHost>
You would need to add change your conf.d/ssl.conf to have something like:
NameVirtualHost *:443
<VirtualHost *:443>
ServerAlias *.scheduler.com
DocumentRoot "/var/www/html/scheduler"
</VirtualHost>

Split DocumentRoot using Apache Alias per request path

I'm trying to slowly take over an existing website, route per route. I found Apache's Alias(Match) which seems to allow me to set a different (content) document root per request. But I'm failing with trailing slashes and more complex paths.
My goal now is to have the old website serve everything as it is used to. And to have a new website, serving a first specific request, say /foo and /foo/*.
I have my vhost setup like this:
<VirtualHost *:80>
ServerName example.com
UseCanonicalName on
AliasMatch ^/foo/(.*)$ /www/new/$1
AliasMatch ^/foo$ /www/new/$1
<Directory /www/new/>
Options +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
DocumentRoot /www/old
<Directory /www/old/>
Options +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
In both directories I have an .htaccess with:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php/$1 [L]
The index.php's show 'old' or 'new' depending on their directory.
What happens to the different routes I test:
When requesting example.com/bar it shows 'old'.
When requesting example.com/foo it redirects too /foo/, and then shows 'new'.
When requesting example.com/foo/bar it shows 'old'.
I don't want the forced redirect of /foo to /foo/. And I want /foo/bar to show 'new'.
I've been following Apache's mod_alias to get the multiple AliasMatch directives to catch anything after /foo but apparently that's not working correctly. Also, I don't read anything there of the trailing slash being added magically.
Anyone knows the magic tricks?
I've been able to fix this by adjusting the Alias to point to the index.php directly:
AliasMatch ^/foo/(.*)$ /www/new/index.php
AliasMatch ^/foo$ /www/new/index.php
Then /bar and anything else goes to the old website, and /foo, /foo/ and /foo/bar goes to the new website.
There's two downsides to this method:
The .htaccess in the new website is skipped completely. But as I mainly use that for letting the index.php pick up every route, that's fine for now.
Frontend resources like css/js go to the old website. Fix that with another simple alias: example.com/frontend/app.css + Alias /frontend /www/new/public_html/frontend.

How can I get .htaccess to be seen when I make my site live

I have a .htaccess file which (among other things) creates pretty urls. Here's a sample of part of the file:
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
...
# Pretty urls
RewriteRule ^home(\d+)*$ ./index.html
RewriteRule ^contact(\d+)*$ ./contact.html
RewriteRule ^enquire(\d+)*$ ./enquire.html
RewriteRule ^terms(\d+)*$ ./terms.html
RewriteRule ^about(\d+)*$ ./about.html
RewriteRule ^owners(\d+)*$ ./owners.html
I am currently moving the site to new hosting on digitalocean. When I test the site out by browsing the IP e.g.
111.222.333.444/html_docs/contact
the .htaccess file is working perfectly. Rewrite rules are on and the site properly rewrites the url and serves (in this case, contact.html) to the browser.
When I change the nameservers and browse the site by domain after propogation e.g.
mydomain.com/contact
the .htacces file fails to do the redirect, at least, it seems like it's not being seen at all. This is weird to me since it works when I'm browsing by ip. I purposely put some rubbish into the .htaccess to test if it was being picked up. Again, if I browse via the ip I get a 500 which I would expect, but when browsing by domain name I do not get an error but the rewrites don't work.
I'm banging my head at this stage and can't figure it out. Any help appreciated,
many thanks,
Wittner
Ok, this was less of a lack of knowledge about how .htaccess works and more to do with not configuring my vhosts settings properly.
<VirtualHost *:80>
ServerName mydomain.com
ServerAlias www.mydomain.com
ServerAdmin me#mydomain.com
DocumentRoot "/var/www/mydomain.com/html_docs/"
<Directory "/var/www/mydomain.com/html_docs/"> <-- Problem was here
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Turns out that in the tag I had left out the path to my domain root. So when I directly browsed the site via the IP the system was able to figure it out, but no while browsing. All my .htaccess stuff is now working. Thanks to all who looked and anyone who replied. Live and learn I guess :-)
cheers,
Wittner

Using .htaccess to get content from directory for sub-domain

I've read a tonne of questions on this and tried a few solutions, but I'm just not getting the results I want.
I'm currently using:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^cp\.example\.net
RewriteRule ^(.*)$ http://example.net/gamepanel/public/$1 [L,NC,QSA]
Which doesn't quite work as intended. When I navigate to cp.example.net I am redirected to http://example.net/gamepanel/public/
What I want to have happen is for cp.example.net to show the content at http://example.net/gamepanel/public, whilst showing the subdomain in the URL.
Also cp.example.net/user should show content from example.net/gamepanel/public/user
Some help on achieving this would be much appreciated!
Turns out I was a little off the mark on what I needed to do and that .htaccess wasn't the best way to do this.
Adding this in my apache files solved it
<VirtualHost *:80>
ServerName cp.example.net
DocumentRoot /var/www/gamepanel/public
<Directory /var/www/gamepanel/public>
Options -Indexes
</Directory>
</VirtualHost>