Link to home
Start Free TrialLog in
Avatar of Julie Kurpa
Julie KurpaFlag for United States of America

asked on

Get Apache to show alternate image if requested image not found.

Some of our webpages have missing images.

We'd like to have an alternate image show when the requested image is not found.

I'm having difficulty understanding apache documentation on where to put the code needed to do this.  

We have apache2-2.2.12-59.1 on Suse Linux.

The path of images as shown in the apache error_log is:  /mnt/data/pawebdata/images/sketches/*.jpg

I plan to put the alternate image in that same directory called "no_sketch.jpg".

Thank you for your assistance.
Avatar of Julie Kurpa
Julie Kurpa
Flag of United States of America image

ASKER

I've added these lines to the httpd.conf file.

So far, it's not working.  Still shows a little box with "x" in it instead of the alternate image I've called "no_sketch.jpg"

<Directory />
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
  RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
</Directory>
actually, the above statement caused all my web pages to fail.   After qualifying it with a directory path, my web pages work OK but still the alternate image doesn't show.

<Directory "/mnt/data/pawebdata/images/sketches">
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
  RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
</Directory>
Avatar of arnold
I think you should do !-f %{request_filename}
It makes no sense the other way, I

Your second line if you want to run a comparison to see whether the request has a specific suffix, I do not think it is the correct syntax,

It seems, I jumped before,..

http://httpd.apache.org/docs/2.2/rewrite/intro.html

Add mod_rewrite logging to file to determine what is going when your rewrite conditions are accessed/....
Whether it actually get looked at.
Thanks Arnold.  I'm reading the apache link now.

From reading this documentation so far, it appears the correct syntax  for the RewriteCond has to be with the "!-f" at the end.  I can't find anything that specifies otherwise.  

RewriteCond %{REQUEST_FILENAME} !-f

I really, really need help with the syntax of the RewriteRule.   So many people in the internet forums describe exactly what I'm trying to do (which is to replace a missing image that is nested inside a webpage...not the webpage itself....but only the image...with an alternate image.  

The solutions (when given) are all different and each person says it worked for them.  I've tried to mimic the syntaxes with no avail.  

The link you gave in the apache document appears to me to give an alternate webpage if a requested webpage is not found.   I could be completely misreading this but that is how it appears to me.  

Sorry if I'm not explaining myself well.  I don't know all the correct lingo.
The difficulty is that you are checking an image, and I do not think the !-f will validate it . see if !-e an option.
But best is to add the trace within the section where you have it to output to a file, It might be that your rewrite engine is not event on (module not loaded) and those rules are not actually evaluated thus not being processed/acted on.

ReWriteRule * http://www.yourdomain.com/redirect_page_worked.html 

Try create a completely different directory withing images/redirect_everything
and define a rule for that directory that no matter the request it should redirect to the main page



Note further that you have a Directory / specification meaning it will only act within this location, it might be that the definition is applied to a location different where the request is being handled.
Another there are some variations among the version, check which apache version is running on your system. and look for the trace/log http://httpd.apache.org/docs/2.4/rewrite/intro.html

One has that you can define the tracing/logging within the item of interest versus system wide.
Thanks Arnold.

I don't see "!-e" as an option in the apache documentation.  

I will see if I can put a trace in there.  

For your statement :

"Try create a completely different directory withing images/redirect_everything
 and define a rule for that directory that no matter the request it should redirect to the main page"

I don't want to redirect the page.  The other information on the page is very important and should be given.  

I'm uploading a snapshot of the webpage.   It is a property record page which gives building information and, if available, an JPG sketch image of the property.   Some properties have many buildings and would have many sketches.  

All sketches are in the same directory (this is Linux).  The alternate sketch I'd like shown if a sketch is missing is also in the same directory.    

Hopefully the snapshot is help describe what I need.
Here is the snapshot.
missing-image-page.png
We are using apache2-2.2.12-59.1 on Suse Linux.
The suggestion is to test whether an unconditional redirect will work.
i.e. you and I currently working on the assumption that the redirects are evaluated but there is something wrong with them and that is the cause of the thing not working. The other possibility is that your mod_rewrite module is not loaded for the web server such that Rewrite Engine on means nothing and the subsequent RewriteCond, RewriteRule are ignored. and that is what the issue is rather than the syntax used.
Ok.  I get it now.

Let's please see if the rewrite is working at all.

Thanks for your patience as I get my head wrapped around this.  

I did a command that is supposed to tell me if the rewrite is enabled.  The output indicates that it is indeed enabled:

# a2enmod rewrite
"rewrite" already present

So now I want to test the unconditional redirect...right?  I will need help to build the code to do this.

1)  Please confirm that I do this code in the httpd.conf file, right?

The website HTML calls a CGI script.  The CGI script queries an oracle database and builds the property record card.   When it gets to the part about the buildings, it will pull in sketch JPGs from a directory   /webdata/images/sketches and include the appropriate sketches.   I believe the sketch names (which are numeric) are identified in an oracle table.  

There is a vhosts.d directory with ssl and non-ssl configuration files that give aliases for the directory holding the images.  I'm pretty sure that these files are used.  I am using the non-ssl URL so I'm assuming that if I need to modify something in the vhosts.d directory, for this test, I would modify the non-ssl.conf file.

I'm including the alias here in case it is relevant:

Alias /images/ /pawebdata/images/
 <Directory /pawebdata/images>
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>

2.  What code should I try to redirect a page?  should it be with an html or the cgi that gets called?   Not sure how to approach this test.  

Thank you very much.
I just did the following syntax and it worked for those missing images.

<Directory "/images/sketches/">
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ \no_sketch.jpg
</Directory>
Nevermind on that last post.

I found that the developer coded something in his CGI script to handle the missing image without telling me.

When I finish beating him, I may revisit this code.
As to where you would place, it depends if your httpd.conf allowoverride you can use .htaccess to enable rewrites but the logging part is if memory serves is not available at that level, but has to be one at the httpd.conf and would apply to all sites.
The httpd.conf contains the following:

# forbid access to the entire filesystem by default
<Directory />
    Options None
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>

Where do I go from here?  I read in the apache documentation that they do not recommend using ".htaccess" but instead to use httpd.conf.   I'd like to follow the recommendations, if possible.  

Thank you for your assistance with this.
The httpd.conf also has this:

# use .htaccess files for overriding,
AccessFileName .htaccess
# and never show them
<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
</Files>
That is not, look for AllowOverride does it have none or all or something in between. This directive sets whether some or all settings can be overriden within .htaccess.
I'm sorry but I did not understand your sentence.  Would you rephrase it?
What you posted defines the file where one can add rules on which Apache web server can have functionality/features altered .
Within httpd.conf look for AllowOverride this I the directive on what can be altered on the fly by adding directives to .htaccess within a directory that could affect how and what is presented when accessed.

For example, in images you can add the .htaccess with the redirect/rewrite rules you were doing before, but these hangers do not require the restart of the Apache server to take effect.
There is one place in the httpd.conf where "AllowOverride" is specified.   I am pasting it below.

Please tell me what I should change in this (if there is something I should change).  Or do I need to add another one for the directory I have the images stored?

<Directory />
    Options None
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>
Changes are unnecessary since you are implementing your options using httpd.conf

Is this a shared environment or your own server/setup?
Altering AllowOverride to allow .htaccess to include rewriterules, et could make your modification/changes take effect in. More instant matter.
This environment serves a busy public website and nothing else.    I have the advantage of a test environment in which to work on this.  

Where do I alter AllowOverride?  And to what value to I alter it?
Your current setting is none. The most permissive is all. There are individual rights you can grant I.e. Addtype redirect etc.
Here is the reference http://httpd.apache.org/docs/current/mod/core.html#allowoverride the next section deals with allowoverridelist
From the documentation, AllowOverride NONE means that .htaccess files are ignored.

This fine with me because I'd like to do the rewrite inside the httpd.conf file.

 I only want to rewrite missing *.jpg files with a specific jpg called "no-sketch.jpg",  how do I do this?
Unless you are asking me to use the .htaccess file just to see if the rewrite works at all.   Is that correct?
I changed the AllowOverride to ALL in my test environment.   When attempting to do show a record on the website, I get a 403 error and the following appears in the apache error_log:


[Tue Apr 26 11:30:04 2016] [client 172.30.29.19] Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden: /mnt/data/pawebdata/cgi/search.cgi, referer: http://pawebdev1.vcgov.org/searchak.html
Because I wasn't sure where to place the .htaccess file, I had created an .htaccess file in a couple places:

/etc/apache2
/mnt/data/pawebdata/images/sketches  (where all JPGs are stored including the no_sketch.jpg)

I put the following in the .htaccess files:

<IfModule mod_rewrite.c>
  RewriteEngine on
  Options +FollowSymLinks
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
  RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
</IfModule>
The .htaccess files needs to be in the directory path where you want it to apply

/mnt/data/pawebdata/images/sketches
I do not believe .htaccess can load modules, those have to be loaded/activated within httpd.conf

Are you using symlinks?

Usually symlinks are from home/user location to the ......
I only added the symlinks because somebody said they did it to get rid of the 403 error.  I don't know if I'm using them or not.  

So I would just have the following in the /mnt/dta/pawebdata/images/sketches/.htaccess ?

  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
  RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
Here's what I have right now:

The httpd.conf line that had AllowOverride set to "None" now is set to "All":

<Directory />
    Options None
    AllowOverride All
    Order deny,allow
    Deny from all
</Directory>


I created an .htaccess file in the /mnt/data/pawebdata/images/sketches directory with privileges "-rw-r--r--" and owned by the web user that also owns the jpg's.  

The content of .htaccess is:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]


In testing the website, it doesn't change it's behavior.  Still tries to show the original, missing jpg instead of showing the alternate one.  

I added some garbage on the first line of the .htaccess to see if I'd get an error but error_log did not report any thing other than not being able to find the missing image.  

It seems it is not seeing the .htaccess in the /mnt/data/pawebdata/images/sketches directory.
I moved the .htaccess (with the garbage in it) to /mnt/data/pawebdata and am now getting the 403 when trying to view data on the webpage.  

the error log reported:

[Tue Apr 26 13:11:27 2016] [alert] [client 172.30.29.19] /mnt/data/pawebdata/.htaccess: Invalid command 'ladjf;aldfja;ldfja;ldifj;alsdjf', perhaps misspelled or defined by a module not included in the server configuration, referer: http://pawebdev1.vcgov.org/searchowner.html

Then I removed the garbage and put in the rewrite code.  I still get the 403 but the error log reports the following;

[Tue Apr 26 13:13:39 2016] [client 172.30.29.19] Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden: /mnt/data/pawebdata/cgi/search.cgi, referer: http://pawebdev1.vcgov.org/searchak.html
I found a vhost.conf file in the vhosts.d directory that has some settings for the /mnt/data/pawebdata/cgi directory.   See below:

<Directory "/mnt/data/pawebdata/cgi">
   AllowOverride None
   #   Options +ExecCGI -Includes
   Options None
   Order allow,deny
   Allow from all
</Directory>


So I changed the "Options None" to "Options FollowSymLinks".  Still 403.
I changed the "AllowOverride None" to "AllowOverride All".

Now I get the following in the error_log:

[Tue Apr 26 13:46:22 2016] [client 172.30.29.19] Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace., referer: http://pawebdev1.vcgov.org/cgi-bin/search.cgi

Will update if I try anything else.  But really, I'm blindly fumbling around and could use some expertise.
It seems that your validation/rule means that it loops through the changes because the replacement image is within the same section as the one you wish to replace.
instead of RewriteRule
try redirect and point to http://yoursite/images/sketches/no_sketch.jpg

Your use of /mt especially that you seem to be using symlinks, which suggests apache might run into a situtation even through it is following symlinks, it lacks access meaning the ! -f rule is always met.

i.e. apache can get to /mnt and then to /data and then to pawebdata and then it can to images/ but that is here it fails it can not access sketches.
Try adding the first condition to make sure the image being requested is not no_sketch.jpg

RewriteEngine on
RewriteCond %{REQUEST_URI} ^.*\/[^no_sketch\.jpg]$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]

Open in new window

I added your code to the .htaccess file but it's still not redirecting to the "no-sketch.jpg".  

I'm attaching the output from the trace file.
rewrite.log
Here's my entire setup so far:

In httpd.conf:

<Directory />
   Options None
   AllowOverride All
   Order deny,allow
   Deny from all
</Directory>

In vhosts.d config file:

<Directory "/mnt/data/pawebdata/cgi">
    AllowOverride All
    #   Options +ExecCGI -Includes
    Options FollowSymLinks  <-- I added this because I kept getting 403 errors.
    Order allow,deny
    Allow from all
</Directory>

In .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine on
Options +FollowSymLinks  <-- added this because I kept getting 403 errors.
options +SymLinksIfOwnerMatch  <--added this because I kept getting 403 errors.
RewriteCond %{REQUEST_URI} ^.*\/[^no_sketch\.jpg]$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
</IfModule>
~
where is your virtualhost definition ?
Forgive my lack of knowledge on this, I didn't configure this setup, but I think the it must be in this directory:  /etc/apache2/vhosts.d

There are two config files in the vhosts.d directory:

vcpa-non-ssl-vhost.conf  
vcpa-nss-vhost.conf

Since I'm using the "http" path to access the website, I'm assuming I'm using the vcpa-non-ssl-vhost.conf .

The /etc/apache2/httpd.conf has the following line:

Include /etc/apache2/vhosts.d/*.conf

Is that the answer you needed?
Yes. While you define items, they apply in relation to something.

Look in the referenced vhost file and if there is a log define, you can see whether your requests are recorded there. You would then need to add your refirect rules in the vhost file or within .htaccess file ....
What does a "log define" look like?    The only reference to a log in the vhosts file is:

ErrorLog /var/log/apache2/error_log
Here's the stuff that shows in the error_log when I do the test:

[Thu Apr 28 09:26:36 2016] [client 172.30.29.19] File does not exist: /mnt/data/pawebdata/images/sketches/82989.jpg, referer: http://pawebdev1.vcgov.org/cgi-bin/search.cgi
[Thu Apr 28 09:26:36 2016] Unknown cipher des
[Thu Apr 28 09:26:36 2016] Unknown cipher desede3
[Thu Apr 28 09:26:36 2016] Unknown cipher rc2
[Thu Apr 28 09:26:36 2016] Unknown cipher rc2export
[Thu Apr 28 09:26:36 2016] Unknown cipher rc4
[Thu Apr 28 09:26:36 2016] Unknown cipher rc4export
[Thu Apr 28 09:26:36 2016] Unknown cipher fortezza
[Thu Apr 28 09:26:36 2016] Unknown cipher fortezza_rc4_128_sha
[Thu Apr 28 09:26:36 2016] Unknown cipher fortezza_null
[Thu Apr 28 09:26:37 2016] Unknown cipher des
[Thu Apr 28 09:26:37 2016] Unknown cipher desede3
[Thu Apr 28 09:26:37 2016] Unknown cipher rc2
[Thu Apr 28 09:26:37 2016] Unknown cipher rc2export
[Thu Apr 28 09:26:37 2016] Unknown cipher rc4
[Thu Apr 28 09:26:37 2016] Unknown cipher rc4export
[Thu Apr 28 09:26:37 2016] Unknown cipher fortezza
[Thu Apr 28 09:26:37 2016] Unknown cipher fortezza_rc4_128_sha
[Thu Apr 28 09:26:37 2016] Unknown cipher fortezza_null
[Thu Apr 28 09:26:37 2016] Unknown cipher des
[Thu Apr 28 09:26:37 2016] Unknown cipher desede3
[Thu Apr 28 09:26:37 2016] Unknown cipher rc2
[Thu Apr 28 09:26:37 2016] Unknown cipher rc2export
[Thu Apr 28 09:26:37 2016] Unknown cipher rc4
[Thu Apr 28 09:26:37 2016] Unknown cipher rc4export
[Thu Apr 28 09:26:37 2016] Unknown cipher fortezza
[Thu Apr 28 09:26:37 2016] Unknown cipher fortezza_rc4_128_sha
[Thu Apr 28 09:26:37 2016] Unknown cipher fortezza_null
within the vhost file do you have a
<virtualhost ...>
ServerName mydomain.com
ServerAlias www.mydomain.com
DocumentRoot
Log ......
options Definition, etc.

</VirtualHost>
I am uploading the vcpa-non-ssl-vhost.conf file.
vcpa-non-ssl-vhost.conf.txt
I increased the rewritelog trace to 4.  Perhaps this will help.  Am uploading the file.
rewrite.log
Well at least we know that redirect works, but in your log there is no entry that has a check whether the file exists !-f because the negative test to make sure it does not enter this process when no_sketch.jpg is the pattern is not working.


what is reflected in the log when you access http://www.yourdomain.com//images/sketches/no_sketch.jpg?

Usually, the vhost fles are not duplicative of the main httpd.conf which yours seems to be,

usually the VirtualHost file just defines the limited scope of the document root, you could define the cgi-bin directory. Does the system have local users and you want to grant them publishing rights via http://www.yourdomain.com/~username which would mean that /home/username/public_html will have web accessible files?

Certain things are better left to configurations within .htaccess as those can be added at will provided the configuration in httpd.conf and vhost allows it. in the current scenario if you are not doing these tests in .htaccess that you have to restart apache on every change.

lets try the code again tinkering with the formualtion of the query to make sure it does not loop/redirect when no_sketch
RewriteEngine on
RewriteCond %{REQUEST_URI} ^.*/[^no_sketch\.jpg]$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]

