Need to redirect subdomain that has the url as parameter - .htaccess

I'm wanting to redirect
http://m.example.com/?url=http://www.example.com/directory/page.html
to
http://www.example.com/directory/page.html (always the value of 'url=')
The are mobile versions of my site that I want to serve on my main site. Right now the search results contain my mobile pages. Until the main, responsive pages are crawled I want to force them to be viewed.

As mentioned in the comments to the question your incoming url is invalid. The query parameter (the value) would have to be url encoded like that to be valid: http://m.example.com/?url=http%3A%2F%2Fwww.example.com%2Fdir‌​ectory%2Fpage.html. Though probably that invalid URL will work in most cases.
This should do what you are looking for:
RewriteMap unescape int:unescape
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*)url=http(s?)%3A%2F%2F([^%]+)%2F([^&]+)(&?.*)$
RewriteRule ^ http%2://%3/${unescape:%4}?%1%5 [R=301,END]
Note that the RewriteMap directive can only be used inside the http servers host configuration, not in dynamic configuration files. If you need to use such a file (see general note below), you have to split the above into two separate sections:
Inside your http servers (virtual) host configuration:
RewriteMap unescape int:unescape
Inside your dynamic configuration file:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*)url=http(s?)%3A%2F%2F([^%]+)%2F([^&]+)(&?.*)$
RewriteRule ^ http%2://%3/${unescape:%4}?%1%5 [R=301,END]
If you do not want any http GET parameters to be handed over to the final redirection target, then the above can be simplified:
RewriteMap unescape int:unescape
RewriteEngine on
RewriteCond %{QUERY_STRING} url=http(s?)%3A%2F%2F([^%]+)%2F([^&]+)
RewriteRule ^ http%1://%2/${unescape:%3} [R=301,END,QSD]
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Related

How can I apply manual rules in htaccess with one global rule?

I am using OpenCart for my e-commerce software and I have the following requirement I want to have for my store. Certain URLs I wish to apply my own rules before the normal OpenCart rules.
I tried a few tutorials online and the best I have come without causing a 500 is the following - I am placing the URL rules before the Opencart generic one. But it returns 404 in the browser - at least it is not a 500.
RewriteEngine On
RewriteBase /
# MY RULES
RewriteRule ^/bag$ /index.php?route=checkout/cart
# START OPENCART
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
I tried adding the [L] after the custom URL but it still won't display /bag
I should be able to do
/bag which should loading /index.php?route=checkout/cart
And I should be able to follow the rules below which are the normal OpenCart rules. /bag is giving me 404 however.
The documentation of the rewriting module explicitly states that RewriteRules operate on relative paths, when implemented in dynamic configuration files (".htaccess") as oposed to absolute path when implemented in the real http server's host configuration. That means that you need to change your rules matching pattern. Such rule can actually be implemented in a generic patter that will work in both situation which makes the implementation reusable.
Also you need to terminate the rewriting process when that rule gets applied. Otherwise the following rules will again rewrite the result of your own rule which is not what you want.
RewriteRule ^/?bag$ /index.php?route=checkout/cart [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

I need to redirect my dynamic URL to a clean and SEO friendly static URL using htaccess

I am a web developer. I have developed a news portal for my client. But the URLs of the articles are dynamic and I need to redirect it to a static URL for SEO purpose.
The current URL : https://example.com/single-post.php?id=1&category=news&title=this-is-a-title
Desired URL : https://example.com/news/this-is-a-title
Someone please help me.
I have wrote this :
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)(?:&|$)
RewriteCond %{QUERY_STRING} (?:^|&)title=([^&]+)(?:&|$)
RewriteRule ^/?single-post\.php$ /%2/%1 [R=301]
RewriteRule ^/?(.*)/(\d+)$ single-post.php?title=$1&id=$2 [END]
But the URL output is not what I expected. It is like :
https://example.com/this-is-title/?id=1&title=this-is-title
The only title came first without the id and then the old format came again after the slash. I can't understand what is going on here.
What you ask actually is not possible. There is no way for the rewriting module to somehow magically guess the numerical ID of that object you request. What you can actually do is publish URL in the style of https://example.com/news/1/this-is-a-title. Notice the ID in there, that is what is usally done. For that his should point you into the right direction:
RewriteEngine on
RewriteRule ^/?news/(\d+)/(.*)/?$ /single-post.php?id=$1&category=news&title=$2 [END]
Typically your application logic will only need the numerical ID of the requested object to fetch it from your database. So you typically can silently drop the title in the internal rewriting which makes things even more simple:
RewriteEngine on
RewriteRule ^/?news/(\d+) /single-post.php?id=$1&category=news [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
UPDATE:
in your comment to this answer you suggest to also do an explit redirection in case the target URL is used on the client side. Here is a variant of version 2 above which adds that redirection:
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)(?:&|$)
RewriteRule ^/?single-post\.php$ /news/%1 [R=301]
RewriteRule ^/?news/(\d+) /single-post.php?id=$1&category=news [END]
A variant of version 1 would look similar:
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)(?:&|$)
RewriteCond %{QUERY_STRING} (?:^|&)title=([^&]+)(?:&|$)
RewriteRule ^/?single-post\.php$ /news/%1/%2 [R=301]
RewriteRule ^/?news/(\d+) /single-post.php?id=$1&category=news [END]
Is is a good idea to start with a 302 redirection first. And only change that to a 301 redirection once everything works fine. That saves you from hassles with client side caching while you are still trying things out.

