Rewriting Link with mod-rewrite - apache

I have a link being sent to users in one format, but I need to make sure it passes through a main index page for login purposes. I figured mod rewrite was the way to go.
Link being clicked on by user:
https://sub.domain.com/link/link.jsp?pageId=1234567&id=12345
Where it needs to go:
https://sub.domain.com/index.html?o=(full original URL from above, including query string)
The o= in this case will let the user login and pass them along to that original URL. Now, there are also some images and a style sheet involved, so I need to have the rewrite ignore them.
After reading documentation and a number of code examples (many from this site), I tried to just get a basic code going to see if my rewrites will even work, as I'm new to this.
This appears to force the URL to rewrite but isn't passing the user along to the original link:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^sub.domain.com [NC]
RewriteRule .* https://sub.domain.com/index.html?o=%{HTTP_HOST}%{REQUEST_URI}?%{QUERY_STRING} [L]
Also please note this is all going inside a virtual host, not htaccess. As I said, the code above appears to redirect when I test it, but it might be unintended and not at all how I should write it.
I also tried adding in this code for images/stylesheet ignores
RewriteCond %{REQUEST_URI} !\.(css|jpg|jpeg)$ [NC]
At that point everything went crazy, but I know it's because I'm slapping code together and thinking it's going to work. From that point I tried a lot of changes, but most resulted in a loop condition and I kept falling back to square one (original code you see above). Apologies for the long winded post, but I'm hitting my head against a wall at something I thought wouldn't be difficult. Obviously, despite reading, I'm lacking some understanding. Any guidance would be very helpful.

The problem with your current solution is: an URL is only allowed to have one ? inside.
Note that your code will send a redirection status code to redirect inside the browser, because you provided a FQDN. Try doing an internal redirect by just using /index.html?o=.... If that doesn't work either (not sure right now), URL-Encode the second ?
[Edit]: rewrite, guess I got the question wrong.

Related

Can someone prompt me in the right direction to use mod_rewrite?

I am a bit new to this but I am trying to learn. I know that in PHP we can have a URL that ends in ?id=something but it seems to me that some websites are doing it just forward slashes. Is this possible using PHP? I saw these questions that seem to say it is possible but I haven't cracked it yet.
Can someone prompt me in the right direction for mod_rewrite? I would like to change the following URL
http://www.example.com/all-products/?onsale=true&topic=health&item=adaaos45
into
http://www.example.com/all-products/items-on-sale/health/adaaos45
Can you point me into the right way?
What you are looking for is Apache Url Rewriting.
I will break it down a bit for you to help you understand, it helps to know a bit of regex.
there are a lot of answers here that discuss the method, but to sum it all up, you need to do three things.
# Switch on URL Rewriting
# Choose the URL that you want to display
# Point it to the true URL that gives the information.
Options FollowSymLinks
RewriteEngine On
RewriteRule ^all-products/items-on-sale/health/adaaos45/?$ all-products/?onsale=true&topic=health&item=adaaos45 [NC,L]
Now of course, if you would want to match any results for the variables, you need to match the word in regex, and remember it, and use it in the last part of the line. But this should get you started on understanding what is going on.
With this code in your .htaccess, browsing to
http://www.example.com/all-products/items-on-sale/health/adaaos45
will show you the content that displays on this page.
http://www.example.com/all-products/?onsale=true&topic=health&item=adaaos45

Disallow double or junk wildcard subdomains in htaccess mod rewrite for SEO