Open in new window

or if that also returns the no match when
try which should work, it looks the pattern matcher auto-added an extra escape (\) which may have altered the initial pattern making it appear that it was looking for literally /images/sketches\/ which can never occur. the above and the below should work reflecting a match on an image request.

RewriteEngine on
RewriteCond %{REQUEST_URI} ^.*/[^no_sketch.jpg]$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]

Open in new window

What I am looking for when you access any image other than no_sketch.jpg I am looking for the log to reflect a Match (meaning yep, the file being requested is not no_sletch.jpg)

it might be wiser to move the test for requested file suffixes above the test whether the file exists it may save in evaluation transaction.
is the file not no_sketches.jpg? yes, proceed; no skip the rest.
is the file an image? yes, proceed; no. skip the rest
does the file exist? yes, rewritepointing to no_sketch.jpg; no skip the rest.
I tested with just the link to the no_sketch.jpg and saw the image with no problem.

I saw no errors in the error_log and nothing in the rewrite.log trace.

Then tried code #1 where the extra escape was removed.  I still kept the options specified though.  
The no_sketch.jpg still didn't and I'm uploading the rewrite.log (rewrite-escape.log) of the output.

RewriteEngine on
 Options +FollowSymLinks
 options +SymLinksIfOwnerMatch
RewriteCond %{REQUEST_URI} ^.*/[^no_sketch\.jpg]$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
Tried the 2nd code without the escape.  Same behavior.  Am uploading the rewrite.log (rewrite-no-escape.log) of the output.