Redirect addon domain to webapge htaccess

Not quite sure if this is possible. So I have domain2.com and it maps to domain.com.
On the site I have a page called /domain-2-landing
When I hit domain2.com I want that to redirect to domain2.com/domain-2-landing or even better yet mask domain.com and serve the content of /domain-2-landing
Is this possible via .htaccess?
Your question is a bit vague, since you write about two separate things. Here are two approaches that hopefully will point you into the right direction:
To redirect any request to "domain2.com" to that "landing page" this probably is what you are looking for:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain2\.com$
RewriteCond %{REQUEST_URI} !^/domain-2-landing$
RewriteRule ^ /domain-2-landing [R=301]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
To deliver the content of that page as a response to requests to "domain.com" there are two diffferent situations:
If the domains are served from separate http servers you can use the proxy feature integrated into the rewriting module if the proxy module is installed:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com$
RewriteRule ^ https://domain2.com/domain-2-landing [P,END]
If both domains are served from a single http server you can do something similar as above, if both hosts share the same DOCUMENT_ROOT:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com$
RewriteRule ^ /domain-2-landing [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
These rules will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

How to rewrite rule based on folder and file type in htaccess?

I have been trying to implement a rewrite rule for a downloads folder so that I can serve files that end with .gif, .jpg, .png, .css, .js or .swf and send users to user.php for every other file.
For example: I should hit this URL : www.somewhere.com/downloads/mypic.jpg,
but when I try : www.somewhere.com/downloads/my.pdf I should be redirected to user.php.
So far, I have :
RewriteRule ^*/downloads//!(.*)\.(gif|jpg|png|jpeg|css|js|swf)$ /base/user.php?a=$1 [R=302,L]
Here are some samples for expected behaviour :
good
www.somewhere.com/downloads/mypic.jpg
www.somewhere.com/downloads/otherpic.png
www.somewhere.com/downloads/scripts/jquery.js
bad
www.somewhere.com/downloads/my.pdf > send the request to www.somewhere.com/base/user.php
www.somewhere.com/downloads/readme.txt > send the request to www.somewhere.com/base/user.php
www.somewhere.com/downloads/postman.json > send the request to www.somewhere.com/base/user.php
This probably is what you are looking for:
RewriteEngine on
RewriteRule ^/?downloads/([^/]+)\.(gif|jpg|png|jpeg|css|js|swf)$ /base/user.php?a=$1 [R=302]
The above rule will redirect the browser, so change the visible URL. That is what you suggest yourself in your question. In case you want to implement an internal rewriting instead you need to alter the flag slightly:
RewriteEngine on
RewriteRule ^/?downloads/([^/]+)\.(gif|jpg|png|jpeg|css|js|swf)$ /base/user.php?a=$1 [END]
This rule will work in the http servers host configuration and likewise in dynamic configuration files (.htaccess). Obviously the rewriting modules must be enabled in your http server. If you decide to use a dynamic configuration you need to enable its interpretation first, take a look at the AllowOverride directive in the official documentation for that.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
In your modification of the question it becomes clear that what you try to implement actually is the opposite of what you apparently asked before. Here is a modified version of the above rule:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/downloads/[^/]+\.(gif|jpg|png|jpeg|css|js|swf)$
RewriteRule !^/?downloads/([^/]+\.\w+)$ /base/user.php?a=$1 [R=302]
And another general remark: often it makes more sense to not grant any access directly to files in the server side physical file system but to implement a router script instead which controls access to all such files. This allows for more fine grained access control and keeps the physical layout separated from the URL set you define.
Have this rule inside downloads/.htaccess file (create it if it doesn't exist):
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.(gif|png|jpe?g|css|js|swf)$ [NC]
RewriteRule .* /base/user.php?a=$0 [R=302,L,NC,QSA]
I decided to redirect, when a request to a forbidden extension exists. This worked for me :
RewriteRule ^/downloads/(..(pdf|txt|json))$ /base/user.php?a=$0 [R=302,L]

How to write a 301 redirect from an asp page to a php page in a htaccses file

This code is not responding:
RewriteEngine On
RewriteRule ^/index.asp?lang=he&cid=270$ /?aid=2260 [R=301,L]
The query string ("http get arguments") is not part of the URL when the rule pattern is compared against it. You need to use a separate condition to match it:
RewriteEngine On
RewriteCond %{QueryString} ^lang=he&cid=270$
RewriteRule ^/?index\.asp$ /?aid=2260 [R=301,L]
Also note the additional ? near the start of the rules matching pattern. The URL is compared as relative (so without leading slash) in dynamic configuration files. The additional ? makes that leading slash optional, so the rule now will work in dynamic configuration files (".htaccess" style files) and likewise in the real http servers host configuration.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
this code made my redirect:
RewriteCond %{QUERY_STRING} ^lang=he&cid=270($|&)
RewriteRule ^/?index.asp$ /?aid=2260 [R=301,L]

Resources