I have wildcard subdomains enabled on my domain. I use this so that I can rewrite urls like es.domain.com to domain.com/page.php?lang=es and display to the user the local language version of page.php.
The one potential problem I see with allowing wildcard subdomains is that people can link to www.es.domain.com or even anything.they.like.domain.com and it will display a perfectly working clone of the website. I presume this 'duplicate content' is bad for SEO.
Can anyone come up with a RewriteRule which detects subdomains of more than 2 letters (www. excluded of course) and 301 redirects offending urls to the clean base domain.com? I'm having trouble when I consider domains like domain.co.uk which already look like they are on a subdomain.
As a side note, are there any similar implications for SEO on the opposite side of the url, with query parameters? For example, domain.com?param=anything-I-like will surely show a duplicate page. How does Google handle this content?
UPDATE:
Here's the rewrite rule I'm using currently. If I wanted to clean up bad urls with PHP, I'd need to modify this to catch all subdomains. i need to do this generically (without specifying domain.com) as it's going to be used on a CMS. Any suggestions?
RewriteCond %{HTTP_HOST} ^([a-z]{2})\.
RewriteRule p/(.*) page.php?p=$1&lang=%1
I honestly can't speak to fixing your actual issue, but I can confirm that anything.I.want.domain.com is really, REALLY bad for SEO. I've got two years' experience in the field and I'm currently working on a project cleaning up links for our main U.S. site. A couple of the biggest problems have come from sites just like you described where there were around 100 *.domain.com. The biggest issue is the effect of this problem with trust flow, it basically sends a link's trust rating to 0 and tells Google that, not only should this link be disregarded, the domain it came from and links to should be investigated for potential spammy-ness.
As to your final question on implications:
Query parameters can be just as helpful or detrimental as any other URL structure, so you want to be careful with those, as well. If you've got different language versions of your site, be sure to have one (especially if you don't have entirely unique content) as the rel-canonical page. The thing is, linking structure is important to search engines, but not overly so. It's one of many metrics. I'd be far more concerned about the subdomains. If you happen to be able to sneak in some small, basic keywords that help describe the page in with your query vars, it could help a bit. I would, however, highly suggest that you have a three or four tiered structure to your site, supported in the URLS.
See this
Google tends to like: domain.com/landingpage/category/subcategory?somevars=44
Going more than three deep spreads you too thin and less than that makes the site too bulky to navigate. I believe it's covered somewhat here if you've never seen it: http://moz.com/beginners-guide-to-seo
Search Engine Journal
Single Grain and
Moz
can answer a lot of your SEO questions and tools like:
Majestic
Soolve
Mozcast
SERPMetrics Flux
can help a lot, too. Try doing a little reading and see if you can decide a good scheme for your links.
Again, sorry, I don't know really any Apache, but hopefully that'll help!
Presumably you have a rewrite rule that takes anything in front of domain.com and puts it into the lang parameter. Rather than having a rewrite rule to do the redirecting, have your page.php script examine the lang parameter and issue a redirect for invalid values.
Thanks to all for the info & replies on this. The solution I've found is to write a more generic .htaccess rule to catch all subdomains and forward them to PHP for processing. PHP then checks if the subdomain is valid and if not, 301 redirects the visitor to the root domain. This way if someone links to blah.blah.domain.com, Search engines should see that as a link to just domain.com. I'm only using language subdomains on my site but it should work for any subdomains you want to use.
Here's the htaccess rewrite:
The regex works by finding the last instance of more than 3 domain-name-valid characters, followed by a dot, followed by any other string. The idea is that it finds the domain name in the url, then captures everything before it. Obviously this wont work for domains which are shorter than 3 characters.
#All sub domains are redirected to p.php for processing:
RewriteCond %{HTTP_HOST} ^(.*)\.[a-z0-9\-]{3,}\..*
RewriteRule (.*) p.php?subdom=%1 [L]
Here's the PHP:
function redirect301($page='/'){
header("HTTP/1.1 301 Moved Permanently");
header("Location:{$page}");
exit();
}
$subdom = $_REQUEST['subdomain']; //you should sanitise this if using this script!
$defaultLang = 'en';
$alternateLangs = "de|es"; //list of allowed subdomains
$alternateLangs = explode('|',$alternateLangs);
if(!empty($subdom) && $subdom!= 'www'){
if( !in_array($subdom,$alternateLangs) ) redirect301(); //redirect to homepage
$ISOlangCode = $subdom; // en,es,de,etc - capture code for use later
}
if($defaultLang && $ISOlangCode == $defaultLang) redirect301(); //disallow subdomain for default language (redirect to homepage)
Hopefully this helps someone out.

Simple mod_rewrite, replace one word in every instance

