6.6.1. _ _END_ _ and _ _DATA_ _ Tokens
An Apache::Registry
script cannot contain
_ _END_ _
or _ _DATA_
_ tokens, because Apache::Registry wraps
the original script's code into a subroutine called
handler( ), which is then called. Consider the
following script, accessed as /perl/test.pl:
print "Content-type: text/plain\n\n";
print "Hi";
When this script is executed under
Apache::Registry, it becomes wrapped in a
handler( )subroutine, like this:
package Apache::ROOT::perl::test_2epl;
use Apache qw(exit);
sub handler {
print "Content-type: text/plain\n\n";
print "Hi";
}
If we happen to put an _ _END_ _ tag in the code,
like this:
print "Content-type: text/plain\n\n";
print "Hi";
_ _END_ _
Some text that wouldn't be normally executed
it will be turned into:
package Apache::ROOT::perl::test_2epl;
use Apache qw(exit);
sub handler {
print "Content-type: text/plain\n\n";
print "Hi";
_ _END_ _
Some text that wouldn't be normally executed
}
When issuing a request to /perl/test.pl, the
following error will then be reported:
Missing right bracket at .... line 4, at end of line
Perl cuts everything after the _ _END_ _ tag.
Therefore, the subroutine handler(
)'s closing curly bracket is not seen by
Perl. The same applies to the _ _DATA_ _ tag.
6.6.2. Symbolic Links
Apache::Registry caches the script in the
package whose name is constructed from the URI from which the script
is accessed. If the same script can be reached by different URIs,
which is possible if you have used symbolic links or aliases, the
same script will be stored in memory more than once, which is a
waste.
For example, assuming that you already have the script at
/home/httpd/perl/news/news.pl, you can create a
symbolic link:
panic% ln -s /home/httpd/perl/news/news.pl /home/httpd/perl/news.pl
Now the script can be reached through both URIs,
/news/news.pl and /news.pl.
This doesn't really matter until the two URIs get
advertised and users reach the same script from the two of them.
Now start the server in single-server mode and issue a request to
both URIs:
http://localhost/perl/news/news.pl
http://localhost/perl/news.pl
To reveal the duplication, you should use the
Apache::Status module. Among other things, it
shows all the compiled Apache::Registryscripts
(using their respective packages). If you are using the default
configuration directives, you should either use this URI:
http://localhost/perl-status?rgysubs
or just go to the main menu at:
http://localhost/perl-status
and click on the "Compiled Registry
Scripts" menu item.
If the script was accessed through the two URIs, you will see the
output shown in Figure 6-1.
Figure 6-1. Compiled Registry Scripts output
You can usually spot this kind of problem by running a link checker
that goes recursively through all the pages of the service by
following all links, and then using Apache::Status
to find the symlink duplicates (without restarting the server, of
course). To make it easier to figure out what to look for, first find
all symbolic links. For example, in our case, the following command
shows that we have only one symlink:
panic% find /home/httpd/perl -type l
/home/httpd/perl/news.pl
So now we can look for that symlink in the output of the Compiled
Registry Scripts section.
Notice that if you perform the testing in multi-server mode, some
child processes might show only one entry or none at all, since they
might not serve the same requests as the others.
6.6.3. Return Codes
Apache::Registry
normally assumes a return code of
OK (200) and sends it for you. If a different
return code needs to be sent, $r->status(
) can be used. For example, to send the
return code 404 (Not Found), you can use the
following code:
use Apache::Constants qw(NOT_FOUND);
$r->status(NOT_FOUND);
If this method is used, there is no need to call
$r->send_http_header(
) (assuming that the
PerlSendHeader Offsetting is in effect).