URL rewriting with mod_rewrite to provide RESTful URLs - apache

The web server is Apache. I want to rewrite URL so a user won't know the actual directory. For example:
The original URL:
www.mydomainname.com/en/piecework/piecework.php?piecework_id=11
Expected URL:
piecework.mydomainname.com/en/11
I added the following statements in .htaccess:
RewriteCond %{HTTP_HOST} ^(?!www)([^.]+)\.mydomainname\.com$ [NC]
RewriteRule ^(w+)/(\d+)$ /$1/%1/%1.php?%1_id=$2 [L]
Of course I replaced mydomainname with my domain name.
.htaccess is placed in the site root, but when I access piecework.mydomainname.com/en/11, I got "Object not found".(Of course I replaced mydomainname with my domain name.)
I added the following statements in .htaccess:
RewriteRule ^/(.*)/en/piecework/(.*)piecework_id=([0-9]+)(.*) piecework.mydomainname.com/en/$3
Of course I replaced mydomainname with my domain name.
.htaccess is placed in the site root, but when I access piecework.mydomainname.com/en/11, I got "Object not found".(Of course I replaced mydomainname with my domain name.)
What's wrong?

Try using RewriteLog in your vhost or server-conf in order to check the rewriting process. Right now you just seem to guess what mod_rewrite does.
By using RewriteLogLevel you can modify the extend of the logging. For starters I'd recommend level 5.
PS: Don't forget to reload/restart the server after modifying the config.

Here's a quick overview of what's happening:
RewriteCond %{HTTP_HOST} ^(?!www)([^.]+)\.mydomainname\.com$ [NC]
First, the question mark is supposed to be at the end.
$1 would (should) match anything that is not 'www' 0 or 1 times.
$2 matches anything that is not a character 1 or more times, which theoretically would match a blank space there but likely would never match anything.
Then it requires '.mydomainname.com' after those two groupings.
Your first two conditions are looking for two separate groupings.
I'm not sure exactly how you're trying to set up your structure, but here is how I would write it based on your original and expected URL's:
RewriteCond %{HTTP_HOST} !^www\.mydomainname\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(\w+)\.mydomainname\.com$ [NC]
RewriteRule ^(\w+)/(\d+)$ /$1/%1/%1.php?%1_id=$2 [L]
Basically, your first condition is to make sure it's not the URL beginning with 'www' (it's easier to just make it a separate rule). The second condition makes it check any word that could possibly be in front of your domain name. Then your rewrite rule will redirect it appropriately.
Get rid of the last .htaccess line there in your question...
Someone please correct me if I typed something wrong. I don't remember if you have to have the '\' in front of '\w' and '\d' but I included them anyways.

You are doing it backwards. The idea is that you will give people the friendly address, and the re-write rule will point requests to this friendly, non-existent page to the real page without them seeing it. So right now you have it only handling what to do when they go to the ugly URL, but you are putting in the friendly URL. since no rule exists for when people put the friendly URL directly, apache looks for it and says "Object not Found"
So add a line:
RewriteRule piecework.mydomainname.com/en/(*.) ^/$3/en/piecework/$3?piecework_id=([0-9]+)(.*)
Sorry, that's quite right, but the basic idea is, if they put in the URL you like, Apache is ready to redirect to the real page without the browser seeing it.
Update
I'm way to sleepy to do regex correctly, so I had just tried my best to move your example around, sorry. I would try something more simple first just to get the basic concept down first. Try this:
RewriteRule www.mydomainname.com/en/piecework/piecework\.php\?piecework_id\=11 piecework.mydomainname.com/en/11
At the very least, it will be easier to see what isn't working if you get errors.

Related

How to create a redirect rule for 404 pages with many different path

