Apache-ASP
view release on metacpan or search on metacpan
CgiHeaders
default 0. When true, script output that looks like HTTP / CGI headers,
will be added to the HTTP headers of the request. So you could add:
Set-Cookie: test=message
<html>...
to the top of your script, and all the headers preceding a newline
will be added as if with a call to $Response->AddHeader(). This
functionality is here for compatibility with raw cgi scripts,
and those used to this kind of coding.
When set to 0, CgiHeaders style headers will not be parsed from the
script response.
PerlSetVar CgiHeaders 0
Clean
default 0, may be set between 1 and 9. This setting determine how much
text/html output should be compressed. A setting of 1 strips mostly
white space saving usually 10% in output size, at a performance cost of
less than 5%. A setting of 9 goes much further saving anywhere 25% to
50% typically, but with a performance hit of 50%.
This config option is implemented via HTML::Clean. Per script
configuration of this setting is available via the $Response->{Clean}
property, which may also be set between 0 and 9.
PerlSetVar Clean 0
CompressGzip
default 0, if true will gzip compress HTML output on the fly if
Compress::Zlib is installed, and the client browser supports it.
Depending on the HTML being compressed, the client may see a 50% to 90%
reduction in HTML output. I have seen 40K of HTML squeezed down to just
under 6K. This will come at a 5%-20% hit to CPU usage per request
compressed.
Note there are some cases when a browser says it will accept gzip
encoding, but then not render it correctly. This behavior has been seen
with IE5 when set to use a proxy but not using a proxy, and the URL does
not end with a .html or .htm. No work around has yet been found for this
case so use at your own risk.
PerlSetVar CompressGzip 1
FormFill
default 0, if true will auto fill HTML forms with values from
$Request->Form(). This functionality is provided by use of
HTML::FillInForm. For more information please see "perldoc
HTML::FillInForm", and the example ./site/eg/formfill.asp.
This feature can be enabled on a per form basis at runtime with
$Response->{FormFill} = 1
PerlSetVar FormFill 1
TimeHiRes
default 0, if set and Time::HiRes is installed, will do sub second
timing of the time it takes Apache::ASP to process a request. This will
not include the time spent in the session manager, nor modperl or
Apache, and is only a rough approximation at best.
If Debug is set also, you will get a comment in your HTML output that
indicates the time it took to process that script.
If system debugging is set with Debug -1 or -2, you will also get this
time in the Apache error log with the other system messages.
Mail Administration
Apache::ASP has some powerful administrative email extensions that let you
sleep at night, knowing full well that if an error occurs at the web site,
you will know about it immediately. With these features already enabled, it
was also easy to provide the $Server->Mail(\%mail) API extension which you
can read up about in the OBJECTS section.
MailHost
The mail host is the smtp server that the below Mail* config directives
will use when sending their emails. By default Net::SMTP uses smtp mail
hosts configured in Net::Config, which is set up at install time, but
this setting can be used to override this config.
The mail hosts specified in the Net::Config file will be used as backup
smtp servers to the MailHost specified here, should this primary server
not be working.
PerlSetVar MailHost smtp.yourdomain.com.foobar
MailFrom
Default NONE, set this to specify the default mail address placed in the
From: mail header for the $Server->Mail() API extension, as well as
MailErrorsTo and MailAlertTo.
PerlSetVar MailFrom youremail@yourdomain.com.foobar
MailErrorsTo
No default, if set, ASP server errors, error code 500, that result while
compiling or running scripts under Apache::ASP will automatically be
emailed to the email address set for this config. This allows an
administrator to have a rapid response to user generated server errors
resulting from bugs in production ASP scripts. Other errors, such as 404
not found will be handled by Apache directly.
An easy way to see this config in action is to have an ASP script which
calls a die(), which generates an internal ASP 500 server error.
The Debug config of value 2 and this setting are mutually exclusive, as
Debug 2 is a development setting where errors are displayed in the
browser, and MailErrorsTo is a production setting so that errors are
silently logged and sent via email to the web admin.
PerlSetVar MailErrorsTo youremail@yourdomain.com
MailAlertTo
The address configured will have an email sent on any ASP server error
500, and the message will be short enough to fit on a text based pager.
This config setting would be used to give an administrator a heads up
that a www server error occurred, as opposed to MailErrorsTo would be
used for debugging that server error.
This config does not work when Debug 2 is set, as it is a setting for
use in production only, where Debug 2 is for development use.
Please note that if you are on Win32, you will need to call binmode on a
file handle before reading, if its data is binary.
$Response->Clear()
Erases buffered ASP output.
$Response->Cookies($name, [$key,] $value)
Sets the key or attribute of cookie with name $name to the value $value.
If $key is not defined, the Value of the cookie is set. ASP CookiePath
is assumed to be / in these examples.
$Response->Cookies('name', 'value');
--> Set-Cookie: name=value; path=/
$Response->Cookies("Test", "data1", "test value");
$Response->Cookies("Test", "data2", "more test");
$Response->Cookies(
"Test", "Expires",
&HTTP::Date::time2str(time+86400)
);
$Response->Cookies("Test", "Secure", 1);
$Response->Cookies("Test", "Path", "/");
$Response->Cookies("Test", "Domain", "host.com");
--> Set-Cookie:Test=data1=test%20value&data2=more%20test; \
expires=Fri, 23 Apr 1999 07:19:52 GMT; \
path=/; domain=host.com; secure
The latter use of $key in the cookies not only sets cookie attributes
such as Expires, but also treats the cookie as a hash of key value pairs
which can later be accesses by
$Request->Cookies('Test', 'data1');
$Request->Cookies('Test', 'data2');
Because this is perl, you can (NOT PORTABLE) reference the cookies
directly through hash notation. The same 5 commands above could be
compressed to:
$Response->{Cookies}{Test} =
{
Secure => 1,
Value =>
{
data1 => 'test value',
data2 => 'more test'
},
Expires => 86400, # not portable, see above
Domain => 'host.com',
Path => '/'
};
and the first command would be:
# you don't need to use hash notation when you are only setting
# a simple value
$Response->{Cookies}{'Test Name'} = 'Test Value';
I prefer the hash notation for cookies, as this looks nice, and is quite
perlish. It is here to stay. The Cookie() routine is very complex and
does its best to allow access to the underlying hash structure of the
data. This is the best emulation I could write trying to match the
Collections functionality of cookies in IIS ASP.
For more information on Cookies, please go to the source at
http://home.netscape.com/newsref/std/cookie_spec.html
$Response->Debug(@args)
API Extension. If the Debug config option is set greater than 0, this
routine will write @args out to server error log. refs in @args will be
expanded one level deep, so data in simple data structures like
one-level hash refs and array refs will be displayed. CODE refs like
$Response->Debug(sub { "some value" });
will be executed and their output added to the debug output. This
extension allows the user to tie directly into the debugging
capabilities of this module.
While developing an app on a production server, it is often useful to
have a separate error log for the application to catch debugging output
separately. One way of implementing this is to use the Apache ErrorLog
configuration directive to create a separate error log for a virtual
host.
If you want further debugging support, like stack traces in your code,
consider doing things like:
$Response->Debug( sub { Carp::longmess('debug trace') };
$SIG{__WARN__} = \&Carp::cluck; # then warn() will stack trace
The only way at present to see exactly where in your script an error
occurred is to set the Debug config directive to 2, and match the error
line number to perl script generated from your ASP script.
However, as of version 0.10, the perl script generated from the asp
script should match almost exactly line by line, except in cases of
inlined includes, which add to the text of the original script, pod
comments which are entirely yanked out, and <% # comment %> style
comments which have a \n added to them so they still work.
If you would like to see the HTML preceding an error while developing,
consider setting the BufferingOn config directive to 0.
$Response->End()
Sends result to client, and immediately exits script. Automatically
called at end of script, if not already called.
$Response->ErrorDocument($code, $uri)
API extension that allows for the modification the Apache ErrorDocument
at runtime. $uri may be a on site document, off site URL, or string
containing the error message.
This extension is useful if you want to have scripts set error codes
with $Response->{Status} like 401 for authentication failure, and to
then control from the script what the error message looks like.
For more information on the Apache ErrorDocument mechanism, please see
ErrorDocument in the CORE Apache settings, and the
Apache->custom_response() API, for which this method is a wrapper.
$Response->Flush()
# in global.asa
use vars qw( $Params );
sub Script_OnStart {
$Params = $Request->Params;
}
$Request->QueryString($name)
Returns the value of the input of name $name used in a form with GET
method, or passed by appending a query string to the end of a url as in
http://localhost/?data=value. If $name is not specified, returns a ref
to a hash of all the query string data.
$Request->ServerVariables($name)
Returns the value of the server variable / environment variable with
name $name. If $name is not specified, returns a ref to a hash of all
the server / environment variables data. The following would be a common
use of this method:
$env = $Request->ServerVariables();
# %{$env} here would be equivalent to the cgi %ENV in perl.
$Application Object
Like the $Session object, you may use the $Application object to store data
across the entire life of the application. Every page in the ASP application
always has access to this object. So if you wanted to keep track of how many
visitors there where to the application during its lifetime, you might have
a line like this:
$Application->{num_users}++
The Lock and Unlock methods are used to prevent simultaneous access to the
$Application object.
$Application->Lock()
Locks the Application object for the life of the script, or until
UnLock() unlocks it, whichever comes first. When $Application is locked,
this guarantees that data being read and written to it will not suddenly
change on you between the reads and the writes.
This and the $Session object both lock automatically upon every read and
every write to ensure data integrity. This lock is useful for concurrent
access control purposes.
Be careful to not be too liberal with this, as you can quickly create
application bottlenecks with its improper use.
$Application->UnLock()
Unlocks the $Application object. If already unlocked, does nothing.
$Application->GetSession($sess_id)
This NON-PORTABLE API extension returns a user $Session given a session
id. This allows one to easily write a session manager if session ids are
stored in $Application during Session_OnStart, with full access to these
sessions for administrative purposes.
Be careful not to expose full session ids over the net, as they could be
used by a hacker to impersonate another user. So when creating a session
manager, for example, you could create some other id to reference the
SessionID internally, which would allow you to control the sessions.
This kind of application would best be served under a secure web server.
The ./site/eg/global_asa_demo.asp script makes use of this routine to
display all the data in current user sessions.
$Application->SessionCount()
This NON-PORTABLE method returns the current number of active sessions
in the application, and is enabled by the SessionCount configuration
setting. This method is not implemented as part of the original ASP
object model, but is implemented here because it is useful. In
particular, when accessing databases with license requirements, one can
monitor usage effectively through accessing this value.
$Server Object
The server object is that object that handles everything the other objects
do not. The best part of the server object for Win32 users is the
CreateObject method which allows developers to create instances of ActiveX
components, like the ADO component.
$Server->{ScriptTimeout} = $seconds
Not implemented. May never be. Please see the Apache Timeout
configuration option, normally in httpd.conf.
$Server->Config($setting)
API extension. Allows a developer to read the CONFIG settings, like
Global, GlobalPackage, StateDir, etc. Currently implemented as a wrapper
around
Apache->dir_config($setting)
May also be invoked as $Server->Config(), which will return a hash ref
of all the PerlSetVar settings.
$Server->CreateObject($program_id)
Allows use of ActiveX objects on Win32. This routine returns a reference
to an Win32::OLE object upon success, and nothing upon failure. It is
through this mechanism that a developer can utilize ADO. The equivalent
syntax in VBScript is
Set object = Server.CreateObject(program_id)
For further information, try 'perldoc Win32::OLE' from your favorite
command line.
$Server->Execute($file, @args)
New method from ASP 3.0, this does the same thing as
$Response->Include($file, @args)
and internally is just a wrapper for such. Seems like we had this
important functionality before the IIS/ASP camp!
$Server->File()
Returns the absolute file path to current executing script. Same as
Apache->request->filename when running under mod_perl.
ASP API extension.
$Server->GetLastError()
Not implemented, will likely not ever be because this is dependent on
how IIS handles errors and is not relevant in Apache.
$Server->HTMLEncode( $string || \$string )
Returns an HTML escapes version of $string. &, ", >, <, are each escapes
with their HTML equivalents. Strings encoded in this nature should be
raw text displayed to an end user, as HTML tags become escaped with this
method.
As of version 2.23, $Server->HTMLEncode() may take a string reference
for an optmization when encoding a large buffer as an API extension.
Here is how one might use one over the other:
my $buffer = '&' x 100000;
$buffer = $Server->HTMLEncode($buffer);
print $buffer;
- or -
Standalone CGI Mode, without mod_perl
As of version 2.19, Apache::ASP scripts may be run as standalone CGI
scripts without mod_perl being loaded into Apache. Work to date has only
been done with mod_cgi scripts under Apache on a Unix platform, and it
is unlikely to work under other web servers or Win32 operating systems
without further development.
To run the ./site/eg scripts as CGI scripts, you copy the ./site
directory to some location accessible by your web server, in this
example its /usr/local/apache/htdocs/aspcgi, then in your httpd.conf
activate Apache::ASP cgi scripts like so:
Alias /aspcgi/ /usr/local/apache/htdocs/aspcgi/
<Directory /usr/local/apache/htdocs/aspcgi/eg/ >
AddType application/x-httpd-cgi .htm
AddType application/x-httpd-cgi .html
AddType application/x-httpd-cgi .asp
AddType application/x-httpd-cgi .xml
AddType application/x-httpd-cgi .ssi
AllowOverride None
Options +ExecCGI +Indexes
</Directory>
Then install the asp-perl script from the distribution into /usr/bin, or
some other directory. This is so the CGI execution line at the top of
those scripts will invoke the asp-perl wrapper like so:
#!/usr/bin/perl /usr/bin/asp-perl
The asp-perl script is a cgi wrapper that sets up the Apache::ASP
environment in lieu of the normal mod_perl handler request. Because
there is no Apache->dir_config() data available under mod_cgi, the
asp-perl script will load a asp.conf file that may define a hash %Config
of data for populating the dir_config() data. An example of a complex
asp.conf file is at ./site/eg/asp.conf
So, a trivial asp.conf file might look like:
# asp.conf
%Config = (
'Global' => '.',
'StateDir' => '/tmp/aspstate',
'NoState' => 0,
'Debug' => 3,
);
The default for NoState is 1 in CGI mode, so one must set NoState to 0
for objects like $Session & $Application to be defined.
CGI.pm
CGI.pm is a very useful module that aids developers in the building of
these applications, and Apache::ASP has been made to be compatible with
function calls in CGI.pm. Please see cgi.htm in the ./site/eg directory
for a sample ASP script written almost entirely in CGI.
As of version 0.09, use of CGI.pm for both input and output is seamless
when working under Apache::ASP. Thus if you would like to port existing
cgi scripts over to Apache::ASP, all you need to do is wrap <% %> around
the script to get going. This functionality has been implemented so that
developers may have the best of both worlds when building their web
applications.
For more information about CGI.pm, please see the web site
http://search.cpan.org/dist/CGI/
Query Object Initialization
You may create a CGI.pm $query object like so:
use CGI;
my $query = new CGI;
As of Apache::ASP version 0.09, form input may be read in by CGI.pm upon
initialization. Before, Apache::ASP would consume the form input when
reading into $Request->Form(), but now form input is cached, and may be
used by CGI.pm input routines.
CGI headers
Not only can you use the CGI.pm $query->header() method to put out
headers, but with the CgiHeaders config option set to true, you can also
print "Header: value\n", and add similar lines to the top of your
script, like:
Some-Header: Value
Some-Other: OtherValue
<html><body> Script body starts here.
Once there are no longer any cgi style headers, or the there is a
newline, the body of the script begins. So if you just had an asp script
like:
print join(":", %{$Request->QueryString});
You would likely end up with no output, as that line is interpreted as a
header because of the semicolon. When doing basic debugging, as long as
you start the page with <html> you will avoid this problem.
print()ing CGI
CGI is notorious for its print() statements, and the functions in CGI.pm
usually return strings to print(). You can do this under Apache::ASP,
since print just aliases to $Response->Write(). Note that $| has no
affect.
print $query->header();
print $query->start_form();
File Upload
CGI.pm is used for implementing reading the input from file upload. You
may create the file upload form however you wish, and then the data may
be recovered from the file upload by using $Request->Form(). Data from a
file upload gets written to a file handle, that may in turn be read
from. The original file name that was uploaded is the name of the file
handle.
my $filehandle = $Request->Form('file_upload_field_name');
print $filehandle; # will get you the file name
my $data;
while(read($filehandle, $data, 1024)) {
# data from the uploaded file read into $data
in PerlScript under IIS. Most of that work revolved around bringing a
Win32::OLE Collection interface to many of the objects in Apache::ASP, which
are natively written as perl hashes.
New as of version 2.05 is new functionality enabled with the CollectionItem
setting, to giver better support to more recent PerlScript syntax. This
seems helpful when porting from an IIS/PerlScript code base. Please see the
CONFIG section for more info.
The following objects in Apache::ASP respond as Collections:
$Application
$Session
$Request->FileUpload *
$Request->FileUpload('upload_file') *
$Request->Form
$Request->QueryString
$Request->Cookies
$Response->Cookies
$Response->Cookies('some_cookie')
* FileUpload API Extensions
And as such may be used with the following syntax, as compared with the
Apache::ASP native calls. Please note the native Apache::ASP interface is
compatible with the deprecated PerlScript interface.
C = PerlScript Compatibility N = Native Apache::ASP
## Collection->Contents($name)
[C] $Application->Contents('XYZ')
[N] $Application->{XYZ}
## Collection->SetProperty($property, $name, $value)
[C] $Application->Contents->SetProperty('Item', 'XYZ', "Fred");
[N] $Application->{XYZ} = "Fred"
## Collection->GetProperty($property, $name)
[C] $Application->Contents->GetProperty('Item', 'XYZ')
[N] $Application->{XYZ}
## Collection->Item($name)
[C] print $Request->QueryString->Item('message'), "<br>\n\n";
[N] print $Request->{QueryString}{'message'}, "<br>\n\n";
## Working with Cookies
[C] $Response->SetProperty('Cookies', 'Testing', 'Extra');
[C] $Response->SetProperty('Cookies', 'Testing', {'Path' => '/'});
[C] print $Request->Cookies(Testing) . "<br>\n";
[N] $Response->{Cookies}{Testing} = {Value => Extra, Path => '/'};
[N] print $Request->{Cookies}{Testing} . "<br>\n";
Several incompatibilities exist between PerlScript and Apache::ASP:
> Collection->{Count} property has not been implemented.
> VBScript dates may not be used for Expires property of cookies.
> Win32::OLE::in may not be used. Use keys() to iterate over.
> The ->{Item} property does not work, use the ->Item() method.
STYLE GUIDE
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
PerlInitHandler My::InitHandler
<Perl>
package My::InitHandler;
use Apache;
sub handler {
my $r = shift; # get the Apache request object
# if not a Mozilla User Agent, then disable sessions explicitly
unless($r->headers_in('User-Agent') =~ /^Mozilla/) {
$r->dir_config('AllowSessionState', 'Off');
}
return 200; # return OK mod_perl status code
}
1;
</Perl>
This will configure your environment before Apache::ASP executes and
sees the configuration settings. You can use the mod_perl API in this
way to configure Apache::ASP at runtime.
Note that the Session Manager is very robust on its own, and denial of
service attacks of the types that spiders and other web bots normally
execute are not likely to affect the Session Manager significantly.
How can I use $Session to store a $dbh database handle ?
You cannot use $Session to store a $dbh handle. This can be awkward for
those coming from the IIS/NT world, where you could store just about
anything in $Session, but this boils down to a difference between
threads vs. processes.
Database handles often have per process file handles open, which cannot
be shared between requests, so though you have stored the $dbh data in
$Session, all the other initializations are not relevant in another
httpd process.
All is not lost! Apache::DBI can be used to cache database connections
on a per process basis, and will work for most cases.
Development
VBScript or JScript supported?
Only Perl scripting is supported with this module.
How is database connectivity handled?
Database connectivity is handled through perl's DBI & DBD interfaces. In
the UNIX world, it seems most databases have cross platform support in
perl. You can find the book on DBI programming at
http://www.oreilly.com/catalog/perldbi/
DBD::ODBC is often your ticket on Win32. On UNIX, commercial vendors
like OpenLink Software (http://www.openlinksw.com/) provide the nuts and
bolts for ODBC.
Database connections can be cached per process with Apache::DBI.
What is the best way to debug an ASP application ?
There are lots of perl-ish tricks to make your life developing and
debugging an ASP application easier. For starters, you will find some
helpful hints by reading the $Response->Debug() API extension, and the
Debug configuration directive.
How are file uploads handled?
Please see the CGI section. File uploads are implemented through CGI.pm
which is loaded at runtime only for this purpose. This is the only time
that CGI.pm will be loaded by Apache::ASP, which implements all other
cgi-ish functionality natively. The rationale for not implementing file
uploads natively is that the extra 100K in memory for CGI.pm shouldn't
be a big deal if you are working with bulky file uploads.
How do I access the ASP Objects in general?
All the ASP objects can be referenced through the main package with the
following notation:
$main::Response->Write("html output");
This notation can be used from anywhere in perl, including routines
registered with $Server->RegisterCleanup().
You use the normal notation in your scripts, includes, and global.asa:
$Response->Write("html output");
Can I print() in ASP?
Yes. You can print() from anywhere in an ASP script as it aliases to the
$Response->Write() method. Using print() is portable with PerlScript
when using Win32::ASP in that environment.
Do I have access to ActiveX objects?
Only under Win32 will developers have access to ActiveX objects through
the perl Win32::OLE interface. This will remain true until there are
free COM ports to the UNIX world. At this time, there is no ActiveX for
the UNIX world.
Support and Production
How do I get things I want done?!
If you find a problem with the module, or would like a feature added,
please mail support, as listed in the SUPPORT section, and your needs
will be promptly and seriously considered, then implemented.
What is the state of Apache::ASP? Can I publish a web site on it?
Apache::ASP has been production ready since v.02. Work being done on the
module is on a per need basis, with the goal being to eventually have
the ASP API completed, with full portability to ActiveState PerlScript
and MKS PScript. If you can suggest any changes to facilitate these
goals, your comments are welcome.
TUNING
A little tuning can go a long way, and can make the difference between a web
site that gets by, and a site that screams with speed. With Apache::ASP, you
can easily take a poorly tuned site running at 10 hits/second to 50+
hits/second just with the right configuration.
Documented below are some simple things you can do to make the most of your
site.
Online Resources
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).
( run in 0.621 second using v1.01-cache-2.11-cpan-39bf76dae61 )