RewriteEngine on
  Options +FollowSymLinks
  options +SymLinksIfOwnerMatch
 RewriteCond %{REQUEST_URI} ^.*/[^no_sketch.jpg]$
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
 RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
I found some support forum where the engineer suggested using some funky characters (&#37;) before the {REQUEST_FILENAME}.   Still the same behavior but the output was interesting even though I have no idea what it means.

<IfModule mod_rewrite.c>
RewriteEngine on
Options +FollowSymLinks
options +SymLinksIfOwnerMatch
RewriteCond &#37;{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
</IfModule>
Tried this combination...more interesting.  Uploading rewrite15.log.

<IfModule mod_rewrite.c>
RewriteEngine on
Options +FollowSymLinks
options +SymLinksIfOwnerMatch
RewriteCond &#37;{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png)$
RewriteRule .* /mnt/data/pawebdata/images/sketches/no_sketch.jpg [L]
</IfModule>
Rewrite log not uploaded.
oops.   Forgot to click the upload button.  

Will upload all referenced logs.
rewrite15.log
rewrite_no-escape.log
rewrite-escape.log
note that there is no directory "docs/mnt/data/pawebdata/images/sketches/no_sketch.jpg" as referenced by the logs....  no "docs" in the first octet.  

Paths are:
/mnt/data/pawebdata/docs
/mnt/data/pawebdata/images
/mnt/data/pawebdata/cgi
/mnt/data/pawebdata/scripts
/mnt/data/pawebdata/styles
i think what you saw with the &#38; is merely an encoding mechanism for the forum where it was posed as you note in the rewrite15.log instead of expanding the %{} variable to reflect the requested file, it ..... And matched.

The docs/404.html is the consequence of an erroneous definition of a CustomError handler.

I quick glanced, but did not see where your CustomError rules are defined, but it seems the definition is relative versus explicit I.e. Docs/404.html versus /mnt/paw../docs/404.html.

Variable parameters/env have to be in the form %{parameter}
Am uploading the httpd.conf and the errors.conf.

Is this what you are talking about CustomError rules?
httpd.conf.txt
errors.conf.txt
I may have gotten it to work.  Still skeptical...need more testing...

Here's what I've done:

Removed the .htaccess file.

Added the following to the vhosts file (note removal of the options):

<IfModule mod_rewrite.c>
RewriteEngine on
# Options +FollowSymLinks
# options +SymLinksIfOwnerMatch
RewriteCond {REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} "\.(gif|jpg|jpeg|png)$"
RewriteRule images/sketches/\.* "/mnt/data/pawebdata/images/sketches/no_sketch.jpg" [L]
</IfModule>

It's not producing anything in the rewrite.log.  I suppose that may be because it's not using the .htaccess file?
further testing shows that the "no_sketch.jpg" is showing for all the images instead of just the missing ones.
I added the RewriteLog to the code in the vhosts file and got some information.  Will upload.  

Below is what I now have in the vhosts file.   All images in the /mnt/data/pawebdata/images/sketches path are being replaced with the "no_sketch.jpg" instead of only the missing ones.

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteLog /var/log/apache2/rewrite.log
RewriteLogLevel 4
RewriteCond {REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} "\.(gif|jpg|jpeg|png)$"
RewriteRule images/sketches/\.* "/mnt/data/pawebdata/images/sketches/no_sketch.jpg" [L]
</IfModule>
rewrite20.log
Closing up for the weekend.  I really hope you can help me further on Monday?
rewrite rule I think rewrites, you might want to use the redirect instead.
try rewriterule /images/sketches/(.)$ /images/sketches/no_sketch.jpg


<IfModule mod_rewrite.c>
RewriteEngine on
RewriteLog /var/log/apache2/rewrite.log
RewriteLogLevel 4

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} "\.(gif|jpg|jpeg|png)$"
RewriteRule ^(/images/sketches/) .*$  $1/no_sketch.jpg [PT] 

