|
|
| |
Getting Started with CGI
Since you are reading this section, it is presumed that you already know
what CGI processing is. If not, a good
introduction can
be found here.
Yahoo! has a good index of CGI references.
Getting started with CGI can seem to be a daunting task. Many of the
posts to
comp.infosystems.www.servers.unix
contain requests for help to get CGI working. Like all types of network
programming, it is necessary to get more than one thing running correctly
before you see any results, but it's not difficult, others have done it
before, and after setting the configuration options in this section, your
server should be configured to process CGI requests.
Note: Through out this document, I refer to CGI scripts. This is only
a convention. CGI programs can be written in virtually any language you are
conversant with. The can be compiled or interpreted or a mixture of both.
The choice is yours. This guide will not help you write CGI scripts, but
will help you get them to run, and help you to debug them is they don't. If
you don't know how to program, you are going to have to learn, or find someone
who will do the programming for you!.
Minimum Configuration
Apache provides a number of configuration options relating to CGIs. There are
two main options for CGIs and Apache:
- Configure a directory where all CGI scripts will reside or
- Configure Apache to recognize specific file extensions as CGI programs.
We are going to use the first option, and define a directory, by convention
cgi-bin which will contain all our scripts. Again this is a convention
which many (most?) web sites Adhere to. Your milage may vary.
Many Linux distributions now have cgi-bin enabled in the default configuration.
CGI Location
The ScriptAlias option allows you to group all you CGI scripts into a
single directory. Any files found in this directory will be treated
by Apache as CGI scripts.
I have a personal dislike for the default location of the cgi-bin directory for Apache 2.x under the Ubuntu distribution. For some reason it is located in:
/usr/lib/cgi-bin>
which forces you to either be SuperUser to update it, or give yourself write privileges to a sub-directory of /usr/lib, and area that is generally read-only on most disto's and Unix's.
My personal preference is to have the cgi-bin directory adjacent to the DocumentRoot (html) directory, in some where like /var/virtual/VM_Name/, but then that's just my personal preferences.
To specify a directory where you cgi scripts will reside, edit
srm.conf and change
| |
# ScriptAlias: This controls which directories contain server scripts.
# Format: ScriptAlias fakename realname
#ScriptAlias /cgi-bin/ /apache/cgi-bin/
|
|
| |
To: (just remove the '#' comment character)
| |
# ScriptAlias: This controls which directories contain server scripts.
# Format: ScriptAlias fakename realname
ScriptAlias /cgi-bin/ /apache/cgi-bin/
|
|
| |
Here we have specified that files found in the directory /apache/cgi-bin/
should be treated as CGI scripts. NT users would specify:
| |
# ScriptAlias: This controls which directories contain server scripts.
# Format: ScriptAlias fakename realname
ScriptAlias /cgi-bin/ c:/apache/cgi-bin/
|
|
| |
Note: in both the Unix and NT examples, we have specified an absolute path from the
root of the file system.
CGI scripts, in the above example would be referenced by the url:
<a href="http://your.host.name/cgi-bin/your_script_name">
or
<a href="/cgi-bin/your_script_name">
Once you have decided where you CGI directory will be located, edit access.conf
and change the following to conform with the ScriptAliases changes.
| |
# /apache/cgi-bin should be changed to whatever your ScriptAliased
# CGI directory exists, if you have that configured.
<Directory c:/apache/cgi-bin>
AllowOverride None
Options None
</Directory>
|
|
| |
Re-start your Apache web server and then proceed to
test your CGI configuration.
References
General
Apache Directives
Testing CGI
Here is a simple shell script which I always use when I first set up a new
web server. It prints out some of the CGI environment variables and gives
you a warm feeling that everything is working.
| |
#!/bin/sh
# disable filename globbing
set -f
echo Content-type: text/plain
echo
echo CGI/1.0 test script report:
echo
echo argc is $#. argv is "$*".
echo
echo SERVER_SOFTWARE = $SERVER_SOFTWARE
echo SERVER_NAME = $SERVER_NAME
echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE
echo SERVER_PROTOCOL = $SERVER_PROTOCOL
echo SERVER_PORT = $SERVER_PORT
echo REQUEST_METHOD = $REQUEST_METHOD
echo HTTP_ACCEPT = "$HTTP_ACCEPT"
echo PATH_INFO = "$PATH_INFO"
echo PATH_TRANSLATED = "$PATH_TRANSLATED"
echo SCRIPT_NAME = "$SCRIPT_NAME"
echo QUERY_STRING = "$QUERY_STRING"
echo REMOTE_HOST = $REMOTE_HOST
echo REMOTE_ADDR = $REMOTE_ADDR
echo REMOTE_USER = $REMOTE_USER
echo AUTH_TYPE = $AUTH_TYPE
echo CONTENT_TYPE = $CONTENT_TYPE
echo CONTENT_LENGTH = $CONTENT_LENGTH
|
|
| |
Cut and past this file into your favorite editor and save it in your CGI
directory as testcgi. Make sure to set the execute permissions on it (Unix).
| |
|
|
| |
And an NT version which is not quit as good, but give you most of the
information. I would appreciate an e-mail on
how to get the argument count and all the arguments (like **argv in 'C') in a
dos batch file.
| |
@echo off
echo Content-type: text/plain
echo.
echo CGI/1.0 test script report:
echo.
rem echo argc is %0
echo argv is %0
echo.
echo SERVER_SOFTWARE = %SERVER_SOFTWARE%
echo SERVER_NAME = %SERVER_NAME%
echo GATEWAY_INTERFACE = %GATEWAY_INTERFACE%
echo SERVER_PROTOCOL = %SERVER_PROTOCOL%
echo SERVER_PORT = %SERVER_PORT%
echo REQUEST_METHOD = %REQUEST_METHOD%
echo HTTP_ACCEPT = "%HTTP_ACCEPT%"
echo PATH_INFO = "%PATH_INFO%"
echo PATH_TRANSLATED = "%PATH_TRANSLATED%"
echo SCRIPT_NAME = "%SCRIPT_NAME%"
echo QUERY_STRING = "%QUERY_STRING%"
echo REMOTE_HOST = %REMOTE_HOST%
echo REMOTE_ADDR = %REMOTE_ADDR%
echo REMOTE_USER = %REMOTE_USER%
echo AUTH_TYPE = %AUTH_TYPE%
echo CONTENT_TYPE = %CONTENT_TYPE%
echo CONTENT_LENGTH = %CONTENT_LENGTH%
|
|
| |
NT users should save this file as testcgi.bat. Be sure to use the .bat extension on
NT so that NT can make the association with the file extension and run it correctly.
Accessing the script
| |
http://your_domain/cgi-bin/testcgi.bat
or
http://your_ip_address/cgi-bin/testcgi.bat
|
|
| |
What you should see
If all goes well, your script should display something like.
| |
CGI/1.0 test script report:
argc is 0. argv is .
SERVER_SOFTWARE = Apache/1.2.4
SERVER_NAME = www.jlk.net
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.0
SERVER_PORT = 80
REQUEST_METHOD = GET
HTTP_ACCEPT = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
PATH_INFO =
PATH_TRANSLATED =
SCRIPT_NAME = /cgi-bin/test-cgi
QUERY_STRING =
REMOTE_HOST = 158.76.200.102
REMOTE_ADDR = 158.76.200.102
REMOTE_USER =
AUTH_TYPE =
CONTENT_TYPE =
CONTENT_LENGTH =
|
|
| |
What can go wrong, and what to do about it
| |
Not Found
The requested URL /cgi-bin/testcgi was not found on this server.
|
|
| |
You have either:
- typed in the incorrect URL
- saved the file with a different name
Check you typing and/or the file names in you CGI directory.
- specified a different directory for CGIs
- or CGIs are not configured
Check your srm.conf configuration for ScriptAliases
(see Getting Started with CGIs)
| |
Internal Server Error
The server encountered an internal error or mis-configuration and
was unable to complete your request.
Please contact the server administrator, webmaster@jlk.net and
inform them of the time the error occurred, and anything you
might have done that may have caused the error.
|
|
| |
It means, that someway, somehow, you have screwed up the above scripts.
Every CGI script must return:
- One or more Header lines
(i.e. Content-type: text/html)
- A blank line
- the body of the document (optional but recommended)
and when this error occurs, either 1 or 2 or both are missing.
Check you scripts!
| |
Forbidden
You don't have permission to access /cgi-bin/test-cgi on this server.
|
|
| |
You have forgotten to set the execute bit on the script (Unix though you
may be able to mess with the permissions on NT and get this error).
| |
# cd /var/apache/cgi-bin
# ls -l test-cgi
-rw-r--r-- 1 103 20 757 Apr 8 14:12 test-cgi
# chmod +x test-cgi
# ls -l test-cgi
-rwxr-xr-x 1 103 20 757 Apr 8 14:12 test-cgi
#
|
|
| |
Once you have basic CGIs working, there are some
more Apache configuration options which
you can apply that may make your life easier while developing CGI scripts.
Debugging CGI
Once you have a basic CGI configuration working, there are some additional
Apache directives which can assist you in debugging your CGI scripts.
Warning! You should only use these directives
during development. They are not optimised for a production machine
and can cause a significant overhead on you server.
Getting more Information
Adding the directive ScriptAliases in your srm.comf will
enable logging of CGI error information.
| |
# ScriptAlias: This controls which directories contain server scripts.
# Format: ScriptAlias fakename realname
ScriptAlias /cgi-bin/ c:/apache/cgi-bin/
ScriptLog c:/apache/logs/cgi_errors_logs
|
|
| |
Remember! to re-start Apache after any changes you
make to the configuration file.
So we can show the difference between a good and bad script response, we are
going to "modify" the test-cgi script we used to in
Testing CGI to give a bad error response.
Change the script so as to remove the header information.
| |
@echo off
rem echo Content-type: text/plain
rem echo argv is %0
rem echo.
echo SERVER_SOFTWARE = %SERVER_SOFTWARE%
.
.
.
|
|
| |
And then try out the script file again. Your ErrorLog should
product something like....
| |
[Thu Apr 09 10:33:00 1998] [error] malformed header from script.
Bad header=SERVER_SOFTWARE = Apache/1.3b3: c:/apache/cgi-bin/test-cgi.bat
|
|
| |
Which in this simple case, is sufficient to determine what is causing the error.
The ScriltLog produces considerable more information.
We can see that Apache returned error code 500: and Internal Server Error
We know from our modifications, that this is caused by the lack of header information.
After the %stdout we can see actually what the script was attempting to
send back to the browser. As per the error code, there is no
Content-type: text/plain
header information.
| |
%% [Thu Apr 09 10:33:00 1998] GET /cgi-bin/test-cgi.bat HTTP/1.0
%% 500 c:/apache/cgi-bin/test-cgi.bat
%request
Connection: Keep-Alive
User-Agent: Mozilla/4.0 [en] (WinNT; I)
Pragma: no-cache
Host: jaunty
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
%response
SERVER_SOFTWARE = Apache/1.3b3
%stdout
SERVER_NAME = jaunty
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.0
SERVER_PORT = 80
REQUEST_METHOD = GET
HTTP_ACCEPT = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"
PATH_INFO = ""
PATH_TRANSLATED = ""
SCRIPT_NAME = "/cgi-bin/test-cgi.bat"
QUERY_STRING = ""
REMOTE_HOST = 158.76.200.102
REMOTE_ADDR = 158.76.200.102
REMOTE_USER =
AUTH_TYPE =
CONTENT_TYPE =
CONTENT_LENGTH =
|
|
| |
Here is a Unix example using Perl. A simple script which prints the
now famous "hello, world". There is a minor syntax error on
the last line of the script. The semi-colon ";" is a missing.
| |
#!/usr/local/bin/perl
print "Content-type: text/html\n\n";
print "<html><head><title>hello, world</title></head>";
print "<body><h1>hello, world</body></html>"
|
|
| |
When we try to access the script, the ErrorLog shows us that
their was and error in running the script.
| |
[Thu Apr 9 11:53:22 1998] access to /var/apache/cgi-bin/hello.pl
failed for 158.76.200.102, reason: Premature end of script headers
|
|
| |
But the ScriptLog shows us why it went wrong. Perl wrote on
stderr that there was a syntax error near line 5.
| |
%% [Thu Apr 9 11:53:22 1998] GET /cgi-bin/hello.pl HTTP/1.0
%% 500 /var/apache/cgi-bin/hello.pl
%request
Connection: Keep-Alive
User-Agent: Mozilla/4.0 [en] (WinNT; I)
Pragma: no-cache
Host: www.jlk.net
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
%response
%stderr
syntax error at /var/apache/cgi-bin/hello.pl line 5, near "print"
Execution of /var/apache/cgi-bin/hello.pl aborted due to compilation errors.
|
|
| |
This trivial error could have been found by running hello.pl from
the command line but is sufficient to demonstrate the additional
script debugging features of Apache.
There are a few other directives
that you should be aware of when debugging CGIs scripts with
Apache.
Other Debug Directives
ScriptLog file logs grow very quickly due the the amount
of data generated. You can limit the size of of ScriptLog file
with the ScriptLogLength
to a certain number of bytes.
|
| |
Additionally the number of bytes logged during a Post request to a CGI script
can be limited with the ScriptLogBuffer
|
| |
References
Apache Directives
|
|