Apache-ASP
view release on metacpan or search on metacpan
my $buffer = '&' x 100000;
$buffer = $Server->HTMLEncode($buffer);
print $buffer;
- or -
my $buffer = '&' x 100000;
$Server->HTMLEncode(\$buffer);
print $buffer;
Using the reference passing method in benchmarks on 100K of data was 5%
more efficient, but maybe useful for some. It saves on copying the 100K
buffer twice.
$Server->MapInclude($include)
API extension. Given the include $include, as an absolute or relative
file name to the current executing script, this method returns the file
path that the include would be found from the include search path. The
include search path is the current script directory, Global, and
IncludesDir directories.
If the include is not found in the includes search path, then undef, or
bool false, is returned. So one may do something like this:
if($Server->MapInclude('include.inc')) {
$Response->Include('include.inc');
}
This code demonstrates how one might only try to execute an include if
it exists, which is useful since a script will error if it tries to
execute an include that does not exist.
$Server->MapPath($url);
Given the url $url, absolute, or relative to the current executing
script, this method returns the equivalent filename that the server
would translate the request to, regardless or whether the request would
be valid.
Only a $url that is relative to the host is valid. Urls like "." and "/"
are fine arguments to MapPath, but http://localhost would not be.
To see this method call in action, check out the sample
./site/eg/server.htm script.
$Server->Mail(\%mail, %smtp_args);
With the Net::SMTP and Net::Config modules installed, which are part of
the perl libnet package, you may use this API extension to send email.
The \%mail hash reference that you pass in must have values for at least
the To, From, and Subject headers, and the Body of the mail message.
The return value of this routine is 1 for success, 0 for failure. If the
MailHost SMTP server is not available, this will have a return value of
0.
You could send an email like so:
$Server->Mail({
To => 'somebody@yourdomain.com.foobar',
From => 'youremail@yourdomain.com.foobar',
Subject => 'Subject of Email',
Body =>
'Body of message. '.
'You might have a lot to say here!',
Organization => 'Your Organization',
CC => 'youremailcc@yourdomain.com.foobar',
BCC => 'youremailbcc@yourdomain.com.foobar',
Debug => 0 || 1,
});
Any extra fields specified for the email will be interpreted as headers
for the email, so to send an HTML email, you could set 'Content-Type' =>
'text/html' in the above example.
If you have MailFrom configured, this will be the default for the From
header in your email. For more configuration options like the MailHost
setting, check out the CONFIG section.
The return value of this method call will be boolean for success of the
mail being sent.
If you would like to specially configure the Net::SMTP object used
internally, you may set %smtp_args and they will be passed on when that
object is initialized. "perldoc Net::SMTP" for more into on this topic.
If you would like to include the output of an ASP page as the body of
the mail message, you might do something like:
my $mail_body = $Response->TrapInclude('mail_body.inc');
$Server->Mail({ %mail, Body => $$mail_body });
$Server->RegisterCleanup($sub)
non-portable extension
Sets a subroutine reference to be executed after the script ends,
whether normally or abnormally, the latter occurring possibly by the
user hitting the STOP button, or the web server being killed. This
subroutine must be a code reference created like:
$Server->RegisterCleanup(sub { $main::Session->{served}++; });
or
sub served { $main::Session->{served}++; }
$Server->RegisterCleanup(\&served);
The reference to the subroutine passed in will be executed. Though the
subroutine will be executed in anonymous context, instead of the script,
all objects will still be defined in main::*, that you would reference
normally in your script. Output written to $main::Response will have no
affect at this stage, as the request to the www client has already
completed.
Check out the ./site/eg/register_cleanup.asp script for an example of
this routine in action.
$Server->Transfer($file, @args)
New method from ASP 3.0. Transfers control to another script. The
Response buffer will not be cleared automatically, so if you want this
to serve as a faster $Response->Redirect(), you will need to call
$Response->Clear() before calling this method.
This new script will take over current execution and the current script
will not continue to be executed afterwards. It differs from Execute()
because the original script will not pick up where it left off.
So we now have more ways to track sessions with the SessionQuery* CONFIG
settings, that allow a web developer to embed the session id in URL query
strings when use of cookies is denied. The implementations work such that if
a user has cookies turned on, then cookies will be used, but for those users
with cookies turned off, the session ids will be parsed into document URLs.
The first and easiest method that a web developer may use to implement
cookieless sessions are with SessionQueryParse* directives which enable
Apache::ASP to the parse the session id into document URLs on the fly.
Because this is resource inefficient, there is also the SessionQuery*
directives that may be used with the $Server->URL($url,\%params) method to
generate custom URLs with the session id in its query string.
To see an example of these cookieless sessions in action, check out the
./site/eg/session_query_parse.asp example.
*** WARNING ***
If you do use these methods, then be VERY CAREFUL of linking offsite from a
page that was accessed with a session id in a query string. This is because
this session id will show up in the HTTP_REFERER logs of the linked to site,
and a malicious hacker could use this information to compromise the security
of your site's $Sessions, even if these are run under a secure web server.
In order to shake a session id off an HTTP_REFERER for a link taking a user
offsite, you must point that link to a redirect page that will redirect a
user, like so:
<%
# "cross site scripting bug" prevention
my $sanitized_url =
$Server->HTMLEncode($Response->QueryString('OffSiteUrl'));
%>
<html>
<head>
<meta http-equiv=refresh content='0;URL=<%=$sanitized_url%>'>
</head>
<body>
Redirecting you offsite to
<a href=<%=$sanitized_url%> >here</a>...
</body>
</html>
Because the web browser visits a real page before being redirected with the
<meta> tag, the HTTP_REFERER will be set to this page. Just be sure to not
link to this page with a session id in its query string.
Unfortunately a simple $Response->Redirect() will not work here, because the
web browser will keep the HTTP_REFERER of the original web page if only a
normal redirect is used.
XML/XSLT
Custom Tags with XMLSubsMatch
Before XML, there was the need to make HTML markup smarter. Apache::ASP
gives you the ability to have a perl subroutine handle the execution of any
predefined tag, taking the tag descriptors, and the text contained between,
as arguments of the subroutine. This custom tag technology can be used to
extend a web developer's abilities to add dynamic pieces without having to
visibly use <% %> style code entries.
So, lets say that you have a table that you want to insert for an employee
with contact info and the like, you could set up a tag like:
<my:new-employee name="Jane" last="Doe" phone="555-2222">
Jane Doe has been here since 1998.
</my:new-employee>
To render it with a custom tag, you would tell the Apache::ASP parser to
render the tag with a subroutine:
PerlSetVar XMLSubsMatch my:new-employee
Any colons, ':', in the XML custom tag will turn into '::', a perl package
separator, so the my:employee tag would translate to the my::employee
subroutine, or the employee subroutine in the my package. Any dash "-" will
also be translated to an underscore "_", as dash is not valid in the names
of perl subroutines.
Then you would create the my::employee subroutine in the my perl package or
whereever like so:
package my;
sub new_employee {
my($attributes, $body) = @_;
$main::Response->Include('new_employee.inc', $attributes, $body);
}
1;
<!-- # new_employee.inc file somewhere else, maybe in Global directory -->
<% my($attributes, $body) = @_; %>
<table>
<% for('name', 'last', 'phone') { %>
<tr>
<td><b><%=ucfirst $_ %></b>:</td>
<td><%= $attributes->{$_} %></td>
</tr>
<% } %>
<tr><td colspan=2><%= $body %></td></tr>
</table>
<!-- # end new_employee.inc file -->
The $main::Response->Include() would then delegate the rendering of the
new-employee to the new_employee.inc ASP script include.
Though XML purists would not like this custom tag technology to be related
to XML, the reality is that a careful site engineer could render full XML
documents with this technology, applying all the correct styles that one
might otherwise do with XSLT.
Custom tags defined in this way can be used as XML tags are defined with
both a body and without as it
<my:new-employee>...</my:new-employee>
and just
<my:new-employee />
These tags are very powerful in that they can also enclose normal ASP logic,
like:
Here are some general style guidelines. Treat these as tips for best
practices on Apache::ASP development if you will.
UseStrict
One of perl's blessings is also its bane, variables do not need to be
declared, and are by default globally scoped. The problem with this in
mod_perl is that global variables persist from one request to another even
if a different web browser is viewing a page.
To avoid this problem, perl programmers have often been advised to add to
the top of their perl scripts:
use strict;
In Apache::ASP, you can do this better by setting:
PerlSetVar UseStrict 1
which will cover both script & global.asa compilation and will catch "use
strict" errors correctly. For perl modules, please continue to add "use
strict" to the top of them.
Because its so essential in catching hard to find errors, this configuration
will likely become the default in some future release. For now, keep setting
it.
Do not define subroutines in scripts.
DO NOT add subroutine declarations in scripts. Apache::ASP is optimized by
compiling a script into a subroutine for faster future invocation. Adding a
subroutine definition to a script then looks like this to the compiler:
sub page_script_sub {
...
... some HTML ...
...
sub your_sub {
...
}
...
}
The biggest problem with subroutines defined in subroutines is the side
effect of creating closures, which will not behave as usually desired in a
mod_perl environment. To understand more about closures, please read up on
them & "Nested Subroutines" at:
http://perl.apache.org/docs/general/perl_reference/perl_reference.html
Instead of defining subroutines in scripts, you may add them to your sites
global.asa, or you may create a perl package or module to share with your
scripts. For more on perl objects & modules, please see:
http://perldoc.perl.org/perlobj.html
Use global.asa's Script_On* Events
Chances are that you will find yourself doing the same thing repeatedly in
each of your web application's scripts. You can use Script_OnStart and
Script_OnEnd to automate these routine tasks. These events are called before
and after each script request.
For example, let's say you have a header & footer you would like to include
in the output of every page, then you might:
# global.asa
sub Script_OnStart {
$Response->Include('header.inc');
}
sub Script_OnEnd {
$Response->Include('footer.inc');
}
Or let's say you want to initialize a global database connection for use in
your scripts:
# global.asa
use Apache::DBI; # automatic persistent database connections
use DBI;
use vars qw($dbh); # declare global $dbh
sub Script_OnStart {
# initialize $dbh
$dbh = DBI->connect(...);
# force you to explicitly commit when you want to save data
$Server->RegisterCleanup(sub { $dbh->rollback; });
}
sub Script_OnEnd {
# not really necessary when using persistent connections, but
# will free this one object reference at least
$dbh = undef;
}
FAQ
The following are some frequently asked questions about Apache::ASP.
Installation
Examples don't work, I see the ASP script in the browser?
This is most likely that Apache is not configured to execute the
Apache::ASP scripts properly. Check the INSTALL QuickStart section for
more info on how to quickly set up Apache to execute your ASP scripts.
Apache Expat vs. XML perl parsing causing segfaults, what do I do?
Make sure to compile apache with expat disabled. The
./make_httpd/build_httpds.sh in the distribution will do this for you,
with the --disable-rule=EXPAT in particular:
cd ../$APACHE
echo "Building apache =============================="
./configure \
--prefix=/usr/local/apache \
--activate-module=src/modules/perl/libperl.a \
--enable-module=ssl \
--enable-module=proxy \
--enable-module=so \
--disable-rule=EXPAT
^^^^^
keywords: segmentation fault, segfault seg fault
Why do variables retain their values between requests?
Unless scoped by my() or local(), perl variables in mod_perl are treated
as globals, and values set may persist from one request to another. This
can be seen in as simple a script as this:
<HTML><BODY>
$counter++;
$Response->Write("<BR>Counter: $counter");
</BODY></HTML>
TESTIMONIALS
Here are testimonials from those using Apache::ASP. If you use this software
and would like to show your support please send your testimonial to
Apache::ASP mailing list at asp[at]perl.apache.org and indicate that we can
post it to the web site.
For a list of sites using Apache::ASP, please see the SITES USING section.
Red Hat
We're using Apache::ASP on www.redhat.com. We find Apache::ASP very easy
to use, and it's quick for new developers to get up to speed with it,
given that many people have already been exposed to the ASP object model
that Apache::ASP is based on.
The documentation is comprehensive and easy to understand, and the
community and maintainer have been very helpful whenever we've had
questions.
-- Tom Lancaster, Red Hat
Anime Wallpaper at Anime Cubed
Your suite has got our old CGI implementation beat, hands down. Our site
is divided into two main areas, each run by a separate developer, and
the Apache::ASP section runs head and shoulders above the other side.
Anyone who is still using anything but your product to implement their
webpages seriously needs to take a look at how versatile and powerful
Apache::ASP is. Thanks again for such great work!
-- Al from 'Anime Wallpaper at Anime Cubed', http://www.animecubed.com/wallpapers/
gutscheinwurst.de
I am the web master of http://www.gutscheinwurst.de , a German voucher
community. We use Apache::Asp to run our backend & administration
servers for the system. We started using Apache::ASP to see whether it
is a valid alternative to IIS legacy systems. So far all expectations in
regard of performance, ease of development and integration have been
fulfilled or exceeded. Thank's for such a great product :)
-- Johnannes Leimbach
D. L. Fox
I had programmed in Perl for some time ... but, since I also knew VB, I
had switched to VB in IIS-ASP for web stuff because of its ease of use
in embedding code with HTML ... When I discovered Apache-ASP, it was
like a dream come true. I would much rather code in Perl than any other
language. Thanks for such a fine product!
HOSTING 321, LLC.
After discontinuing Windows-based hosting due to the high cost of
software, our clients are thrilled with Apache::ASP and they swear ASP
it's faster than before. Installation was a snap on our 25-server web
farm with a small shell script and everything is running perfectly! The
documentation is very comprehensive and everyone has been very helpful
during this migration.
Thank you!
-- Richard Ward, HOSTING 321, LLC.
Concept Online Ltd.
I would like to say that your ASP module rocks :-) We have practically
stopped developing in anything else about half a year ago, and are now
using Apache::ASP extensively. I just love Perl, and whereever we are
not "forced" to use JSP, we chose ASP. It is fast, reliable, versatile,
documented in a way that is the best for professionals - so thank you
for writting and maintaining it!
-- Csongor Fagyal, Concept Online Ltd.
WebTime
As we have seen with WebTime, Apache::ASP is not only good for the
development of website, but also for the development of webtools. Since
I first discoverd it, I made it a must-have in my society by taking
traditional PHP users to the world of perl afficionados.
Having the possibility to use Apache::ASP with mod_perl or mod_cgi make
it constraintless to use because of CGI's universality and perl's
portability.
-- Grégoire Lejeune
David Kulp
First, I just want to say that I am very very impressed with
Apache::ASP. I just want to gush with praise after looking at many other
implementations of perl embedded code and being very underwhelmed. This
is so damn slick and clean. Kudos! ...
... I'm very pleased how quickly I've been able to mock up the
application. I've been writing Perl CGI off and on since 1993(!) and I
can tell you that Apache::ASP is a pleasure. (Last year I tried Zope and
just about threw my computer out the window.)
-- David Kulp
MFM Commmunication Software, Inc.
Working in a team environment where you have HTML coders and perl
coders, Apache::ASP makes it easy for the HTML folks to change the look
of the page without knowing perl. Using Apache::ASP (instead of another
embedded perl solution) allows the HTML jockeys to use a variety of HTML
tools that understand ASP, which reduces the amount of code they break
when editing the HTML. Using Apache::ASP instead of M$ ASP allows us to
use perl (far superior to VBScript) and Apache (far superior to IIS).
We've been very pleased with Apache::ASP and its support.
Planet of Music
Apache::ASP has been a great tool. Just a little background.... the
whole site had been in cgi flat files when I started here. I was looking
for a technology that would allow me to write the objects and NEVER
invoke CGI.pm... I found it and hopefuly I will be able to implement
this every site I go to.
When I got here there was a huge argument about needing a game engine
and I belive this has been the key... Games are approx. 10 time faster
than before. The games don't break anylonger. All in all a great tool
for advancement.
-- JC Fant IV
Cine.gr
...we ported our biggest yet ASP site from IIS (well, actually rewrote),
Cine.gr and it is a killer site. In some cases, the whole thing got
almost 25 (no typo) times faster... None of this would ever be possible
without Apache::ASP (I do not ever want to write ``print "<HTML>\n";''
again).
RESOURCES
Here are some important resources listed related to the use of Apache::ASP
for publishing web applications. If you have any more to suggest, please
email the Apache::ASP list at asp[at]perl.apache.org
Articles
Apache::ASP Introduction ( #1 in 3 part series )
http://www.apache-asp.org/articles/perlmonth1_intro.html
Apache::ASP Site Building ( #2 in 3 part series )
http://www.apache-asp.org/articles/perlmonth2_build.html
Apache::ASP Site Tuning ( #3 in 3 part series )
http://www.apache-asp.org/articles/perlmonth3_tune.html
Embedded Perl ( part of a series on Perl )
http://www.wdvl.com/Authoring/Languages/Perl/PerlfortheWeb/index15.html
( run in 0.406 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )