PC Plus HelpDesk - issue 227
This month, Paul Grosse gives you more insight into
some of the topics dealt with in HelpDesk and HelpDesk
Extra
From the pages of HelpDesk, we look at:
- Apache Fancy Indexing;
- Arbitrary angle motion blur; and,
- JPEG compression.
From HelpDesk Extra, we look at Server-Side
Includes (SSIs):
- Configuration file;
- Code in html files; and,
- Code to run.
|
 |
HelpDesk
Apache Fancy Indexing
Usually, if a file called index.html exists in a
directory, that file will be sent to the client by the
server when it gets a request for the default file in a
directory so, when asking for http://www.foo.com/, the
file http://www.foo.com/index.html will be sent. The
default file does not have to be index.html, this can be
changed if you want using the DirectoryIndex directive.
In httpd.conf, you should find the line
DirectoryIndex index.html
so, if you want to use home.htm as your default file,
just change this to...
DirectoryIndex home.htm
If, however the default file is not there and Fancy
Indexing is turned on, you will get a page that Apache
has created dynamically for you.
To turn it on, you need a module loaded, so you need a
like that looks like...
LoadModule autoindex_module /usr/lib/apache/mod_autoindex.so
and also a line like
AddModule mod_autoindex.c
These should be in your default Apache htpd.conf file
and you just need to make sure that they are there if you
cannot get it working.
With the module loaded and added, that page looks like
the one below...
 |
| If you click the column links, the page is
re-sent using the column you clicked on to order
the page contents - clicking again reverses that
order. Whist this is good enough for most
purposes, you can add a personalised header and
footer to the page. Again, this is done by adding
files to the directory. To get the header, you
add a file called 'HEADER' and to get the footer,
you add a file called 'README' as follows...
|
 |