Here my problem, the site I'm working on has many 404 pages, but they used to be the same pages with a different path
/mens/designers/mens/wales-bonner
/mens/designers/casual-shirts/wales-bonner
/mens/designers/coats-and-jackets/wales-bonner
etc.
THe client wants the redirect to go to the category, so
/mens/designers/mens/
/mens/designers/casual-shirts/
/mens/designers/coats-and-jackets/
I'm pretty sure, there must be a way to have regex rule to cover them all, but I can't seem to find how
Something like
RewriteRule ^/mens/designers/(.*)/wales-bonner /mens/designers/(.*)
but it doesn't work, I don't know how to group the middle part of the URL
Can anyone help ?
I see several potential problems with your rewrite rule:
You have a capturing group in the output URL rather than using $1 to use the result of the capturing group from the input URL.
^/ won't work in .htaccess, only in Apache .conf files. I' would use ^/? instead which will work in either context. That makes the starting slash optional.
You don't include an [R] flag on the rule to make it a redirect.
You don't include an [L] flag on the rule to prevent any following rules from interfering with it.
You can also add "mens/designers" to the capturing group so that you don't have to repeat it in the output. I would suggest:
RewriteRule ^/?(mens/designers/.*)/wales-bonner /$1 [R=301,L]

I want to set up redirects in htaccess from one domain to another but I've gone wrong somewhere

I have a website, let's say fruit.com, and currently I have a bunch of redirects set up that work just fine, so for example fruit.com/apples/mcintosh will redirect to fruit.com/apples.php?id=mcintosh.
I also used to have some redirects set up to allow me to use a short URL, so fru.it/mcintosh would redirect to fruit.com/apples.php?id=mcintosh.
So far so good. A few years ago, though, my short domain lapsed and I didn't renew. Recently I've purchased it again and I'm interested in getting the same setup back.
Now, though, the redirects from the short domain to the main domain aren't working, although I've used exactly the same code, so I'm at a bit of a loss for what's going wrong.
RewriteCond %{HTTP_HOST} ^www\.fru\.it$
RewriteRule ^([0-9]+)$ "http\:\/\/www\.fruit\.com\/apples.php?id=$1" [R=301,L]
although I've used exactly the same code
But the code you've posted won't redirect the stated example URL fru.it/mcintosh, since the code matches digits only, not letters.
Try the following instead:
RewriteCond %{HTTP_HOST} ^www\.fru\.it
RewriteRule ^(\w+)$ http://www.fruit.com/apples.php?id=$1 [R=301,L]
The \w shorthand character class matches upper and lowercase letters, numbers and underscore.
You don't need all the backslash-escapes in the substitution string.
Also bear in mind that the order of these directives can be important. This rule would likely need to go near the top of the .htaccess file to avoid conflicts.
Test first with a 302 (temporary) redirect to avoid potential caching issues. Clear your browser cache before testing.
Aside:
fruit.com/apples/mcintosh will redirect to fruit.com/apples.php?id=mcintosh
It would seem to make more sense that this would be a (internal) "rewrite", not a (external) "redirect"? The shortcode would then redirect to fruit.com/apples/mcintosh, not fruit.com/apples.php?id=mcintosh?

Using .htaccess to control a 'parked' domain

My question is to ask if the level of domain name control I'd like with .htaccess is even possible, and how it might be achieved.
Here's the current situation. At the moment I have a main domain (call it primary.com) that has several language variants, under a file structure like
/lang/chinese
/lang/russian
etcetera. I decided to create a sub-domain for just one of them, so now I have china.primary.com. Of course I created a .htaccess file to make all variants of primary.com and www.primary.com point to the same place (www.primary.com), and now also china.primary.com points to www.primary.com/lang/chinese. Everything works well.
Next I added a second domain (secondary.com) as a 'parked' domain on the site. A little fight with .htaccess and now I have all requests for any version of secondary.com being rewritten as a call to www.primary.com. All good. Then comes the final finesse that is the nub of my question.
While I have anything.secondary.com point to www.primary.com at the moment, is it possible to add in an exception for the possible case where a user tries to access china.secondary.com? In that event I'd like it rewritten to china.primary.com and pointed at www.primary.com/lang/china.
Note I have not created a sub-domain china.secondary.com as my understanding is that it shouldn't be necessary. I think this either can or can't be done through .htaccess alone. Please excuse my iinexperience: what I have works but has been copy & pasted together as a result of finding various examples online. Here is what I have that works well right now - except the final line I added that because I hoped it would solve this, but it doesn't work.
Do I actually have to create a sub domain china.secondary.com for this to work? If so my goal is dead in the water since I cannot create a subdomain on a parked domain, I believe.
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^primary.com [NC]
RewriteRule ^(.*)$ http://www.primary.com$1 [L,R=301]
RedirectMatch 301 ^/lang/chinese/(.*)$ http://china.primary.com/$1
RewriteCond %{http_host} ^secondary\.com [nc]
RewriteRule ^(.*)$ http://www.primary.com/$1 [R=permanent,nc,L]
RedirectMatch 301 ^/lang/chinese/(.*)$ http://china.primary.com/$1
Steered in the right direction by Anubhava I researched this question even more. It seems a basic assumption of mine was incorrect. It looks like you do need to create a subdomain in order to steer people away from it with .htaccess. Seems deeply counter-intuitive to me, but there it is.
Of course I cannot create a sub-domain on a domain that is merely parked with a hosting company, so attempting to support users who mistype a specific subdomain.parkeddomain.com (where they meant to type subdomain.maindomain.com) is in fact, not possible. Very surprising to me indeed, but I learnt something of value. Thank you all those that looked in on this.