I've been looking for an answer to this forever and can't find it, yet it seems like it should be so simple!
I want to use mod_rewrite to replace a word in a url in every instance that it shows up, but I don't want a redirect to happen, just changing the way the url appears to site users.
Example:
Change
mysite.com/something/groups/anything...
to:
mysite.com/something/projects/anything...
I know I could go through and start tweaking files but mod_rewrite would work much better because I'm sure I'll mess something up otherwise (for reference I'm using joomla/jomsocial).
RewriteEngine On
RewriteRule something/groups/.*$ something/projects/$1

Apache - Prettifying URLs with mod_rewrite while also catching some edge cases

Sorry to bug everyone with another mod_rewrite problem but you know the drill.
Basically, I have viewer.php, which accepts two arguments, chapter and page. Sometimes people will request a chapter only, and sometimes they will request a chapter and page. i.e. viewer.php?chapter=10 or viewer.php?chapter=10&page=5. The php is smart enough to display page one for users who don't specify a page, and I don't care about users who request viewer.php?page=3&chapter=50, nobody will do that.
I want to hide viewer.php from the public and make the format c5/p3.html and c5 canonical. i.e. example.com/c5/p3.html displays the results of example.com/viewer.php?chapter=5&page=3 and example.com/c5 displays the results of example.com/viewer.php?chapter=5. If I can I'd also like to catch people who forget the .html, i.e. example.com/c14/p3. In all these cases I want their address-bar URL to change as well as them being served the appropriate viewer.php content.
This is my current attempt at doing that, but it has problems.
## PRETTIFY URLS
# We'll help those who screw it up and forget the .html (i.e. /c12/p3), but..
RewriteRule c([0-9\.]+)/p([0-9]+)?$ /c$1/p$2.html [R=Permanent,NC]
# (this is a vestige of when I thought I wanted /p1.html appended for those who didn't specify a page, changed my mind now)
RewriteRule c([0-9\.]+)(/)?$ /c$1/p1.html [R=Permanent,NC]
# The canonical form is /c12/p3.html and that's that.
RewriteRule c([0-9\.]+)/p([0-9]+).html?$ /viewer.php?chapter=$1&page=$2`
This works great for c1, c14/p3.html and c14/p3. But: by virtue of the second RewriteRule (which I can't figure out how to remove without Apache showing a "Moved permanently" error page that links to itself) it transforms c5/ into c5/p1.html when I'd rather it just remove the trailing slash and become c5. It also throws a 404 if the user requests c5/p4/ instead of knowing what they meant and transforming it into c5/p4.html.
As an additional problem, I have a form somewhere that uses method="get" to submit a chapter to viewer.php, and in that case the underlying view.php?chapter=5 structure is shown to them in the resultant URL, so maybe I should add a rule that grabs direct requests to viewer.php and puts them in the newer style somehow.
So, could anyone help me with this? I hope I've been clear enough in what I want. It would seem to me that if modifying my existing code, I need to handle trailing slashes better and somehow clean up requests for viewer.php in the c5 style without causing an infinite loop.
Help is so so much appreciated.
Try these rules:
RewriteRule ^c([0-9]+)/p([0-9]+)/?$ /c$1/p$2.html [R=Permanent,NC]
RewriteRule ^c([0-9]+)/?$ /c$1/p1.html [R=Permanent,NC]
RewriteRule ^c([0-9]+)/p([0-9]+)\.html$ viewer.php?chapter=$1&page=$2

.htaccess - route to selected desination but change browser url

Problem:
I'd like to accept the original request. Say its, /IWantToGoHere/index.php
but I want to return to the browser, /GoHere/index.php
To be clear:
I actually want to send the original request location down to the script requested, however, I want to return the user a browser URL to another destination.
Code:
RewriteEngine on
RewriteRule ^(.*)IWantToGoHere\/\.php$ GoHere/index.php [NC,C]
RewriteRule ^GoHere/index.php$ GoHere/index.php [R,NC]
Notes:
I realize the code above doesn't work. I've tried a number of different calls. I spent umpteen hours yesterday trying every clever solution I could pull out of my limited mod_rewrite knowledge bank. Based on my understanding of mod_rewrite, I don't think it's do able. I understand its not what the preprocessed was designed to do. At least not from anything I could find on the Apache web site. I've been told that if I could dream it up, that it could be done:) I was wondering if anyone had and ideas how to get it to work.
Why would you want to do that?:
Because I do. No really, I want the URL returned to the user for further processing.
weez
If I understand the question correctly, to accomplish this you'll need to send a header from /IWantToGoHere/index.php that redirects to /GoHere/index.php once the script is finished executing. That is, if you want Apache to still call IWantToGoHere but return to GoHere. So at the end of processing for IWantToGoHere script something like this:
header('Location: /GoHere/Index.php');
Which will redirect correctly.