Open in new window


Then try Redirect ^(/images/sketches/).*$ $1/no_sketch.jpg

your log still matches on every !-f because you forgot to add the % to indicate environment variable.
Thanks!
The first one didn't seem to work and still tries to show the missing jpg.  I'm uploading the rewrite22.log for you if you want it.
rewrite22.log
The 2nd line of code you suggested does the same behavior where it still tries to show the missing jpg.  Am  uploading the rewrite23.log for you to review, if helpful.
rewrite23.log
Could you pease access the image http://www.yourdomain/images/no_sketch.jpg?
What do you see, do you also get the 404.html error page?
Yes, I see the 404.html error page.
I put in the path of another sketch and the image came right up.  Then when I refreshed the page, I got the 404.  

I checked the privileges of the no_sketch.jpg and it is the same as the others.
I'm uploading the rewrite.log for a search for an existing jpg.    

Here is what I currently have in the vhosts.conf:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteLog /var/log/apache2/rewrite.log
RewriteLogLevel 4
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} "\.(gif|jpg|jpeg|png)$"
RewriteRule  ^(/images/sketches).*$ $1/no_sketch.jpg
</IfModule>
rewrite-for-existing-jpg.log
Double check your DocumentRoot definition which seems to be where the docs reference is coming from.

172.30.29.19 - - [02/May/2016:09:40:40 --0400] [pawebdev1.vcgov.org/sid#7f9b4cc69bf0][rid#7f9b4cd75cc8/initial] (2) prefixed with document_root to /mnt/data/pawebdata/docs/images/sketches/no_sketch.jpg
172.30.29.19 - - [02/May/2016:09:40:40 --0400] [pawebdev1.vcgov.org/sid#7f9b4cc69bf0][rid#7f9b4cd75cc8/initial] (1) go-ahead with /mnt/data/pawebdata/docs/images/sketches/no_sketch.jpg [OK]

Open in new window

I see in the vhosts.conf file, there is a "DocumentRoot /mnt/data/pawebdata/docs".

Like I said earlier, I didn't configure the apache on this server but am only trying to get this one thing to work for missing images in the "/mnt/data/pawebdata/images/sketches" path.

The DocumentRoot /mnt/data/pawebdata/docs path is where all the "html" documents are located.
Also some JPGs used by those documents.

The path /mnt/data/pawebdata/cgi is where the compiled cgi is that does the database queries.   The CGI program is what calls the jpgs in the "/mnt/data/pawebdata/images/sketches" path.

I don't know if the person to put the DocumentRoot in the vhosts.file did it for a particular purpose.  What do you think I should do?
there's an aliase set for the "/mnt/data/pawebdata/images" path in the vhosts.conf file.  Can we utilize that?

Alias /images/ /mnt/data/pawebdata/images/
 <Directory /mnt/data/pawebdata/images>
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>
I am not sure why you are defining aliases when the directory is in the path.

I do not understand how your vhosts are organized. and how you are hosting your site/s.

Commonly, httpd.conf defines certain parameters for default web site.
the vhost in /etc/httpd/conf.d/domain1.com defines how the requests received by the web server are routed using name based hosting when you only have one IP.

the vhose file defines the <virtualhost *:80>
SeverName mydomain.com
ServerAlias www.mydomain.com
DocumentRoot /
CustomError.

and so on and so.......

then within this virtualhost you can define the aliases, redirect rules.



Do you have it so the HTTPd.conf and the vhost fles are basically a continuation of the single server/site setup?
I'm sorry but I don't fully understand your last question.    I didn't configure this apache environment and am coming in to modify someone else's work.  

I have previously uploaded the vhosts.conf file.  Would you benefit by my uploading the httpd.conf file?
Your documentroot has docs at the end, when using rewriterules, aliases are not how /images/sketches/no_sketches.jpg is interpreted instead it appended to the DocumentRoot. Instead if rewriterules use redirect to http://www.yourdomain.com/images/sketches/no_sketches.jpg
I need help with the redirect then please.
Replace the rewriterules
With
Refirect .* http://www.yourdomain.com/images/sketches/no_sketch.jpg
Another option is to create a symbolic link in docs to point to the images directory.
Thanks.   I have the following in the vhosts.conf file:

 <IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteLog /var/log/apache2/rewrite.log
  RewriteLogLevel 4
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_URI} "\.(gif|jpg|jpeg|png)$"
  Redirect  .* http://pawebdev1.vcgov.org/images/sketches/no_sketch.jpg
 </IfModule>

The "no_sketch.jpg" image is not showing for the missing jpg's.

Am uploading the rewrite.log
rewrite.log
ASKER CERTIFIED SOLUTION
Avatar of Julie Kurpa
Julie Kurpa
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Double check that your test environment DocumentRoot  is defined the same way as the production.
The issue is that your site stracture is such that images are outside the DocumentRoot for some reason and uses alias to define /images/

...
I agree that having the images somewhere else is the problem.  It's just what the people who configured this decided to do.  

I hope, hope that the production is the same as Test.  It should be, but I will be doing comparisons.  

Thank you for your patience Arnold.    I hope that this helps someone else with the same issue.
I suspect the consideration dealt with backup of site and minimizing the size of the backup as the text files can compress significantly while binary image can not.
I think something else is/was going on that interfered. your rewriteRule earlier referenced full path yet it was not working, the change is effectively converts the two checks in three lines to be two checks in two lines.

http:#a41571366
Yes, I had the full path in the Rewrite Rule, but it was replacing all JPGs with the no-sketch.jpg.

So it appears, it just wasn't able to restrict the RewriteRule to only a missing JPG unless that path was included with the {REQUEST_URI}.  

In trying some alternate versions of the RewriteCond line with the {REQUEST_URI}, nothing works unless I have that path specified.  

The line, RewriteCond %{REQUEST_FILENAME} !-f,  seems to have no effect on anything in my environment.  

I hate being sloppy, but if this is the only way to get it to work because of the file structures, then I guess I have to be sloppy.   :(
Do you know if Apache can still write something in the error_log to show that a Rewrite was done for a missing JPG?
Something similar to the previous error when it didn't find the JPG all like below?

[Tue May 03 14:03:37 2016] [client 97.96.228.194] File does not exist: /mnt/data/pawebdata/images/sketches/265668.jpg, referer: http://www.vcpa.vcgov.org/cgi-bin/search.cgi

I have a script that monitors the error_log for errors related to "sketch".  When it finds one, it emails me the name of the sketch.  

I'd like to still be able to identify the missing JPGs but with this code in place, it no longer reports the 404 in the error_log.
It is no longer seen as an error by apache so no error log entry will be created/added.

Look at mod_rewrite and logging settings that you could use to record when the rewrite is triggered. i.e. you will not have it as verbose as it is now and will only record the !-f matched event. in your rewrite file.

Alternatively, instead of redirecting to a static image, you could redirect to a dynamic reference that will output the no_sketch.jpg while recording/notifying you of the missing file.
Though it will take

RewriteRule (/images/sketches/.*)\.(gif|jpe?g|png|bmp)$ "/mnt/data/pawebdata/cgi-bin/missingsketch.php?'$1.$2'" [NC,L]

the missingsketch.php can respond with
Content-Type: image/jpg

stream out the contents of no_sketch.jpg or issue a Location: http://www.yourdomain.com/images/sketches/no_sketch.jpg

while after that Query_string will have the requested image which it can notify you via email or record in a .......
Thanks...I will look into running a script through the RewriteRule.  

I'm having trouble figuring out how to apply points in this Question.   Do you have suggestions?
You can pick one comment as the best solution, and any other comment as assisted solution if multiple comments helped you. You can also combine picking comments as helpful and your own as the solution. this will trigger an automated review process.
Start selecting comments that you find assisted with the best solution last.
I appreciated the efforts by the other commenter, but none of their suggestions or comments got me to the answer.   I ended up finally finding some blogger site that helped me assemble the correct code.  
I reviewed and reviewed the commenter's submissions and could not find any resemblance to the solution beyond what I had already put together myself.  
Selecting any of Arnold's comments as a solution would have been misleading.  Perhaps the moderators would have a different opinion?