multiple folder redirect

I have been trying variations of the following without success:
Redirect permanent /([0-9]+)/([0-9]+)/(.?).html http://example.com/($3)
It seems to have no effect. I have also tried rewrite with similar lack of results.
I want all links similar to: http://example.com/2002/10/some-long-title.html
to redirect the browser and spiders to: http://example.com/some-long-title
When I save this to my server, and visit a link with the nested folders, it just returns a 404 with the original URL unchanged in the address bar. What I want is the new location in the address bar (and the content of course).
I guess this is more or less what you are looking for:
RewriteEngine On
ReriteRule ^/([0-9]+)/([0-9]+)/(.?)\.html$ http://example.com/$3 [L,R=301]
This can be used inside the central apache configuration. If you have to use .htaccess files because you don't have access to the apache configuration then the syntax is slightly different.
Using mod_alias, you want the RedirectMatch, not the regular Redirect directive:
RedirectMatch permanent ^/([0-9]+)/([0-9]+)/(.+)\.html$ http://example.com/$3
Your last grouping needs to be (.+) which means anything that's 1 character or more, what you had before, (.?) matches anything that is either 0 or 1 character. Also, the last backreference doesn't need the parentheses.
Using mod_rewrite, it looks similar:
RewriteEngine On
RewriteRule ^/([0-9]+)/([0-9]+)/(.+)\.html$ http://example.com/$3 [L,R=301]

Apache mod_rewrite not persisting the name

I usually put my mod_rewrite conditions in an .htaccess file, but this is a case where it must go into the httpd.conf file.
I am confused because what I want to do seems simple:
The root of the site is a nested directory: mydomain.com/foo/bar/
It just has to be that way.
I want to write a rule so a person can enter:
mydomain.com/simple and it will show content from mydomain/foo/bar
Also, if a person clicks around the site, I want the mydomain.com/simple/some-other-page structure to persist.
The closest I've gotten is this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^simple$ /foo/bar/$1 [PT]
</IfModule>
However, using this rule, when a person types mydomain.com/simple it rewrites the URI in the browser to mydomain.com/foo/bar
What am I doing wrong?
Thanks in advance.
First, there may be a problem with this rule:
RewriteRule ^simple$ /foo/bar/$1 [PT]
The expression ^simple will probably never match, since all requests will start with a /.
You're using $1 in the right-hand side of the rule, but there are no match groups in the left-hand side that will populate this. This means that a request for /simple would get you /foo/bar/, but a request for /simple/somethingelse wouldn't match the rule. If this isn't the behavior you want, you probably mean this:
RewriteRule ^/simple(.*)$ /foo/bar$1 [PT]
(Note that I've added the missing leading / here as well).
With these changes in place, this rule behaves on my system as I think you're expecting.
Lastly, turning on the RewriteLog and setting RewriteLogLevel (assuming a pre-2.4 version of Apache) will help expose the details of exactly what's happening.