If you want to change the name of those
files, you can find the lines in the httpd.conf
file that read...ReadmeName README
HeaderName HEADER
and replace the names of the file with
whatever you want. The content of the header and
footer files can be just plain text. If it is
only text, it will appear at the top or bottom of
the page as though it was between <PRE> and
</PRE> tags.
You are not limited to using plain text
though. If you want, you can put html in there to
do whatever you want. However, remember that you
don't need to add the <HTML> <HEAD>
<TITLE> </TITLE> </HEAD>
<BODY> tags or, in the footer (README
file), the </BODY> </HTML> tags.
Remember though, that if you do use html tags,
any plain text will just be mangled in the way
that web pages mangle plain text - ie, that all
new lines are ignored and spaces are condensed
down to a single space so if you have some
formatted text such as that ascii art picture
you've been working on for days or as in 'VIDEO'
in the example above, this will just become
meaningless unless you do bracket it with
<PRE> and </PRE> tags.
VVV VVV IIIIIII DDD and so on.
If there are files in the directory that you
want to hide from the index, you can hide them by
using the IndexIgnore directive inside a
</Directory> in the httpd.conf like so
IndexIgnore HEADER README .htaccess *~
In this way, you can refine the list so that
people can only see what you want them to.
If you have run a web server for a while, you
will notice that some search engine spiders will
try to get a fancy index by supplying the server
with a request for the directory with the
conditions appended as though they had already
got a fancy index - in a directory that has an
index.html file. ie...
http://myserver.com/abcdef/?M=A
On Apache, this gets them nowhere.
You can find out more about Fancy Indexing
from http://httpd.apache.org/docs/mod/mod_autoindex.html
|
|
Arbitrary angle motion blur
If
you blur a normal photograph, such as the one of
the Roborovski hamster on the right, you can blur
it at any angle you want. and it will look all
right (assuming that blur is the effect you
want). |
Like,
so. This is because there are different sized
areas of different densities and the viewer
concentrates on details (s)he recognises. |
However, if you want to blur
something that only has small details and you
want to use an angle that is close to a multiple
of 45 degrees, you have something of a problem.
Take the image on the right... |
If we give this a blur of 16 pixels,
on an angle of 4 degrees and then bring the
density range up so that we can see what we are
looking at (as I will do with all of these as the
dots will get lost if I don't), we see that there
are distinct steps in the blur trace. |
We can get around this by scaling up
the image by, say, a factor of four and using no
interpolation method so that the pixels end up as
squares like so... |
Next, we apply the blur (remembering
to multiply the distance by the same factor that
we blew up the image by), like so...You can
see that the lines are still stepped over the
pixels but how they render themselves in the
final image depends upon how you scale it down
again...
|
| Using no
interpolation, we get the same
image that we would have got if we hadn't
bothered to do the scaling at all... |
 |
 |
|
| Using linear
interpolation, we get better
results - on the right, the full image
and on the left, a blow-up of it. |
 |
 |
|
| Finally, this is with cubic
interpolation which is the
better of the three interpolation methods
that are on offer with the Gimp 2.0. |
 |
 |
|
If your graphics package cannot do arbitrary
blur angles, you can blow up the image, then rotate it,
blur it at 0 degrees, rotate it back again and then
shrink it back down again. Again, the reason for blowing
it up is so that any cross-pixel steps are obscured.
You might notice in the blown up images above, that
there are a number of distinct steps in the density of
the blurred dots.. If you want this to be smoother, you
can blow it up by a larger factor but remember that in
your strive for perfection, you might be chasing detail
that nobody is going to look for.
|
JPEG compression
Many cameras come with jpeg compressed files (.jpg)
being the only option for the image files they produce.
Whilst it is commendable that they conserve memory use by
using a compressed image file format, jpeg does leave a
number of artefacts in the reproduced image.
One of the predominant artefacts is the way that the
compression puts everything into blocks. This is noticed
if you are doing anything that cuts down on the number of
colours (such as posterisation) or enhances any edges
(edge detect ends up with loads of edges that run in a
square fashion in addition to the edge lines that you are
actually interested in.
One advantage about jpeg is that you can control the
level of compression so that you can balance image file
size against image quality.
| |
Quality |
Size
(/kB) |
Saved
Image |
Enhanced
Portion |
| This is the photograph of the
Horse Chestnut in all of its autumnal glory saved
as a JPEG image file with least compression. If
you want to see the .png file that these images
came from, just click here.
Even with this amount of compression (taking
the original 396kB and compressing it to 51.5kB),
you can still notice some block-like structures
in the enhanced slice on the right.
|
1.00 |
51.5 |
 |
 |
| 0.80 gives a fairly good pay-off
of image size for quality if you are going to use
the image on the web. In the enhanced slice,
you can now see, more plainly, square features
creeping into the image.
|
0.80 |
14.9 |
 |
 |
| At 0.60, the image is down to
10kB and whilst looking all right, the enhanced
version is showing distinct blocks now. |
0.60 |
10.0 |
 |
 |
| At 0.40, the plain image is
starting to show some signs of blocks. |
0.40 |
7.7 |
 |
 |
| By 0.20, the image is not really
good enough to show on the web. If you had
trouble seeing where the artefacts were on the
enhanced version, you can now see where to look
from this one and when you look at the images
above, they will be clearer.
|
0.20 |
4.9 |
 |
 |
| This is for the morbidly
curious. You can see how JPEG creates blocks of
plain colour and blocks that have gradients in
them. In the enhanced image, you can see a new
design for that tiling project for the kitchen.
|
0.00 |
0.9 |
 |
 |
All of these images were produced on the GIMP
version 2.0. The enhanced versions were created using
Filters> Enhance> Sharpen... with the sharpness set
to 90.
|
HelpDesk Extra
Server-Side Includes
Server-Side Includes (SSIs) allow you to have dynamic
content in your web pages without having to go to the
length of producing pages that are made up entirely of
program-generated html code. Whilst CGI (Common Gateway
Interface) scripts are an effective way of processing
forms and other user input, they are something of a
sledgehammer of a way of doing things. For SSIs, a walnut
sized problem, you do not need such a sledgehammer.
In effect, SSIs allow you to have a normal html file
but include within it, a reference that the server will
see and then process. In the final output, the reference
is replaced completely so the user will not be aware of
the existence of SSI code in the original html file.
To get the server to read through the file (parse it),
we need to let it know that it needs parsing. There are
two ways of doing this:
- Use a special file extension such as .shtml; or,
- Set a meta-data bit on the file.
Apache supports both of these. It is better to use the
normal file extensions because:
- The end user will not be aware that they are
getting the opportunity to run a program on your
server; and,
- Any file that you decide to add SSI code to will
not need to have its file extension changed
(easy) or have every page that refers to it
changed so that the new reference has the new
extension (difficult).
To get Apache to use normal (.html) file extensions,
you need to set the executable bit on the file so that
the file is executable. Unfortunately, Windows doesn't
recognise files by their content, only by their extension
so you cannot do this on Windows.
Linux, *BSD et al
However, on Linux (et al), you can modify the x-bit
simply by
right-clicking
on the file and selecting properties... |
...
then, making sure that the exec bit is checked. |
Windows
On Windows, you can only change the file extension to
.shtml
Configuration file
General
In order to make SSIs work, you need to have
directives in the httpd.conf file that reads...
LoadModule includes_module /usr/lib/apache/mod_include.so
.. and also a line like ...
AddModule mod_include.c
.shtml (Windows, Linux, *BSD, UNIX...)
To get Apache to read .shtml files, you need to have a
couple of lines in httpd.conf as follows...
AddType text/html .shtml
... which adds .shtml to the list of file extensions
that are to be considered fair game for the server,
and...
AddHandler server-parsed .shtml
... which tells Apache that .shtml files need to be
scanned through for SSI code instead of just being copied
to the client's browser.
x-bit (Linux, *BSD, UNIX...)
To get Apache to search through normal .html files
that have the exec bit turned on, you need a line in the
httpd.conf file that looks like...
<IfModule mod_include.c>
XBitHack on
</IfModule>
Apache will now parse .html files with the x-bit on.
Just before we leave the httpd.conf file, there are
still one or two things we can do with it that are
related to SSIs.
We can add a line that look at the browser and,
dependent upon the type of browser, set various
variables. This is done by having a line that looks
like...
BrowserMatchNoCase MSIE IE
...which looks for the string 'MSIE' in the browser
information that the browser sends Apache. As the name
suggests, it is case-independent. If it finds the string,
it sets the variable 'IE'. You can, of course, look for
other sub-strings such as Gecko, Firefox, Links and so on
and have any number of variables. We can use these
variables in the SSI code as follows...
|
Code in html files
Now that we can get Apache to read our .html files for
code, we need to put some code in there.
With SSIs we can do many things:
- select static text from within the page - no
external references
- add static text from other files - insert the
contents of another file
- add dynamic text from local variables
- add dynamic text from a script.
All of this is achieved without having anything
special on the URI (the browser address line) other than
the page name that is being requested.
Dynamic Text - Local Variables
So, as an example, to add the date, we need to use the
DATE_LOCAL variable within our html file. This is done
like so...
<!--#echo var="DATE_LOCAL" -->
The <--#command other necessary bits --> part is
replaced so remember to include spaces where necessary.
Select Static Text From Within Page
To select text from within a page, you need to have
some way of knowing what is gong on (otherwise you may as
well just use static text). So, if in your httpd.conf
file, you have set a variable for MSIE (which you have
called 'IE') and one for NetScape (which you have called
NETSC), you can now use them for selecting code within
your page. Thus...
<p>
<!--#if expr="${IE}" -->
You are using Internet Explorer.
The United States Computer Emergency
Readiness Team (US-CERT) suggests that
you use a different browser.<br><br>
Also, there are some issues with
standards compliance with this browser
so you might have a degraded experience
of these pages as a result of this
non-compliance.
<!--#elif expr="${NETSC}" -->
You are using Netscape.
Some of the functionality of these
pages will be lost as a result of
standards non-compliance.
<!--#else -->
Have a nice Day
<!--#endif -->
</p>
You can, of course, include anything you want
including html tags that refer to images and so on.
Add Static Text From Other Files
To add the contents of another file, you just need to
make sure that the context of that file is correct (if
you are adding something to the middle of a table, such
as a menu, you need to have your html tags sorted out).
If we have a partial file called specialmenu.txt and
we wanted to include it, we would need the line...
<!--#include virtual="specialmenu.txt" -->
which simply replaces the text between the <>
(as well as the < and the >) with the contents of
the file specialmenu.txt.
The contents of the menu file would be along the lines
of...
<center>
<a href="index.html">Home</a><br>
<a href="blog.html">WebLog</a><br>
<a href="dls.html">Downloads</a><br>
<a href="links.html">Links</a><br>
</center>
.. which, whilst making it easy to update the menu for
all of the pages, would have the disadvantage of giving a
live link to the page that the user was already looking
at.
Add Dynamic Text From A Script
To add dynamic text from a script (instead of having a
file with the text already in it, we run a program that
generates the text according to a set of conditions) such
as if we wanted to have a program that generates a menu
that has a current-page-link that is not live, we need to
use a line like the following in our parsed html page...
<!--#exec cgi="cgi-bin/menus/ms1.cgi" -->
... where cgi-bin/menus/ is where ms1.cgi is stored.
As for the contents of such as script...
|
Code to run
Once we have our page looking for a script to run, we
need to justify the requirement. So, let's look at two
scripts, one for a counter and the other for a dynamic
version of the menu in the previous section. You can find
these files in Windows readable format (ie, crlf) in the
files directory or by clicking here.
Counter
#!/usr/bin/perl -w
print "Content-type: text/plain", "\n\n";
$counter_file = "counter1.txt";
open(FILE, ">>$counter_file");
close(FILE);
chmod(0777,"counter1.txt");
open (FILE, "<" . $counter_file) ||
die "Can not read from the counter file.\n";
flock (FILE, 2);
$number_accesses = <FILE>;
flock (FILE, 8);
close (FILE);
open (FILE, ">" . $counter_file) ||
die "Can not write to the counter file.\n";
flock (FILE, 2);
$number_accesses++;
print FILE $number_accesses;
flock (FILE, 8);
close (FILE);
1 while $number_accesses =~ s/^(\d+)(\d\d\d)/$1,$2/;
print $number_accesses;
exit (0);
Basically, it lets Apache know what it is up to with
the content type and then two blank lines, then it finds
out that the file is there, locks it, reads it,
increments it, saves it, unlocks it and then the last few
lines format the value into comma-separated thousands and
then prints it.
Dynamic Menu
This is similar although we look at an environment
variable passed to it by Apache - DOCUMENT_NAME
I've highlighted the first part in Blue so that it is
more visible
#!/usr/bin/perl -w
print "Content-type: text\/plain", "\n\n";
my $thispage = $ENV{DOCUMENT_NAME};
print "<center>\n";
if ($thispage eq "index.html") {
print <b>Home</b>";
} else {
print "<a href=\"index.html\"
><b>Home</b></a>";
};
print " <br>\n";
if ($thispage eq "blog.html") {
print <b>WebLog</b>";
} else {
print "<a href=\"blog.html\"
><b>WebLog</b></a>";
};
print " <br>\n";
if ($thispage eq "dls.html") {
print <b>Downloads</b>";
} else {
print "<a href=\"dls.html\"
><b>Downloads</b></a>";
};
print " <br\n";
if ($thispage eq "links.html") {
print <b>Links</b>";
} else {
print "<a href=\"links.html\"
><b>Links</b></a>";
};
print "</center>\n"
You can see that it compares the name of the page that
the output of this program will become and if it is the
same, just outputs a plain piece of text (albeit bold).
If it is not, then it uses an anchor href to generate a
link to that page.
|
Back to PC Plus Archive Index Page
|