Fairly basic mod Rewrite issue - mod-rewrite

My site filters everything through the index.php script, and in reading the docs for mod_rewrite, it seems pretty darn easy, but I'm a bit stuck. I figured I would begin a page at a time to see if i could get it to work, and got stuck pretty quickly.
I have user profiles, the longform of which is basically:
http://www.mysite.com/index.php?content=profile&id=2172
So i added one Rewrite rule to my .htaccess file that sits in the root folder:
RewriteRule ^profile/([0-9]+)$ index.php?content=profile&id=$1
The idea is now to be able to enter mysite.com/profile/2172
The redirect does bring up the proper page, but what is happening is that every CSS file, image, etc is getting /profile/ added in the middle, which is of course not where the image and CSS files are located. I use relative pathnames in the code so an example of an image in the code might be: images/userimage.jpg
What is happening is that the relative link shown above gets turned into:
mysite.com/profile/images/username.jpg
To me that makes no sense as the image path does not match the rewrite pattern (/profile/*), so why does the bogus path add /profile/ to all of my internal links?
I tried adding RewriteCond %{SCRIPT_FILENAME} !-f to the htaccess just before the rewriterule just to see what happened, no change.
Sorry if this is a simple and basic question, but can anyone with real mod rewrite expertise give me some pointers so that I can make this simple case work and bring up the page with the proper references in my code to my included css and image files? I didn't use any flags to the Rewriterule since I only have that one line after the engine is turned on (and the followsymlink line is there as well).

To me that makes no sense as the image path does not match the rewrite pattern (/profile/*), so why does the bogus path add /profile/ to all of my internal links?
Your images are relative to the page being served, which does have /profile/ e.g. mysite.com/profile/2172. You may want to consider changing your image/css links to be absolute from root i.e. /images/imag.jpg.
If that is not possible you could use another rewrite to correct the issue (just for this case, not really recommended in general) as below.
RewriteEngine on
RewriteBase /
#rewrite to remove profile for jpg, css etc, must go above existing rule below
RewriteRule ^profile/(.+\.(jpg|css|js|png))$ $1 [L,NC]
#existing rule
RewriteRule ^profile/([0-9]+)$ index.php?content=profile&id=$1 [L,NC]

Related

Htaccess direct linking image to page

I'd like to prevent direct image viewing without the entire page.
If someone goes to
mysite.com/images/image1.jpg forward to mysite.com/image1.htm
mysite.com/images/image2.jpg forward to mysite.com/image1.htm
mysite.com/images/image3.jpg forward to mysite.com/image2.htm
mysite.com/images/image4.jpg forward to mysite.com/image2.htm
Is Htaccess the best way to do this and how would I set it up?
You can check for the "Referer" request header. Browsers sometimes use it to tell the server what URL told the browser to load the file. However, not all browsers will use the referer header and it can easily be forged, so this is not a sure way to prevent direct linking to your images.
You can add this at the top of your htaccesss file:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https?://mysite\.com/
RewriteRule ^images/(.+)\.jpg$ /$1.html [L,R]
Reading the comments, I'd recommend to avoid maintaining N RewriteRules for N images. Such a setup will turn into a maintenance nightmare for the site admin who will need to copy and paste a new rule for every new image on the site. And if you ever need to change the rules, well... good luck with that.
If you have the flexibility to choose a better directory structure, it can simplify your .htaccess file down to a single rewrite rule. In that case, you can choose a directory structure where given a path to an image you can easily determine the path to the page it belongs to. For example:
root/
.htaccess
page1/
index.html
image/
image1.jpg
image2.jpg
page2/
index.html
image/
img.jpg
Here the rewrite definition within root/.htaccess is simple (adapted from #jon-lin's answer):
# Rewrite any image URL `/<page>/images/*` to `/<page>/`.
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https?://mysite\.com/
RewriteRule ^([^/]+)/image/ /$1/ [L,R]
Pros
One RewriteRule to rule them all.
Your images do not have to be .jpg, as long as they reside in /<page>/image/.
Cons
Need to reorganize existing files.
Directory structure very tailored to the rewriting problem. It would be awkward for a page to access an image which "belongs" to another page.

redirect image to different image htaccess

I have tried cpanel redirect but it is not specific. I made a change to my site where anyone using a now old image needs to show a new image. I would like to redirect the link to the old image to the url to the new image.
I have an image
http://mysite.com/images/image.png
When the image is called I want to show
http://mysite.com/images/image.gif
What do I add to htaccess to create this specific rule?
Note that image1 is a png and I am replacing it with a gif so I cant just overwrite with the new image. This is why I am looking for a redirect solution.
EDIT: I can give the image the same name, it will just have different extension.
EDIT 2: change to show image would have the same name, different extension.
A simple URL rewrite should do the trick!
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^images/([a-zA-Z0-9]+).png$ images/$1.gif
Whatever is entered here '([a-zA-Z]+)' will be entered here '$1'. Hope that makes sence.
Let me know how you get on!
(Note: there is no rewrite condition to check if the file exists because you want the url rewritten whether there is a file there or not)
Edit:
Probably best to put a .htaccess in the images directory, in this case you can miss out the file paths as you are already in the directory.
If you're looking to replace this one specific image1.png to image2.gif, then this rule should work:
RewriteRule ^images/image1.png$ images/image2.gif [NC,L]
If you're looking for something more general-purpose, then it depends on your image naming.

Remove encoded question mark from URL

Hi I started a fact check wiki where each fact check page page ends in a question mark, for example:
http://wecheck.org/wiki/Did_Mitt_Romney_ever_work_as_a_garbage_collector%3F
But when I share this link on many sites including Facebook by pasting it into a comment box, it strips the %3f (thinking it's the start of a query string I guess) making the link unreachable. I have to use bit.ly to connect to the link which is inconvenient and a problem for novice users.
I think I may be able to use mod-rewrite to take the %3F off. My current rewrite rules are:
RewriteEngine On
RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]
RewriteRule ^/?$ %{DOCUMENT_ROOT}/w/index.php [L]
How would I modify them to strip out the %3F ?
It doesn't look like you want to strip out the %3F. Mediawiki has its own routing so if you mess with the title names, you're more likely break something than fix anything. You need to modify your media-wiki to either disallow pages with a ? at the end, or add a module or wiki bot to go through all the pages, and if there's a page that ends with ?, create a #REDIRECT [[]] page without the ? and point it to the page with the ?.
The answer is to create pages that do not have question marks at the end and then set
$wgRestrictDisplayTitle = false; in LocalSettings.php
and use the following magicwords in the page markup:
{{DISPLAYTITLE:{{PAGENAME}}?}}
You can see an example here: http://wecheck.org/wiki/Question_Mark_Problem

Apache serve default image when an image is missing

We have several different size images for products. We want to return the correct size default image whenever the product image is missing.
The path to the images are different for each product.
path /www/docroot/images/brand/product/product1_l.jpg
path /www/docroot/images/differentbrand/differentproduct/someotherproduct1_l.jpg
The size of the images look something like the items on the left. We would want to chose the corresponding default image on the right.
product1_l.jpg large noimage_l.jpg
product1_m.jpg medium noimage_m.jpg
product1_s.jpg small noimage_s.jpg
I have seen some examples of people achieving something similar using mod_rewrite. Can anyone give any guidance on how I can use that to fit my scenario?
You need an intelligent 404 handler. If Apache throws a 404 (File not found) error the intelligent handler should try to salvage the event by looking at the pattern of the URL, and locating a known resource to serve instead. You should also handle the possibility that the fall back image might also not be there.
This page can show you how to check if a file is present, but the logic will need to be in the last line.
http://www.phpriot.com/articles/search-engine-urls/5
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1
Or you can go the .htaccess route (I think that's cleaner)
http://httpd.apache.org/docs/2.2/mod/core.html#errordocument
Assuming you could use .htaccess and PHP here is one solution:
Add this line to your .htaccess:
ErrorDocument 404 /error.php
Then add this code to you error.php like this
<?php
if(preg_match("/^/images/thumbnail/", $_SERVER['REQUEST_URI'])) {
//do a 302 redirect
header( 'Location: /images/defualtImage.jpg' ) ;
} else {
//You need to go somewhere to handle actual 404 errors
header( 'Location: /static/404.html' ) ;
}
?>
302 redirect directs would work best here.
Thanks for all your comments. We ended up going with a different solution. We used the onerror js tag to point to the appropriate noimg location. This was cleaner and easier for our environment

RewriteRule doesn't work as I expect

I want the following url:
http://www.mydomain.com/search/string
to go to
http://www.mydomain.com/dir/search.php?param=string
This is my rewrite rule:
RewriteRule ^search/(string)$ /dir/search.php?param=$1 [NC,L]
What's driving me crazy is that it sort of works. All the links within the result page have 'dir' within the a elements. For example, I hover the mouse over a link that shows
http://www.mydomain.com/search/myawesomescript.php
in the status bar. The correct URL is
http://www.mydomain.com/myawesomescript.php
The .htaccess file is at the root. Why does 'search' insert itself into the rewrite? What is it that I don't understand?
Your RewriteRule is telling apache that if requests come in to search/(string) they should be handled by /dir/search.php, but it does not do anything to change the URL as being displayed.
What you're talking about would be accomplished by something like this:
RewriteRule .* /dir/search.php?param=$1 [NC,L]
Keep in mind this wold redirect everything to search.php, so you'd want to either modify the regex or use some RewriteCond rules to limit the scope.

Resources