1NAME
2      Apache::ASP - Active Server Pages for Apache with mod_perl
3
4SYNOPSIS
5      SetHandler  perl-script
6      PerlModule  Apache::ASP
7      PerlHandler Apache::ASP
8      PerlSetVar  Global /tmp/asp
9
10DESCRIPTION
11    Apache::ASP provides an Active Server Pages port to the Apache Web Server
12    with Perl scripting only, and enables developing of dynamic web applications
13    with session management and embedded Perl code. There are also many powerful
14    extensions, including XML taglibs, XSLT rendering, and new events not
15    originally part of the ASP API!
16
17    This module works under the Apache Web Server with the mod_perl module
18    enabled. See http://www.apache.org and http://perl.apache.org for further
19    information.
20
21    This is a portable solution, similar to ActiveState's PerlScript for NT/IIS
22    ASP. Work has been done and will continue to make ports to and from this
23    implementation as smooth as possible.
24
25    For Apache::ASP downloading and installation, please read the INSTALL
26    section. For installation troubleshooting check the FAQ and the SUPPORT
27    sections.
28
29    For database access, ActiveX, scripting languages, and other miscellaneous
30    issues please read the FAQ section.
31
32WEBSITE
33    The Apache::ASP web site is at http://www.apache-asp.org/ which you can also
34    find in the ./site directory of the source distribution.
35
36INSTALL
37    The installation process for Apache::ASP is geared towards those with
38    experience with Perl, Apache, and unix systems. For those without this
39    experience, please understand that the learning curve can be significant.
40    But what you have at the end will be a web site running on superior open
41    source software.
42
43    If installing onto a Windows operating system, please see the section titled
44    Win32 Install.
45
46  Need Help
47    Often, installing the mod_perl part of the Apache server can be the hardest
48    part. If this is the case for you, check out the FAQ and SUPPORT sections
49    for further help, as well as the "Modern Linux Distributions" notes in this
50    section.
51
52    Please also see the mod_perl site at http://perl.apache.org/ which one ought
53    to give a good read before undertaking a mod_perl project.
54
55  Download and CPAN Install
56    You may download the latest Apache::ASP from your nearest CPAN, and also:
57
58      http://search.cpan.org/dist/Apache-ASP/
59      http://cpan.org/modules/by-module/Apache/
60
61    As a Perl developer, you should make yourself familiar with the CPAN.pm
62    module, and how it may be used to install Apache::ASP, and other related
63    modules. The easiest way to install Apache::ASP for the first time from Perl
64    is to fire up the CPAN shell like:
65
66     shell prompt> perl -MCPAN -e shell
67      ... configure CPAN ...
68      ... then upgrade to latest CPAN ...
69     cpan> install CPAN
70      ...
71     cpan> install Bundle::Apache::ASP
72
73    Installing the Apache::ASP bundle will automatically install all the modules
74    Apache::ASP is dependent on as well as Apache::ASP itself. If you have
75    trouble installing the bundle, then try installing the necessary modules one
76    at a time:
77
78     cpan> install MLDBM
79     cpan> install MLDBM::Sync
80     cpan> install Digest::MD5  *** may not be needed for perl 5.8+ ***
81     cpan> install Apache::ASP
82
83    For extra/optional functionality in Apache::ASP 2.31 or greater, like
84    support for FormFill, XSLT, or SSI, you can install this bundle via CPAN:
85
86      cpan> install Bundle::Apache::ASP::Extra
87
88  Regular Perl Module Install
89    If not doing the CPAN install, download Apache::ASP and install it using the
90    make or nmake commands as shown below. Otherwise, just copy ASP.pm to
91    $PERLLIB/site/Apache
92
93      > perl Makefile.PL
94      > make
95      > make test
96      > make install
97
98      * use nmake for win32
99
100    Please note that you must first have the Apache Web Server & mod_perl
101    installed before using this module in a web server environment. The offline
102    mode for building static html at ./cgi/asp-perl may be used with just perl.
103
104  Modern Linux Distributions
105    If you have a modern Linux distribution like CentOS or Ubuntu, you will
106    likely have the easiest path by using the repository tools to automatically
107    install mod_perl and Apache before installing Apache::ASP via CPAN.
108
109    For example for CentOS, this will install mod_perl into your apache httpd,
110    the latter likely being installed already by default on your server:
111
112      bash> sudo yum install mod_perl-devel.x86_64
113
114    For Ubuntu this would be done like this:
115
116      bash> sudo apt-get install libapache2-mod-perl2
117
118  Quick Start
119    Once you have successfully built the Apache Web Server with mod_perl, copy
120    the ./site/eg/ directory from the Apache::ASP installation to your Apache
121    document tree and try it out! You must put "AllowOverride All" in your
122    httpd.conf <Directory> config section to let the .htaccess file in the
123    ./site/eg installation directory do its work. If you want a starter config
124    file for Apache::ASP, just look at the .htaccess file in the ./site/eg/
125    directory.
126
127    So, you might add this to your Apache httpd.conf file just to get the
128    scripts in ./site/eg working, where $DOCUMENT_ROOT represents the
129    DocumentRoot config for your apache server:
130
131      <Directory $DOCUMENT_ROOT/asp/eg >
132        Options FollowSymLinks
133        AllowOverride All
134      </Directory>
135
136    To copy the entire site, including the examples, you might do a raw
137    directory copy as in:
138
139      shell> cp -rpd ./site $DOCUMENT_ROOT/asp
140
141    So you could then reference the Apache::ASP docs at /asp/ at your site, and
142    the examples at /asp/eg/ .
143
144    This is not a good production configuration, because it is insecure with the
145    FollowSymLinks, and tells Apache to look for .htaccess which is bad for
146    performance but it should be handy for getting started with development.
147
148    You will know that Apache::ASP is working normally if you can run the
149    scripts in ./site/eg/ without any errors. Common problems can be found in
150    the FAQ section.
151
152  Build static Apache and mod_perl for Apache 1.3.x
153    For a quick build of apache, there is a script in the distribution at
154    ./make_httpd/build_httpds.sh that can compile a statically linked Apache
155    with mod_ssl and mod_perl. Just drop the sources into the make_httpd
156    directory, configure the environments as appropriate, and execute the script
157    like this:
158
159     make_httpd> ./build_httpds.sh
160
161    You might also find helpful a couple items:
162
163      Stas's mod_perl guide install section
164      http://perl.apache.org/guide/install.html
165
166      Apache Toolbox
167      http://www.apachetoolbox.com/
168
169    People have been using Apache Toolbox to automate their complex builds of
170    Apache 1.3.x with great success.
171
172  Win32 / Windows Install
173    If you are on a Win32 platform, like WinNT or Windows 2000, you can download
174    the win32 binaries linked to from:
175
176      http://perl.apache.org/download/binaries.html#Win32
177
178    and install the latest perl-win32-bin-*.exe file.
179
180    Randy Kobes has graciously provided these, which include compiled versions
181    perl, mod_perl, apache, mod_ssl, as well as all the modules required by
182    Apache::ASP and Apache::ASP itself.
183
184    After installing this distribution, in Apache2\conf\perl.conf (pulled in via
185    Apache2\conf\httpd.conf) there's directives that have Apache::ASP handle
186    files placed under the Apache2\asp\ directory. There should be a sample
187    Apache::ASP script there, printenv.html, accessed as
188    http://127.0.0.1/asp/printenv.html which, if working, will print out your
189    environment variables.
190
191  WinME / 98 / 95 flock() workaround
192    For those on desktop Windows operation systems, Apache::ASP v2.25 and later
193    needs a special work around for the lack of flock() support on these
194    systems. Please add this to your Apache httpd.conf to fix this problem after
195    mod_perl is installed:
196
197      <Perl>
198       *CORE::GLOBAL::flock = sub { 1 };
199      </Perl>
200      PerlModule  Apache::ASP
201
202    Please be sure to add this configuration before Apache::ASP is loaded via
203    PerlModule, or a PerlRequire statement.
204
205CONFIG
206    You may use a <Files ...> directive in your httpd.conf Apache configuration
207    file to make Apache::ASP start ticking. Configure the optional settings if
208    you want, the defaults are fine to get started. The settings are documented
209    below. Make sure Global is set to where your web applications global.asa is
210    if you have one!
211
212     PerlModule  Apache::ASP
213     <Files ~ (\.asp)>
214       SetHandler  perl-script
215       PerlHandler Apache::ASP
216       PerlSetVar  Global .
217       PerlSetVar  StateDir /tmp/asp
218     </Files>
219
220    NOTE: do not use this for the examples in ./site/eg. To get the examples
221    working, check out the Quick Start section of INSTALL
222
223    You may use other Apache configuration tags like <Directory>, <Location>,
224    and <VirtualHost>, to separately define ASP configurations, but using the
225    <Files> tag is natural for ASP application building because it lends itself
226    naturally to mixed media per directory. For building many separate ASP
227    sites, you might want to use separate .htaccess files, or <Files> tags in
228    <VirtualHost> sections, the latter being better for performance.
229
230  Core
231    Global
232        Global is the nerve center of an Apache::ASP application, in which the
233        global.asa may reside defining the web application's event handlers.
234
235        This directory is pushed onto @INC, so you will be able to "use" and
236        "require" files in this directory, and perl modules developed for this
237        application may be dropped into this directory, for easy use.
238
239        Unless StateDir is configured, this directory must be some writeable
240        directory by the web server. $Session and $Application object state
241        files will be stored in this directory. If StateDir is configured, then
242        ignore this paragraph, as it overrides the Global directory for this
243        purpose.
244
245        Includes, specified with <!--#include file=somefile.inc--> or
246        $Response->Include() syntax, may also be in this directory, please see
247        section on includes for more information.
248
249          PerlSetVar Global /tmp
250
251    GlobalPackage
252        Perl package namespace that all scripts, includes, & global.asa events
253        are compiled into. By default, GlobalPackage is some obscure name that
254        is uniquely generated from the file path of the Global directory, and
255        global.asa file. The use of explicitly naming the GlobalPackage is to
256        allow scripts access to globals and subs defined in a perl module that
257        is included with commands like:
258
259          in perl script: use Some::Package;
260          in apache conf: PerlModule Some::Package
261
262          PerlSetVar GlobalPackage Some::Package
263
264    UniquePackages
265        default 0. Set to 1 to compile each script into its own perl package, so
266        that subroutines defined in one script will not collide with another.
267
268        By default, ASP scripts in a web application are compiled into the
269        *same* perl package, so these scripts, their includes, and the
270        global.asa events all share common globals & subroutines defined by each
271        other. The problem for some developers was that they would at times
272        define a subroutine of the same name in 2+ scripts, and one subroutine
273        definition would redefine the other one because of the namespace
274        collision.
275
276          PerlSetVar UniquePackages 0
277
278    DynamicIncludes
279        default 0. SSI file includes are normally inlined in the calling script,
280        and the text gets compiled with the script as a whole. With this option
281        set to TRUE, file includes are compiled as a separate subroutine and
282        called when the script is run. The advantage of having this turned on is
283        that the code compiled from the include can be shared between scripts,
284        which keeps the script sizes smaller in memory, and keeps compile times
285        down.
286
287          PerlSetVar DynamicIncludes 0
288
289    IncludesDir
290        no defaults. If set, this directory will also be used to look for
291        includes when compiling scripts. By default the directory the script is
292        in, and the Global directory are checked for includes.
293
294        This extension was added so that includes could be easily shared between
295        ASP applications, whereas placing includes in the Global directory only
296        allows sharing between scripts in an application.
297
298          PerlSetVar IncludesDir .
299
300        Also, multiple includes directories may be set by creating a directory
301        list separated by a semicolon ';' as in
302
303          PerlSetVar IncludesDir ../shared;/usr/local/asp/shared
304
305        Using IncludesDir in this way creates an includes search path that would
306        look like ., Global, ../shared, /usr/local/asp/shared The current
307        directory of the executing script is checked first whenever an include
308        is specified, then the Global directory in which the global.asa resides,
309        and finally the IncludesDir setting.
310
311    NoCache
312        Default 0, if set to 1 will make it so that neither script nor include
313        compilations are cached by the server. Using this configuration will
314        save on memory but will slow down script execution. Please see the
315        TUNING section for other strategies on improving site performance.
316
317          PerlSetVar NoCache 0
318
319  State Management
320    NoState
321        default 0, if true, neither the $Application nor $Session objects will
322        be created. Use this for a performance increase. Please note that this
323        setting takes precedence over the AllowSessionState and
324        AllowApplicationState settings.
325
326          PerlSetVar NoState 0
327
328    AllowSessionState
329        Set to 0 for no session tracking, 1 by default If Session tracking is
330        turned off, performance improves, but the $Session object is
331        inaccessible.
332
333          PerlSetVar AllowSessionState 1
334
335        Note that if you want to dissallow session creation for certain non web
336        browser user agents, like search engine spiders, you can use an init
337        handler like:
338
339          PerlInitHandler "sub { $_[0]->dir_config('AllowSessionState', 0) }"
340
341    AllowApplicationState
342        Default 1. If you want to leave $Application undefined, then set this to
343        0, for a performance increase of around 2-3%. Allowing use of
344        $Application is less expensive than $Session, as there is more work for
345        the StateManager associated with $Session garbage collection so this
346        parameter should be only used for extreme tuning.
347
348          PerlSetVar AllowApplicationState 1
349
350    StateDir
351        default $Global/.state. State files for ASP application go to this
352        directory. Where the state files go is the most important determinant in
353        what makes a unique ASP application. Different configs pointing to the
354        same StateDir are part of the same ASP application.
355
356        The default has not changed since implementing this config directive.
357        The reason for this config option is to allow operating systems with
358        caching file systems like Solaris to specify a state directory
359        separately from the Global directory, which contains more permanent
360        files. This way one may point StateDir to /tmp/myaspapp, and make one's
361        ASP application scream with speed.
362
363          PerlSetVar StateDir ./.state
364
365    StateManager
366        default 10, this number specifies the numbers of times per
367        SessionTimeout that timed out sessions are garbage collected. The bigger
368        the number, the slower your system, but the more precise Session_OnEnd's
369        will be run from global.asa, which occur when a timed out session is
370        cleaned up, and the better able to withstand Session guessing hacking
371        attempts. The lower the number, the faster a normal system will run.
372
373        The defaults of 20 minutes for SessionTimeout and 10 times for
374        StateManager, has dead Sessions being cleaned up every 2 minutes.
375
376          PerlSetVar StateManager 10
377
378    StateDB
379        default SDBM_File, this is the internal database used for state objects
380        like $Application and $Session. Because an SDBM_File %hash has a limit
381        on the size of a record key+value pair, usually 1024 bytes, you may want
382        to use another tied database like DB_File or MLDBM::Sync::SDBM_File.
383
384        With lightweight $Session and $Application use, you can get away with
385        SDBM_File, but if you load it up with complex data like $Session{key} =
386        { # very large complex object } you might max out the 1024 limit.
387
388        Currently StateDB can be: SDBM_File, MLDBM::Sync::SDBM_File, DB_File,
389        and GDBM_File. Please let me know if you would like to add any more to
390        this list.
391
392        As of version .18, you may change this setting in a live production
393        environment, and new state databases created will be of this format.
394        With a prior version if you switch to a new StateDB, you would want to
395        delete the old StateDir, as there will likely be incompatibilities
396        between the different database formats, including the way garbage
397        collection is handled.
398
399          PerlSetVar StateDB SDBM_File
400
401    StateCache
402        Deprecated as of 2.23. There is no equivalent config for the
403        functionality this represented from that version on. The 2.23 release
404        represented a significant rewrite of the state management, moving to
405        MLDBM::Sync for its subsystem.
406
407    StateSerializer
408        default Data::Dumper, you may set this to Storable for faster
409        serialization and storage of data into state objects. This is
410        particularly useful when storing large objects in $Session and
411        $Application, as the Storable.pm module has a faster implementation of
412        freezing and thawing data from and to perl structures. Note that if you
413        are storing this much data in your state databases, you may want to use
414        DB_File since it does not have the default 1024 byte limit that
415        SDBM_File has on key/value lengths.
416
417        This configuration setting may be changed in production as the state
418        database's serializer type is stored in the internal state manager which
419        will always use Data::Dumper & SDBM_File to store data.
420
421          PerlSetVar StateSerializer Data::Dumper
422
423  Sessions
424    CookiePath
425        URL root that client responds to by sending the session cookie. If your
426        asp application falls under the server url "/asp", then you would set
427        this variable to /asp. This then allows you to run different
428        applications on the same server, with different user sessions for each
429        application.
430
431          PerlSetVar CookiePath /
432
433    CookieDomain
434        Default 0, this NON-PORTABLE configuration will allow sessions to span
435        multiple web sites that match the same domain root. This is useful if
436        your web sites are hosted on the same machine and can share the same
437        StateDir configuration, and you want to shared the $Session data across
438        web sites. Whatever this is set to, that will add a
439
440          ; domain=$CookieDomain
441
442        part to the Set-Cookie: header set for the session-id cookie.
443
444          PerlSetVar CookieDomain .your.global.domain
445
446    SessionTimeout
447        Default 20 minutes, when a user's session has been inactive for this
448        period of time, the Session_OnEnd event is run, if defined, for that
449        session, and the contents of that session are destroyed.
450
451          PerlSetVar SessionTimeout 20
452
453    SecureSession
454        default 0. Sets the secure tag for the session cookie, so that the
455        cookie will only be transmitted by the browser under https
456        transmissions.
457
458          PerlSetVar SecureSession 1
459
460    HTTPOnlySession
461        default 0. Sets HttpOnly flag to session cookie to mitigate XSS attacks.
462        Supported by most modern browsers, it only allows access to the session
463        cookie by the server (ie NOT Javascript)
464
465          PerlSetVar HTTPOnlySession 1
466
467    ParanoidSession
468        default 0. When true, stores the user-agent header of the browser that
469        creates the session and validates this against the session cookie
470        presented. If this check fails, the session is killed, with the
471        rationale that there is a hacking attempt underway.
472
473        This config option was implemented to be a smooth upgrade, as you can
474        turn it off and on, without disrupting current sessions. Sessions must
475        be created with this turned on for the security to take effect.
476
477        This config option is to help prevent a brute force cookie search from
478        being successful. The number of possible cookies is huge, 2^128, thus
479        making such a hacking attempt VERY unlikely. However, on the off chance
480        that such an attack is successful, the hacker must also present
481        identical browser headers to authenticate the session, or the session
482        will be destroyed. Thus the User-Agent acts as a backup to the real
483        session id. The IP address of the browser cannot be used, since because
484        of proxies, IP addresses may change between requests during a session.
485
486        There are a few browsers that will not present a User-Agent header.
487        These browsers are considered to be browsers of type "Unknown", and this
488        method works the same way for them.
489
490        Most people agree that this level of security is unnecessary, thus it is
491        titled paranoid :)
492
493          PerlSetVar ParanoidSession 0
494
495    SessionSerialize
496        default 0, if true, locks $Session for duration of script, which
497        serializes requests to the $Session object. Only one script at a time
498        may run, per user $Session, with sessions allowed.
499
500        Serialized requests to the session object is the Microsoft ASP way, but
501        is dangerous in a production environment, where there is risk of
502        long-running or run-away processes. If these things happen, a session
503        may be locked for an indefinite period of time. A user STOP button
504        should safely quit the session however.
505
506          PerlSetVar SessionSerialize 0
507
508    SessionCount
509        default 0, if true enables the $Application->SessionCount API which
510        returns how many sessions are currently active in the application. This
511        config was created because there is a performance hit associated with
512        this count tracking, so it is disabled by default.
513
514          PerlSetVar SessionCount 1
515
516  Cookieless Sessions
517    SessionQueryParse
518        default 0, if true, will automatically parse the $Session session id
519        into the query string of each local URL found in the $Response buffer.
520        For this setting to work therefore, buffering must be enabled. This
521        parsing will only occur when a session cookie has not been sent by a
522        browser, so the first script of a session enabled site, and scripts
523        viewed by web browsers that have cookies disabled will trigger this
524        behavior.
525
526        Although this runtime parsing method is computationally expensive, this
527        cost should be amortized across most users that will not need this URL
528        parsing. This is a lazy programmer's dream. For something more
529        efficient, look at the SessionQuery setting. For more information about
530        this solution, please read the SESSIONS section.
531
532          PerlSetVar SessionQueryParse 0
533
534    SessionQueryParseMatch
535        default 0, set to a regexp pattern that matches all URLs that you want
536        to have SessionQueryParse parse in session ids. By default
537        SessionQueryParse only modifies local URLs, but if you name your URLs of
538        your site with absolute URLs like http://localhost then you will need to
539        use this setting. So to match http://localhost URLs, you might set this
540        pattern to ^http://localhost. Note that by setting this config, you are
541        also setting SessionQueryParse.
542
543          PerlSetVar SessionQueryParseMatch ^https?://localhost
544
545    SessionQuery
546        default 0, if set, the session id will be initialized from the
547        $Request->QueryString if not first found as a cookie. You can use this
548        setting coupled with the
549
550          $Server->URL($url, \%params)
551
552        API extension to generate local URLs with session ids in their query
553        strings, for efficient cookieless session support. Note that if a
554        browser has cookies disabled, every URL to any page that needs access to
555        $Session will need to be created by this method, unless you are using
556        SessionQueryParse which will do this for you automatically.
557
558          PerlSetVar SessionQuery 0
559
560    SessionQueryMatch
561        default 0, set to a regexp pattern that will match URLs for
562        $Server->URL() to add a session id to. SessionQuery normally allows
563        $Server->URL() to add session ids just to local URLs, so if you use
564        absolute URL references like http://localhost/ for your web site, then
565        just like with SessionQueryParseMatch, you might set this pattern to
566        ^http://localhost
567
568        If this is set, then you don't need to set SessionQuery, as it will be
569        set automatically.
570
571          PerlSetVar SessionQueryMatch ^http://localhost
572
573    SessionQueryForce
574        default 0, set to 1 if you want to disallow the use of cookies for
575        session id passing, and only allow session ids to be passed on the query
576        string via SessionQuery and SessionQueryParse settings.
577
578          PerlSetVar SessionQueryForce 1
579
580  Developer Environment
581    UseStrict
582        default 0, if set to 1, will compile all scripts, global.asa and
583        includes with "use strict;" inserted at the head of the file, saving you
584        from the painful process of strictifying code that was not strict to
585        begin with.
586
587        Because of how essential "use strict" programming is in a mod_perl
588        environment, this default might be set to 1 one day, but this will be up
589        for discussion before that decision is made.
590
591        Note too that errors triggered by "use strict" are now captured as part
592        of the normal Apache::ASP error handling when this configuration is set,
593        otherwise "use strict" errors will not be handled properly, so using
594        UseStrict is better than your own "use strict" statements.
595
596        PerlSetVar UseStrict 1
597
598    Debug
599        1 for server log debugging, 2 for extra client html output, 3 for
600        microtimes logged. Use 1 for production debugging, use 2 or 3 for
601        development. Turn off if you are not debugging. These settings activate
602        $Response->Debug().
603
604          PerlSetVar Debug 2
605
606        If Debug 3 is set and Time::HiRes is installed, microtimes will show up
607        in the log, and also calculate the time between one $Response->Debug()
608        and another, so good for a quick benchmark when you glance at the logs.
609
610          PerlSetVar Debug 3
611
612        If you would like to enable system level debugging, set Debug to a
613        negative value. So for system level debugging, but no output to browser:
614
615          PerlSetVar Debug -1
616
617    DebugBufferLength
618        Default 100, set this to the number of bytes of the buffered output's
619        tail you want to see when an error occurs and Debug 2 or MailErrorsTo is
620        set, and when BufferingOn is enabled.
621
622        With buffering the script output will not naturally show up when the
623        script errors, as it has been buffered by the $Response object. It helps
624        to see where in the script output an error halted the script, so the
625        last bytes of the buffered output are included with the rest of the
626        debugging information.
627
628        For a demo of this functionality, try the ./site/eg/syntax_error.asp
629        script, and turn buffering on.
630
631    PodComments
632        default 1. With pod comments turned on, perl pod style comments and
633        documentation are parsed out of scripts at compile time. This make for
634        great documentation and a nice debugging tool, and it lets you comment
635        out perl code and html in blocks. Specifically text like this:
636
637         =pod
638         text or perl code here
639         =cut
640
641        will get ripped out of the script before compiling. The =pod and =cut
642        perl directives must be at the beginning of the line, and must be
643        followed by the end of the line.
644
645          PerlSetVar PodComments 1
646
647    CollectionItem
648        Enables PerlScript syntax like:
649
650          $Request->Form('var')->Item;
651          $Request->Form('var')->Item(1);
652          $Request->Form('var')->Count;
653
654        Old PerlScript syntax, enabled with
655
656          use Win32::OLE qw(in valof with OVERLOAD);
657
658        is like native syntax
659
660          $Request->Form('var');
661
662        Only in Apache::ASP, can the above be written as:
663
664          $Request->{Form}{var};
665
666        which you would do if you _really_ needed the speed.
667
668  XML / XSLT
669    XMLSubsMatch
670        default not defined, set to some regexp pattern that will match all XML
671        and HTML tags that you want to have perl subroutines handle. The is
672        Apache::ASP's custom tag technology, and can be used to create powerful
673        extensions to your XML and HTML rendering.
674
675        Please see XML/XSLT section for instructions on its use.
676
677          PerlSetVar XMLSubsMatch my:[\w\-]+
678
679    XMLSubsStrict
680        default 0, when set XMLSubs will only take arguments that are properly
681        formed XML tag arguments like:
682
683         <my:sub arg1="value" arg2="value" />
684
685        By default, XMLSubs accept arbitrary perl code as argument values:
686
687         <my:sub arg1=1+1 arg2=&perl_sub()/>
688
689        which is not always wanted or expected. Set XMLSubsStrict to 1 if this
690        is the case.
691
692          PerlSetVar XMLSubsStrict 1
693
694    XMLSubsPerlArgs
695        default 1, when set attribute values will be interpreted as raw perl
696        code so that these all would execute as one would expect:
697
698         <my:xmlsubs arg='1' arg2="2" arg3=$value arg4="1 $value" />
699
700        With the 2.45 release, 0 may be set for this configuration or a more ASP
701        style variable interpolation:
702
703         <my:xmlsubs arg='1' arg2="2" args3="<%= $value %>" arg4="1 <%= $value %>" />
704
705        This configuration is being introduced experimentally in version 2.45,
706        as it will become the eventual default in the 3.0 release.
707
708          PerlSetVar XMLSubsPerlArgs Off
709
710    XSLT
711        default not defined, if set to a file, ASP scripts will be regarded as
712        XML output and transformed with the given XSL file with XML::XSLT. This
713        XSL file will also be executed as an ASP script first, and its output
714        will be the XSL data used for the transformation. This XSL file will be
715        executed as a dynamic include, so may be located in the current
716        directory, Global, or IncludesDir.
717
718        Please see the XML/XSLT section for an explanation of its use.
719
720          PerlSetVar XSLT template.xsl
721
722    XSLTMatch
723        default .*, if XSLT is set by default all ASP scripts will be XSL
724        transformed by the specified XSL template. This regexp setting will tell
725        XSLT which file names to match with doing XSL transformations, so that
726        regular HTML ASP scripts and XML ASP scripts can be configured with the
727        same configuration block. Please see ./site/eg/.htaccess for an example
728        of its use.
729
730          PerlSetVar XSLTMatch \.xml$
731
732    XSLTParser
733        default XML::XSLT, determines which perl module to use for XSLT parsing.
734        This is a new config as of 2.11. Also supported is XML::Sablotron which
735        does not handle XSLT with the exact same output, but is about 10 times
736        faster than XML::XSLT. XML::LibXSLT may also be used as of version 2.29,
737        and seems to be about twice again as fast as XML::Sablotron, and a very
738        complete XSLT implementation.
739
740          PerlSetVar XSLTParser XML::XSLT
741          PerlSetVar XSLTParser XML::Sablotron
742          PerlSetVar XSLTParser XML::LibXSLT
743
744    XSLTCache
745        Activate XSLT file based caching through CacheDB, CacheDir, and
746        CacheSize settings. This gives cached XSLT performance near AxKit and
747        greater than Cocoon. XSLT caches transformations keyed uniquely by XML &
748        XSLT inputs.
749
750          PerlSetVar XSLTCache 1
751
752    XSLTCacheSize
753        as of version 2.11, this config is no longer supported.
754
755  Caching
756    The output caching layer is a file dbm based output cache that runs on top
757    of the MLDBM::Sync so inherits its performance characteristics. With CacheDB
758    set to MLDBM::Sync::SDBM_File, the cache layer is very fast at caching
759    entries up to 20K in size, but for greater cached items, you should set
760    CacheDB to another dbm like DB_File or GDBM_File.
761
762    In order for the cache layer to function properly, whether for
763    $Response->Include() output caching, see OBJECTS, or XSLT caching, see
764    XML/XSLT, then Apache::ASP must be loaded in the parent httpd like so:
765
766      # httpd.conf
767      PerlModule Apache::ASP
768        -- or --
769      <Perl>
770        use Apache::ASP;
771      </Perl>
772
773    The cache layer automatically expires entries upon server restart, but for
774    this to work, a $ServerID must be computed when the Apache::ASP module gets
775    loaded to store in each cached item. Without the above done, each child
776    httpd process will get its own $ServerID, so caching will not work at all.
777
778    This said, output caching will not work in raw CGI mode, just running under
779    mod_perl.
780
781    CacheDB
782        Like StateDB, sets dbm format for caching. Since SDBM_File only support
783        key/values pairs of around 1K max in length, the default for this is
784        MLDBM::Sync::SDBM_File, which is very fast for < 20K output sizes. For
785        caching larger data than 20K, DB_File or GDBM_File are probably better
786        to use.
787
788          PerlSetVar CacheDB MLDBM::Sync::SDBM_File
789
790        For your own benchmarks to test the relative speeds of the various DBMs
791        under MLDBM::Sync, which is used by CacheDB, you may run the
792        ./bench/bench_sync.pl script from the MLDBM::Sync distribution on your
793        system.
794
795    CacheDir
796        By default, the cache directory is at StateDir/cache, but CacheDir can
797        be used to set the StateDir value for caching purposes. One may want the
798        CacheDir separate from StateDir for example StateDir might be a
799        centrally network mounted file system, while CacheDir might be a local
800        file cache.
801
802          PerlSetVar CacheDir /tmp/asp_demo
803
804        On a system like Solaris where there is a RAM disk mounted on the system
805        like /tmp, I could put the CacheDir there. On a system like Linux where
806        files are cached pretty well by default, this is less important.
807
808    CacheSize
809        By default, this is 10M of data per cache. When any cache, like the
810        XSLTCache, reaches this limit, the cache will be purged by deleting the
811        cached dbm files entirely. This is better for long term running of dbms
812        than deleting individual records, because dbm formats will often degrade
813        in performance with lots of insert & deletes.
814
815        Units of M, K, and B are supported for megabytes, kilobytes, and bytes,
816        with the default unit being B, so the following configs all mean the
817        same thing;
818
819          PerlSetVar CacheSize 10M
820          PerlSetVar CacheSize 10240K
821          PerlSetVar CacheSize 10485760B
822          PerlSetVar CacheSize 10485760
823
824        There are 2 caches currently, the XSLTCache, and the Response cache, the
825        latter which is currently invoked for caching output from includes with
826        special syntax. See $Response->Include() for more info on the Response
827        cache.
828
829  Miscellaneous
830    AuthServerVariables
831        default 0. If you are using basic auth and would like
832        $Request->ServerVariables set like AUTH_TYPE, AUTH_USER, AUTH_NAME,
833        REMOTE_USER, & AUTH_PASSWD, then set this and Apache::ASP will
834        initialize these values from Apache->*auth* commands. Use of these
835        environment variables keeps applications cross platform compatible as
836        other servers set these too when performing basic 401 auth.
837
838          PerlSetVar AuthServerVariables 0
839
840    BufferingOn
841        default 1, if true, buffers output through the response object.
842        $Response object will only send results to client browser if a
843        $Response->Flush() is called, or if the asp script ends. Lots of output
844        will need to be flushed incrementally.
845
846        If false, 0, the output is immediately written to the client, CGI style.
847        There will be a performance hit server side if output is flushed
848        automatically to the client, but is probably small.
849
850        I would leave this on, since error handling is poor, if your asp script
851        errors after sending only some of the output.
852
853          PerlSetVar BufferingOn 1
854
855    InodeNames
856        Default 0. Set to 1 to uses a stat() call on scripts and includes to
857        derive subroutine namespace based on device and inode numbers. In case
858        of multiple symbolic links pointing to the same script this will result
859        in the script being compiled only once. Use only on unix flavours which
860        support the stat() call that know about device and inode numbers.
861
862          PerlSetVar InodeNames 1
863
864    RequestParams
865        Default 0, if set creates $Request->Params object with combined contents
866        of $Request->QueryString and $Request->Form. This is for developer
867        convenience simlar to CGI.pm's param() method.
868
869          PerlSetVar RequestParams 1
870
871    RequestBinaryRead
872        Default On, if set to Off will not read POST data into $Request->Form().
873
874        One potential reason for configuring this to Off might be to initialize
875        the Apache::ASP object in an Apache handler phase earlier than the
876        normal PerlRequestHandler phase, so that it does not interfere with
877        normal reading of POST data later in the request.
878
879          PerlSetVar RequestBinaryRead On
880
881    StatINC
882        default 0, if true, reloads perl libraries that have changed on disk
883        automatically for ASP scripts. If false, the www server must be
884        restarted for library changes to take effect.
885
886        A known bug is that any functions that are exported, e.g. confess Carp
887        qw(confess), will not be refreshed by StatINC. To refresh these, you
888        must restart the www server.
889
890        This setting should be used in development only because it is so slow.
891        For a production version of StatINC, see StatINCMatch.
892
893          PerlSetVar StatINC 1
894
895    StatINCMatch
896        default undef, if defined, it will be used as a regular expression to
897        reload modules that match as in StatINC. This is useful because StatINC
898        has a very high performance penalty in production, so if you can narrow
899        the modules that are checked for reloading each script execution to a
900        handful, you will only suffer a mild performance penalty.
901
902        The StatINCMatch setting should be a regular expression like: Struct|LWP
903        which would match on reloading Class/Struct.pm, and all the LWP/.*
904        libraries.
905
906        If you define StatINCMatch, you do not need to define StatINC.
907
908          PerlSetVar StatINCMatch .*
909
910    StatScripts
911        default 1, if set to 0, changed scripts, global.asa, and includes will
912        not be reloaded. Coupled with Apache mod_perl startup and restart
913        handlers executing Apache::ASP->Loader() for your application this
914        allows your application to be frozen, and only reloaded on the next
915        server restart or stop/start.
916
917        There are a few advantages for not reloading scripts and modules in
918        production. First there is a slight performance improvement by not
919        having to stat() the script, its includes and the global.asa every
920        request.
921
922        From an application deployment standpoint, you also gain the ability to
923        deploy your application as a snapshot taken when the server starts and
924        restarts. This provides you with the reassurance that during a
925        production server update from development sources, you do not have to
926        worry with sources being used for the wrong libraries and such, while
927        they are all being copied over.
928
929        Finally, though you really should not do this, you can work on a live
930        production application, with a test server reloading changes, but your
931        production server does see the changes until you restart or stop/start
932        it. This saves your public from syntax errors while you are just doing a
933        quick bug fix.
934
935          PerlSetVar StatScripts 1
936
937    SoftRedirect
938        default 0, if true, a $Response->Redirect() does not end the script.
939        Normally, when a Redirect() is called, the script is ended
940        automatically. SoftRedirect 1, is a standard way of doing redirects,
941        allowing for html output after the redirect is specified.
942
943          PerlSetVar SoftRedirect 0
944
945    Filter
946        On/Off, default Off. With filtering enabled, you can take advantage of
947        full server side includes (SSI), implemented through Apache::SSI. SSI is
948        implemented through this mechanism by using Apache::Filter. A sample
949        configuration for full SSI with filtering is in the ./site/eg/.htaccess
950        file, with a relevant example script ./site/eg/ssi_filter.ssi.
951
952        You may only use this option with modperl v1.16 or greater installed and
953        PERL_STACKED_HANDLERS enabled. Filtering may be used in conjunction with
954        other handlers that are also "filter aware". If in doubt, try building
955        your mod_perl with
956
957          perl Makefile.PL EVERYTHING=1
958
959        With filtering through Apache::SSI, you should expect near a a 20%
960        performance decrease.
961
962          PerlSetVar Filter Off
963
964    CgiHeaders
965        default 0. When true, script output that looks like HTTP / CGI headers,
966        will be added to the HTTP headers of the request. So you could add:
967        Set-Cookie: test=message
968
969          <html>...
970        to the top of your script, and all the headers preceding a newline
971        will be added as if with a call to $Response->AddHeader().  This
972        functionality is here for compatibility with raw cgi scripts,
973        and those used to this kind of coding.
974
975        When set to 0, CgiHeaders style headers will not be parsed from the
976        script response.
977
978          PerlSetVar CgiHeaders 0
979
980    Clean
981        default 0, may be set between 1 and 9. This setting determine how much
982        text/html output should be compressed. A setting of 1 strips mostly
983        white space saving usually 10% in output size, at a performance cost of
984        less than 5%. A setting of 9 goes much further saving anywhere 25% to
985        50% typically, but with a performance hit of 50%.
986
987        This config option is implemented via HTML::Clean. Per script
988        configuration of this setting is available via the $Response->{Clean}
989        property, which may also be set between 0 and 9.
990
991          PerlSetVar Clean 0
992
993    CompressGzip
994        default 0, if true will gzip compress HTML output on the fly if
995        Compress::Zlib is installed, and the client browser supports it.
996        Depending on the HTML being compressed, the client may see a 50% to 90%
997        reduction in HTML output. I have seen 40K of HTML squeezed down to just
998        under 6K. This will come at a 5%-20% hit to CPU usage per request
999        compressed.
1000
1001        Note there are some cases when a browser says it will accept gzip
1002        encoding, but then not render it correctly. This behavior has been seen
1003        with IE5 when set to use a proxy but not using a proxy, and the URL does
1004        not end with a .html or .htm. No work around has yet been found for this
1005        case so use at your own risk.
1006
1007          PerlSetVar CompressGzip 1
1008
1009    FormFill
1010        default 0, if true will auto fill HTML forms with values from
1011        $Request->Form(). This functionality is provided by use of
1012        HTML::FillInForm. For more information please see "perldoc
1013        HTML::FillInForm", and the example ./site/eg/formfill.asp.
1014
1015        This feature can be enabled on a per form basis at runtime with
1016        $Response->{FormFill} = 1
1017
1018          PerlSetVar FormFill 1
1019
1020    TimeHiRes
1021        default 0, if set and Time::HiRes is installed, will do sub second
1022        timing of the time it takes Apache::ASP to process a request. This will
1023        not include the time spent in the session manager, nor modperl or
1024        Apache, and is only a rough approximation at best.
1025
1026        If Debug is set also, you will get a comment in your HTML output that
1027        indicates the time it took to process that script.
1028
1029        If system debugging is set with Debug -1 or -2, you will also get this
1030        time in the Apache error log with the other system messages.
1031
1032  Mail Administration
1033    Apache::ASP has some powerful administrative email extensions that let you
1034    sleep at night, knowing full well that if an error occurs at the web site,
1035    you will know about it immediately. With these features already enabled, it
1036    was also easy to provide the $Server->Mail(\%mail) API extension which you
1037    can read up about in the OBJECTS section.
1038
1039    MailHost
1040        The mail host is the smtp server that the below Mail* config directives
1041        will use when sending their emails. By default Net::SMTP uses smtp mail
1042        hosts configured in Net::Config, which is set up at install time, but
1043        this setting can be used to override this config.
1044
1045        The mail hosts specified in the Net::Config file will be used as backup
1046        smtp servers to the MailHost specified here, should this primary server
1047        not be working.
1048
1049          PerlSetVar MailHost smtp.yourdomain.com.foobar
1050
1051    MailFrom
1052        Default NONE, set this to specify the default mail address placed in the
1053        From: mail header for the $Server->Mail() API extension, as well as
1054        MailErrorsTo and MailAlertTo.
1055
1056          PerlSetVar MailFrom youremail@yourdomain.com.foobar
1057
1058    MailErrorsTo
1059        No default, if set, ASP server errors, error code 500, that result while
1060        compiling or running scripts under Apache::ASP will automatically be
1061        emailed to the email address set for this config. This allows an
1062        administrator to have a rapid response to user generated server errors
1063        resulting from bugs in production ASP scripts. Other errors, such as 404
1064        not found will be handled by Apache directly.
1065
1066        An easy way to see this config in action is to have an ASP script which
1067        calls a die(), which generates an internal ASP 500 server error.
1068
1069        The Debug config of value 2 and this setting are mutually exclusive, as
1070        Debug 2 is a development setting where errors are displayed in the
1071        browser, and MailErrorsTo is a production setting so that errors are
1072        silently logged and sent via email to the web admin.
1073
1074          PerlSetVar MailErrorsTo youremail@yourdomain.com
1075
1076    MailAlertTo
1077        The address configured will have an email sent on any ASP server error
1078        500, and the message will be short enough to fit on a text based pager.
1079        This config setting would be used to give an administrator a heads up
1080        that a www server error occurred, as opposed to MailErrorsTo would be
1081        used for debugging that server error.
1082
1083        This config does not work when Debug 2 is set, as it is a setting for
1084        use in production only, where Debug 2 is for development use.
1085
1086          PerlSetVar MailAlertTo youremail@yourdomain.com
1087
1088    MailAlertPeriod
1089        Default 20 minutes, this config specifies the time in minutes over which
1090        there may be only one alert email generated by MailAlertTo. The purpose
1091        of MailAlertTo is to give the admin a heads up that there is an error at
1092        the www server. MailErrorsTo is for to aid in speedy debugging of the
1093        incident.
1094
1095          PerlSetVar MailAlertPeriod 20
1096
1097  File Uploads
1098    FileUploadMax
1099        default 0, if set will limit file uploads to this size in bytes. This is
1100        currently implemented by setting $CGI::POST_MAX before handling the file
1101        upload. Prior to this, a developer would have to hardcode a value for
1102        $CGI::POST_MAX to get this to work.
1103
1104          PerlSetVar 100000
1105
1106    FileUploadTemp
1107        default 0, if set will leave a temp file on disk during the request,
1108        which may be helpful for processing by other programs, but is also a
1109        security risk in that other users on the operating system could
1110        potentially read this file while the script is running.
1111
1112        The path to the temp file will be available at
1113        $Request->{FileUpload}{$form_field}{TempFile}. The regular use of file
1114        uploads remains the same with the <$filehandle> to the upload at
1115        $Request->{Form}{$form_field}. Please see the CGI section for more
1116        information on file uploads, and the $Request section in OBJECTS.
1117
1118          PerlSetVar FileUploadTemp 0
1119
1120SYNTAX
1121  General
1122    ASP embedding syntax allows one to embed code in html in 2 simple ways. The
1123    first is the <% xxx %> tag in which xxx is any valid perl code. The second
1124    is <%= xxx %> where xxx is some scalar value that will be inserted into the
1125    html directly. An easy print.
1126
1127      A simple asp page would look like:
1128
1129      <!-- sample here -->
1130      <html>
1131      <body>
1132      For loop incrementing font size: <p>
1133      <% for(1..5) { %>
1134            <!-- iterated html text -->
1135            <font size="<%=$_%>" > Size = <%=$_%> </font> <br>
1136      <% } %>
1137      </body>
1138      </html>
1139      <!-- end sample here -->
1140
1141    Notice that your perl code blocks can span any html. The for loop above
1142    iterates over the html without any special syntax.
1143
1144  XMLSubs
1145    XMLSubs allows a developer to define custom handlers for HTML & XML tags,
1146    which can extend the natural syntax of the ASP environment. Configured like:
1147
1148      PerlSetVar XMLSubsMatch site:\w+
1149
1150    A simple tag like:
1151
1152      <site:header title="Page Title" />
1153
1154    can be constructed that could translate into:
1155
1156      sub site::header {
1157          my $args = shift;
1158          print "<html><head><title>$args->{title}</title></head>\n";
1159          print "<body bgcolor=white>\n";
1160      }
1161
1162    Better yet, one can use this functionality to trap and post process embedded
1163    HTML & XML like:
1164
1165      <site:page title="Page Title">
1166        ... some HTML here ...
1167      </site:page>
1168
1169    and then:
1170
1171      sub site::page {
1172        my($args, $html) = @_;
1173        &site::header($args);
1174        $main::Response->Write($html);
1175        $main::Response->Write("</body></html>");
1176      }
1177
1178    Though this could be used to fully render XML documents, it was not built
1179    for this purpose, but to add powerful tag extensions to HTML development
1180    environments. For full XML rendering, you ought to try an XSLT approach,
1181    also supported by Apache::ASP.
1182
1183  Editors
1184    As Apache::ASP supports a mixing of perl and HTML, any editor which supports
1185    development of one or the other would work well. The following editors are
1186    known to work well for developing Apache::ASP web sites:
1187
1188     * Emacs, in perl or HTML modes.  For a mmm-mode config
1189       that mixes HTML & perl modes in a single buffer, check
1190       out the editors/mmm-asp-perl.el file in distribution.
1191
1192     * Vim, special syntax support with editors/aasp.vim file in distribution.
1193
1194     * UltraEdit32 ( http://www.ultraedit.com/ ) has syntax highlighting,
1195       good macros and a configurable wordlist (so one can have syntax
1196       highlighting both for Perl and HTML).
1197
1198    Please feel free to suggest your favorite development environment for this
1199    list.
1200
1201EVENTS
1202  Overview
1203    The ASP platform allows developers to create Web Applications. In
1204    fulfillment of real software requirements, ASP allows event-triggered
1205    actions to be taken, which are defined in a global.asa file. The global.asa
1206    file resides in the Global directory, defined as a config option, and may
1207    define the following actions:
1208
1209            Action                  Event
1210            ------                  ------
1211            Script_OnStart *        Beginning of Script execution
1212            Script_OnEnd *          End of Script execution
1213            Script_OnFlush *        Before $Response being flushed to client.
1214            Script_OnParse *        Before script compilation
1215            Application_OnStart     Beginning of Application
1216            Application_OnEnd       End of Application
1217            Session_OnStart         Beginning of user Session.
1218            Session_OnEnd           End of user Session.
1219
1220      * These are API extensions that are not portable, but were
1221        added because they are incredibly useful
1222
1223    These actions must be defined in the $Global/global.asa file as subroutines,
1224    for example:
1225
1226      sub Session_OnStart {
1227          $Application->{$Session->SessionID()} = started;
1228      }
1229
1230    Sessions are easy to understand. When visiting a page in a web application,
1231    each user has one unique $Session. This session expires, after which the
1232    user will have a new $Session upon revisiting.
1233
1234    A web application starts when the user visits a page in that application,
1235    and has a new $Session created. Right before the first $Session is created,
1236    the $Application is created. When the last user $Session expires, that
1237    $Application expires also. For some web applications that are always busy,
1238    the Application_OnEnd event may never occur.
1239
1240  Script_OnStart & Script_OnEnd
1241    The script events are used to run any code for all scripts in an application
1242    defined by a global.asa. Often, you would like to run the same code for
1243    every script, which you would otherwise have to add by hand, or add with a
1244    file include, but with these events, just add your code to the global.asa,
1245    and it will be run.
1246
1247    There is one caveat. Code in Script_OnEnd is not guaranteed to be run when
1248    $Response->End() is called, since the program execution ends immediately at
1249    this event. To always run critical code, use the API extension:
1250
1251            $Server->RegisterCleanup()
1252
1253  Session_OnStart
1254    Triggered by the beginning of a user's session, Session_OnStart gets run
1255    before the user's executing script, and if the same session recently timed
1256    out, after the session's triggered Session_OnEnd.
1257
1258    The Session_OnStart is particularly useful for caching database data, and
1259    avoids having the caching handled by clumsy code inserted into each script
1260    being executed.
1261
1262  Session_OnEnd
1263    Triggered by a user session ending, Session_OnEnd can be useful for cleaning
1264    up and analyzing user data accumulated during a session.
1265
1266    Sessions end when the session timeout expires, and the StateManager performs
1267    session cleanup. The timing of the Session_OnEnd does not occur immediately
1268    after the session times out, but when the first script runs after the
1269    session expires, and the StateManager allows for that session to be cleaned
1270    up.
1271
1272    So on a busy site with default SessionTimeout (20 minutes) and StateManager
1273    (10 times) settings, the Session_OnEnd for a particular session should be
1274    run near 22 minutes past the last activity that Session saw. A site
1275    infrequently visited will only have the Session_OnEnd run when a subsequent
1276    visit occurs, and theoretically the last session of an application ever run
1277    will never have its Session_OnEnd run.
1278
1279    Thus I would not put anything mission-critical in the Session_OnEnd, just
1280    stuff that would be nice to run whenever it gets run.
1281
1282  Script_OnFlush
1283    API extension. This event will be called prior to flushing the $Response
1284    buffer to the web client. At this time, the $Response->{BinaryRef} buffer
1285    reference may be used to modify the buffered output at runtime to apply
1286    global changes to scripts output without having to modify all the scripts.
1287
1288     sub Script_OnFlush {
1289       my $ref = $Response->{BinaryRef};
1290       $$ref =~ s/\s+/ /sg; # to strip extra white space
1291     }
1292
1293    Check out the ./site/eg/global.asa for an example of its use.
1294
1295  Script_OnParse
1296    This event allows one to set up a source filter on the script text, allowing
1297    one to change the script on the fly before the compilation stage occurs. The
1298    script text is available in the $Server->{ScriptRef} scalar reference, and
1299    can be accessed like so:
1300
1301     sub Script_OnParse {
1302       my $code = $Server->{ScriptRef}
1303       $$code .= " ADDED SOMETHING ";
1304     }
1305
1306  Application_OnStart
1307    This event marks the beginning of an ASP application, and is run just before
1308    the Session_OnStart of the first Session of an application. This event is
1309    useful to load up $Application with data that will be used in all user
1310    sessions.
1311
1312  Application_OnEnd
1313    The end of the application is marked by this event, which is run after the
1314    last user session has timed out for a given ASP application.
1315
1316  Server_OnStart ( pseudo-event )
1317    Some might want something like a Server_OnStart event, where some code gets
1318    runs when the web server starts. In mod_perl, this is easy to achieve
1319    outside of the scope of an ASP application, by putting some initialization
1320    code into a <Perl> section in the httpd.conf file. Initializations that you
1321    would like to be shared with the child httpds are particularly useful, one
1322    such being the Apache::ASP->Loader() routine which you can read more about
1323    in the TUNING section - Precompile Scripts subsection. It is could be called
1324    like:
1325
1326      # httpd.conf
1327      <Perl>
1328         Apache::ASP->Loader($path, $pattern, %config)
1329      </Perl>
1330
1331    So a <Perl> section is your Server_OnStart routine!
1332
1333  mod_perl handlers
1334    If one wants to extend one's environment with mod_perl handlers, Apache::ASP
1335    does not stop this. Basic use of Apache::ASP in fact only involves the
1336    content handler phase of mod_perl's PerlHandler, like
1337
1338      SetHandler perl-script
1339      PerlModule Apache::ASP
1340      PerlHandler Apache::ASP
1341
1342    But mod_perl allows for direct access to many more Apache event stages, for
1343    full list try "perldoc mod_perl" or buy the mod_perl Eagle book. Some
1344    commonly used ones are:
1345
1346      PerlInitHandler
1347      PerlTransHandler
1348      PerlFixupHandler
1349      PerlHandler
1350      PerlLogHandler
1351      PerlCleanupHandler
1352
1353    For straight Apache::ASP programming, there are some equivalents, say
1354    Script_OnStart event instead of Init/Fixup stages, or
1355    $Server->RegisterCleanup() for Log/Cleanup stages, but you can do things in
1356    the mod_perl handlers that you cannot do in Apache::ASP, especially if you
1357    want to handle all files globally, and not just ASP scripts.
1358
1359    For many Apache::* modules for use with mod_perl, of which Apache::ASP is
1360    just one, check out http://perl.apache.org/src/apache-modlist.html
1361
1362    To gain access to the ASP objects like $Session outside in a non-PerlHandler
1363    mod_perl handler, you may use this API:
1364
1365      my $ASP = Apache::ASP->new($r); # $r is Apache->request object
1366
1367    as in this possible Authen handler:
1368
1369      <Perl>
1370        use Apache::ASP;
1371        sub My::Auth::handler {
1372          my $r = shift;
1373          my $ASP = Apache::ASP->new($r)
1374          my $Session = $ASP->Session;
1375        }
1376      </Perl>
1377
1378    Here are some examples of do-it-yourself mod_perl handler programming...
1379
1380     === Forbid Bad HSlide User Agent ===
1381
1382     # httpd.conf
1383     PerlAccessHandler My::Access
1384     <Perl>
1385       sub My::Access::handler {
1386         my $r = shift;
1387         if($r->headers_in->{'USER_AGENT'} =~ /HSlide/) {
1388             403;
1389         } else {
1390             200;
1391         }
1392       }
1393     </Perl>
1394
1395     === Runtime Path Parsing ===
1396
1397    This example shows how one might take an arbitrary URL path
1398    /$path/$file.asp, and turn that into a runtime config for your site, so your
1399    scripts get executed always in your sites DocumentRoot.
1400
1401     INPUT URL /SomeCategory/
1402     OUTPUT
1403      Script: index.asp
1404      $Server->Config('PATH') eq '/SomeCategory'
1405
1406     INPUT URL /SomeCategory/index.asp
1407     OUTPUT
1408      Script: index.asp
1409      $Server->Config('PATH') eq '/SomeCategory'
1410
1411     INPUT URI /index.asp
1412     OUTPUT
1413      Script: index.asp
1414      $Server->Config('PATH') eq ''
1415
1416     # httpd.conf
1417     PerlTransHandler My::Init
1418     use lib qw( $custom_perllib );
1419
1420     # $custom_perllib/My/Init.pm
1421     package My::Init;
1422     use strict;
1423     use Apache::Constants qw(:common);
1424     sub handler {
1425        my $r = shift;
1426
1427        my $uri = $r->uri || '/';
1428        unless($uri =~ m|^(.*)(/([^/.]+\.[\w]+)?)$|i) {
1429            warn("can't parse uri $uri");
1430            return DECLINED;
1431        }
1432        $uri = $2;
1433        my $PATH = $1 || '';
1434        $r->dir_config('PATH', $PATH);
1435
1436        if($uri eq '/') {
1437            $uri = '/index.asp';
1438        }
1439
1440        $r->uri($uri);
1441        $r->filename($r->document_root.$uri);
1442
1443        DECLINED;
1444     }
1445
1446     1;
1447
1448OBJECTS
1449    The beauty of the ASP Object Model is that it takes the burden of CGI and
1450    Session Management off the developer, and puts them in objects accessible
1451    from any ASP script & include. For the perl programmer, treat these objects
1452    as globals accessible from anywhere in your ASP application.
1453
1454    The Apache::ASP object model supports the following:
1455
1456      Object         Function
1457      ------         --------
1458      $Session      - user session state
1459      $Response     - output to browser
1460      $Request      - input from browser
1461      $Application  - application state
1462      $Server       - general methods
1463
1464    These objects, and their methods are further defined in the following
1465    sections.
1466
1467    If you would like to define your own global objects for use in your scripts
1468    and includes, you can initialize them in the global.asa Script_OnStart like:
1469
1470     use vars qw( $Form $Site ); # declare globals
1471     sub Script_OnStart {
1472         $Site = My::Site->new;  # init $Site object
1473         $Form = $Request->Form; # alias form data
1474         $Server->RegisterCleanup(sub { # garbage collection
1475                                      $Site->DESTROY;
1476                                      $Site = $Form = undef;
1477                                  });
1478     }
1479
1480    In this way you can create site wide application objects and simple aliases
1481    for common functions.
1482
1483  $Session Object
1484    The $Session object keeps track of user and web client state, in a
1485    persistent manner, making it relatively easy to develop web applications.
1486    The $Session state is stored across HTTP connections, in database files in
1487    the Global or StateDir directories, and will persist across web server
1488    restarts.
1489
1490    The user session is referenced by a 128 bit / 32 byte MD5 hex hashed cookie,
1491    and can be considered secure from session id guessing, or session hijacking.
1492    When a hacker fails to guess a session, the system times out for a second,
1493    and with 2**128 (3.4e38) keys to guess, a hacker will not be guessing an id
1494    any time soon.
1495
1496    If an incoming cookie matches a timed out or non-existent session, a new
1497    session is created with the incoming id. If the id matches a currently
1498    active session, the session is tied to it and returned. This is also similar
1499    to the Microsoft ASP implementation.
1500
1501    The $Session reference is a hash ref, and can be used as such to store data
1502    as in:
1503
1504        $Session->{count}++;        # increment count by one
1505        %{$Session} = ();   # clear $Session data
1506
1507    The $Session object state is implemented through MLDBM, and a user should be
1508    aware of the limitations of MLDBM. Basically, you can read complex
1509    structures, but not write them, directly:
1510
1511      $data = $Session->{complex}{data};     # Read ok.
1512      $Session->{complex}{data} = $data;     # Write NOT ok.
1513      $Session->{complex} = {data => $data}; # Write ok, all at once.
1514
1515    Please see MLDBM for more information on this topic. $Session can also be
1516    used for the following methods and properties:
1517
1518    $Session->{CodePage}
1519        Not implemented. May never be until someone needs it.
1520
1521    $Session->{LCID}
1522        Not implemented. May never be until someone needs it.
1523
1524    $Session->{SessionID}
1525        SessionID property, returns the id for the current session, which is
1526        exchanged between the client and the server as a cookie.
1527
1528    $Session->{Timeout} [= $minutes]
1529        Timeout property, if minutes is being assigned, sets this default
1530        timeout for the user session, else returns the current session timeout.
1531
1532        If a user session is inactive for the full timeout, the session is
1533        destroyed by the system. No one can access the session after it times
1534        out, and the system garbage collects it eventually.
1535
1536    $Session->Abandon()
1537        The abandon method times out the session immediately. All Session data
1538        is cleared in the process, just as when any session times out.
1539
1540    $Session->Lock()
1541        API extension. If you are about to use $Session for many consecutive
1542        reads or writes, you can improve performance by explicitly locking
1543        $Session, and then unlocking, like:
1544
1545          $Session->Lock();
1546          $Session->{count}++;
1547          $Session->{count}++;
1548          $Session->{count}++;
1549          $Session->UnLock();
1550
1551        This sequence causes $Session to be locked and unlocked only 1 time,
1552        instead of the 6 times that it would be locked otherwise, 2 for each
1553        increment with one to read and one to write.
1554
1555        Because of flushing issues with SDBM_File and DB_File databases, each
1556        lock actually ties fresh to the database, so the performance savings
1557        here can be considerable.
1558
1559        Note that if you have SessionSerialize set, $Session is already locked
1560        for each script invocation automatically, as if you had called
1561        $Session->Lock() in Script_OnStart. Thus you do not need to worry about
1562        $Session locking for performance. Please read the section on
1563        SessionSerialize for more info.
1564
1565    $Session->UnLock()
1566        API Extension. Unlocks the $Session explicitly. If you do not call this,
1567        $Session will be unlocked automatically at the end of the script.
1568
1569  $Response Object
1570    This object manages the output from the ASP Application and the client web
1571    browser. It does not store state information like the $Session object but
1572    does have a wide array of methods to call.
1573
1574    $Response->{BinaryRef}
1575        API extension. This is a perl reference to the buffered output of the
1576        $Response object, and can be used in the Script_OnFlush global.asa event
1577        to modify the buffered output at runtime to apply global changes to
1578        scripts output without having to modify all the scripts. These changes
1579        take place before content is flushed to the client web browser.
1580
1581         sub Script_OnFlush {
1582           my $ref = $Response->{BinaryRef};
1583           $$ref =~ s/\s+/ /sg; # to strip extra white space
1584         }
1585
1586        Check out the ./site/eg/global.asa for an example of its use.
1587
1588    $Response->{Buffer}
1589        Default 1, when TRUE sends output from script to client only at the end
1590        of processing the script. When 0, response is not buffered, and client
1591        is sent output as output is generated by the script.
1592
1593    $Response->{CacheControl}
1594        Default "private", when set to public allows proxy servers to cache the
1595        content. This setting controls the value set in the HTTP header
1596        Cache-Control
1597
1598    $Response->{Charset}
1599        This member when set appends itself to the value of the Content-Type
1600        HTTP header. If $Response->{Charset} = 'ISO-LATIN-1' is set, the
1601        corresponding header would look like:
1602
1603          Content-Type: text/html; charset=ISO-LATIN-1
1604
1605    $Response->{Clean} = 0-9;
1606        API extension. Set the Clean level, default 0, on a per script basis.
1607        Clean of 1-9 compresses text/html output. Please see the Clean config
1608        option for more information. This setting may also be useful even if
1609        using compression to obfuscate HTML.
1610
1611    $Response->{ContentType} = "text/html"
1612        Sets the MIME type for the current response being sent to the client.
1613        Sent as an HTTP header.
1614
1615    $Response->{Debug} = 1|0
1616        API extension. Default set to value of Debug config. May be used to
1617        temporarily activate or inactivate $Response->Debug() behavior.
1618        Something like:
1619
1620         {
1621           local $Response->{Debug} = 1;
1622           $Response->Debug($values);
1623         }
1624
1625        maybe be used to always log something. The Debug() method can be better
1626        than AppendToLog() because it will log data in data structures one level
1627        deep, whereas AppendToLog prints just raw string/scalar values.
1628
1629    $Response->{Expires} = $time
1630        Sends a response header to the client indicating the $time in SECONDS in
1631        which the document should expire. A time of 0 means immediate
1632        expiration. The header generated is a standard HTTP date like: "Wed, 09
1633        Feb 1994 22:23:32 GMT".
1634
1635    $Response->{ExpiresAbsolute} = $date
1636        Sends a response header to the client with $date being an absolute time
1637        to expire. Formats accepted are all those accepted by
1638        HTTP::Date::str2time(), e.g.
1639
1640         "Wed, 09 Feb 1994 22:23:32 GMT"     -- HTTP format
1641         "Tuesday, 08-Feb-94 14:15:29 GMT"   -- old rfc850 HTTP format
1642
1643         "08-Feb-94"       -- old rfc850 HTTP format
1644         "09 Feb 1994"     -- proposed new HTTP format
1645
1646         "Feb  3  1994"    -- Unix 'ls -l' format
1647         "Feb  3 17:03"    -- Unix 'ls -l' format
1648
1649    $Response->{FormFill} = 0|1
1650        If true, HTML forms generated by the script output will be auto filled
1651        with data from $Request->Form. This feature requires HTML::FillInForm to
1652        be installed. Please see the FormFill CONFIG for more information.
1653
1654        This setting overrides the FormFill config at runtime for the script
1655        execution only.
1656
1657    $Response->{IsClientConnected}
1658        1 if web client is connected, 0 if not. This value starts set to 1, and
1659        will be updated whenever a $Response->Flush() is called. If BufferingOn
1660        is set, by default $Response->Flush() will only be called at the end of
1661        the HTML output.
1662
1663        As of version 2.23 this value is updated correctly before global.asa
1664        Script_OnStart is called, so global script termination may be correctly
1665        handled during that event, which one might want to do with excessive
1666        user STOP/RELOADS when the web server is very busy.
1667
1668        An API extension $Response->IsClientConnected may be called for
1669        refreshed connection status without calling first a $Response->Flush
1670
1671    $Response->{PICS}
1672        If this property has been set, a PICS-Label HTTP header will be sent
1673        with its value. For those that do not know, PICS is a header that is
1674        useful in rating the internet. It stands for Platform for Internet
1675        Content Selection, and you can find more info about it at:
1676        http://www.w3.org
1677
1678    $Response->{Status} = $status
1679        Sets the status code returned by the server. Can be used to set messages
1680        like 500, internal server error
1681
1682    $Response->AddHeader($name, $value)
1683        Adds a custom header to a web page. Headers are sent only before any
1684        text from the main page is sent, so if you want to set a header after
1685        some text on a page, you must turn BufferingOn.
1686
1687    $Response->AppendToLog($message)
1688        Adds $message to the server log. Useful for debugging.
1689
1690    $Response->BinaryWrite($data)
1691        Writes binary data to the client. The only difference from
1692        $Response->Write() is that $Response->Flush() is called internally
1693        first, so the data cannot be parsed as an html header. Flushing flushes
1694        the header if has not already been written.
1695
1696        If you have set the $Response->{ContentType} to something other than
1697        text/html, cgi header parsing (see CGI notes), will be automatically be
1698        turned off, so you will not necessarily need to use BinaryWrite for
1699        writing binary data.
1700
1701        For an example of BinaryWrite, see the binary_write.htm example in
1702        ./site/eg/binary_write.htm
1703
1704        Please note that if you are on Win32, you will need to call binmode on a
1705        file handle before reading, if its data is binary.
1706
1707    $Response->Clear()
1708        Erases buffered ASP output.
1709
1710    $Response->Cookies($name, [$key,] $value)
1711        Sets the key or attribute of cookie with name $name to the value $value.
1712        If $key is not defined, the Value of the cookie is set. ASP CookiePath
1713        is assumed to be / in these examples.
1714
1715         $Response->Cookies('name', 'value');
1716          --> Set-Cookie: name=value; path=/
1717
1718         $Response->Cookies("Test", "data1", "test value");
1719         $Response->Cookies("Test", "data2", "more test");
1720         $Response->Cookies(
1721                "Test", "Expires",
1722                &HTTP::Date::time2str(time+86400)
1723                );
1724         $Response->Cookies("Test", "Secure", 1);
1725         $Response->Cookies("Test", "Path", "/");
1726         $Response->Cookies("Test", "Domain", "host.com");
1727          -->   Set-Cookie:Test=data1=test%20value&data2=more%20test;   \
1728                        expires=Fri, 23 Apr 1999 07:19:52 GMT;          \
1729                        path=/; domain=host.com; secure
1730
1731        The latter use of $key in the cookies not only sets cookie attributes
1732        such as Expires, but also treats the cookie as a hash of key value pairs
1733        which can later be accesses by
1734
1735         $Request->Cookies('Test', 'data1');
1736         $Request->Cookies('Test', 'data2');
1737
1738        Because this is perl, you can (NOT PORTABLE) reference the cookies
1739        directly through hash notation. The same 5 commands above could be
1740        compressed to:
1741
1742         $Response->{Cookies}{Test} =
1743                {
1744                        Secure  => 1,
1745                        Value   =>
1746                                {
1747                                        data1 => 'test value',
1748                                        data2 => 'more test'
1749                                },
1750                        Expires => 86400, # not portable, see above
1751                        Domain  => 'host.com',
1752                        Path    => '/'
1753                };
1754
1755        and the first command would be:
1756
1757         # you don't need to use hash notation when you are only setting
1758         # a simple value
1759         $Response->{Cookies}{'Test Name'} = 'Test Value';
1760
1761        I prefer the hash notation for cookies, as this looks nice, and is quite
1762        perlish. It is here to stay. The Cookie() routine is very complex and
1763        does its best to allow access to the underlying hash structure of the
1764        data. This is the best emulation I could write trying to match the
1765        Collections functionality of cookies in IIS ASP.
1766
1767        For more information on Cookies, please go to the source at
1768        http://home.netscape.com/newsref/std/cookie_spec.html
1769
1770    $Response->Debug(@args)
1771        API Extension. If the Debug config option is set greater than 0, this
1772        routine will write @args out to server error log. refs in @args will be
1773        expanded one level deep, so data in simple data structures like
1774        one-level hash refs and array refs will be displayed. CODE refs like
1775
1776         $Response->Debug(sub { "some value" });
1777
1778        will be executed and their output added to the debug output. This
1779        extension allows the user to tie directly into the debugging
1780        capabilities of this module.
1781
1782        While developing an app on a production server, it is often useful to
1783        have a separate error log for the application to catch debugging output
1784        separately. One way of implementing this is to use the Apache ErrorLog
1785        configuration directive to create a separate error log for a virtual
1786        host.
1787
1788        If you want further debugging support, like stack traces in your code,
1789        consider doing things like:
1790
1791         $Response->Debug( sub { Carp::longmess('debug trace') };
1792         $SIG{__WARN__} = \&Carp::cluck; # then warn() will stack trace
1793
1794        The only way at present to see exactly where in your script an error
1795        occurred is to set the Debug config directive to 2, and match the error
1796        line number to perl script generated from your ASP script.
1797
1798        However, as of version 0.10, the perl script generated from the asp
1799        script should match almost exactly line by line, except in cases of
1800        inlined includes, which add to the text of the original script, pod
1801        comments which are entirely yanked out, and <% # comment %> style
1802        comments which have a \n added to them so they still work.
1803
1804        If you would like to see the HTML preceding an error while developing,
1805        consider setting the BufferingOn config directive to 0.
1806
1807    $Response->End()
1808        Sends result to client, and immediately exits script. Automatically
1809        called at end of script, if not already called.
1810
1811    $Response->ErrorDocument($code, $uri)
1812        API extension that allows for the modification the Apache ErrorDocument
1813        at runtime. $uri may be a on site document, off site URL, or string
1814        containing the error message.
1815
1816        This extension is useful if you want to have scripts set error codes
1817        with $Response->{Status} like 401 for authentication failure, and to
1818        then control from the script what the error message looks like.
1819
1820        For more information on the Apache ErrorDocument mechanism, please see
1821        ErrorDocument in the CORE Apache settings, and the
1822        Apache->custom_response() API, for which this method is a wrapper.
1823
1824    $Response->Flush()
1825        Sends buffered output to client and clears buffer.
1826
1827    $Response->Include($filename, @args)
1828        This API extension calls the routine compiled from asp script in
1829        $filename with the args @args. This is a direct translation of the SSI
1830        tag
1831
1832          <!--#include file=$filename args=@args-->
1833
1834        Please see the SSI section for more on SSI in general.
1835
1836        This API extension was created to allow greater modularization of code
1837        by allowing includes to be called with runtime arguments. Files included
1838        are compiled once, and the anonymous code ref from that compilation is
1839        cached, thus including a file in this manner is just like calling a perl
1840        subroutine. The @args can be found in @_ in the includes like:
1841
1842          # include.inc
1843          <% my @args = @_; %>
1844
1845        As of 2.23, multiple return values can be returned from an include like:
1846
1847         my @rv = $Response->Include($filename, @args);
1848
1849    $Response->Include(\%cache_args, @sub_args) *CACHE API*
1850        As of version 2.23, output from an include may be cached with this API
1851        and the CONFIG settings CacheDir & CacheDB. This can be used to execute
1852        expensive includes only rarely where applicable, drastically increasing
1853        performance in some cases.
1854
1855        This API extension applies to the entire include family:
1856
1857          my @rv = $Response->Include(\%cache_args, @include_args)
1858          my $html_ref = $Response->TrapInclude(\%cache_args, @include_args)
1859          $Server->Execute(\%cache_args, @include_args)
1860
1861        For this output cache to work, you must load Apache::ASP in the Apache
1862        parent httpd like so:
1863
1864          # httpd.conf
1865          PerlModule Apache::ASP
1866
1867        The cache arguments are shown here
1868
1869          $Response->Include({
1870            File => 'file.inc',
1871            Cache => 1, # to activate cache layer
1872            Expires => 3600, # to expire in one hour
1873            LastModified => time() - 600, # to expire if cached before 10 minutes ago
1874            Key => $Request->Form, # to cache based on checksum of serialized form data,
1875            Clear => 1, # always executes include & cache output
1876          }, @include_args);
1877
1878          File - include file to execute, can be file name or \$script
1879            script data passed in as a string reference.
1880
1881          Cache - activate caching, will run like normal include without this
1882
1883          Expires - only cache for this long in seconds
1884
1885          LastModified - if cached before this time(), expire
1886
1887          Key - The cache item identity.  Can be $data, \$data, \%data, \@data,
1888            this data is serialized and combined with the filename & @include_args
1889            to create a MD5 checksum to fetch from the cache with. If you wanted
1890            to cache the results of a search page from form data POSTed,
1891            then this key could be
1892
1893              { Key => $Request->Form }
1894
1895          Clear - If set to 1, or boolean true, will always execute the include
1896            and update the cache entry for it.
1897
1898        Motivation: If an include takes 1 second to execute because of complex
1899        SQL to a database, and you can cache the output of this include because
1900        it is not realtime data, and the cache layer runs at .01 seconds, then
1901        you have a 100 fold savings on that part of the script. Site scalability
1902        can be dramatically increased in this way by intelligently caching
1903        bottlenecks in the web application.
1904
1905        Use Sparingly: If you have a fast include, then it may execute faster
1906        than the cache layer runs, in which case you may actually slow your site
1907        down by using this feature. Therefore try to use this sparingly, and
1908        only when sure you really need it. Apache::ASP scripts generally execute
1909        very quickly, so most developers will not need to use this feature at
1910        all.
1911
1912    $Response->Include(\$script_text, @args)
1913        Added in Apache::ASP 2.11, this method allows for executing ASP scripts
1914        that are generated dynamically by passing in a reference to the script
1915        data instead of the file name. This works just like the normal
1916        $Response->Include() API, except a string reference is passed in instead
1917        of a filename. For example:
1918
1919          <%
1920            my $script = "<\% print 'TEST'; %\>";
1921            $Response->Include(\$script);
1922          %>
1923
1924        This include would output TEST. Note that tokens like <% and %> must be
1925        escaped so Apache::ASP does not try to compile those code blocks
1926        directly when compiling the original script. If the $script data were
1927        fetched directly from some external resource like a database, then these
1928        tokens would not need to be escaped at all as in:
1929
1930          <%
1931            my $script = $dbh->selectrow_array(
1932               "select script_text from scripts where script_id = ?",
1933               undef, $script_id
1934               );
1935            $Response->Include(\$script);
1936          %>
1937
1938        This method could also be used to render other types of dynamic scripts,
1939        like XML docs using XMLSubs for example, though for complex runtime XML
1940        rendering, one should use something better suited like XSLT. See the
1941        $Server->XSLT API for more on this topic.
1942
1943    $Response->IsClientConnected()
1944        API Extension. 1 for web client still connected, 0 if disconnected which
1945        might happen if the user hits the stop button. The original API for this
1946        $Response->{IsClientConnected} is only updated after a $Response->Flush
1947        is called, so this method may be called for a refreshed status.
1948
1949        Note $Response->Flush calls $Response->IsClientConnected to update
1950        $Response->{IsClientConnected} so to use this you are going straight to
1951        the source! But if you are doing a loop like:
1952
1953          while(@data) {
1954            $Response->End if ! $Response->{IsClientConnected};
1955            my $row = shift @data;
1956            %> <%= $row %> <%
1957            $Response->Flush;
1958          }
1959
1960        Then its more efficient to use the member instead of the method since
1961        $Response->Flush() has already updated that value for you.
1962
1963    $Response->Redirect($url)
1964        Sends the client a command to go to a different url $url. Script
1965        immediately ends.
1966
1967    $Response->TrapInclude($file, @args)
1968        Calls $Response->Include() with same arguments as passed to it, but
1969        instead traps the include output buffer and returns it as as a perl
1970        string reference. This allows one to postprocess the output buffer
1971        before sending to the client.
1972
1973          my $string_ref = $Response->TrapInclude('file.inc');
1974          $$string_ref =~ s/\s+/ /sg; # squash whitespace like Clean 1
1975          print $$string_ref;
1976
1977        The data is returned as a referenece to save on what might be a large
1978        string copy. You may dereference the data with the $$string_ref
1979        notation.
1980
1981    $Response->Write($data)
1982        Write output to the HTML page. <%=$data%> syntax is shorthand for a
1983        $Response->Write($data). All final output to the client must at some
1984        point go through this method.
1985
1986  $Request Object
1987    The request object manages the input from the client browser, like posts,
1988    query strings, cookies, etc. Normal return results are values if an index is
1989    specified, or a collection / perl hash ref if no index is specified.
1990    WARNING, the latter property is not supported in ActiveState PerlScript, so
1991    if you use the hashes returned by such a technique, it will not be portable.
1992
1993    A normal use of this feature would be to iterate through the form variables
1994    in the form hash...
1995
1996     $form = $Request->Form();
1997     for(keys %{$form}) {
1998            $Response->Write("$_: $form->{$_}<br>\n");
1999     }
2000
2001    Please see the ./site/eg/server_variables.htm asp file for this method in
2002    action.
2003
2004    Note that if a form POST or query string contains duplicate values for a
2005    key, those values will be returned through normal use of the $Request
2006    object:
2007
2008      @values = $Request->Form('key');
2009
2010    but you can also access the internal storage, which is an array reference
2011    like so:
2012
2013      $array_ref = $Request->{Form}{'key'};
2014      @values = @{$array_ref};
2015
2016    Please read the PERLSCRIPT section for more information on how things like
2017    $Request->QueryString() & $Request->Form() behave as collections.
2018
2019    $Request->{Method}
2020        API extension. Returns the client HTTP request method, as in GET or
2021        POST. Added in version 2.31.
2022
2023    $Request->{TotalBytes}
2024        The amount of data sent by the client in the body of the request,
2025        usually the length of the form data. This is the same value as
2026        $Request->ServerVariables('CONTENT_LENGTH')
2027
2028    $Request->BinaryRead([$length])
2029        Returns a string whose contents are the first $length bytes of the form
2030        data, or body, sent by the client request. If $length is not given, will
2031        return all of the form data. This data is the raw data sent by the
2032        client, without any parsing done on it by Apache::ASP.
2033
2034        Note that BinaryRead will not return any data for file uploads. Please
2035        see the $Request->FileUpload() interface for access to this data.
2036        $Request->Form() data will also be available as normal.
2037
2038    $Request->ClientCertificate()
2039        Not implemented.
2040
2041    $Request->Cookies($name [,$key])
2042        Returns the value of the Cookie with name $name. If a $key is specified,
2043        then a lookup will be done on the cookie as if it were a query string.
2044        So, a cookie set by:
2045
2046         Set-Cookie: test=data1=1&data2=2
2047
2048        would have a value of 2 returned by $Request->Cookies('test','data2').
2049
2050        If no name is specified, a hash will be returned of cookie names as keys
2051        and cookie values as values. If the cookie value is a query string, it
2052        will automatically be parsed, and the value will be a hash reference to
2053        these values.
2054
2055        When in doubt, try it out. Remember that unless you set the Expires
2056        attribute of a cookie with $Response->Cookies('cookie', 'Expires',
2057        $xyz), the cookies that you set will only last until you close your
2058        browser, so you may find your self opening & closing your browser a lot
2059        when debugging cookies.
2060
2061        For more information on cookies in ASP, please read $Response->Cookies()
2062
2063    $Request->FileUpload($form_field, $key)
2064        API extension. The FileUpload interface to file upload data is
2065        stabilized. The internal representation of the file uploads is a hash of
2066        hashes, one hash per file upload found in the $Request->Form()
2067        collection. This collection of collections may be queried through the
2068        normal interface like so:
2069
2070          $Request->FileUpload('upload_file', 'ContentType');
2071          $Request->FileUpload('upload_file', 'FileHandle');
2072          $Request->FileUpload('upload_file', 'BrowserFile');
2073          $Request->FileUpload('upload_file', 'Mime-Header');
2074          $Request->FileUpload('upload_file', 'TempFile');
2075
2076          * note that TempFile must be use with the UploadTempFile
2077            configuration setting.
2078
2079        The above represents the old slow collection interface, but like all
2080        collections in Apache::ASP, you can reference the internal hash
2081        representation more easily.
2082
2083          my $fileup = $Request->{FileUpload}{upload_file};
2084          $fileup->{ContentType};
2085          $fileup->{BrowserFile};
2086          $fileup->{FileHandle};
2087          $fileup->{Mime-Header};
2088          $fileup->{TempFile};
2089
2090    $Request->Form($name)
2091        Returns the value of the input of name $name used in a form with POST
2092        method. If $name is not specified, returns a ref to a hash of all the
2093        form data. One can use this hash to create a nice alias to the form data
2094        like:
2095
2096         # in global.asa
2097         use vars qw( $Form );
2098         sub Script_OnStart {
2099           $Form = $Request->Form;
2100         }
2101         # then in ASP scripts
2102         <%= $Form->{var} %>
2103
2104        File upload data will be loaded into $Request->Form('file_field'), where
2105        the value is the actual file name of the file uploaded, and the contents
2106        of the file can be found by reading from the file name as a file handle
2107        as in:
2108
2109         while(read($Request->Form('file_field_name'), $data, 1024)) {};
2110
2111        For more information, please see the CGI / File Upload section, as file
2112        uploads are implemented via the CGI.pm module. An example can be found
2113        in the installation samples ./site/eg/file_upload.asp
2114
2115    $Request->Params($name)
2116        API extension. If RequestParams CONFIG is set, the $Request->Params
2117        object is created with combined contents of $Request->QueryString and
2118        $Request->Form. This is for developer convenience simlar to CGI.pm's
2119        param() method. Just like for $Response->Form, one could create a nice
2120        alias like:
2121
2122         # in global.asa
2123         use vars qw( $Params );
2124         sub Script_OnStart {
2125           $Params = $Request->Params;
2126         }
2127
2128    $Request->QueryString($name)
2129        Returns the value of the input of name $name used in a form with GET
2130        method, or passed by appending a query string to the end of a url as in
2131        http://localhost/?data=value. If $name is not specified, returns a ref
2132        to a hash of all the query string data.
2133
2134    $Request->ServerVariables($name)
2135        Returns the value of the server variable / environment variable with
2136        name $name. If $name is not specified, returns a ref to a hash of all
2137        the server / environment variables data. The following would be a common
2138        use of this method:
2139
2140         $env = $Request->ServerVariables();
2141         # %{$env} here would be equivalent to the cgi %ENV in perl.
2142
2143  $Application Object
2144    Like the $Session object, you may use the $Application object to store data
2145    across the entire life of the application. Every page in the ASP application
2146    always has access to this object. So if you wanted to keep track of how many
2147    visitors there where to the application during its lifetime, you might have
2148    a line like this:
2149
2150     $Application->{num_users}++
2151
2152    The Lock and Unlock methods are used to prevent simultaneous access to the
2153    $Application object.
2154
2155    $Application->Lock()
2156        Locks the Application object for the life of the script, or until
2157        UnLock() unlocks it, whichever comes first. When $Application is locked,
2158        this guarantees that data being read and written to it will not suddenly
2159        change on you between the reads and the writes.
2160
2161        This and the $Session object both lock automatically upon every read and
2162        every write to ensure data integrity. This lock is useful for concurrent
2163        access control purposes.
2164
2165        Be careful to not be too liberal with this, as you can quickly create
2166        application bottlenecks with its improper use.
2167
2168    $Application->UnLock()
2169        Unlocks the $Application object. If already unlocked, does nothing.
2170
2171    $Application->GetSession($sess_id)
2172        This NON-PORTABLE API extension returns a user $Session given a session
2173        id. This allows one to easily write a session manager if session ids are
2174        stored in $Application during Session_OnStart, with full access to these
2175        sessions for administrative purposes.
2176
2177        Be careful not to expose full session ids over the net, as they could be
2178        used by a hacker to impersonate another user. So when creating a session
2179        manager, for example, you could create some other id to reference the
2180        SessionID internally, which would allow you to control the sessions.
2181        This kind of application would best be served under a secure web server.
2182
2183        The ./site/eg/global_asa_demo.asp script makes use of this routine to
2184        display all the data in current user sessions.
2185
2186    $Application->SessionCount()
2187        This NON-PORTABLE method returns the current number of active sessions
2188        in the application, and is enabled by the SessionCount configuration
2189        setting. This method is not implemented as part of the original ASP
2190        object model, but is implemented here because it is useful. In
2191        particular, when accessing databases with license requirements, one can
2192        monitor usage effectively through accessing this value.
2193
2194  $Server Object
2195    The server object is that object that handles everything the other objects
2196    do not. The best part of the server object for Win32 users is the
2197    CreateObject method which allows developers to create instances of ActiveX
2198    components, like the ADO component.
2199
2200    $Server->{ScriptTimeout} = $seconds
2201        Not implemented. May never be. Please see the Apache Timeout
2202        configuration option, normally in httpd.conf.
2203
2204    $Server->Config($setting)
2205        API extension. Allows a developer to read the CONFIG settings, like
2206        Global, GlobalPackage, StateDir, etc. Currently implemented as a wrapper
2207        around
2208
2209          Apache->dir_config($setting)
2210
2211        May also be invoked as $Server->Config(), which will return a hash ref
2212        of all the PerlSetVar settings.
2213
2214    $Server->CreateObject($program_id)
2215        Allows use of ActiveX objects on Win32. This routine returns a reference
2216        to an Win32::OLE object upon success, and nothing upon failure. It is
2217        through this mechanism that a developer can utilize ADO. The equivalent
2218        syntax in VBScript is
2219
2220         Set object = Server.CreateObject(program_id)
2221
2222        For further information, try 'perldoc Win32::OLE' from your favorite
2223        command line.
2224
2225    $Server->Execute($file, @args)
2226        New method from ASP 3.0, this does the same thing as
2227
2228          $Response->Include($file, @args)
2229
2230        and internally is just a wrapper for such. Seems like we had this
2231        important functionality before the IIS/ASP camp!
2232
2233    $Server->File()
2234        Returns the absolute file path to current executing script. Same as
2235        Apache->request->filename when running under mod_perl.
2236
2237        ASP API extension.
2238
2239    $Server->GetLastError()
2240        Not implemented, will likely not ever be because this is dependent on
2241        how IIS handles errors and is not relevant in Apache.
2242
2243    $Server->HTMLEncode( $string || \$string )
2244        Returns an HTML escapes version of $string. &, ", >, <, are each escapes
2245        with their HTML equivalents. Strings encoded in this nature should be
2246        raw text displayed to an end user, as HTML tags become escaped with this
2247        method.
2248
2249        As of version 2.23, $Server->HTMLEncode() may take a string reference
2250        for an optmization when encoding a large buffer as an API extension.
2251        Here is how one might use one over the other:
2252
2253          my $buffer = '&' x 100000;
2254          $buffer = $Server->HTMLEncode($buffer);
2255          print $buffer;
2256            - or -
2257          my $buffer = '&' x 100000;
2258          $Server->HTMLEncode(\$buffer);
2259          print $buffer;
2260
2261        Using the reference passing method in benchmarks on 100K of data was 5%
2262        more efficient, but maybe useful for some. It saves on copying the 100K
2263        buffer twice.
2264
2265    $Server->MapInclude($include)
2266        API extension. Given the include $include, as an absolute or relative
2267        file name to the current executing script, this method returns the file
2268        path that the include would be found from the include search path. The
2269        include search path is the current script directory, Global, and
2270        IncludesDir directories.
2271
2272        If the include is not found in the includes search path, then undef, or
2273        bool false, is returned. So one may do something like this:
2274
2275          if($Server->MapInclude('include.inc')) {
2276            $Response->Include('include.inc');
2277          }
2278
2279        This code demonstrates how one might only try to execute an include if
2280        it exists, which is useful since a script will error if it tries to
2281        execute an include that does not exist.
2282
2283    $Server->MapPath($url);
2284        Given the url $url, absolute, or relative to the current executing
2285        script, this method returns the equivalent filename that the server
2286        would translate the request to, regardless or whether the request would
2287        be valid.
2288
2289        Only a $url that is relative to the host is valid. Urls like "." and "/"
2290        are fine arguments to MapPath, but http://localhost would not be.
2291
2292        To see this method call in action, check out the sample
2293        ./site/eg/server.htm script.
2294
2295    $Server->Mail(\%mail, %smtp_args);
2296        With the Net::SMTP and Net::Config modules installed, which are part of
2297        the perl libnet package, you may use this API extension to send email.
2298        The \%mail hash reference that you pass in must have values for at least
2299        the To, From, and Subject headers, and the Body of the mail message.
2300
2301        The return value of this routine is 1 for success, 0 for failure. If the
2302        MailHost SMTP server is not available, this will have a return value of
2303        0.
2304
2305        You could send an email like so:
2306
2307         $Server->Mail({
2308                        To => 'somebody@yourdomain.com.foobar',
2309                        From => 'youremail@yourdomain.com.foobar',
2310                        Subject => 'Subject of Email',
2311                        Body =>
2312                         'Body of message. '.
2313                         'You might have a lot to say here!',
2314                        Organization => 'Your Organization',
2315                        CC => 'youremailcc@yourdomain.com.foobar',
2316                        BCC => 'youremailbcc@yourdomain.com.foobar',
2317                        Debug => 0 || 1,
2318                       });
2319
2320        Any extra fields specified for the email will be interpreted as headers
2321        for the email, so to send an HTML email, you could set 'Content-Type' =>
2322        'text/html' in the above example.
2323
2324        If you have MailFrom configured, this will be the default for the From
2325        header in your email. For more configuration options like the MailHost
2326        setting, check out the CONFIG section.
2327
2328        The return value of this method call will be boolean for success of the
2329        mail being sent.
2330
2331        If you would like to specially configure the Net::SMTP object used
2332        internally, you may set %smtp_args and they will be passed on when that
2333        object is initialized. "perldoc Net::SMTP" for more into on this topic.
2334
2335        If you would like to include the output of an ASP page as the body of
2336        the mail message, you might do something like:
2337
2338          my $mail_body = $Response->TrapInclude('mail_body.inc');
2339          $Server->Mail({ %mail, Body => $$mail_body });
2340
2341    $Server->RegisterCleanup($sub)
2342         non-portable extension
2343
2344        Sets a subroutine reference to be executed after the script ends,
2345        whether normally or abnormally, the latter occurring possibly by the
2346        user hitting the STOP button, or the web server being killed. This
2347        subroutine must be a code reference created like:
2348
2349         $Server->RegisterCleanup(sub { $main::Session->{served}++; });
2350           or
2351         sub served { $main::Session->{served}++; }
2352         $Server->RegisterCleanup(\&served);
2353
2354        The reference to the subroutine passed in will be executed. Though the
2355        subroutine will be executed in anonymous context, instead of the script,
2356        all objects will still be defined in main::*, that you would reference
2357        normally in your script. Output written to $main::Response will have no
2358        affect at this stage, as the request to the www client has already
2359        completed.
2360
2361        Check out the ./site/eg/register_cleanup.asp script for an example of
2362        this routine in action.
2363
2364    $Server->Transfer($file, @args)
2365        New method from ASP 3.0. Transfers control to another script. The
2366        Response buffer will not be cleared automatically, so if you want this
2367        to serve as a faster $Response->Redirect(), you will need to call
2368        $Response->Clear() before calling this method.
2369
2370        This new script will take over current execution and the current script
2371        will not continue to be executed afterwards. It differs from Execute()
2372        because the original script will not pick up where it left off.
2373
2374        As of Apache::ASP 2.31, this method now accepts optional arguments like
2375        $Response->Include & $Server->Execute. $Server->Transfer is now just a
2376        wrapper for:
2377
2378          $Response->Include($file, @args);
2379          $Response->End;
2380
2381    $Server->URLEncode($string)
2382        Returns the URL-escaped version of the string $string. +'s are
2383        substituted in for spaces and special characters are escaped to the
2384        ascii equivalents. Strings encoded in this manner are safe to put in
2385        urls... they are especially useful for encoding data used in a query
2386        string as in:
2387
2388         $data = $Server->URLEncode("test data");
2389         $url = "http://localhost?data=$data";
2390
2391         $url evaluates to http://localhost?data=test+data, and is a
2392         valid URL for use in anchor <a> tags and redirects, etc.
2393
2394    $Server->URL($url, \%params)
2395        Will return a URL with %params serialized into a query string like:
2396
2397          $url = $Server->URL('test.asp', { test => value });
2398
2399        which would give you a URL of test.asp?test=value
2400
2401        Used in conjunction with the SessionQuery* settings, the returned URL
2402        will also have the session id inserted into the query string, making
2403        this a critical part of that method of implementing cookieless sessions.
2404        For more information on that topic please read on the setting in the
2405        CONFIG section, and the SESSIONS section too.
2406
2407    $Server->XSLT(\$xsl_data, \$xml_data)
2408         * NON-PORTABLE API EXTENSION *
2409
2410        This method takes string references for XSL and XML data and returns the
2411        XSLT output as a string reference like:
2412
2413          my $xslt_data_ref = $Server->XSLT(\$xsl_data, \$xml_data)
2414          print $$xslt_data_ref;
2415
2416        The XSLT parser defaults to XML::XSLT, and is configured with the
2417        XSLTParser setting, which can also use XML::Sablotron ( support added in
2418        2.11 ), and XML::LibXSLT ( support added in 2.29 ). Please see the
2419        CONFIG section for more information on the XSLT* settings that drive
2420        this API. The XSLT setting itself uses this API internally to do its
2421        rendering.
2422
2423        This API was created to allow developers easy XSLT component rendering
2424        without having to render the entire ASP scripts via XSLT. This will make
2425        an easy plugin architecture for those looking to integrate XML into
2426        their existing ASP application frameworks.
2427
2428        At some point, the API will likely take files as arguments, but not as
2429        of the 2.11 release.
2430
2431SSI
2432    SSI is great! One of the main features of server side includes is to include
2433    other files in the script being requested. In Apache::ASP, this is
2434    implemented in a couple ways, the most crucial of which is implemented in
2435    the file include. Formatted as
2436
2437     <!--#include file=filename.inc-->
2438
2439    ,the .inc being merely a convention, text from the included file will be
2440    inserted directly into the script being executed and the script will be
2441    compiled as a whole. Whenever the script or any of its includes change, the
2442    script will be recompiled.
2443
2444    Includes go a great length to promote good decomposition and code sharing in
2445    ASP scripts, but they are still fairly static. As of version .09, includes
2446    may have dynamic runtime execution, as subroutines compiled into the
2447    global.asa namespace. The first way to invoke includes dynamically is
2448
2449     <!--#include file=filename.inc args=@args-->
2450
2451    If @args is specified, Apache::ASP knows to execute the include at runtime
2452    instead of inlining it directly into the compiled code of the script. It
2453    does this by compiling the script at runtime as a subroutine, and caching it
2454    for future invocations. Then the compiled subroutine is executed and has
2455    @args passed into its as arguments.
2456
2457    This is still might be too static for some, as @args is still hardcoded into
2458    the ASP script, so finally, one may execute an include at runtime by
2459    utilizing this API extension
2460
2461       $Response->Include("filename.inc", @args);
2462
2463    which is a direct translation of the dynamic include above.
2464
2465    Although inline includes should be a little faster, runtime dynamic includes
2466    represent great potential savings in httpd memory, as includes are shared
2467    between scripts keeping the size of each script to a minimum. This can often
2468    be significant saving if much of the formatting occurs in an included header
2469    of a www page.
2470
2471    By default, all includes will be inlined unless called with an args
2472    parameter. However, if you want all your includes to be compiled as subs and
2473    dynamically executed at runtime, turn the DynamicIncludes config option on
2474    as documented above.
2475
2476  Apache::SSI for mod_perl 1.3.x only
2477    One of the things missing above is the
2478
2479     <!--#include virtual=filename.cgi-->
2480
2481    tag. This and many other SSI code extensions are available by filtering
2482    Apache::ASP output through Apache::SSI via the Apache::Filter and the Filter
2483    config options, available in mod_perl 1.3.x / Apache 1.3.x. Unfortunately
2484    this functionality is not available with mod_perl 2 / Apache 2.
2485
2486    For more information on how to wire Apache::ASP and Apache::SSI together,
2487    please see the Filter config option documented above. Also please see
2488    Apache::SSI for further information on the capabilities it offers.
2489
2490  SSI with mod_filter in Apache 2
2491    Apache 2 offers chained filters. It may be possible to chain filters to
2492    Apache::ASP output through mod_filter for SSI processing:
2493
2494      http://httpd.apache.org/docs/2.1/mod/mod_filter.html
2495
2496EXAMPLES
2497    Use with Apache. Copy the ./site/eg directory from the ASP installation to
2498    your Apache document tree and try it out! You have to put "AllowOverride
2499    All" in your <Directory> config section to let the .htaccess file in the
2500    ./site/eg installation directory do its work.
2501
2502    IMPORTANT (FAQ): Make sure that the web server has write access to that
2503    directory. Usually a
2504
2505     chmod -R 0777 eg
2506
2507    will do the trick :)
2508
2509SESSIONS
2510    Cookies are used by default for user $Session support ( see OBJECTS ). In
2511    order to track a web user and associate server side data with that client,
2512    the web server sets, and the web client returns a 32 byte session id
2513    identifier cookie. This implementation is very secure and may be used in
2514    secure HTTPS transactions, and made stronger with SecureSession,
2515    HTTPOnlySession and ParanoidSession settings (see CONFIG ).
2516
2517    However good cookies are for this kind of persistent state management
2518    between HTTP requests, they have long been under fire for security risks
2519    associated with JavaScript security exploits and privacy abuse by large data
2520    tracking companies.
2521
2522    Because of these reasons, web users will sometimes turn off their cookies,
2523    rendering normal ASP session implementations powerless, resulting in a new
2524    $Session generated every request. This is not good for ASP style sessions.
2525
2526  Cookieless Sessions
2527     *** See WARNING Below ***
2528
2529    So we now have more ways to track sessions with the SessionQuery* CONFIG
2530    settings, that allow a web developer to embed the session id in URL query
2531    strings when use of cookies is denied. The implementations work such that if
2532    a user has cookies turned on, then cookies will be used, but for those users
2533    with cookies turned off, the session ids will be parsed into document URLs.
2534
2535    The first and easiest method that a web developer may use to implement
2536    cookieless sessions are with SessionQueryParse* directives which enable
2537    Apache::ASP to the parse the session id into document URLs on the fly.
2538    Because this is resource inefficient, there is also the SessionQuery*
2539    directives that may be used with the $Server->URL($url,\%params) method to
2540    generate custom URLs with the session id in its query string.
2541
2542    To see an example of these cookieless sessions in action, check out the
2543    ./site/eg/session_query_parse.asp example.
2544
2545     *** WARNING ***
2546
2547    If you do use these methods, then be VERY CAREFUL of linking offsite from a
2548    page that was accessed with a session id in a query string. This is because
2549    this session id will show up in the HTTP_REFERER logs of the linked to site,
2550    and a malicious hacker could use this information to compromise the security
2551    of your site's $Sessions, even if these are run under a secure web server.
2552
2553    In order to shake a session id off an HTTP_REFERER for a link taking a user
2554    offsite, you must point that link to a redirect page that will redirect a
2555    user, like so:
2556
2557     <%
2558        # "cross site scripting bug" prevention
2559        my $sanitized_url =
2560            $Server->HTMLEncode($Response->QueryString('OffSiteUrl'));
2561     %>
2562     <html>
2563     <head>
2564     <meta http-equiv=refresh content='0;URL=<%=$sanitized_url%>'>
2565     </head>
2566     <body>
2567            Redirecting you offsite to
2568            <a href=<%=$sanitized_url%> >here</a>...
2569     </body>
2570     </html>
2571
2572    Because the web browser visits a real page before being redirected with the
2573    <meta> tag, the HTTP_REFERER will be set to this page. Just be sure to not
2574    link to this page with a session id in its query string.
2575
2576    Unfortunately a simple $Response->Redirect() will not work here, because the
2577    web browser will keep the HTTP_REFERER of the original web page if only a
2578    normal redirect is used.
2579
2580XML/XSLT
2581  Custom Tags with XMLSubsMatch
2582    Before XML, there was the need to make HTML markup smarter. Apache::ASP
2583    gives you the ability to have a perl subroutine handle the execution of any
2584    predefined tag, taking the tag descriptors, and the text contained between,
2585    as arguments of the subroutine. This custom tag technology can be used to
2586    extend a web developer's abilities to add dynamic pieces without having to
2587    visibly use <% %> style code entries.
2588
2589    So, lets say that you have a table that you want to insert for an employee
2590    with contact info and the like, you could set up a tag like:
2591
2592     <my:new-employee name="Jane" last="Doe" phone="555-2222">
2593       Jane Doe has been here since 1998.
2594     </my:new-employee>
2595
2596    To render it with a custom tag, you would tell the Apache::ASP parser to
2597    render the tag with a subroutine:
2598
2599      PerlSetVar XMLSubsMatch my:new-employee
2600
2601    Any colons, ':', in the XML custom tag will turn into '::', a perl package
2602    separator, so the my:employee tag would translate to the my::employee
2603    subroutine, or the employee subroutine in the my package. Any dash "-" will
2604    also be translated to an underscore "_", as dash is not valid in the names
2605    of perl subroutines.
2606
2607    Then you would create the my::employee subroutine in the my perl package or
2608    whereever like so:
2609
2610      package my;
2611      sub new_employee {
2612        my($attributes, $body) = @_;
2613        $main::Response->Include('new_employee.inc', $attributes, $body);
2614      }
2615      1;
2616
2617      <!-- # new_employee.inc file somewhere else, maybe in Global directory -->
2618      <% my($attributes, $body) = @_; %>
2619      <table>
2620      <% for('name', 'last', 'phone') { %>
2621        <tr>
2622          <td><b><%=ucfirst $_ %></b>:</td>
2623          <td><%= $attributes->{$_} %></td>
2624        </tr>
2625      <% } %>
2626      <tr><td colspan=2><%= $body %></td></tr>
2627      </table>
2628      <!-- # end new_employee.inc file -->
2629
2630    The $main::Response->Include() would then delegate the rendering of the
2631    new-employee to the new_employee.inc ASP script include.
2632
2633    Though XML purists would not like this custom tag technology to be related
2634    to XML, the reality is that a careful site engineer could render full XML
2635    documents with this technology, applying all the correct styles that one
2636    might otherwise do with XSLT.
2637
2638    Custom tags defined in this way can be used as XML tags are defined with
2639    both a body and without as it
2640
2641      <my:new-employee>...</my:new-employee>
2642
2643    and just
2644
2645      <my:new-employee />
2646
2647    These tags are very powerful in that they can also enclose normal ASP logic,
2648    like:
2649
2650      <my:new-employee>
2651        <!-- normal ASP logic -->
2652        <% my $birthday = &HTTP::Date::time2str(time - 25 * 86400 * 365); %>
2653
2654        <!-- ASP inserts -->
2655        This employee has been online for <%= int(rand()*600)+1 %>
2656        seconds, and was born near <%= $birthday %>.
2657      </my:new-employee>
2658
2659    For an example of this custom XML tagging in action, please check out the
2660    ./site/eg/xml_subs.asp script.
2661
2662  XSLT Tranformations
2663    XML is good stuff, but what can you use it for? The principle is that by
2664    having data and style separated in XML and XSL files, you can reformat your
2665    data more easily in the future, and you can render your data in multiple
2666    formats, just as easily as for your web site, so you might render your site
2667    to a PDA, or a cell phone just as easily as to a browser, and all you have
2668    to do is set up the right XSL stylesheets to do the transformation (XSLT).
2669
2670    With native XML/XSLT support, Apache::ASP scripts may be the source of XML
2671    data that the XSL file transforms, and the XSL file itself will be first
2672    executed as an ASP script also. The XSLT transformation is handled by
2673    XML::XSLT or XML::Sablotron and you can see an example of it in action at
2674    the ./site/eg/xslt.xml XML script.
2675
2676    To specify a XSL stylesheet, use the setting:
2677
2678      PerlSetVar XSLT template.xsl
2679
2680    where template.xsl could be any file. By default this will XSLT transform
2681    all ASP scripts so configured, but you can separate xml scripts from the
2682    rest with the setting:
2683
2684      PerlSetVar XSLTMatch xml$
2685
2686    where all files with the ending xml would undergo a XSLT transformation.
2687
2688    Note that XSLT depends on the installation of XML::XSLT, which in turn
2689    depends on XML::DOM, and XML::Parser. As of version 2.11, XML::Sablotron may
2690    also be used by setting:
2691
2692      PerlSetVar XSLTParser XML::Sablotron
2693
2694    and XML::LibXSLT may be used, as of 2.29, by setting
2695
2696      PerlSetVar XSLTParser XML::LibXSLT
2697
2698    If you would like to install XML::Sablotron or XML::LibXSLT, you will first
2699    have to install the libraries that these perl modules use, which you can get
2700    at:
2701
2702      libxslt - The XSLT C Library for Gnome
2703      http://xmlsoft.org/XSLT/
2704
2705      Sablotron - Ginger Alliance
2706      http://www.gingerall.com
2707
2708    For more on XML::XSLT, the default XSLT engine that Apache::ASP will use,
2709    please see:
2710
2711      XML::XSLT
2712      http://xmlxslt.sourceforge.net/
2713
2714    XML:XSLT was the first supported XSLT engine as has the benefit of being
2715    written in pure perl so that though while it is slower than the other
2716    solutions, it is easier to port.
2717
2718    If you would like to cache XSLT tranformations, which is highly recommended,
2719    just set:
2720
2721      PerlSetVar XSLTCache 1
2722
2723    Please see the Cache settings in the CONFIG section for more about how to
2724    configure the XSLTCache.
2725
2726  References
2727    For more information about XSLT, please see the standard at:
2728
2729      http://www.w3.org/TR/xslt
2730
2731    For their huge ground breaking XML efforts, these other XML OSS projects
2732    need mention:
2733
2734      Cocoon - XML-based web publishing, in Java
2735      http://cocoon.apache.org/
2736
2737      AxKit - XML web publishing with Apache & mod_perl
2738      http://www.axkit.org/
2739
2740CGI
2741    CGI has been the standard way of deploying web applications long before ASP
2742    came along. In the CGI gateway world, CGI.pm has been a widely used module
2743    in building CGI applications, and Apache::ASP is compatible with scripts
2744    written with CGI.pm. Also, as of version 2.19, Apache::ASP can run in
2745    standalone CGI mode for the Apache web server without mod_perl being
2746    available. See "Standalone CGI Mode" section below.
2747
2748    Following are some special notes with respect to compatibility with CGI and
2749    CGI.pm. Use of CGI.pm in any of these ways was made possible through a great
2750    amount of work, and is not guaranteed to be portable with other perl ASP
2751    implementations, as other ASP implementations will likely be more limited.
2752
2753    Standalone CGI Mode, without mod_perl
2754        As of version 2.19, Apache::ASP scripts may be run as standalone CGI
2755        scripts without mod_perl being loaded into Apache. Work to date has only
2756        been done with mod_cgi scripts under Apache on a Unix platform, and it
2757        is unlikely to work under other web servers or Win32 operating systems
2758        without further development.
2759
2760        To run the ./site/eg scripts as CGI scripts, you copy the ./site
2761        directory to some location accessible by your web server, in this
2762        example its /usr/local/apache/htdocs/aspcgi, then in your httpd.conf
2763        activate Apache::ASP cgi scripts like so:
2764
2765         Alias /aspcgi/ /usr/local/apache/htdocs/aspcgi/
2766         <Directory /usr/local/apache/htdocs/aspcgi/eg/ >
2767           AddType application/x-httpd-cgi .htm
2768           AddType application/x-httpd-cgi .html
2769           AddType application/x-httpd-cgi .asp
2770           AddType application/x-httpd-cgi .xml
2771           AddType application/x-httpd-cgi .ssi
2772           AllowOverride None
2773           Options +ExecCGI +Indexes
2774         </Directory>
2775
2776        Then install the asp-perl script from the distribution into /usr/bin, or
2777        some other directory. This is so the CGI execution line at the top of
2778        those scripts will invoke the asp-perl wrapper like so:
2779
2780         #!/usr/bin/perl /usr/bin/asp-perl
2781
2782        The asp-perl script is a cgi wrapper that sets up the Apache::ASP
2783        environment in lieu of the normal mod_perl handler request. Because
2784        there is no Apache->dir_config() data available under mod_cgi, the
2785        asp-perl script will load a asp.conf file that may define a hash %Config
2786        of data for populating the dir_config() data. An example of a complex
2787        asp.conf file is at ./site/eg/asp.conf
2788
2789        So, a trivial asp.conf file might look like:
2790
2791         # asp.conf
2792         %Config = (
2793           'Global' => '.',
2794           'StateDir' => '/tmp/aspstate',
2795           'NoState' => 0,
2796           'Debug' => 3,
2797         );
2798
2799        The default for NoState is 1 in CGI mode, so one must set NoState to 0
2800        for objects like $Session & $Application to be defined.
2801
2802    CGI.pm
2803        CGI.pm is a very useful module that aids developers in the building of
2804        these applications, and Apache::ASP has been made to be compatible with
2805        function calls in CGI.pm. Please see cgi.htm in the ./site/eg directory
2806        for a sample ASP script written almost entirely in CGI.
2807
2808        As of version 0.09, use of CGI.pm for both input and output is seamless
2809        when working under Apache::ASP. Thus if you would like to port existing
2810        cgi scripts over to Apache::ASP, all you need to do is wrap <% %> around
2811        the script to get going. This functionality has been implemented so that
2812        developers may have the best of both worlds when building their web
2813        applications.
2814
2815        For more information about CGI.pm, please see the web site
2816
2817          http://search.cpan.org/dist/CGI/
2818
2819    Query Object Initialization
2820        You may create a CGI.pm $query object like so:
2821
2822                use CGI;
2823                my $query = new CGI;
2824
2825        As of Apache::ASP version 0.09, form input may be read in by CGI.pm upon
2826        initialization. Before, Apache::ASP would consume the form input when
2827        reading into $Request->Form(), but now form input is cached, and may be
2828        used by CGI.pm input routines.
2829
2830    CGI headers
2831        Not only can you use the CGI.pm $query->header() method to put out
2832        headers, but with the CgiHeaders config option set to true, you can also
2833        print "Header: value\n", and add similar lines to the top of your
2834        script, like:
2835
2836         Some-Header: Value
2837         Some-Other: OtherValue
2838
2839         <html><body> Script body starts here.
2840
2841        Once there are no longer any cgi style headers, or the there is a
2842        newline, the body of the script begins. So if you just had an asp script
2843        like:
2844
2845            print join(":", %{$Request->QueryString});
2846
2847        You would likely end up with no output, as that line is interpreted as a
2848        header because of the semicolon. When doing basic debugging, as long as
2849        you start the page with <html> you will avoid this problem.
2850
2851    print()ing CGI
2852        CGI is notorious for its print() statements, and the functions in CGI.pm
2853        usually return strings to print(). You can do this under Apache::ASP,
2854        since print just aliases to $Response->Write(). Note that $| has no
2855        affect.
2856
2857                print $query->header();
2858                print $query->start_form();
2859
2860    File Upload
2861        CGI.pm is used for implementing reading the input from file upload. You
2862        may create the file upload form however you wish, and then the data may
2863        be recovered from the file upload by using $Request->Form(). Data from a
2864        file upload gets written to a file handle, that may in turn be read
2865        from. The original file name that was uploaded is the name of the file
2866        handle.
2867
2868                my $filehandle = $Request->Form('file_upload_field_name');
2869                print $filehandle; # will get you the file name
2870                my $data;
2871                while(read($filehandle, $data, 1024)) {
2872                        # data from the uploaded file read into $data
2873                };
2874
2875        Please see the docs on CGI.pm (try perldoc CGI) for more information on
2876        this topic, and ./site/eg/file_upload.asp for an example of its use.
2877        Also, for more details about CGI.pm itself, please see the web site:
2878
2879            http://search.cpan.org/dist/CGI/
2880
2881        Occasionally, a newer version of CGI.pm will be released which breaks
2882        file upload compatibility with Apache::ASP. If you find this to occur,
2883        then you might consider downgrading to a version that works. For
2884        example, one can install a working CGI.pm v2.78 for a working version,
2885        and to get old versions of this module, one can go to BACKPAN at:
2886
2887            http://backpan.cpan.org/modules/by-authors/id/L/LD/LDS/
2888
2889        There is also $Request->FileUpload() API extension that you can use to
2890        get more data about a file upload, so that the following properties are
2891        available for querying:
2892
2893          my $file_upload = $Request->{FileUpload}{upload_field};
2894          $file_upload->{BrowserFile}
2895          $file_upload->{FileHandle}
2896          $file_upload->{ContentType}
2897
2898          # only if FileUploadTemp is set
2899          $file_upload->{TempFile}
2900
2901          # whatever mime headers are sent with the file upload
2902          # just "keys %$file_upload" to find out
2903          $file_upload->{?Mime-Header?}
2904
2905        Please see the $Request section in OBJECTS for more information.
2906
2907PERLSCRIPT
2908    Much work has been done to bring compatibility with ASP applications written
2909    in PerlScript under IIS. Most of that work revolved around bringing a
2910    Win32::OLE Collection interface to many of the objects in Apache::ASP, which
2911    are natively written as perl hashes.
2912
2913    New as of version 2.05 is new functionality enabled with the CollectionItem
2914    setting, to giver better support to more recent PerlScript syntax. This
2915    seems helpful when porting from an IIS/PerlScript code base. Please see the
2916    CONFIG section for more info.
2917
2918    The following objects in Apache::ASP respond as Collections:
2919
2920            $Application
2921            $Session
2922            $Request->FileUpload *
2923            $Request->FileUpload('upload_file') *
2924            $Request->Form
2925            $Request->QueryString
2926            $Request->Cookies
2927            $Response->Cookies
2928            $Response->Cookies('some_cookie')
2929
2930      * FileUpload API Extensions
2931
2932    And as such may be used with the following syntax, as compared with the
2933    Apache::ASP native calls. Please note the native Apache::ASP interface is
2934    compatible with the deprecated PerlScript interface.
2935
2936     C = PerlScript Compatibility   N = Native Apache::ASP
2937
2938     ## Collection->Contents($name)
2939     [C] $Application->Contents('XYZ')
2940     [N] $Application->{XYZ}
2941
2942     ## Collection->SetProperty($property, $name, $value)
2943     [C] $Application->Contents->SetProperty('Item', 'XYZ', "Fred");
2944     [N] $Application->{XYZ} = "Fred"
2945
2946     ## Collection->GetProperty($property, $name)
2947     [C] $Application->Contents->GetProperty('Item', 'XYZ')
2948     [N] $Application->{XYZ}
2949
2950     ## Collection->Item($name)
2951     [C] print $Request->QueryString->Item('message'), "<br>\n\n";
2952     [N] print $Request->{QueryString}{'message'}, "<br>\n\n";
2953
2954     ## Working with Cookies
2955     [C] $Response->SetProperty('Cookies', 'Testing', 'Extra');
2956     [C] $Response->SetProperty('Cookies', 'Testing', {'Path' => '/'});
2957     [C] print $Request->Cookies(Testing) . "<br>\n";
2958     [N] $Response->{Cookies}{Testing} = {Value => Extra, Path => '/'};
2959     [N] print $Request->{Cookies}{Testing} . "<br>\n";
2960
2961    Several incompatibilities exist between PerlScript and Apache::ASP:
2962
2963     > Collection->{Count} property has not been implemented.
2964     > VBScript dates may not be used for Expires property of cookies.
2965     > Win32::OLE::in may not be used.  Use keys() to iterate over.
2966     > The ->{Item} property does not work, use the ->Item() method.
2967
2968STYLE GUIDE
2969    Here are some general style guidelines. Treat these as tips for best
2970    practices on Apache::ASP development if you will.
2971
2972  UseStrict
2973    One of perl's blessings is also its bane, variables do not need to be
2974    declared, and are by default globally scoped. The problem with this in
2975    mod_perl is that global variables persist from one request to another even
2976    if a different web browser is viewing a page.
2977
2978    To avoid this problem, perl programmers have often been advised to add to
2979    the top of their perl scripts:
2980
2981      use strict;
2982
2983    In Apache::ASP, you can do this better by setting:
2984
2985      PerlSetVar UseStrict 1
2986
2987    which will cover both script & global.asa compilation and will catch "use
2988    strict" errors correctly. For perl modules, please continue to add "use
2989    strict" to the top of them.
2990
2991    Because its so essential in catching hard to find errors, this configuration
2992    will likely become the default in some future release. For now, keep setting
2993    it.
2994
2995  Do not define subroutines in scripts.
2996    DO NOT add subroutine declarations in scripts. Apache::ASP is optimized by
2997    compiling a script into a subroutine for faster future invocation. Adding a
2998    subroutine definition to a script then looks like this to the compiler:
2999
3000      sub page_script_sub {
3001        ...
3002        ... some HTML ...
3003        ...
3004        sub your_sub {
3005          ...
3006        }
3007        ...
3008      }
3009
3010    The biggest problem with subroutines defined in subroutines is the side
3011    effect of creating closures, which will not behave as usually desired in a
3012    mod_perl environment. To understand more about closures, please read up on
3013    them & "Nested Subroutines" at:
3014
3015      http://perl.apache.org/docs/general/perl_reference/perl_reference.html
3016
3017    Instead of defining subroutines in scripts, you may add them to your sites
3018    global.asa, or you may create a perl package or module to share with your
3019    scripts. For more on perl objects & modules, please see:
3020
3021      http://perldoc.perl.org/perlobj.html
3022
3023  Use global.asa's Script_On* Events
3024    Chances are that you will find yourself doing the same thing repeatedly in
3025    each of your web application's scripts. You can use Script_OnStart and
3026    Script_OnEnd to automate these routine tasks. These events are called before
3027    and after each script request.
3028
3029    For example, let's say you have a header & footer you would like to include
3030    in the output of every page, then you might:
3031
3032     # global.asa
3033     sub Script_OnStart {
3034       $Response->Include('header.inc');
3035     }
3036     sub Script_OnEnd {
3037       $Response->Include('footer.inc');
3038     }
3039
3040    Or let's say you want to initialize a global database connection for use in
3041    your scripts:
3042
3043     # global.asa
3044     use Apache::DBI;   # automatic persistent database connections
3045     use DBI;
3046
3047     use vars qw($dbh); # declare global $dbh
3048
3049     sub Script_OnStart {
3050       # initialize $dbh
3051       $dbh = DBI->connect(...);
3052
3053       # force you to explicitly commit when you want to save data
3054       $Server->RegisterCleanup(sub { $dbh->rollback; });
3055     }
3056
3057     sub Script_OnEnd {
3058       # not really necessary when using persistent connections, but
3059       # will free this one object reference at least
3060       $dbh = undef;
3061     }
3062
3063FAQ
3064    The following are some frequently asked questions about Apache::ASP.
3065
3066  Installation
3067    Examples don't work, I see the ASP script in the browser?
3068        This is most likely that Apache is not configured to execute the
3069        Apache::ASP scripts properly. Check the INSTALL QuickStart section for
3070        more info on how to quickly set up Apache to execute your ASP scripts.
3071
3072    Apache Expat vs. XML perl parsing causing segfaults, what do I do?
3073        Make sure to compile apache with expat disabled. The
3074        ./make_httpd/build_httpds.sh in the distribution will do this for you,
3075        with the --disable-rule=EXPAT in particular:
3076
3077         cd ../$APACHE
3078         echo "Building apache =============================="
3079         ./configure \
3080            --prefix=/usr/local/apache \
3081            --activate-module=src/modules/perl/libperl.a \
3082            --enable-module=ssl \
3083            --enable-module=proxy \
3084            --enable-module=so \
3085            --disable-rule=EXPAT
3086
3087                           ^^^^^
3088
3089        keywords: segmentation fault, segfault seg fault
3090
3091    Why do variables retain their values between requests?
3092        Unless scoped by my() or local(), perl variables in mod_perl are treated
3093        as globals, and values set may persist from one request to another. This
3094        can be seen in as simple a script as this:
3095
3096          <HTML><BODY>
3097            $counter++;
3098            $Response->Write("<BR>Counter: $counter");
3099          </BODY></HTML>
3100
3101        The value for $counter++ will remain between requests. Generally use of
3102        globals in this way is a BAD IDEA, and you can spare yourself many
3103        headaches if do "use strict" perl programming which forces you to
3104        explicity declare globals like:
3105
3106          use vars qw($counter);
3107
3108        You can make all your Apache::ASP scripts strict by default by setting:
3109
3110          PerlSetVar UseStrict 1
3111
3112    Apache errors on the PerlHandler or PerlModule directives ?
3113        You get an error message like this:
3114
3115         Invalid command 'PerlModule', perhaps mis-spelled or defined by a
3116         module not included in the server configuration.
3117
3118        You do not have mod_perl correctly installed for Apache. The PerlHandler
3119        and PerlModule directives in Apache *.conf files are extensions enabled
3120        by mod_perl and will not work if mod_perl is not correctly installed.
3121
3122        Common user errors are not doing a 'make install' for mod_perl, which
3123        installs the perl side of mod_perl, and not starting the right httpd
3124        after building it. The latter often occurs when you have an old apache
3125        server without mod_perl, and you have built a new one without copying
3126        over to its proper location.
3127
3128        To get mod_perl, go to http://perl.apache.org
3129
3130    Error: no request object (Apache=SCALAR(0x???????):)
3131        Your Apache + mod_perl build is not working properly, and is likely a
3132        RedHat Linux RPM DSO build. Make sure you statically build your Apache +
3133        mod_perl httpd, recompiled fresh from the sources.
3134
3135    I am getting a tie or MLDBM / state error message, what do I do?
3136        Make sure the web server or you have write access to the eg directory,
3137        or to the directory specified as Global in the config you are using.
3138        Default for Global is the directory the script is in (e.g. '.'), but
3139        should be set to some directory not under the www server document root,
3140        for security reasons, on a production site.
3141
3142        Usually a
3143
3144         chmod -R -0777 eg
3145
3146        will take care of the write access issue for initial testing purposes.
3147
3148        Failing write access being the problem, try upgrading your version of
3149        Data::Dumper and MLDBM, which are the modules used to write the state
3150        files.
3151
3152  Sessions
3153    How can I use $Session to store complex data structures.
3154        Very carefully. Please read the $Session documentation in the OBJECTS
3155        section. You can store very complex objects in $Session, but you have to
3156        understand the limits, and the syntax that must be used to make this
3157        happen.
3158
3159        In particular, stay away from statements that that have more than one
3160        level of indirection on the left side of an assignment like:
3161
3162          BAD: $Session->{complex}{object} = $data;
3163
3164    How can I keep search engine spiders from killing the session manager?
3165        If you want to disallow session creation for certain non web browser
3166        user agents, like search engine spiders, you can use a mod_perl
3167        PerlInitHandler like this to set configuration variables at runtime:
3168
3169         # put the following code into httpd.conf and stop/start apache server
3170         PerlInitHandler My::InitHandler
3171
3172         <Perl>
3173
3174          package My::InitHandler;
3175          use Apache;
3176
3177          sub handler {
3178            my $r = shift; # get the Apache request object
3179
3180            # if not a Mozilla User Agent, then disable sessions explicitly
3181            unless($r->headers_in('User-Agent') =~ /^Mozilla/) {
3182               $r->dir_config('AllowSessionState', 'Off');
3183            }
3184
3185            return 200; # return OK mod_perl status code
3186          }
3187
3188          1;
3189
3190         </Perl>
3191
3192        This will configure your environment before Apache::ASP executes and
3193        sees the configuration settings. You can use the mod_perl API in this
3194        way to configure Apache::ASP at runtime.
3195
3196        Note that the Session Manager is very robust on its own, and denial of
3197        service attacks of the types that spiders and other web bots normally
3198        execute are not likely to affect the Session Manager significantly.
3199
3200    How can I use $Session to store a $dbh database handle ?
3201        You cannot use $Session to store a $dbh handle. This can be awkward for
3202        those coming from the IIS/NT world, where you could store just about
3203        anything in $Session, but this boils down to a difference between
3204        threads vs. processes.
3205
3206        Database handles often have per process file handles open, which cannot
3207        be shared between requests, so though you have stored the $dbh data in
3208        $Session, all the other initializations are not relevant in another
3209        httpd process.
3210
3211        All is not lost! Apache::DBI can be used to cache database connections
3212        on a per process basis, and will work for most cases.
3213
3214  Development
3215    VBScript or JScript supported?
3216        Only Perl scripting is supported with this module.
3217
3218    How is database connectivity handled?
3219        Database connectivity is handled through perl's DBI & DBD interfaces. In
3220        the UNIX world, it seems most databases have cross platform support in
3221        perl. You can find the book on DBI programming at
3222        http://www.oreilly.com/catalog/perldbi/
3223
3224        DBD::ODBC is often your ticket on Win32. On UNIX, commercial vendors
3225        like OpenLink Software (http://www.openlinksw.com/) provide the nuts and
3226        bolts for ODBC.
3227
3228        Database connections can be cached per process with Apache::DBI.
3229
3230    What is the best way to debug an ASP application ?
3231        There are lots of perl-ish tricks to make your life developing and
3232        debugging an ASP application easier. For starters, you will find some
3233        helpful hints by reading the $Response->Debug() API extension, and the
3234        Debug configuration directive.
3235
3236    How are file uploads handled?
3237        Please see the CGI section. File uploads are implemented through CGI.pm
3238        which is loaded at runtime only for this purpose. This is the only time
3239        that CGI.pm will be loaded by Apache::ASP, which implements all other
3240        cgi-ish functionality natively. The rationale for not implementing file
3241        uploads natively is that the extra 100K in memory for CGI.pm shouldn't
3242        be a big deal if you are working with bulky file uploads.
3243
3244    How do I access the ASP Objects in general?
3245        All the ASP objects can be referenced through the main package with the
3246        following notation:
3247
3248         $main::Response->Write("html output");
3249
3250        This notation can be used from anywhere in perl, including routines
3251        registered with $Server->RegisterCleanup().
3252
3253        You use the normal notation in your scripts, includes, and global.asa:
3254
3255         $Response->Write("html output");
3256
3257    Can I print() in ASP?
3258        Yes. You can print() from anywhere in an ASP script as it aliases to the
3259        $Response->Write() method. Using print() is portable with PerlScript
3260        when using Win32::ASP in that environment.
3261
3262    Do I have access to ActiveX objects?
3263        Only under Win32 will developers have access to ActiveX objects through
3264        the perl Win32::OLE interface. This will remain true until there are
3265        free COM ports to the UNIX world. At this time, there is no ActiveX for
3266        the UNIX world.
3267
3268  Support and Production
3269    How do I get things I want done?!
3270        If you find a problem with the module, or would like a feature added,
3271        please mail support, as listed in the SUPPORT section, and your needs
3272        will be promptly and seriously considered, then implemented.
3273
3274    What is the state of Apache::ASP? Can I publish a web site on it?
3275        Apache::ASP has been production ready since v.02. Work being done on the
3276        module is on a per need basis, with the goal being to eventually have
3277        the ASP API completed, with full portability to ActiveState PerlScript
3278        and MKS PScript. If you can suggest any changes to facilitate these
3279        goals, your comments are welcome.
3280
3281TUNING
3282    A little tuning can go a long way, and can make the difference between a web
3283    site that gets by, and a site that screams with speed. With Apache::ASP, you
3284    can easily take a poorly tuned site running at 10 hits/second to 50+
3285    hits/second just with the right configuration.
3286
3287    Documented below are some simple things you can do to make the most of your
3288    site.
3289
3290  Online Resources
3291    For more tips & tricks on tuning Apache and mod_perl, please see the tuning
3292    documents at:
3293
3294      Stas Bekman's mod_perl guide
3295      http://perl.apache.org/guide/
3296
3297    Written in late 1999 this article provides an early look at how to tune your
3298    Apache::ASP web site. It has since been updated to remain current with
3299    Apache::ASP v2.29+
3300
3301      Apache::ASP Site Tuning
3302      http://www.apache-asp.org/articles/perlmonth3_tune.html
3303
3304  Tuning & Benchmarking
3305    When performance tuning, it is important to have a tool to measure the
3306    impact of your tuning change by change. The program ab, or Apache Bench,
3307    provides this functionality well, and is freely included in the apache
3308    distribution.
3309
3310    Because performance tuning can be a neverending affair, it is a good idea to
3311    establish a threshold where performance is "good enough", that once reached,
3312    tuning stops.
3313
3314  $Application & $Session State
3315    Use NoState 1 setting if you don't need the $Application or $Session
3316    objects. State objects such as these tie to files on disk and will incur a
3317    performance penalty.
3318
3319    If you need the state objects $Application and $Session, and if running an
3320    OS that caches files in memory, set your "StateDir" directory to a cached
3321    file system. On WinNT, all files may be cached, and you have no control of
3322    this. On Solaris, /tmp is a RAM disk and would be a good place to set the
3323    "StateDir" config setting to. When cached file systems are used there is
3324    little performance penalty for using state files. Linux tends to do a good
3325    job caching its file systems, so pick a StateDir for ease of system
3326    administration.
3327
3328    On Win32 systems, where mod_perl requests are serialized, you can freely use
3329    SessionSerialize to make your $Session requests faster, and you can achieve
3330    similar performance benefits for $Application if you call
3331    $Application->Lock() in your global.asa's Script_OnStart.
3332
3333  Low MaxClients
3334    Set your MaxClients low, such that if you have that many httpd servers
3335    running, which will happen on busy site, your system will not start swapping
3336    to disk because of excessive RAM usage. Typical settings are less than 100
3337    even with 1 gig RAM! To handle more client connections, look into a dual
3338    server, mod_proxy front end.
3339
3340  High MaxRequestsPerChild
3341    Set your max requests per child thread or process (in httpd.conf) high, so
3342    that ASP scripts have a better chance being cached, which happens after they
3343    are first compiled. You will also avoid the process fork penalty on UNIX
3344    systems. Somewhere between 50 - 500 is probably pretty good. You do not want
3345    to set this too high though or you will risk having your web processes use
3346    too much RAM. One may use Apache::SizeLimit or Apache::GTopLimit to
3347    optimally tune MaxRequestsPerChild at runtime.
3348
3349  Precompile Modules
3350    For those modules that your Apache::ASP application uses, make sure that
3351    they are loaded in your sites startup.pl file, or loaded with PerlModule in
3352    your httpd.conf, so that your modules are compiled pre-fork in the parent
3353    httpd.
3354
3355  Precompile Scripts
3356    Precompile your scripts by using the Apache::ASP->Loader() routine
3357    documented below. This will at least save the first user hitting a script
3358    from suffering compile time lag. On UNIX, precompiling scripts upon server
3359    startup allows this code to be shared with forked child www servers, so you
3360    reduce overall memory usage, and use less CPU compiling scripts for each
3361    separate www server process. These savings could be significant. On a PII300
3362    Solaris x86, it takes a couple seconds to compile 28 scripts upon server
3363    startup, with an average of 50K RAM per compiled script, and this savings is
3364    passed on to the ALL child httpd servers, so total savings would be
3365    50Kx28x20(MaxClients)=28M!
3366
3367    Apache::ASP->Loader() can be called to precompile scripts and even entire
3368    ASP applications at server startup. Note also that in modperl, you can
3369    precompile modules with the PerlModule config directive, which is highly
3370    recommended.
3371
3372     Apache::ASP->Loader($path, $pattern, %config)
3373
3374    This routine takes a file or directory as its first argument. If a file,
3375    that file will be compiled. If a directory, that directory will be recursed,
3376    and all files in it whose file name matches $pattern will be compiled.
3377    $pattern defaults to .*, which says that all scripts in a directory will be
3378    compiled by default.
3379
3380    The %config args, are the config options that you may want set that affect
3381    compilation. These options include: Debug, Global, GlobalPackage,
3382    DynamicIncludes, IncludesDir, InodeNames, PodComments, StatINC,
3383    StatINCMatch, UseStrict, XMLSubsPerlArgs, XMLSubsMatch, and XMLSubsStrict.
3384    If your scripts are later run with different config options, your scripts
3385    may have to be recompiled.
3386
3387    Here is an example of use in a *.conf file:
3388
3389     <Perl>
3390     Apache::ASP->Loader(
3391            '/usr/local/proj/site', "(asp|htm)\$",
3392            'Global' => '/proj/perllib',
3393            'Debug' => -3, # see system output when starting apache
3394
3395            # OPTIONAL configs if you use them in your apache configuration
3396            # these settings affect how the scripts are compiled and loaded
3397            'GlobalPackage' => 'SomePackageName',
3398            'DynamicIncludes' => 1,
3399            'StatINC' => 1,
3400            'StatINCMatch' => 'My',
3401            'UseStrict' => 1,
3402            'XMLSubsMatch' => 'my:\w+',
3403            'XMLSubsStrict' => 0 || 1,
3404            );
3405     </Perl>
3406
3407    This config section tells the server to compile all scripts in c:/proj/site
3408    that end in asp or htm, and print debugging output so you can see it work.
3409    It also sets the Global directory to be /proj/perllib, which needs to be the
3410    same as your real config since scripts are cached uniquely by their Global
3411    directory. You will probably want to use this on a production server, unless
3412    you cannot afford the extra startup time.
3413
3414    To see precompiling in action, set Debug to 1 for the Loader() and for your
3415    application in general and watch your error_log for messages indicating
3416    scripts being cached.
3417
3418  No .htaccess or StatINC
3419    Don't use .htaccess files or the StatINC setting in a production system as
3420    there are many more files touched per request using these features. I've
3421    seen performance slow down by half because of using these. For eliminating
3422    the .htaccess file, move settings into *.conf Apache files.
3423
3424    Instead of StatINC, try using the StatINCMatch config, which will check a
3425    small subset of perl libraries for changes. This config is fine for a
3426    production environment, and if used well might only incur a 10-20%
3427    performance penalty, depending on the number of modules your system loads in
3428    all, as each module needs to be checked for changes on a per request basis.
3429
3430  Turn off Debugging
3431    Turn off system debugging by setting Debug to 0-3. Having the system debug
3432    config option on slows things down immensely, but can be useful when
3433    troubleshooting your application. System level debugging is settings -3
3434    through -1, where user level debugging is 1 to 3. User level debugging is
3435    much more light weight depending on how many $Reponse->Debug() statements
3436    you use in your program, and you may want to leave it on.
3437
3438  Memory Sparing, NoCache
3439    If you have a lot (1000's+) of scripts, and limited memory, set NoCache to
3440    1, so that compiled scripts are not cached in memory. You lose about 10-15%
3441    in speed for small scripts, but save at least 10K RAM per cached script.
3442    These numbers are very rough and will largely depend on the size of your
3443    scripts and includes.
3444
3445  Resource Limits
3446    Make sure your web processes do not use too many resources like CPU or RAM
3447    with the handy Apache::Resource module. Such a config might look like:
3448
3449     PerlModule Apache::Resource
3450     PerlSetEnv PERL_RLIMIT_CPU  1000
3451     PerlSetEnv PERL_RLIMIT_DATA 60:60
3452
3453    If ever a web process should begin to take more than 60M ram or use more
3454    than 1000 CPU seconds, it will be killed by the OS this way. You only want
3455    to use this configuration to protect against runaway processes and web
3456    program errors, not for terminating a normally functioning system, so set
3457    these limits HIGH!
3458
3459SEE ALSO
3460    perl(1), mod_perl(3), Apache(3), MLDBM(3), HTTP::Date(3), CGI(3),
3461    Win32::OLE(3)
3462
3463NOTES
3464    Many thanks to those who helped me make this module a reality. With Apache +
3465    ASP + Perl, web development could not be better!
3466
3467    Special thanks go to my father Kevin & wife Lina for their love and support
3468    through it all, and without whom none of it would have been possible.
3469
3470    Other honorable mentions include:
3471
3472     !! Gregory Youngblood, Thanos Chatziathanassiou, & Tsirkin Evgeny for keeping the flame alive!
3473
3474     :) Doug MacEachern, for moral support and of course mod_perl
3475     :) Helmut Zeilinger, Skylos, John Drago, and Warren Young for their help in the community
3476     :) Randy Kobes, for the win32 binaries, and for always being the epitome of helpfulness
3477     :) Francesco Pasqualini, for bug fixes with stand alone CGI mode on Win32
3478     :) Szymon Juraszczyk, for better ContentType handling for settings like Clean.
3479     :) Oleg Kobyakovskiy, for identifying the double Session_OnEnd cleanup bug.
3480     :) Peter Galbavy, for reporting numerous bugs and maintaining the OpenBSD port.
3481     :) Richard Curtis, for reporting and working through interesting module
3482        loading issues under mod_perl2 & apache2, and pushing on the file upload API.
3483     :) Rune Henssel, for catching a major bug shortly after 2.47 release,
3484        and going to great lengths to get me reproducing the bug quickly.
3485     :) Broc, for keeping things filter aware, which broke in 2.45,
3486        & much help on the list.
3487     :) Manabu Higashida, for fixes to work under perl 5.8.0
3488     :) Slaven Rezic, for suggestions on smoother CPAN installation
3489     :) Mitsunobu Ozato, for working on a japanese translation of the site & docs.
3490     :) Eamon Daly for persistence in resolving a MailErrors bug.
3491     :) Gert, for help on the mailing list, and pushing the limits of use on Win32
3492        in addition to XSLT.
3493     :) Maurice Aubrey, for one of the early fixes to the long file name problem.
3494     :) Tom Lancaster, for pushing the $Server->Mail API and general API discussion.
3495     :) Ross Thomas, for pushing into areas so far unexplored.
3496     :) Harald Kreuzer, for bug discovery & subsequent testing in the 2.25 era.
3497     :) Michael Buschauer for his extreme work with XSLT.
3498     :) Dariusz Pietrzak for a nice parser optimization.
3499     :) Ime Smits, for his inode patch facilitating cross site code reuse, and
3500        some nice performance enhancements adding another 1-2% speed.
3501     :) Michael Davis, for easier CPAN installation.
3502     :) Brian Wheeler, for keeping up with the Apache::Filter times,
3503        and pulling off filtering ASP->AxKit.
3504     :) Ged Haywood, for his great help on the list & professionally.
3505     :) Vee McMillen, for OSS patience & understanding.
3506     :) Craig Samuel, at LRN, for his faith in open source for his LCEC.
3507     :) Geert Josten, for his wonderful work on XML::XSLT
3508     :) Gerald Richter, for his Embperl, collaboration and competition!
3509     :) Stas Bekman, for his beloved guide, and keeping us all worldly.
3510     :) Matt Sergeant, again, for ever the excellent XML critique.
3511     :) Remi Fasol + Serge Sozonoff who inspired cookieless sessions.
3512     :) Matt Arnold, for the excellent graphics !
3513     :) Adi, who thought to have full admin control over sessions
3514     :) Dmitry Beransky, for sharable web application includes, ASP on the big.
3515     :) Russell Weiss again, for finding the internal session garbage collection
3516        behaving badly with DB_File sensitive i/o flushing requirements.
3517     :) Tony Merc Mobily, inspiring tweaks to compile scripts 10 times faster
3518     :) Paul Linder, who is Mr. Clean... not just the code, its faster too !
3519        Boy was that just the beginning.  Work with him later facilitated better
3520        session management and XMLSubsMatch custom tag technology.
3521     :) Russell Weiss, for being every so "strict" about his code.
3522     :) Bill McKinnon, who understands the finer points of running a web site.
3523     :) Richard Rossi, for his need for speed & boldly testing dynamic includes.
3524     :) Greg Stark, for endless enthusiasm, pushing the module to its limits.
3525     :) Marc Spencer, who brainstormed dynamic includes.
3526     :) Doug Silver, for finding most of the bugs.
3527     :) Darren Gibbons, the biggest cookie-monster I have ever known.
3528     :) Ken Williams, for great teamwork bringing full SSI to the table
3529     :) Matt Sergeant, for his great tutorial on PerlScript and love of ASP
3530     :) Jeff Groves, who put a STOP to user stop button woes
3531     :) Alan Sparks, for knowing when size is more important than speed
3532     :) Lincoln Stein, for his blessed CGI.pm module
3533     :) Michael Rothwell, for his love of Session hacking
3534     :) Francesco Pasqualini, for bringing ASP to CGI
3535     :) Bryan Murphy, for being a PerlScript wiz
3536     :) Lupe Christoph, for his immaculate and stubborn testing skills
3537     :) Ryan Whelan, for boldly testing on Unix in the early infancy of ASP
3538
3539SUPPORT
3540  COMMUNITY
3541    Mailing List Archives
3542        Try the Apache::ASP mailing list archive first when working through an
3543        issue as others may have had the same question as you, then try the
3544        mod_perl list archives since often problems working with Apache::ASP are
3545        really mod_perl ones.
3546
3547        The Apache::ASP mailing list archives are located at:
3548
3549         http://groups.yahoo.com/group/apache-asp/
3550         http://www.mail-archive.com/asp%40perl.apache.org/
3551
3552        The mod_perl mailing list archives are located at:
3553
3554         http://mail-archives.apache.org/mod_mbox/perl-modperl/
3555
3556    Mailing List
3557        Please subscribe to the Apache::ASP mailing list by sending an email to
3558        asp-subscribe[at]perl.apache.org and send your questions or comments to
3559        the list after your subscription is confirmed.
3560
3561        To unsubscribe from the Apache::ASP mailing list, just send an email to
3562        asp-unsubscribe[at]perl.apache.org
3563
3564        If you think this is a mod_perl specific issue, you can send your
3565        question to modperl[at]apache.org
3566
3567    Donations
3568        Apache::ASP is freely distributed under the terms of the Perl artistic
3569        license ( see the LICENSE section ). If you would like to donate time to
3570        the project, please get involved on the Apache::ASP Mailing List, and
3571        submit ideas, bug fixes and patches for the core system, and perhaps
3572        most importantly to simply support others in learning the ins and outs
3573        of the software.
3574
3575  COMMERCIAL
3576    If you would like commercial support for Apache::ASP, please check out any
3577    of the following listed companies. Note that this is not an endorsement, and
3578    if you would like your company listed here, please email
3579    asp[at]perl.apache.org with your information.
3580
3581    AlterCom
3582        We use, host and support mod_perl. We would love to be able to help
3583        anyone with their mod_perl Apache::ASP needs. Our mod_perl hosting is
3584        $24.95 mo.
3585
3586          http://altercom.com/home.html
3587
3588    The Cyberchute Connection
3589        Our hosting services support Apache:ASP along with Mod_Perl, PHP and
3590        MySQL.
3591
3592          http://www.Cyberchute.com
3593
3594    OmniTI
3595        OmniTI supports Apache and mod_perl (including Apache::ASP) and offers
3596        competitive pricing for both hourly and project-based jobs. OmniTI has
3597        extensive experience managing and maintaining both large and small
3598        projects. Our services range from short-term consulting to project-based
3599        development, and include ongoing maintenance and hosting.
3600
3601          http://www.omniti.com
3602
3603    TUX IT AG
3604        Main business is implementing and maintaining infrastructure for big
3605        websites and portals, as well as developing web applications for our
3606        customers (Apache, Apache::ASP, PHP, Perl, MySQL, etc.)
3607
3608        The prices for our service are about 900 EUR per day which is negotiable
3609        (for longer projects, etc.).
3610
3611          http://www.tuxit.de
3612
3613SITES USING
3614    What follows is a list of public sites that are using Apache::ASP. If you
3615    use the software for your site, and would like to show your support of the
3616    software by being listed, please send your link to asp[at]perl.apache.org
3617
3618    For a list of testimonials of those using Apache::ASP, please see the
3619    TESTIMONIALS section.
3620
3621            PERSONiO Match
3622            http://www.personio.com/home.asp
3623
3624            gutscheinwurst.de - a German voucher community
3625            http://www.gutscheinwurst.de
3626
3627            SalesJobs.com
3628            http://www.salesjobs.com
3629
3630            hanschur.de
3631            http://www.hanschur.de
3632
3633            Webtist
3634            http://www.webtist.de
3635
3636            FreeLotto
3637            http://www.freelotto.com
3638
3639            Hungarian TOP1000
3640            http://www.hungariantop1000.com
3641
3642            Hungarian Registry
3643            http://www.hunreg.com
3644
3645            Kepeslap.com
3646            http://www.kepeslap.com
3647
3648            yourpostcardsite.com
3649            http://www.yourpostcardsite.com
3650
3651            WebTime
3652            http://webtime-project.net
3653
3654            AlterCom, Advanced Web Hosting
3655            http://altercom.com/
3656
3657            AmericanGamers.com
3658            http://www.AmericanGamers.com/
3659
3660            ESSTECwebservices
3661            http://www.esstec.be/
3662
3663            Alumni.NET
3664            http://www.alumni.net
3665
3666            Anime Wallpapers dot com
3667            http://www.animewallpapers.com/
3668
3669            Cine.gr
3670            http://www.cine.gr
3671
3672            Condo-Mart Web Service
3673            http://www.condo-mart.com
3674
3675            Discountclick.com
3676            http://www.discountclick.com/
3677
3678            HCST
3679            http://www.hcst.net
3680
3681            International Telecommunication Union
3682            http://www.itu.int
3683
3684            Integra
3685            http://www.integra.ru/
3686
3687            Money FM
3688            http://www.moneyfm.gr
3689
3690            Motorsport.com
3691            http://www.motorsport.com
3692
3693            MLS of Greater Cincinnati
3694            http://www.cincymls.com
3695
3696            NodeWorks Link Checker
3697            http://www.nodeworks.com
3698
3699            OnTheWeb Services
3700            http://www.ontheweb.nu
3701
3702            Prices for Antiques
3703            http://www.p4a.com
3704
3705            redhat.com | support
3706            http://www.redhat.com/apps/support/
3707
3708            Spotlight
3709            http://www.spotlight.com.au
3710
3711            USCD Electrical & Computer Engineering
3712            http://ece-local.ucsd.edu
3713
3714TESTIMONIALS
3715    Here are testimonials from those using Apache::ASP. If you use this software
3716    and would like to show your support please send your testimonial to
3717    Apache::ASP mailing list at asp[at]perl.apache.org and indicate that we can
3718    post it to the web site.
3719
3720    For a list of sites using Apache::ASP, please see the SITES USING section.
3721
3722    Red Hat
3723        We're using Apache::ASP on www.redhat.com. We find Apache::ASP very easy
3724        to use, and it's quick for new developers to get up to speed with it,
3725        given that many people have already been exposed to the ASP object model
3726        that Apache::ASP is based on.
3727
3728        The documentation is comprehensive and easy to understand, and the
3729        community and maintainer have been very helpful whenever we've had
3730        questions.
3731
3732          -- Tom Lancaster, Red Hat
3733
3734    Anime Wallpaper at Anime Cubed
3735        Your suite has got our old CGI implementation beat, hands down. Our site
3736        is divided into two main areas, each run by a separate developer, and
3737        the Apache::ASP section runs head and shoulders above the other side.
3738        Anyone who is still using anything but your product to implement their
3739        webpages seriously needs to take a look at how versatile and powerful
3740        Apache::ASP is. Thanks again for such great work!
3741
3742          -- Al from 'Anime Wallpaper at Anime Cubed', http://www.animecubed.com/wallpapers/
3743
3744    gutscheinwurst.de
3745        I am the web master of http://www.gutscheinwurst.de , a German voucher
3746        community. We use Apache::Asp to run our backend & administration
3747        servers for the system. We started using Apache::ASP to see whether it
3748        is a valid alternative to IIS legacy systems. So far all expectations in
3749        regard of performance, ease of development and integration have been
3750        fulfilled or exceeded. Thank's for such a great product :)
3751
3752         -- Johnannes Leimbach
3753
3754    D. L. Fox
3755        I had programmed in Perl for some time ... but, since I also knew VB, I
3756        had switched to VB in IIS-ASP for web stuff because of its ease of use
3757        in embedding code with HTML ... When I discovered Apache-ASP, it was
3758        like a dream come true. I would much rather code in Perl than any other
3759        language. Thanks for such a fine product!
3760
3761    HOSTING 321, LLC.
3762        After discontinuing Windows-based hosting due to the high cost of
3763        software, our clients are thrilled with Apache::ASP and they swear ASP
3764        it's faster than before. Installation was a snap on our 25-server web
3765        farm with a small shell script and everything is running perfectly! The
3766        documentation is very comprehensive and everyone has been very helpful
3767        during this migration.
3768
3769        Thank you!
3770
3771         -- Richard Ward, HOSTING 321, LLC.
3772
3773    Concept Online Ltd.
3774        I would like to say that your ASP module rocks :-) We have practically
3775        stopped developing in anything else about half a year ago, and are now
3776        using Apache::ASP extensively. I just love Perl, and whereever we are
3777        not "forced" to use JSP, we chose ASP. It is fast, reliable, versatile,
3778        documented in a way that is the best for professionals - so thank you
3779        for writting and maintaining it!
3780
3781          -- Csongor Fagyal, Concept Online Ltd.
3782
3783    WebTime
3784        As we have seen with WebTime, Apache::ASP is not only good for the
3785        development of website, but also for the development of webtools. Since
3786        I first discoverd it, I made it a must-have in my society by taking
3787        traditional PHP users to the world of perl afficionados.
3788
3789        Having the possibility to use Apache::ASP with mod_perl or mod_cgi make
3790        it constraintless to use because of CGI's universality and perl's
3791        portability.
3792
3793          -- Gr�goire Lejeune
3794
3795    David Kulp
3796        First, I just want to say that I am very very impressed with
3797        Apache::ASP. I just want to gush with praise after looking at many other
3798        implementations of perl embedded code and being very underwhelmed. This
3799        is so damn slick and clean. Kudos! ...
3800
3801        ... I'm very pleased how quickly I've been able to mock up the
3802        application. I've been writing Perl CGI off and on since 1993(!) and I
3803        can tell you that Apache::ASP is a pleasure. (Last year I tried Zope and
3804        just about threw my computer out the window.)
3805
3806          -- David Kulp
3807
3808    MFM Commmunication Software, Inc.
3809        Working in a team environment where you have HTML coders and perl
3810        coders, Apache::ASP makes it easy for the HTML folks to change the look
3811        of the page without knowing perl. Using Apache::ASP (instead of another
3812        embedded perl solution) allows the HTML jockeys to use a variety of HTML
3813        tools that understand ASP, which reduces the amount of code they break
3814        when editing the HTML. Using Apache::ASP instead of M$ ASP allows us to
3815        use perl (far superior to VBScript) and Apache (far superior to IIS).
3816
3817        We've been very pleased with Apache::ASP and its support.
3818
3819    Planet of Music
3820        Apache::ASP has been a great tool. Just a little background.... the
3821        whole site had been in cgi flat files when I started here. I was looking
3822        for a technology that would allow me to write the objects and NEVER
3823        invoke CGI.pm... I found it and hopefuly I will be able to implement
3824        this every site I go to.
3825
3826        When I got here there was a huge argument about needing a game engine
3827        and I belive this has been the key... Games are approx. 10 time faster
3828        than before. The games don't break anylonger. All in all a great tool
3829        for advancement.
3830
3831          -- JC Fant IV
3832
3833    Cine.gr
3834        ...we ported our biggest yet ASP site from IIS (well, actually rewrote),
3835        Cine.gr and it is a killer site. In some cases, the whole thing got
3836        almost 25 (no typo) times faster... None of this would ever be possible
3837        without Apache::ASP (I do not ever want to write ``print "<HTML>\n";''
3838        again).
3839
3840RESOURCES
3841    Here are some important resources listed related to the use of Apache::ASP
3842    for publishing web applications. If you have any more to suggest, please
3843    email the Apache::ASP list at asp[at]perl.apache.org
3844
3845  Articles
3846           Apache::ASP Introduction ( #1 in 3 part series )
3847           http://www.apache-asp.org/articles/perlmonth1_intro.html
3848
3849           Apache::ASP Site Building ( #2 in 3 part series )
3850           http://www.apache-asp.org/articles/perlmonth2_build.html
3851
3852           Apache::ASP Site Tuning ( #3 in 3 part series )
3853           http://www.apache-asp.org/articles/perlmonth3_tune.html
3854
3855           Embedded Perl ( part of a series on Perl )
3856           http://www.wdvl.com/Authoring/Languages/Perl/PerlfortheWeb/index15.html
3857
3858  Books
3859           mod_perl "Eagle" Book
3860           http://www.modperl.com
3861
3862           mod_perl Developer's Cookbook
3863           http://www.modperlcookbook.org
3864
3865           Programming the Perl DBI
3866           http://www.oreilly.com/catalog/perldbi/
3867
3868  Reference Cards
3869            Apache & mod_perl Reference Cards
3870            http://www.refcards.com/
3871
3872  Web Sites
3873            mod_perl Apache web module
3874            http://perl.apache.org
3875
3876            mod_perl 1.x Guide
3877            http://perl.apache.org/guide/
3878
3879            Perl Programming Language
3880            http://www.perl.com
3881
3882            Apache Web Server
3883            http://www.apache.org
3884
3885TODO
3886    There is no specific time frame in which these things will be implemented.
3887    Please let me know if any of these is of particular interest to you, and I
3888    will give it higher priority.
3889
3890  WILL BE DONE
3891     + Database storage of $Session & $Application, so web clusters
3892       may scale better than the current NFS/CIFS StateDir implementation
3893       allows, maybe via Apache::Session.
3894
3895CHANGES
3896    Apache::ASP has been in development since 1998, and was production ready
3897    since its .02 release. Releases are always used in a production setting
3898    before being made publically available.
3899
3900    In July 2000, the version numbers of releases went from .19 to 1.9 which is
3901    more relevant to software development outside the perl community. Where a
3902    .10 perl module usually means first production ready release, this would be
3903    the equivalent of a 1.0 release for other kinds of software.
3904
3905     + = improvement   - = bug fix    (d) = documentations
3906
3907    $VERSION = 2.63; $DATE="03/14/2018"
3908         + Added section ``raw'' to MailErrors.inc to debug POSTs without
3909           form fields
3910
3911         - MailErrorsHTML now uses monospaced fonts for errors. Easier on
3912           the eyes and more informative
3913
3914    $VERSION = 2.62; $DATE="08/16/2011"
3915         - Fixed 'application/x-www-form-urlencoded' for AJAX POSTs post
3916           Firefox 3.x
3917
3918         + First sourceforge.net hosted version
3919
3920         + Incremented version number to actually match SVN branch tag
3921
3922    $VERSION = 2.61; $DATE="05/24/2008"
3923         - updated for more recent mod_perl 2 environment to trigger correct loading of modules
3924
3925         + loads modules in a backwards compatible way for older versions of mod_perl 1.99_07 to 1.99_09
3926
3927         + license changes from GPL to Perl Artistic License
3928
3929    $VERSION = 2.59; $DATE="05/23/2005"
3930         + added "use bytes" to Response object to calculate Content-Length
3931           correctly for UTF8 data, which should require therefore at least
3932           perl version 5.6 installed
3933
3934         + updated to work with latest mod_perl 2.0 module naming convention,
3935           thanks to Randy Kobes for patch
3936
3937         + examples now exclude usage of Apache::Filter & Apache::SSI under mod_perl 2.0
3938
3939    $VERSION = 2.57; $DATE="01/29/2004"
3940         - $Server->Transfer will update $0 correctly
3941
3942         - return 0 for mod_perl handler to work with latest mod_perl 2 release
3943           when we were returning 200 ( HTTP_OK ) before
3944
3945         - fixed bug in $Server->URL when called like $Server->URL($url)
3946           without parameters.  Its not clear which perl versions this bug
3947           affected.
3948
3949    $VERSION = 2.55; $DATE="08/09/2003"
3950         - Bug fixes for running on standalone CGI mode on Win32 submitted
3951           by Francesco Pasqualini
3952
3953         + Added Apache::ASP::Request::BINMODE for binmode() being
3954           called on STDIN after STDIN is tied to $Request object
3955
3956         + New RequestBinaryRead configuration created, may be turned off
3957           to prevent $Request object from reading POST data
3958
3959         ++ mod_perl 2 optmizations, there was a large code impact on this,
3960           as much code was restructured to reduce the differences between
3961           mod_perl 1 and mod_perl 2, most importantly, Apache::compat is
3962           no longer used
3963
3964         + preloaded CGI for file uploads in the mod_perl environment
3965
3966         - When XSLT config is set, $Response->Redirect() should work now
3967           Thanks to Marcus Zoller for pointing problem out
3968
3969         + Added CookieDomain setting, documented, and added test to cover
3970           it in t/cookies.t . Setting suggested by Uwe Riehm, who nicely
3971           submitted some code for this.
3972
3973    $VERSION = 2.53; $DATE="04/10/2003"
3974         + XMLSubs tags with "-" in them will have "-" replaced with "_" or underscore, so a
3975           tag like <my:render-table /> will be translated to &my::render_table() ... tags with
3976           - in them are common in extended XML syntaxes, but perl subs cannot have - in them only.
3977
3978         + Clean setting now works on output when $Response->{ContentType} begins with text/html;
3979           like "text/html; charset=iso-8859-2" ... before Clean would only work on output marked
3980           with ContentType text/html.  Thanks to Szymon Juraszczyk for recommending fix.
3981
3982         --Fixed a bug which would cause Session_OnEnd to be called twice on sessions in a certain case,
3983           particularly when an old expired session gets reused by and web browser... this bug was
3984           a result of a incomplete session cleanup method in this case.  Thanks to Oleg Kobyakovskiy
3985           for reporting this bug.  Added test in t/session_events.t to cover this problem going forward.
3986
3987         - Compile errors from Apache::ASP->Loader() were not being reported.  They will
3988           be reported again now.  Thanks to Thanos Chatziathanassiou for discovering and
3989           documenting this bug.  Added test in t/load.t to cover this problem going forward.
3990
3991         + use of chr(hex($1)) to decode URI encoded parameters instead of pack("c",hex($1))
3992           faster & more correct, thanks to Nikolay Melekhin for pointing out this need.
3993
3994         (d) Added old perlmonth.com articles to ./site/articles in distribution
3995           and linked to them from the docs RESOURCES section
3996
3997         (d) Updated documention for the $Application->SessionCount API
3998
3999         + Scripts with named subroutines, which is warned against in the style guide,
4000           will not be cached to help prevent my closure problems that often
4001           hurt new developers working in mod_perl environments.  The downside
4002           is that these script will have a performance penalty having to be
4003           recompiled each invocation, but this will kill many closure caching
4004           bugs that are hard to detect.
4005
4006         - $Request->FileUpload('upload_file', 'BrowserFile') would return
4007           a glob before that would be the file name in scalar form.  However
4008           this would be interpreted as a reference incorrectly.  The fix
4009           is to make sure this is always a scalar by stringifying
4010           this data internally.  Thanks to Richard Curtis for pointing
4011           out this bug.
4012
4013    $VERSION = 2.51; $DATE="02/10/2003"
4014         + added t/session_query_parse.t test to cover use of SessionQueryParse
4015           and $Server->URL APIs
4016
4017         - Fixed duplicate "&" bug associated with using $Server->URL
4018           and SessionQueryParse together
4019
4020         + Patch to allow $Server->URL() to be called multiple times on the same URL
4021           as in $Server->URL($Server->URL($url, \%params), \%more_params)
4022
4023         (d) Added new testimonials & sites & created a separate testimonials page.
4024
4025         - SessionQueryParse will now add to &amp; to the query strings
4026           embedded in the HTML, instead of & for proper HTML generation.
4027           Thanks to Peter Galbavy for pointing out and Thanos Chatziathanassiou
4028           for suggesting the fix.
4029
4030         - $Response->{ContentType} set to text/html for developer error reporting,
4031           in case this was set to something else before the error occured.
4032           Thanks to Philip Mak for reporting.
4033
4034         - Couple of minor bug fixes under PerlWarn use, thanks Peter Galbavy
4035           for reporting.
4036
4037         + Added automatic load of "use Apache2" for compat with mod_perl2
4038           request objects when Apache::ASP is loaded via "PerlModule Apache::ASP"
4039           Thanks to Richard Curtis for reporting bug & subsequent testing.
4040
4041         - When GlobalPackage config changes, but global.asa has not, global.asa
4042           will be recompiled anyway to update the GlobalPackage correctly.
4043           Changing GlobalPackage before would cause errors if global.asa was
4044           already compiled.
4045
4046         ++ For ANY PerlSetVar type config, OFF/Off/off will be assumed
4047            to have value of 0 for that setting.  Before, only a couple settings
4048            had this semantics, but they all do now for consistency.
4049
4050         - Fix for InodeNames config on OpenBSD, or any OS that might have
4051           a device # of 0 for the file being stat()'d, thanks to Peter Galbavy
4052           for bug report.
4053
4054         ++ Total XSLT speedups, 5-10% on large XSLT, 10-15% on small XSLT
4055
4056         + bypass meta data check like expires for XSLT Cache() API use
4057           because XSLT tranformations don't expire, saves hit to cache dbm
4058           for meta data
4059
4060         + use of direct Apache::ASP::State methods like FETCH/STORE
4061           in Cache() layer so we don't have to go through slower tied interface.
4062           This will speed up XSLT & and include output caching mostly.
4063
4064         + minor optimizations for speed & memory usage
4065
4066    $VERSION = 2.49; $DATE="11/10/2002"
4067         -- bug introduced in 2.47 cached script compilations for executing
4068            scripts ( not includes ) of the same name in different directories
4069            for the same Global/GlobalPackage config for an application.
4070            Fix was to remove optimization that caused problem, and
4071            created test case t/same_name.t to cover bug.
4072
4073    $VERSION = 2.47; $DATE="11/06/2002"
4074         ++ Runtime speed enhancements for 15-20% improvement including:
4075           + INTERNAL API ReadFile() now returns scalar ref as memory optimization
4076           + cache InodeNames config setting in ASP object now for common lookups
4077           + removed CompileChecksum() INTERNAL API, since it was an unnecesary
4078             method decomposition along a common code path
4079           + removed IsChanged() INTERNAL API since compiling of scripts
4080             is now handled by CompileInclude() which does this functionality already
4081           + removed unnecessary decomp of IncludesChanged() INTERNAL API, which was along
4082             critical code path
4083           + do not call INTERNAL SearchDirs() API when compiling base script
4084             since we have already validated its path earlier
4085           + Use stat(_) type shortcut for stat() & -X calls where possible
4086           + Moved @INC initilization up to handler() & consolidated with $INCDir lib
4087           + removed useless Apache::ASP::Collection::DESTROY
4088           + removed useless Apache::ASP::Server::DESTROY
4089           + removed useless Apache::ASP::GlobalASA::DESTROY
4090           + removed useless Apache::ASP::Response::DESTROY
4091
4092         - Default path for $Response->{Cookies} was from CookiePath
4093           config, but this was incorrect as CookiePath config is only
4094           for $Session cookie, so now path for $Response->{Cookies}
4095           defaults to /
4096
4097         - Fixed bug where global.asa events would get undefined with
4098           StatINC and GlobalPackage set when the GlobalPackage library
4099           changed & get reloaded.
4100
4101         (d) Documented long time config NoCache.
4102
4103         -- Fixed use with Apache::Filter, capable as both source
4104            and destination filter.  Added ./site/eg/filter.filter example
4105            to demonstrate these abilities.
4106
4107         + Use $r->err_headers_out->add Apache::Table API for cookies
4108           now instead of $r->cgi_header_out.  Added t/cookies.t test to
4109           cover new code path as well as general $Response->Cookies API.
4110           Also make cookies headers sorted by cookie and dictionary key
4111           while building headers for repeatable behavior, this latter was
4112           to facilitate testing.
4113
4114         - fixed $Server->Mail error_log output when failing to connect
4115           to SMTP server.
4116
4117         + added tests to cover UniquePackages & NoCache configs since this
4118           config logic was updated
4119
4120         + made deprecated warnings for use of certain $Response->Member
4121           calls more loudly write to error_log, so I can remove the AUTOLOAD
4122           for Response one day
4123
4124         - Probably fixed behavior in CgiHeaders, at least under perl 5.8.0, and
4125           added t/cgi_headers.t to cover this config.
4126
4127         + removed $Apache::ASP::CompressGzip setting ability, used to possibly
4128           set CompressGzip in the module before, not documented anyway
4129
4130         + removed $Apache::ASP::Filter setting ability to set Filter globally,
4131           not documented anyway
4132
4133         + removed old work around for setting ServerStarting to 0
4134           at runtime, which was bad for Apache::DBI on win32 a long
4135           time ago:
4136
4137            $Apache::ServerStarting and $Apache::ServerStarting = 0;
4138
4139           If this code is still needed in Apache::ASP->handler() let
4140           me know.
4141
4142         + check to make sure data in internal database is a HASH ref
4143           before using it for session garbage collection.  This is to
4144           help prevent against internal database corruption in a
4145           network share that does not support flock() file locking.
4146
4147         + For new XMLSubs ASP type <%= %> argument interpolation
4148           activated with XMLSubsPerlArgs 0, data references can now
4149           be passed in addition to SCALAR/string references, so one
4150           can pass an object reference like so:
4151
4152             <my:tag value="<%= $Object %>" />
4153
4154           This will only work as long as the variable interpolation <%= %>
4155           are flushed against the containing " " or ' ', or else the object
4156           reference will be stringified when it is concatenated with
4157           the rest of the data.
4158
4159           Testing for this feature was added to ./t/xmlsubs_aspargs.t
4160
4161           This feature is still experimental, and its interface may change.
4162           However it is slated for the 3.0 release as default method,
4163           so feedback is appreciated.
4164
4165         + For new XMLSubs ASP type <%= %> argument interpolation
4166           activated with XMLSubsPerlArgs 0, <% %> will no longer work,
4167           just <%= %>, as in
4168
4169             <my:tag value="some value <%= $value %> more data" />
4170
4171           This feature is still experimental, and its interface may change.
4172           However it is slated for the 3.0 release as default method,
4173           so feedback is appreciated.
4174
4175    $VERSION = 2.45; $DATE="10/13/2002"
4176         ++New XMLSubsPerlArgs config, default 1, indicates how
4177          XMLSubs arguments have always been parsed.  If set to 0,
4178          will enable new XMLSubs args that are more ASP like with
4179          <%= %> for dynamic interpolation, such as:
4180
4181            <my:xmlsub arg="<%= $data %>" arg2="text <%= $data2 %>" />
4182
4183          Settings XMLSubsPerlArgs to 0 is experimental for now, but
4184          will become the default by Apache::ASP version 3.0
4185
4186         ++Optimization for static HTML/XML files that are served up
4187          via Apache::ASP so that they are not compiled into perl subroutines
4188          first.  This makes especially native XSLT both faster & take
4189          less memory to serve, before XSL & XML files being transformed
4190          by XSLT would both be compiled as normal ASP script first, so
4191          now this will happen if they really are ASP scripts with embedded
4192          <% %> code blocks & XMLSubs being executed.
4193
4194         +Consolidate some config data for Apache::ASP->Loader to use
4195          globals in @Apache::ASP::CompileChecksumKeys to know which
4196          config data is important for precompiling ASP scripts.
4197
4198         +Further streamlined code compilation.  Now both base
4199          scripts and includes use the internal CompileInclude() API
4200          to generate code.
4201
4202         -Fixed runtime HTML error output when Debug is set to -2/2,
4203          so that script correctly again gets rendered in final perl form.
4204          Added compile time error output to ./site/eg/syntax_error.asp
4205          when a special link is clicked for a quick visual test.
4206
4207         -Cleaned up some bad coding practices in ./site/eg/global.asa
4208          associated changes in other example files.  Comment example
4209          global.asa some for the first time reader
4210
4211         -DemoASP.pm examples module needed "use strict" fix, thanks
4212          to Allan Vest for bug report
4213
4214         --$rv = $Response->Include({ File => ..., Cache => 1});
4215          now works to get the first returned value fetched from
4216          the cache.  Before, because a list was always returned,
4217          $rv would have been equal to the number of items returned,
4218          even if the return value list has just one element.
4219
4220         (d) added site/robots.txt file with just a comment for
4221             search engine indexing
4222
4223         -fixed ./site/eg/binary_write.htm to not use
4224          $Response->{ContentLength} because it does not exist.
4225          Fixed it to use $Response->AddHeader now instead
4226
4227    $VERSION = 2.41; $DATE="09/29/2002"
4228         -Removed CVS Revision tag from Apache::ASP::Date, which
4229          was causing bad revision numbers in CPAN after CVS integration
4230          of Apache::ASP
4231
4232         +removed cgi/asp link to ../asp-perl from distribution.  This
4233          link was for the deprecated asp script which is now asp-perl
4234
4235    $VERSION = 2.39; $DATE="09/10/2002"
4236         -Turn off $^W explicitly before reloading global.asa.  Reloading
4237          global.asa when $^W is set will trigger subroutine redefinition
4238          warnings.  Reloading global.asa should occur without any problems
4239          under normal usage of the system, thus this work around.
4240
4241          This fix is important to UseStrict functionality because warnings
4242          automatically become thrown as die() errors with UseStrict enabled,
4243          so we have to disable normal soft warnings here.
4244
4245         -$Response->Include() runtime errors now throw a die() that
4246          can be trapped.  This was old functionality that has been restored.
4247          Other compile time errors should still trigger a hard error
4248          like script compilation, global.asa, or $Response->Include()
4249          without an eval()
4250
4251         +Some better error handling with Debug 3 or -3 set, cleaned
4252          up developer errors messages somewhat.
4253
4254    $VERSION = 2.37; $DATE="07/03/2002"
4255         -Fixed the testing directory structures for t/long_names.t
4256          so that tar software like Archive::Tar & Solaris tar that
4257          have problems with long file names will still be able
4258          to untar distribution successfully.  Now t/long_names.t
4259          generates its testing directory structures at runtime.
4260
4261         -Fixes for "make test" to work under perl 5.8.0 RC2,
4262          courtesy of Manabu Higashida
4263
4264         +SessionQueryForce setting created for disabling use of cookies
4265          for $Session session-id passing, rather requiring use of SessionQuery*
4266          functionality for session-id passing via URL query string.
4267
4268          By default, even when SessionQuery* options are used, cookies will
4269          be used if available with SessionQuery* functionality acting only
4270          as a backup, so this makes it so that cookies will never be used.
4271
4272         +Escape ' with HTMLEncode() to &#39;
4273
4274         -Trying to fix t/server_mail.t to work better for platforms
4275          that it should skip testing on.  Updated t/server.t test case.
4276
4277         +Remove exit() from Makefile.PL so CPAN.pm's automatic
4278          follow prereq mechanism works correctly.  Thanks to Slaven Rezic
4279          for pointing this out.
4280
4281         +Added Apache::compat loading in mod_perl environment for better
4282          mod_perl 2.0 support.
4283
4284    $VERSION = 2.35; $DATE="05/30/2002"
4285         +Destroy better $Server & $Response objects so that my
4286          closure references to these to not attempt to work in the future
4287          against invalid internal data. There was enough data left in these
4288          old objects to make debugging the my closure problem confusing, where
4289          it looked like the ASP object state became invalid.
4290
4291         +Added system debug diagnostics to inspect StateManager group cleanup
4292
4293         (d) Documentation update about flock() work around for
4294          Win95/Win98/WinMe systems, confirmed by Rex Arul
4295
4296         (d) Documentation/site build bug found by Mitsunobu Ozato,
4297          where <% %> not being escaped correctly with $Server->HTMLEncode().
4298          New japanese documentation project started by him
4299          at http://sourceforge.jp/projects/apache-asp-jp/
4300
4301         -InitPackageGlobals() called after new Apache::ASP object created so
4302          core system templates can be compiled even when there was a runtime
4303          compilation error of user templates.  Bug fix needed pointed out by
4304          Eamon Daly
4305
4306    $VERSION = 2.33; $DATE="04/29/2002"
4307         - fixed up t/server_mail.t test to skip if a sendmail server
4308           is not available on localhost.  We only want the test to run
4309           if there is a server to test against.
4310
4311         + removed cgi/asp script, just a symlink now to the ./asp-perl script
4312           which in this way deprecates it.  I had it hard linked, but the
4313           distribution did not untar very well on win32 platform.
4314
4315         + Reordered the modules in Bundle::Apache::ASP for a cleaner install.
4316
4317         - Fixed bug where XMLSubs where removing <?xml version ... ?> tag
4318           when it was needed in XSLT mode.
4319
4320         + $Server->Mail({ CC => '...', BCC => '...' }), now works to send
4321           CC & BCC headers/recipients.
4322
4323         + Removed $Apache::ASP::Register definition which defined the current
4324           executing Apache::ASP object.  Only one part of the application was
4325           using it, and this has been fixed.  This would have been an unsafe
4326           use of globals for a threaded environment.
4327
4328         + Decreased latency when doing Application_OnStart, used to sleep(1)
4329           for CleanupMaster sync, but this is not necessary for Application_OnStart
4330           scenario
4331
4332         + Restructure code / core templates for MailErrorsTo funcationality.
4333           Wrote test mail_error.t to cover this.  $ENV{REMOTE_USER} will now
4334           be displayed in the MailErrorsTo message when defined from 401 basic auth.
4335
4336         + $Server->RegisterCleanup should be thread safe now, as it no longer relies
4337           on access to @Apache::ASP::Cleanup for storing the CODE ref stack.
4338
4339         + test t/inode_names.t for InodeNames and other file tests covering case
4340           of long file names.
4341
4342         - Fixed long file name sub identifier bug.  Added test t/long_names.t.
4343
4344         + CacheDir may now be set independently of StateDir.  It used to default
4345           to StateDir if it was set.
4346
4347         ++ Decomposition of modules like Apache::ASP::Session & Apache::ASP::Application
4348           out of ASP.pm file.  This should make the source more developer friendly.
4349
4350           This selective code compilation also speeds up CGI requests that do not
4351           need to load unneeded modules like Apache::ASP::Session, by about 50%,
4352           so where CGI mode ran at about 2.1 hits/sec before, now for
4353           light requests that do not load $Session & $Application, requests
4354           run at 3.4 hits/sec, this is on a dual PIII-450 linux 2.4.x
4355
4356         - Caching like for XSLTCache now works in CGI mode.
4357           This was a bug that it did not before.
4358
4359         + $Server->File() API added, acts as a wrapper around
4360           Apache->request->filename Added test in t/server.t
4361
4362         ++  *** EXPERIMENTAL / ALPHA FEATURE NOTE BEGIN ***
4363
4364           New $PERLLIB/Apache/ASP/Share/ directory created to
4365           hold system & user contributed components, which will be found
4366           on the $Server->MapInclude() path, which helps $Response->Include
4367           search '.',Global,IncludesDir, and now Apache::ASP::Share for
4368           includes to load at runtime.
4369
4370           The syntax for loading a shared include is to prefix the file
4371           name with Share:: as in:
4372
4373            $Response->TrapInclude('Share::CORE/MailError.inc');
4374
4375           New test to cover this at t/share.t
4376
4377           This feature is experimental.  The naming convention may change
4378           and the feature may disappear altogether, so only use if you
4379           are interesting in experimenting with this feature & will
4380           provide feedback about how it works.
4381
4382           *** EXPERIMENTAL / ALPHA FEATURE NOTE END ***
4383
4384         + asp-perl script now uses ./asp.conf instead of ./asp.config
4385           for runtime configuration via %Config defined there.  Update docs
4386           for running in standalone CGI mode
4387
4388         + Make use of MANFEST.SKIP to not publish the dev/* files anymore.
4389
4390         - Script_OnEnd guaranteed to run after $Response->End, but
4391           it will not run if there was an error earlier in the request.
4392
4393         + lots of new test cases covering behaviour of $Response->End
4394           and $Response->Redirect under various conditions like XMLSubs
4395           and SoftRedirect and global.asa Script_OnStart
4396
4397         + asp-perl will be installed into the bin executables when
4398           Apache::ASP is installed.  asp-perl is the command line version
4399           of Apache::ASP that can also be used to run script in CGI mode.
4400           Test case covering asp-perl functionality.
4401
4402         + asp CGI/command line script now called asp-perl.  I picked this
4403           name because Apache::ASP often has the name asp-perl in distributions
4404           of the module.
4405
4406         + Apache::ASP::CGI::Test class now subclass of Apache::ASP::CGI.  To facilitate
4407           this Apache::ASP::CGI::init() now called OO like Apache::ASP::CGI->init()
4408           Fixed up places where the old style was called.  New Test class allows
4409           a dummy Apache request object to be built which caches header & body output
4410           for later inspection instead of writing it to STDOUT.
4411
4412         - $Response->Redirect() under SoftRedirect 1 will not first Clear() buffer
4413
4414         - $Response->Redirect() in an XMLSubs will work now ... behavior
4415           of $Response->Flush() being turned off in an XMLSubs was interfering with this.
4416
4417         + srand() init tracking done better, thanks for patch from Ime Smits
4418
4419         + Added file/directory being used for precompilation in
4420           Apache::ASP->Loader($file, ...) to output like:
4421
4422            [Mon Feb 04 20:19:22 2002] [error] [asp] 4215 (re)compiled 22 scripts
4423              of 22 loaded for $file
4424
4425           This is so that when precompiling multiple web sites
4426           each with different directories, one can easier see the
4427           compile output relevant to the Loader() command being run.
4428
4429         + better decomp of Apache::ASP site build files at ./build/* files,
4430           which is good should anyone look at it for ideas.
4431
4432         + improved test suite to error when unintended output results from
4433           t/*.t test scripts.
4434
4435         - () now supported in XMLSubsMatch config, added xmlsubsmatch.t test...
4436           specifically a config like
4437
4438             PerlSetVar (aaa|bbb):\w+
4439
4440           should now work.  Thanks for bug report from David Kulp.
4441
4442         + Added an early srand() for better $ServerID creation
4443
4444         + Work around for DSO problems where $r is not always correctly
4445           defined in Apache::ASP::handler().  Thanks to Tom Lear for patch.
4446
4447    $VERSION = 2.31; $DATE="01/22/2002";
4448         + $Server->MapInclude() API extension created to wrap up Apache::ASP::SearchDirs
4449           functionality so one may do an conditional check for an include existence befor
4450           executing $Response->Include().  Added API test to server.t
4451
4452         + $Server->Transfer() now allows arguments like $Response->Include(), and now acts just
4453           as a wrapper for:
4454
4455             $Response->Include($file, @args);
4456             $Response->End();
4457
4458           added test case at t/server_transfer.t
4459
4460         + Removed dependency of StatINC functionality on Apache::Symbol.  Apache::Symbol
4461           is no longer required.  Added test of t/stat_inc.t for correct StatINC initialization
4462           for platforms where Devel::Symdump is present.
4463
4464         + Better error message when $Request->Params has not been defined with RequestParams
4465           config & it gets used in script.  Added test case as t/request_params_none.t
4466
4467         + Directories cannot now be included as scripts via $Response->Include(), added
4468           test case to t/include.t
4469
4470         - No longer make $Response->Flush dependent on $Response->IsClientConnected() to
4471           be true to write output to client.  There have been spurious errors reported
4472           about the new ( >= 2.25 ) IsClientConnected code, and this will limit the impact
4473           of that functionality possibly not working still to those users explicitly using
4474           that API.
4475
4476         + $Response->AddHeader($header_name, $value) now will set $Response members
4477           for these headers: Content-Type, Cache-Control, Expires.  This is to avoid
4478           both the application & Apache::ASP sending out duplicate headers.  Added
4479           test cases for this to t/response.t
4480
4481         + split up Bundle::Apache::ASP into that, and Bundle::Apache::ASP::Extra
4482           the former with just the required modules to run, and the latter
4483           for extra functionality in Apache::ASP
4484
4485         + new $Request->{Method} member to return $r->method of GET or POST that
4486           client browser is requesting, added t/request.t sub test to cover this member.
4487
4488    $VERSION = 2.29; $DATE="11/19/2001";
4489         +Added some extra help text to the ./cgi/asp --help message
4490          to clarify how to pass arguments to a script from the command line.
4491
4492         +When using $Server->Mail() API, if Content-Type header is set,
4493          and MIME-Version is not, then a "MIME-Version: 1.0" header will be sent
4494          for the email.  This is correct according to RFC 1521 which specifies
4495          for the first time the Content-Type: header for email documents.
4496          Thanks to Philip Mak for pointing out this correct behavior.
4497
4498         +Made dependent on MLDBM::Sync version .25 to pass the taint_check.t test
4499
4500         +Improved server_mail.t test to work with mail servers were relaying is denied
4501
4502         +Added <html><body> tags to MailErrorsTo email
4503
4504         --Fixed SessionCount / Session_OnEnd bug, where these things were not
4505          working for $Sessions that never had anything written to them.
4506          This bug was introduced in 2.23/2.25 release.
4507
4508          There was an optimization in 2.23/2.25 where a $Session that was never
4509          used does not write its state lock file & dbm files to disk, only if
4510          it gets written too like $Session->{MARK}++.  Tracking of these NULL $Sessions
4511          then is handled solely in the internal database.  For $Session garbage
4512          collection though which would fire Session_OnEnd events and update
4513          SessionCount, the Apache::ASP::State->GroupMembers() function was just
4514          looking for state files on disk ... now it looks in the internal database
4515          too for SessionID records for garbage collection.
4516
4517          Added a test at ./t/session_events.t for these things.
4518
4519         +Some optimizations for $Session API use.
4520
4521         +Added support for XSLT via XML::LibXSLT, patch courtesy of Michael Buschauer
4522
4523         -Got rid of an warning when recompiling changing includes under perl 5.6.1...
4524          undef($code) method did not work for this perl version, rather undef(&$code) does.
4525          Stopped using using Apache::Symbol for this when available.
4526
4527         -Make Apache::ASP script run under perl taint checking -T for perl 5.6.1...
4528          $code =~ tr///; does not work to untaint here, so much use the slower:
4529          $code =~ /^(.*)$/s; $code = $1; method to untaint.
4530
4531         -Check for inline includes changing, included in a dynamic included
4532          loaded at runtime via $Response->Include().  Added test case for
4533          this at t/include_change.t.  If an inline include of a dynamic include
4534          changes, the dynamic include should get recompiled now.
4535
4536         -Make OK to use again with PerlTaintCheck On, with MLDBM::Sync 2.25.
4537          Fixed in ASP.pm, t/global.asa, and created new t/taint_check.t test script
4538
4539         +Load more modules when Apache::ASP is loaded so parent will share more
4540          with children httpd:
4541           Apache::Symbol
4542           Devel::Symdump
4543           Config
4544           lib
4545           MLDBM::Sync::SDBM_File
4546
4547         +When FileUploadMax bytes is exceeded for a file upload, there will not
4548          be an odd error anymore resulting from $CGI::POST_MAX being triggered,
4549          instead the file upload input will simply be ignored via $CGI::DISABLE_UPLOADS.
4550          This gives the developer the opportunity to tell the user the the file upload
4551          was too big, as demonstrated by the ./site/eg/file_upload.asp example.
4552
4553          To not let the web client POST a lot of data to your scripts as a form
4554          of a denial of service attack use the apache config LimitRequestBody for the
4555          max limits.  You can think of PerlSetVar FileUploadMax as a soft limit, and
4556          apache's LimitRequestBody as a hard limit.
4557
4558         --Under certain circumstances with file upload, it seems that IsClientConnected()
4559          would return an aborted client value from $r->connection->aborted, so
4560          the buffer output data would not be flushed to the client, and
4561          the HTML page would return to the browser empty.  This would be under
4562          normal file upload use.  One work-around was to make sure to initialize
4563          the $Request object before $Response->IsClientConnected is called,
4564          then $r->connection->aborted returns the right value.
4565
4566          This problem was probably introduced with IsClientConnected() code changes
4567          starting in the 2.25 release.
4568
4569    $VERSION = 2.27; $DATE="10/31/2001";
4570         + Wrapped call to $r->connection->fileno in eval {} so to
4571           preserve backwards compatibility with older mod_perl versions
4572           that do not have this method defined.  Thanks to Helmut Zeilinger
4573           for catching this.
4574
4575         + removed ./dev directory from distribution, useless clutter
4576
4577         + Removed dependency on HTTP::Date by taking code into
4578           Apache::ASP as Apache::ASP::Date.  This relieves
4579           the dependency of Apache::ASP on libwww LWP libraries.
4580           If you were using HTTP::Date functions before without loading
4581           "use HTTP::Date;" on your own, you will have to do this now.
4582
4583         + Streamlined code execution.  Especially worked on
4584           $Response->IsClientConnected which gets called during
4585           a normal request execution, and got rid of IO::Select
4586           dependency. Some function style calls instead of OO style
4587           calls where private functions were being invokes that one
4588           would not need to override.
4589
4590         - Fixed possible bug when flushing a data buffer where there
4591           is just a '0' in it.
4592
4593         + Updated docs to note that StateCache config was deprecated
4594           as of 2.23.  Removed remaining code that referenced the config.
4595
4596         + Removed references to unused OrderCollections code.
4597
4598         - Better Cache meta key, lower chance of collision with
4599           unrelated data since its using the full MD5 keyspace now
4600
4601         + Optimized some debugging statements that resulted
4602           from recent development.
4603
4604         + Tie::TextDir .04 and above is supported for StateDB
4605           and CacheDB settings with MLDBM::Sync .21. This is good for
4606           CacheDB where output is larger and there are not many
4607           versions to cache, like for XSLTCache, where the site is
4608           mostly static.
4609
4610         + Better RESOURCES section to web site, especially with adding
4611           some links to past Apache::ASP articles & presentations.
4612
4613    $VERSION = 2.25; $DATE="10/11/2001";
4614         + Improved ./site/apps/search application, for better
4615           search results at Apache::ASP site.  Also, reengineered
4616           application better, with more perl code moved to global.asa.
4617           Make use of MLDBM::Sync::SDBM_File, where search database
4618           before was engineering around SDBM_File's shortcomings.
4619
4620         - Fix for SessionSerialize config, which broke in 2.23
4621           Also, added t/session_serialize.t to test suite to catch
4622           this problem in the future.
4623
4624    $VERSION = 2.23; $DATE="10/11/2001";
4625         +Make sure a couple other small standard modules get loaded
4626          upon "PerlModule Apache::ASP", like Time::HiRes, Class::Struct,
4627          and MLDBM::Serializer::Data::Dumper.  If not available
4628          these modules won't cause errors, but will promote child httpd
4629          RAM sharing if they are.
4630
4631         -XMLSubs args parsing fix so an arg like z-index
4632          does not error under UseStrict.  This is OK now:
4633
4634           <my:layer z-index=3 top=0 left=0> HTML </my:layer>
4635
4636         -Only remove outermost <SCRIPT> tags from global.asa
4637          for IIS/PerlScript compatibility.  Used to remove
4638          all <SCRIPT> tags, which hurt when some subs in globa.asa
4639          would be printing some JavaScript.
4640
4641         +$Response->{IsClientConnected} now updated correctly
4642          before global.asa Script_OnStart.  $Response->IsClientConnect()
4643          can be used for accurate accounting, while
4644          $Response->{IsClientConnected} only gets updated
4645          after $Response->Flush().  Added test cases to response.t
4646
4647         +$Server->HTMLEncode(\$data) API extension, now can take
4648          scalar ref, which can give a 5% improvement in benchmarks
4649          for data 100K in size.
4650
4651         -Access to $Application is locked when Application_OnEnd &
4652          Application_OnStart is called, creating a critical section
4653          for use of $Application
4654
4655         ++MLDBM::Sync used now for core DBM support in Apache::ASP::State.
4656          This drastically simplifies/stabilizes the code in there
4657          and will make it easier for future SQL database plugins.
4658
4659         +New API for accessing ASP object information in non content
4660          handler phases:
4661
4662            use Apache::ASP;
4663            sub My::Auth::handler {
4664              my $r = shift;
4665              my $ASP = Apache::ASP->new($r)
4666              my $Session = $ASP->Session;
4667            }
4668
4669          In the above example, $Session would be the same $Session
4670          object created later while running the ASP script for this
4671          same request.
4672
4673          Added t/asp_object.t test for this.  Fixed global.asa to only
4674          init StateDir when application.asp starts which is the first
4675          test script to run.
4676
4677         -Fixed on Win32 to make Apache::ASP->new($r) able to create
4678          multiple master ASP objects per request.  Was not reentrant
4679          safe before, particularly with state locking for dbms like
4680          $Application & $Session.
4681
4682         ++Output caching for includes, built on same layer ( extended )
4683          as XSLTCache, test suite at t/cache.t.  Enabled with special
4684          arguments to
4685
4686            $Response->Include(\%args, @include_args)
4687            $Response->TrapInclude(\%args, @include_args)
4688            $Server->Execute(\%args, @include_args)
4689
4690          where %args = (
4691            File => 'file.inc',
4692            Cache => 1, # to activate cache layer
4693            Expires => 3600, # to expire in one hour
4694            LastModified => time() - 600, # to expire if cached before 10 minutes ago
4695            Key => $Request->Form, # to cache based on checksum of serialized form data,
4696            Clear => 1, # to not allow fetch from cache this time, will always execute include
4697          );
4698
4699          Like the XSLTCache, it uses MLDBM::Sync::SDBM_File
4700          by default, but can use DB_File or GDBM_File if
4701          CacheDB is set to these.
4702
4703          See t/cache.t for API support until this is documented.
4704
4705         +CacheSize now supports units of M, K, B like
4706
4707           CacheSize 10M
4708           CacheSize 10240K
4709           CacheSize 10000000B
4710           CacheSize 10000000
4711
4712         -Better handling of $Session->Abandon() so multiple
4713          request to the same session while its being destroyed
4714          will have the right effect.
4715
4716         +Optimized XMLSubs parsing.  Scripts with lots lof XMLSubs
4717          now parse faster for the first time.  One test script with
4718          almost 200 such tags went from a parse time of around 3 seconds
4719          to .7 seconds after optimizations.
4720
4721         +Updated performance tuning docs, particularly for using
4722          Apache::ASP->Loader()
4723
4724         +$Server->URL($url, \%params) now handles array refs
4725          in the params values like
4726            $Server->URL($url, { key => [ qw( value1 value2 ) ] })
4727
4728          This is so that query string data found in
4729          $Request->QueryString that gets parsed into this form
4730          from a string like: ?key=value&key=value2 would be
4731          able to be reused passed back to $Server->URL to
4732          create self referencing URLs more easily.
4733
4734         -Bug fix where XMLSubs like <s:td /> now works on perl
4735          5.005xx, thanks to Philip Mak for reporting & fix.
4736
4737         +When searching for included files, will now join
4738          the absolute path of the directory of the script
4739          with the name of the file if its a relative file
4740          name like ./header.inc.  Before, would just look
4741          for something like ././header.inc by using '.'
4742          as the first directory to look for includes in.
4743
4744          The result of this is that scripts in two directories
4745          configured with the same Global setting should be able
4746          to have separate local header.inc files without causing
4747          a cached namespace collision.
4748
4749         +$Server->Config() call will return a hash ref
4750          to all the config setting for that request, like
4751          Apache->dir_config would.
4752
4753         -StatINC setting with Apache::ASP->Loader() works again.
4754          This makes StatINC & StatINCMatch settings viable
4755          for production & development use when the system has
4756          very many modules.
4757
4758         -Cookieless session support with configs like SessionQueryParse
4759          and SessionQuery now work for URLs with frags in them
4760          like http://localhost?arg=value#frag
4761
4762         +@rv = $Response->Include() now works where there are
4763          multiple return values from an include like:
4764          <% return(1,2); %>
4765
4766    $VERSION = 2.21; $DATE="8/5/2001";
4767         +Documented RequestParams config in CONFIG misc section.
4768
4769         +Documented new XSLT caching directives.
4770
4771         +Updated ./site/eg/.htaccess XSLT example config
4772          to use XSLTCache setting.
4773
4774         +New FAQ section on why perl variables are sticky globals,
4775          suggested by Mark Seger.
4776
4777         -push Global directory onto @INC during ASP script execution
4778          Protect contents of original @INC with local.  This makes
4779          things compatible with .09 Apache::ASP where we always had
4780          Global in @INC.  Fixed needed by Henrik Tougaard
4781
4782         - ; is a valid separator like & for QueryString Parameters
4783          Fixed wanted by Anders
4784
4785         -XSMLSubsMatch doc fix in CONFIG section
4786
4787         +Reduces number of Session groups to 16 from 32, so
4788          session manager for small user sets will be that much faster.
4789
4790         +optimizations for internal database, $Application, and $Session
4791          creation.
4792
4793         +XSLTCache must be set for XSLT caching to begin using CacheDir
4794
4795         +CacheDB like StateDB bug sets dbm format for caching, which
4796          defaults to MLDBM::Sync::SDBM_File, which works well for caching
4797          output sizes < 50K
4798
4799         +CacheDir config for XSLT caching ... defaults to StateDir
4800
4801         +CacheSize in bytes determines whether the caches in CacheDir
4802          are deleted at the end of the request.  A cache will be
4803          reset in this way back to 0 bytes. Defaults to 10000000 bytes
4804          or about 10M.
4805
4806         +Caching infrastructure work that is being used in XSLT
4807          can be leveraged later for output caching of includes,
4808          or arbitrary user caching.
4809
4810         -t/server_mail.t test now uses valid email for testing
4811          purposes ... doesn't actually send a mail, but for SMTP
4812          runtime validation purposes it should be OK.
4813
4814         +fixed where POST data was read from under MOD_PERL,
4815          harmless bug this was that just generated the wrong
4816          system debugging message.
4817
4818    $VERSION = 2.19; $DATE="7/10/2001";
4819         +update docs in various parts
4820
4821         +added ./make_httpd/build_httpds.sh scripts for quick builds
4822          of apache + mod_perl + mod_ssl
4823
4824         ++plain CGI mode available for ASP execution.
4825          cgi/asp script can now be used to execute ASP
4826          scripts in CGI mode.  See CGI perldoc section for more info.
4827          The examples in ./site/eg have been set up to run
4828          in cgi mode if desired.  Configuration in CGI section
4829          only tested for Apache on Linux.
4830
4831         -Fixed some faulty or out of date docs in XML/XSLT section.
4832
4833         +added t/server_mail.t test for $Server->Mail(), requires
4834          Net::SMTP to be configured properly to succeed.
4835
4836         +Net::SMTP debugging not enabled by Debug 1,2,3 configs,
4837          not only when system debugging is set with Debug -1,-2,-3
4838          However, a Debug param passed to $Server->Mail() will
4839          sucessfully override the Debug -1,-2,-3 setting even
4840          when its Debug => 0
4841
4842         -Check for undef values during stats for inline includes
4843          so we don't trigger unintialized warnings
4844
4845         +Documented ';' may separate many directories in the IncludesDir
4846          setting for creating a more flexible includes search path.
4847
4848    $VERSION = 2.17; $DATE="6/17/2001";
4849         +Added ASP perl mmm-mode subclass and configuration
4850          in editors/mmm-asp-perl.el file for better emacs support.
4851          Updated SYNTAX/Editors documentation.
4852
4853         +Better debugging error message for Debug 2 or 3 settings
4854          for global.asa errors.  Limit debug output for lines
4855          preceding rendered script.
4856
4857         -In old inline include mode, there should no longer
4858          be the error "need id for includes" when using
4859          $Response->Include() ... if DynamicIncludes were
4860          enabled, this problem would not have likely occured
4861          anyway.  DynamicIncludes are preferrable to use so
4862          that compiled includes can be shared between scripts.
4863          This bug was likely introduced in version 2.11.
4864
4865         -Removed logging from $Response->BinaryWrite() in regular
4866          debug mode 1 or 2.  Logging still enabled in system Debug mode, -1 or -2
4867
4868         -Removed other extra system debugging call that is really not
4869          necessary.
4870
4871    $VERSION = 2.15; $DATE="06/12/2001";
4872         -Fix for running under perl 5.6.1 by removing parser optimization
4873          introduced in 2.11.
4874
4875         -Now file upload forms, forms with ENCTYPE="multipart/form-data"
4876          can have multiple check boxes and select items marked for
4877          @params = $Request->Form('param_name') functionality.  This
4878          will be demonstrated via the ./site/eg/file_upload.asp example.
4879
4880    $VERSION = 2.11; $DATE="05/29/2001";
4881         +Parser optimization from Dariusz Pietrzak
4882
4883         -work around for global destruction error message for perl 5.6
4884          during install
4885
4886         +$Response->{IsClientConnected} now will be set
4887          correctly with ! $r->connection->aborted after each
4888          $Response->Flush()
4889
4890         +New XSLTParser config which can be set to XML::XSLT or
4891          XML::Sablotron.  XML::Sablotron renders 10 times faster,
4892          but differently.  XML::XSLT is pure perl, so has wider
4893          platform support than XML::Sablotron.  This config affects
4894          both the XSLT config and the $Server->XSLT() method.
4895
4896         +New $Server->XSLT(\$xsl_data, \$xml_data) API which
4897          allows runtime XSLT on components instead of having to process
4898          the entire ASP output as XSLT.
4899
4900         -XSLT support for XML::XSL 0.32.  Things broke after .24.
4901
4902         -XSLTCacheSize config no longer supported.  Was a bad
4903          Tie::Cache implementation.  Should be file based cache
4904          to greatly increases cache hit ratio.
4905
4906         ++$Response->Include(), $Response->TrapInclude(),
4907          and $Server->Execute() will all take a scalar ref
4908          or \'asdfdsafa' type code as their first argument to execute
4909          a raw script instead of a script file name.  At this time,
4910          compilation of such a script, will not be cached.  It is
4911          compiled/executed as an anonymous subroutine and will be freed
4912          when it goes out of scope.
4913
4914         + -p argument to cgi/asp script to set GlobalPackage
4915          config for static site builds
4916
4917         -pod commenting fix where windows clients are used for
4918          ASP script generation.
4919
4920         +Some nice performance enhancements, thank to submissions from
4921          Ime Smits.  Added some 1-2% per request execution speed.
4922
4923         +Added StateDB MLDBM::Sync::SDBM_File support for faster
4924          $Session + $Application than DB_File, yet still overcomes
4925          SDBM_File's 1024 bytes value limitation.  Documented in
4926          StateDB config, and added Makefile.PL entry.
4927
4928         +Removed deprecated MD5 use and replace with Digest::MD5 calls
4929
4930         +PerlSetVar InodeNames 1 config which will compile scripts hashed by
4931          their device & inode identifiers, from a stat($file)[0,1] call.
4932          This allows for script directories, the Global directory,
4933          and IncludesDir directories to be symlinked to without
4934          recompiling identical scripts.  Likely only works on Unix
4935          systems.  Thanks to Ime Smits for this one.
4936
4937         +Streamlined code internally so that includes & scripts were
4938          compiled by same code.  This is a baby step toward fusing
4939          include & script code compilation models, leading to being
4940          able to compile bits of scripts on the fly as ASP subs,
4941          and being able to garbage collect ASP code subroutines.
4942
4943         -removed @_ = () in script compilation which would trigger warnings
4944          under PerlWarn being set, thanks for Carl Lipo for reporting this.
4945
4946         -StatINC/StatINCMatch fix for not undeffing compiled includes
4947          and pages in the GlobalPackage namespace
4948
4949         -Create new HTML::FillInForm object for each FormFill
4950          done, to avoid potential bug with multiple forms filled
4951          by same object.  Thanks to Jim Pavlick for the tip.
4952
4953         +Added PREREQ_PM to Makefile.PL, so CPAN installation will
4954          pick up the necessary modules correctly, without having
4955          to use Bundle::Apache::ASP, thanks to Michael Davis.
4956
4957         + > mode for opening lock files, not >>, since its faster
4958
4959         +$Response->Flush() fixed, by giving $| = 1 perl hint
4960          to $r->print() and the rest of the perl sub.
4961
4962         +$Response->{Cookies}{cookie_name}{Expires} = -86400 * 300;
4963          works so negative relative time may be used to expire cookies.
4964
4965         +Count() + Key() Collection class API implementations
4966
4967         +Added editors/aasp.vim VIM syntax file for Apache::ASP,
4968          courtesy of Jon Topper.
4969
4970         ++Better line numbering with #line perl pragma.  Especially
4971          helps with inline includes.  Lots of work here, & integrated
4972          with Debug 2 runtime pretty print debugging.
4973
4974         +$Response->{Debug} member toggles on/off whether
4975          $Response->Debug() is active, overriding the Debug setting
4976          for this purpose.  Documented.
4977
4978         -When Filter is on, Content-Length won't be set and compression
4979          won't be used.  These things would not work with a filtering
4980          handler after Apache::ASP
4981
4982    $VERSION = 2.09; $DATE="01/30/2001";
4983         +Examples in ./site/eg are now UseStrict friendly.
4984          Also fixed up ./site/eg/ssi_filter.ssi example.
4985
4986         +Auto purge of old stale session group directories, increasing
4987          session manager performance when using Sessions when migrating
4988          to Apache::ASP 2.09+ from older versions.
4989
4990         +SessionQueryParse now works for all $Response->{ContentType}
4991          starting with 'text' ... before just worked with text/html,
4992          now other text formats like wml will work too.
4993
4994         +32 groups instead of 64, better inactive site session group purging.
4995
4996         +Default session-id length back up to 32 hex bytes.
4997          Better security vs. performance, security more important,
4998          especially when performance difference was very little.
4999
5000         +PerlSetVar RequestParams 1 creates $Request->Params
5001          object with combined contents of $Request->QueryString
5002          and $Request->Form
5003
5004         ++FormFill feature via HTML::FillInForm.  Activate with
5005          $Response->{FormFill} = 1 or PerlSetVar FormFill 1
5006          See site/eg/formfill.asp for example.
5007
5008         ++XMLSubs tags of the same name may be embedded in each other
5009          recursively now.
5010
5011         +No umask() use on Win32 as it seems unclear what it would do
5012
5013         +simpler Apache::ASP::State file handle mode of >> when opening
5014          lock file.  saves doing a -e $file test.
5015
5016         +AuthServerVariables config to init $Request->ServerVariables
5017          with basic auth data as documented.  This used to be default
5018          behavior, but triggers "need AuthName" warnings from recent
5019          versions of Apache when AuthName is not set.
5020
5021         -Renamed Apache::ASP::Loader class to Apache::ASP::Load
5022          as it collided with the Apache::ASP->Loader() function
5023          namespace.  Class used internally by Apache::ASP->Loader()
5024          so no public API changed here.
5025
5026         +-Read of POST input for $Request->BinaryRead() even
5027           if its not from a form.  Only set up $Request->Form
5028           if this is from a form POST.
5029
5030         +faster POST/GET param parsing
5031
5032    $VERSION = 2.07; $DATE="11/26/2000";
5033         -+-+ Session Manager
5034          empty state group directories are not removed, thus alleviating
5035          one potential race condition.  This impacted performance
5036          on idle sites severely as there were now 256 directories
5037          to check, so made many performance enhancements to the
5038          session manager.  The session manager is built to handle
5039          up to 20,000 client sessions over a 20 minute period.  It
5040          will slow the system down as it approaches this capacity.
5041
5042          One such enhancement was session-ids now being 11 bytes long
5043          so that its .lock file is only 16 characters in length.
5044          Supposedly some file systems lookup files 16 characters or
5045          less in a fast hashed lookup.  This new session-id has
5046          4.4 x 10^12 possible values.  I try to keep this space as
5047          large as possible to prevent a brute force attack.
5048
5049          Another enhancement was to limit the group directories
5050          to 64 by only allowing the session-id prefix to be [0-3][0-f]
5051          instead of [0-f][0-f], checking 64 empty directories on an
5052          idle site takes little time for the session manager, compared
5053          to 256 which felt significant from the client end, especially
5054          on Win32 where requests are serialized.
5055
5056          If upgrading to this version, you would do well to delete
5057          empty StateDir group directories while your site is idle.
5058          Upgrading during an idle time will have a similar effect,
5059          as old Apache::ASP versions would delete empty directories.
5060
5061         -$Application->GetSession($session_id) now creates
5062          an session object that only lasts until the next
5063          invocation of $Application->GetSession().  This is
5064          to avoid opening too many file handles at once,
5065          where each session requires opening a lock file.
5066
5067         +added experimental support for Apache::Filter 1.013
5068          filter_register call
5069
5070         +make test cases for $Response->Include() and
5071          $Response->TrapInclude()
5072
5073         +Documented CollectionItem config.
5074
5075         +New $Request->QueryString('multiple args')->Count()
5076          interface implemented for CollectionItem config.
5077          Also $Request->QueryString('multiple args')->Item(1) method.
5078          Note ASP collections start counting at 1.
5079
5080         --fixed race condition, where multiple processes might
5081          try creating the same state directory at the same time, with
5082          one winning, and one generating an error.  Now, web process
5083          will recheck for directory existence and error if
5084          it doesn't.
5085
5086         -global.asa compilation will be cached correctly, not
5087          sure when this broke.  It was getting reloaded every request.
5088
5089         -StateAllWrite config, when set creates state files
5090          with a+rw or 0666 permissions, and state directories
5091          with a+rwx or 0777 permissions.  This allows web servers
5092          running as different users on the same machine to share a
5093          common StateDir config.  Also StateGroupWrite config
5094          with perms 0770 and 0660 respectively.
5095
5096         -Apache::ASP->Loader() now won't follow links to
5097          directories when searching for scripts to load.
5098
5099         +New RegisterIncludes config which is on by default only
5100          when using Apache::ASP->Loader(), for compiling includes
5101          when precompiling scripts.
5102
5103         +Apache::ASP::CompileInclude path optimized, which underlies
5104          $Response->Include()
5105
5106         +$Request->QueryString->('foo')->Item() syntax enabled
5107          with CollectionItem config setting.  Default syntax
5108          supported is $Request->QueryString('foo') which is
5109          in compatible.  Other syntax like $Request->{Form}{foo}
5110          and $Request->Form->Item('foo') will work in either case.
5111
5112         +New fix suggested for missing Apache reference in
5113          Apache::ASP handler startup for RedHat RPMs.  Added
5114          to error message.
5115
5116         --Backup flock() unlocking try for QNX will not corrupt the
5117          normal flock() LOCK_UN usage, after trying to unlock a file
5118          that doesn't exist.  This bug was uncovered from the below
5119          group deletion race condition that existed.
5120
5121         -Session garbage collection will not delete new group
5122          directories that have just been created but are empty.
5123          There was a race condition where a new group directory would
5124          be created, but then deleted by a garbage collector before
5125          it could be initialized correctly with new state files.
5126
5127         +Better random session-id checksums for $Session creation.
5128          per process srand() initialization, because srand()
5129          may be called once prefork and never called again.
5130          Call without arguments to rely on perl's decent rand
5131          seeding.  Then when calling rand() in Secret() we have
5132          enough random data, that even if someone else calls srand()
5133          to something fixed, should not mess things up terribly since
5134          we checksum things like $$ & time, as well as perl memory
5135          references.
5136
5137         +XMLSubs installation make test.
5138
5139         -Fix for multiline arguments for XMLSubs
5140
5141    $VERSION = 2.03; $DATE="08/01/2000";
5142         +License change to GPL.  See LICENSE section.
5143
5144         +Setup of www.apache-asp.org site, finally!
5145
5146         -get rid of Apache::ASP->Loader() warning message for perl 5.6.0
5147
5148    $VERSION = 2.01; $DATE="07/22/2000";
5149         +$data_ref = $Response->TrapInclude('file.inc') API
5150          extension which allows for easy post processing of
5151          data from includes
5152
5153         +./site/eg/source.inc syntax highlighting improvements
5154
5155         +XMLSubsMatch compile time parsing performance improvement
5156
5157    $VERSION = 2.00; $DATE="07/15/2000";
5158         -UniquePackages config works again, broke a couple versions back
5159
5160         +better error handling for methods called on $Application
5161          that don't exist, hard to debug before
5162
5163    $VERSION = 1.95; $DATE="07/10/2000";
5164         !!!!! EXAMPLES SECURITY BUG FOUND & FIXED !!!!!
5165
5166         --FIXED: distribution example ./site/eg/source.asp now parses
5167          out special characters of the open() call when reading local
5168          files.
5169
5170          This bug would allow a malicious user possible writing
5171          of files in the same directory as the source.asp script.  This
5172          writing exploit would only have effect if the web server user
5173          has write permission on those files.
5174
5175          !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
5176
5177         -$0 now set to transferred file, when using $Server->Transfer
5178
5179         -Fix for XMLSubsMatch parsing on cases with 2 or more args passed
5180          to tag sub that was standalone like
5181            <Apps:header type="header" title="Moo" foo="moo" />
5182
5183    $VERSION = 1.93; $DATE="07/03/2000";
5184         -sub second timing with Time::HiRes was adding <!-- -->
5185          comments by HTML by default, which would possibly
5186          break specific programs looking for precise HTML output.
5187          Now this behavior must be explicitly turned on with
5188          the TimeHiRes config setting.
5189
5190          These comments will only appear in HTML only if
5191          Debug is enabled as well.
5192
5193          Timed log entries will only occur if
5194          system debugging is enabled, with Debug -1 or -2
5195
5196    $VERSION = 1.91; $DATE="07/02/2000";
5197         +Documented XMLSubsMatch & XSLT* configuration
5198          settings in CONFIG section.
5199
5200         +XSLT XSL template is now first executed as an
5201          ASP script just like the XML scripts.  This is
5202          just one step away now from implementing XSP logic.
5203
5204         +$Server->Execute and $Server->Transfer API extensions
5205          implemented.  Execute is the same as $Request->Include()
5206          and $Server->Transfer is like an apache internal redirect
5207          but keeps the current ASP objects for the next script.
5208
5209          Added examples, transfer.htm, and modified dynamic_includes.htm.
5210
5211         +Better compile time error debugging with Debug 2 or -2.
5212          Will hilite/link the buggy line for global.asa errors,
5213          include errors, and XML/XSLT errors just like with
5214          ASP scripts before.
5215
5216         +Nice source hiliting when viewing source for the example
5217          scripts.
5218
5219         +Runtime string writing optimization for static HTML going
5220          through $Response.
5221
5222         +New version numbering just like everyone else.  Starting at 1.91
5223          since I seem to be off by a factor of 10, last release would have
5224          been 1.9.
5225
5226    $VERSION = 0.19; $DATE="NOT RELEASED";
5227         +XMLSubsMatch and XSLT* settings documented in
5228          the XML/XSLT section of the site/README.
5229
5230         -XMLSubsMatch will strip parens in a pattern match
5231          so it does not interfere with internal matching use.
5232
5233         +XSLT integration allowing XML to be rendered by XSLT
5234          on the fly.  XSLT specifies XSL file to transform XML.
5235          XSLTMatch is a regexp that matches XML file names, like \.xml$,
5236          which will be transformed by XSLT setting, default .*
5237
5238          XSLTCacheSize when specified uses Tie::Cache to cached XML DOMs
5239          internally and cache XSLT transformations output per XML/XSL
5240          combination.  XML DOM objects can take a lot of RAM, so use
5241          this setting judiciously like setting to 100.  Definitely
5242          experiment with this value.
5243
5244         +More client info in the error mail feature, including
5245          client IP, form data, query string, and HTTP_* client headers
5246
5247         +With Time::HiRes loaded, and Debug set to non 0,
5248          will add a <!-- Apache::ASP served request in xx.xx seconds -->
5249          to text/html output, similar to Cocoon, per user request
5250          Will also add this to the system debug error log output
5251          when Debug is < 0
5252
5253         -bug fix on object initialization optimization earlier
5254          in this release, that was introduced for faster event
5255          handler execution.
5256
5257         +Apache::ASP::Parse() takes a file name, scalar, or
5258          scalar ref for arguments of data to parse for greater
5259          integration ability with other applications.
5260
5261         +PodComments optimization, small speed increase at
5262          compilation time.
5263
5264         +String optimization on internal rendering that avoids
5265          unnecessary copying of static html, by using refs.  Should
5266          make a small difference on sites with large amounts of
5267          static html.
5268
5269         +CompressGzip setting which, when Compress::Zlib is installed,
5270          will compress text/html automatically going out to the web
5271          browser if the client supports gzip encoding.
5272
5273         ++Script_OnFlush event handler, and auxiliary work optimizing
5274          asp events in general.  $Response->{BinaryRef} created which
5275          is a reference to outgoing output, which can be used
5276          to modify the data at runtime before it goes out to the client.
5277
5278         +Some code optimizations that boost speed from 22 to 24
5279          hits per second when using Sessions without $Application,
5280          on a simple hello world benchmark on a WinNT PII300.
5281
5282         ++Better SessionManagement, more aware of server farms that
5283          don't have reliable NFS locking.  The key here is to have only
5284          one process on one server in charge of session garbage collection
5285          at any one time, and try to create this situation with a snazzy
5286          CleanupMaster routine.  This is done by having a process register
5287          itself in the internal database with a server key created at
5288          apache start time.  If this key gets stale, another process can
5289          become the master, and this period will not exceed the period
5290          SessionTimeout / StateManager.
5291
5292          ** Work on session manager sponsored by LRN, http://www.lrn.com.  **
5293          ** This work was used to deploy a server farm in production with  **
5294          ** NFS mounted StateDir. Thanks to Craig Samuel for his belief in **
5295          ** open source. :)                                                **
5296
5297          Future work for server farm capabilities might include breaking
5298          up the internal database into one of 256 internal databases
5299          hashed by the first 2 chars of the session id.  Also on the plate
5300          is Apache::Session like abilities with locking and/or data storage
5301          occuring in a SQL database.  The first dbs to be done will include
5302          MySQL & Oracle.
5303
5304         +Better session security which will create a new session id for an
5305          incoming session id that does not match one already seen.  This will
5306          help for those with Search engines that have bookmarked
5307          pages with the session ids in the query strings.  This breaks away
5308          from standard ASP session id implementation which will automatically
5309          use the session id presented by the browser, now a new session id will
5310          be returned if the presented one is invalid or expired.
5311
5312         -$Application->GetSession will only return a session if
5313          one already existed.  It would create one before by default.
5314
5315         +Script_OnFlush global.asa event handler, and $Response->{BinaryRef}
5316          member which is a scalar reference to the content about to be flushed.
5317          See ./site/eg/global.asa for example usage, used in this case to
5318          insert font tags on the fly into the output.
5319
5320         +Highlighting and linking of line error when Debug is set to 2 or -2.
5321
5322         --removed fork() call from flock() backup routine? How did
5323           that get in there?  Oh right, testing on Win32. :(
5324           Very painful lesson this one, sorry to whom it may concern.
5325
5326         +$Application->SessionCount support turned off by default
5327          must enable with SessionCount config option.  This feature
5328          puts an unnecessary load on busy sites, so not default
5329          behavior now.
5330
5331         ++XMLSubsMatch setting that allows the developer to
5332          create custom tags XML style that execute perl subroutines.
5333          See ./site/eg/xml_subs.asp
5334
5335         +MailFrom config option that defaults the From: field for
5336          mails sent via the Mail* configs and $Server->Mail()
5337
5338         +$Server->Mail(\%mail, %smtp_args) API extension
5339
5340         +MailErrorsTo & MailAlertTo now can take comma
5341          separated email addresses for multiple recipients.
5342
5343         -tracking of subroutines defined in scripts and includes so
5344          StatINC won't undefine them when reloading the GlobalPackage,
5345          and so an warning will be logged when another script redefines
5346          the same subroutine name, which has been the bane of at least
5347          a few developers.
5348
5349         -Loader() will now recompile dynamic includes that
5350          have changed, even if main including script has not.
5351          This is useful if you are using Loader() in a
5352          PerlRestartHandler, for reloading scripts when
5353          gracefully restarting apache.
5354
5355         -Apache::ASP used to always set the status to 200 by
5356          default explicitly with $r->status().  This would be
5357          a problem if a script was being used to as a 404
5358          ErrorDocument, because it would always return a 200 error
5359          code, which is just wrong.  $Response->{Status} is now
5360          undefined by default and will only be used if set by
5361          the developer.
5362
5363          Note that by default a script will still return a 200 status,
5364          but $Response->{Status} may be used to override this behavior.
5365
5366         +$Server->Config($setting) API extension that allows developer
5367          to access config settings like Global, StateDir, etc., and is a
5368          wrapper around Apache->dir_config($setting)
5369
5370         +Loader() will log the number of scripts
5371          recompiled and the number of scripts checked, instead
5372          of just the number of scripts recompiled, which is
5373          misleading as it reports 0 for child httpds after
5374          a parent fork that used Loader() upon startup.
5375
5376         -Apache::ASP->Loader() would have a bad error if it didn't load
5377          any scripts when given a directory, prints "loaded 0 scripts" now
5378
5379    $VERSION = 0.18; $DATE="02/03/2000";
5380         +Documented SessionQuery* & $Server->URL() and
5381          cleaned up formatting some, as well as redoing
5382          some of the sections ordering for better readability.
5383          Document the cookieless session functionality more
5384          in a new SESSIONS section.  Also documented new
5385          FileUpload configs and $Request->FileUpload collection.
5386          Documented StatScripts.
5387
5388         +StatScripts setting which if set to 0 will not reload
5389          includes, global.asa, or scripts when changed.
5390
5391         +FileUpload file handles cleanup at garbage collection
5392          time so developer does not have to worry about lazy coding
5393          and undeffing filehandles used in code.  Also set
5394          uploaded filehandles to binmode automatically on Win32
5395          platforms, saving the developer yet more typing.
5396
5397         +FileUploadTemp setting, default 0, if set will leave
5398          a temp file on disk during the request, which may be
5399          helpful for processing by other programs, but is also
5400          a security risk in that others could potentially read
5401          this file while the script is running.
5402
5403          The path to the temp file will be available at
5404          $Request->{FileUpload}{$form_field}{TempFile}.
5405          The regular use of file uploads remains the same
5406          with the <$filehandle> to the upload at
5407          $Request->{Form}{$form_field}.
5408
5409         +FileUploadMax setting, default 0, currently an
5410          alias for $CGI::POST_MAX, which determines the
5411          max size for a file upload in bytes.
5412
5413         +SessionQueryParse only auto parses session-ids
5414          into links when a session-id COOKIE is NOT found.
5415          This feature is only enabled then when a user has
5416          disabled cookies, so the runtime penalty of this
5417          feature won't drag down the whole site, since most
5418          users will have cookies turned on.
5419
5420         -StatINC & StatINCMatch will not undef Fnctl.pm flock
5421          functions constants like O_RDWR, because the code references
5422          are not well trackable.  This would result in sporadic 500 server
5423          errors when a changed module was reloaded that imported O_* flock
5424          functions from Fnctl.
5425
5426         +SessionQueryParse & SessionQueryParseMatch
5427          settings that enable auto parsing session ids into
5428          URLs for cookieless sessions.  Will pick up URLs in
5429          <a href>, <area href>, <form action>, <frame src>,
5430          <iframe src>, <img src>, <input src>, <link href>
5431          $Response->Redirect($URL) and the first URL in
5432          script tags like <script>*.location.href=$URL</script>
5433
5434          These settings require that buffering be enabled, as
5435          Apache::ASP will parse through the buffer to parse the URLs.
5436
5437          With SessionQueryParse on, it will just parse non-absolute
5438          URLs, but with SessionQueryParseMatch set to some server
5439          url regexp, like ^http://localhost , will also parse
5440          in the session id for URLs that match that.
5441
5442          When testing, the performance hit from this parsing
5443          a script dropped from 12.5 hits/sec on my WinNT box
5444          to 11.7 hits per second for 1K of buffered output.
5445          The difference is .007 of my PII300's processing power
5446          per second.
5447
5448          For 10K of output then, my guess is that this speed
5449          of script, would be slowed to 6.8 hits per second.
5450          This kind of performance hit would also slow a
5451          script running at 40 hits per second on a UNIX box
5452          to 31 hits/sec for 1K, and to 11 hits/sec for 10K parsed.
5453
5454          Your mileage may vary and you will have to test the difference
5455          yourself.  Get yourself a valid URL with a session-id in
5456          it, and run it through ab, or Socrates, with SessionQuery
5457          turned on, and then with SessionQueryParse set to see
5458          the difference.  SessionQuery just enables of session id
5459          setting from the query string but will not auto parse urls.
5460
5461         -If buffering, Content-Length will again be set.
5462          It broke, probably while I was tuning in the past
5463          couple versions.
5464
5465         +UseStrict setting compiles all scripts including
5466          global.asa with "use strict" turned on for catching
5467          more coding errors.  With this setting enabled,
5468          use strict errors die during compilation forcing
5469          Apache::ASP to try to recompile the script until
5470          successful.
5471
5472         -Object use in includes like $Response->Write()
5473          no longer error with "use strict" programming.
5474
5475         +SessionQuery config setting with $Server->URL($url, { %params } )
5476          alpha API extensions to enable cookieless sessions.
5477
5478         +Debugging not longer produces internal debugging
5479          by default.  Set to -1,-2 for internal debugging
5480          for Debug settings 1 & 2.
5481
5482         +Both StateSerializer & StateDB can be changed
5483          without affecting a live web site, by storing
5484          the configurations for $Application & $Session
5485          in an internal database, so that if $Session was
5486          created with SDBM_File for the StateDB (default),
5487          it will keep this StateDB setting until it ends.
5488
5489         +StateSerializer config setting.  Default Data::Dumper,
5490          can also be set to Storable.  Controls how data is
5491          serialized before writing to $Application & $Session.
5492
5493         +Beefed up the make test suite.
5494
5495         +Improved the locking, streamlining a bit of the
5496          $Application / $Session setup process.  Bench is up to
5497          22 from 21 hits / sec on dev NT box.
5498
5499         +Cut more fat for faster startup, now on my dev box
5500          I get 44 hits per sec Apache::ASP vs. 48 Embperl
5501          vs. 52 CGI via Apache::Registry for the HelloWorld Scripts.
5502
5503         -Improved linking for the online site documentation,
5504          where a few links before were bad.
5505
5506    $VERSION = 0.17; $DATE="11/15/99";
5507         ++20%+ faster startup script execution, as measured by the
5508          HelloWorld bench.  I cut a lot of the fat out of
5509          the code, and is now at least 20% faster on startup
5510          both with and without state.
5511
5512          On my dev (NT, apache 1.3.6+mod_perl) machine, I now get:
5513
5514                42 hits per sec on Apache::ASP HelloWorld bench
5515                46 hits per sec on Embperl (1.2b10) and
5516                51 hits per sec for CGI Apache::Registry scripts
5517
5518          Before Apache::ASP was clocking some 31 hits per sec.
5519          Apache::ASP also went from 75 to 102 hits per second
5520          on Solaris.
5521
5522         +PerlTaintCheck On friendly.  This is mod_perl's way
5523          of providing -T taint checking.  When Apache::ASP
5524          is used with state objects like $Session or $Application,
5525          MLDBM must also be made taint friendly with:
5526
5527            $MLDBM::RemoveTaint = 1;
5528
5529          which could be put in the global.asa.  Documented.
5530
5531         +Added $Response->ErrorDocument($error_code, $uri_or_string)
5532          API extension which allows for setting of Apache's error
5533          document at runtime.  This is really just a wrapper
5534          for Apache->custom_response() renamed so it syncs with
5535          the Apache ErrorDocument config setting.  Updated
5536          documentation, and added error_document.htm example.
5537
5538         =OrderCollections setting was added, but then REMOVED
5539          because it was not going to be used.  It bound
5540          $Request->* collections/hashes to Tie::IxHash, so that data
5541          in those collections would be read in the order the
5542          browser sent it, when eaching through or with keys.
5543
5544         -global.asa will be reloaded when changed.  This broke
5545          when I optimized the modification times with (stat($file))[9]
5546          rather than "use File::stat; stat($file)->mtime"
5547
5548         -Make Apache::ASP->Loader() PerlRestartHandler safe,
5549          had some unstrict code that was doing the wrong thing.
5550
5551         -IncludesDir config now works with DynamicIncludes.
5552
5553         +DebugBufferLength feature added, giving control to
5554          how much buffered output gets shown when debugging errors.
5555
5556         ++Tuning of $Response->Write(), which processes all
5557          static html internally, to be almost 50% faster for
5558          its typical use, when BufferingOn is enabled, and
5559          CgiHeaders are disabled, both being defaults.
5560
5561          This can show significant speed improvements for tight
5562          loops that render ASP output.
5563
5564         +Auto linking of ./site/eg/ text to example scripts
5565          at web site.
5566
5567         +$Application->GetSession($session_id) API extension, useful
5568          for managing active user sessions when storing session ids
5569          in $Application.  Documented.
5570
5571         -disable use of flock() on Win95/98 where it is unimplemented
5572
5573         -@array context of $Request->Form('name') returns
5574          undef when value for 'name' is undefined.  Put extra
5575          logic in there to make sure this happens.
5576
5577    $VERSION = 0.16; $DATE="09/22/99";
5578         -$Response->{Buffer} and PerlSetVar BufferingOn
5579          configs now work when set to 0, to unbuffer output,
5580          and send it out to the web client as the script generates it.
5581
5582          Buffering is enabled by default, as it is faster, and
5583          allows a script to error cleanly in the middle of execution.
5584
5585         +more bullet proof loading of Apache::Symbol, changed the
5586          way Apache::ASP loads modules in general.  It used to
5587          check for the module to load every time, if it hadn't loaded
5588          successfully before, but now it just tries once per httpd,
5589          so the web server will have to be restarted to see new installed
5590          modules.  This is just for modules that Apache::ASP relies on.
5591
5592          Old modules that are changed or updated with an installation
5593          are still reloaded with the StatINC settings if so configured.
5594
5595         +ASP web site wraps <font face="courier new"> around <pre>
5596          tags now to override the other font used for the text
5597          areas.  The spacing was all weird in Netscape before
5598          for <pre> sections.
5599
5600         -Fixed Content-Length calculation when using the Clean
5601          option, so that the length is calculated after the HTML
5602          is clean, not before.  This would cause a browser to
5603          hang sometimes.
5604
5605         +Added IncludesDir config option that if set will also be
5606          used to check for includes, so that includes may easily be
5607          shared between applications.  By default only Global and
5608          the directory the script is in are checked for includes.
5609
5610          Also added IncludesDir as a possible configuration option
5611          for Apache::ASP->Loader()
5612
5613         -Re-enabled the Application_OnStart & OnEnd events, after
5614          breaking them when implementing the AllowApplicationState
5615          config setting.
5616
5617         +Better pre-fork caching ... StatINC & StatINCMatch are now
5618          args for Apache::ASP->Loader(), so StatINC symbols loading
5619          may be done pre-fork and shared between httpds.  This lowers
5620          the child httpd init cost of StatINC.  Documented.
5621
5622         +Made Apache::ASP Basic Authorization friendly so authentication
5623          can be handled by ASP scripts.  If AuthName and AuthType Apache
5624          config directives are set, and a $Response->{Status} is set to
5625          401, a user will be prompted for username/password authentication
5626          and the entered data will show up in ServerVariables as:
5627            $env = $Request->ServerVariables
5628            $env->{REMOTE_USER} = $env->{AUTH_USER} = username
5629            $env->{AUTH_PASSWD} = password
5630            $env->{AUTH_NAME}   = your realm
5631            $env->{AUTH_TYPE}   = 'Basic'
5632
5633          This is the same place to find auth data as if Apache had some
5634          authentication handler deal with the auth phase separately.
5635
5636         -MailErrorsTo should report the right file now that generates
5637          the error.
5638
5639    $VERSION = 0.15; $DATE="08/24/1999";
5640         --State databases like $Session, $Application are
5641          now tied/untied to every lock/unlock triggered by read/write
5642          access.  This was necessary for correctness issues, so that
5643          database file handles are flushed appropriately between writes
5644          in a highly concurrent multi-process environment.
5645
5646          This problem raised its ugly head because under high volume,
5647          a DB_File can become corrupt if not flushed correctly.
5648          Unfortunately, there is no way to flush SDBM_Files & DB_Files
5649          consistently other than to tie/untie the databases every access.
5650
5651          DB_File may be used optionally for StateDB, but the default is
5652          to use SDBM_File which is much faster, but limited to 1024 byte
5653          key/value pairs.
5654
5655          For SDBM_Files before, if there were too many concurrent
5656          writes to a shared database like $Application, some of the
5657          writes would not be saved because another process
5658          might overwrite the changes with its own.
5659
5660          There is now a 10 fold performance DECREASE associated
5661          with reading from and writing to files like $Session
5662          and $Application.  With rough benchmarks I can get about
5663          100 increments (++) now per second to $Session->{count}, where
5664          before I could get 1000 increments / second.
5665
5666          You can improve this if you have many reads / writes happening
5667          at the same time, by placing locking code around the group like
5668
5669                $Session->Lock();
5670                $Session->{count}++;
5671                $Session->{count}++;
5672                $Session->{count}++;
5673                $Session->UnLock();
5674
5675          This method will reduce the number of ties to the $Session database
5676          from 6 to 1 for this kind of code, and will improve the performance
5677          dramatically.
5678
5679          Also, instead of using explicit $Session locking, you can
5680          create an automatic lock on $Session per script by setting
5681          SessionSerialize in your config to 1.  The danger here is
5682          if you have any long running scripts, the user will have
5683          to wait for it to finish before another script can be run.
5684
5685          To see the number of lock/unlocks or ties/unties to each database
5686          during a script execution, look at the last lines of debug output
5687          to your error log when Debug is set to 1.  This can help you
5688          performance tweak access to these databases.
5689
5690         +Updated documentation with new config settings and
5691          API extensions.
5692
5693         +Added AllowApplicationState config option which allows
5694          you to leave $Application undefined, and will not
5695          execute Application_OnStart or Application_OnEnd.
5696          This can be a slight performance increase of 2-3% if
5697          you are not using $Application, but are using $Session.
5698
5699         +Added $Session->Lock() / $Session->UnLock() API routines
5700          necessary additions since access to session is not
5701          serialized by default like IIS ASP.  Also prompted
5702          by change in locking code which retied to SDBM_File
5703          or DB_File each lock.  If you $Session->Lock / UnLock
5704          around many read/writes, you will increase performance.
5705
5706         +Added StateCache config which, if set will cache
5707          the file handle locks for $Application and an internal
5708          database used for tracking $Session info.  This caching can
5709          make an ASP application perform up to 10% faster,
5710          at a cost of each web server process holding 2 more
5711          cached file handles open, per ASP application using
5712          this configuration.  The data written to or read from
5713          these state databases is not cached, just the locking
5714          file handles are held open.
5715
5716         -Added in much more locking in session manager
5717          and session garbage collector to help avoid collisions
5718          between the two.  There were definite windows that the
5719          two would collide in, during which bad things could
5720          happen on a high volume site.
5721
5722         -Fixed some warnings in DESTROY and ParseParams()
5723
5724    $VERSION = 0.14; $DATE="07/29/1999";
5725         -CGI & StatINC or StatINCMatch would have bad results
5726          at times, with StatINC deleting dynamically compiled
5727          CGI subroutines, that were imported into other scripts
5728          and modules namespaces.
5729
5730          A couple tweaks, and now StatINC & CGI play nice again ;)
5731          StatINCMatch should be safe to use in production with CGI.
5732          This affects in particular environments that use file upload,
5733          since CGI is loaded automatically by Apache::ASP to handle
5734          file uploads.
5735
5736          This fix should also affect other seemingly random
5737          times when StatINC or StatINCMatch don't seem to do
5738          the right thing.
5739
5740         +use of ASP objects like $Response are now "use strict"
5741          safe in scripts, while UniquePackages config is set.
5742
5743         +Better handling of "use strict" errors in ASP scripts.
5744          The error is detected, and the developer is pointed to the
5745          Apache error log for the exact error.
5746
5747          The script with "use strict" errors will be recompiled again.  Its seems
5748          though that "use strict" will only throw its error once, so that a script
5749          can be recompiled with the same errors, and work w/o any use strict
5750          error messaging.
5751
5752    $VERSION = 0.12; $DATE="07/01/1999";
5753         -Compiles are now 10 +times faster for scripts with lots of big
5754          embedded perl blocks <% #perl %>
5755
5756          Compiles were slow because of an old PerlScript compatibility
5757          parsing trick where $Request->QueryString('hi')->{item}
5758          would be parsed to $Request->QueryString('hi') which works.
5759          I think the regexp that I was using had O(n^2) characteristics
5760          and it took a really big perl block to 10 +seconds to parse
5761          to understand there was a problem :(
5762
5763          I doubt anyone needed this compatibility, I don't even see
5764          any code that looks like this in the online PerlScript examples,
5765          so I've commented out this parsing trick for now.  If you
5766          need me to bring back this functionality, it will be in the
5767          form of a config setting.
5768
5769          For information on PerlScript compatibility, see the PerlScript
5770          section in the ASP docs.
5771
5772         -Added UniquePackages config option, that if set brings back
5773          the old method of compiling each ASP script into its own
5774          separate package.  As of v.10, scripts are compiled by default
5775          into the same package, so that scripts, dynamic includes & global.asa
5776          can share globals.  This BROKE scripts in the same ASP Application
5777          that defined the same sub routines, as their subs would redefine
5778          each other.
5779
5780          UniquePackages has scripts compiled into separate perl packages,
5781          so they may define subs with the same name, w/o fear of overlap.
5782          Under this settings, scripts will not be able to share globals.
5783
5784         -Secure field for cookies in $Response->Cookies() must be TRUE to
5785          force cookie to be secure.  Before, it just had to be defined,
5786          which gave wrong behavior for Secure => 0.
5787
5788         +$Response->{IsClientConnected} set to one by default.  Will
5789          work out a real value when I upgrade to apache 1.3.6.  This
5790          value has no meaning before, as apache aborts the perl code
5791          when a client drops its connection in earlier versions.
5792
5793         +better compile time debugging of dynamic includes, with
5794          Debug 2 setting
5795
5796         +"use strict" friendly handling of compiling dynamic includes
5797          with errors
5798
5799    $VERSION = 0.11; $DATE="06/24/1999";
5800         +Lots of documentation updates
5801
5802         +The MailHost config option is the smtp server used for
5803          relay emails for the Mail* config options.
5804
5805         +MailAlertTo config option used for sending a short administrative
5806          alert for an internal ASP error, server code 500.  This is the
5807          compliment to MailErrorsTo, but is suited for sending a to a
5808          small text based pager.  The email sent by MailErrorsTo would
5809          then be checked by the web admin for quick response & debugging
5810          for the incident.
5811
5812          The MailAlertPeriod config specifies the time in minutes during
5813          which only one alert will be sent, which defaults to 20.
5814
5815         +MailErrorsTo config options sends the results of a 500 error
5816          to the email address specified as if Debug were set to 2.
5817          If Debug 2 is set, this config will not be on, as it is
5818          for production use only.  Debug settings less than 2 only
5819          log errors to the apache server error log.
5820
5821         -StatINCMatch / StatINC can be used in production and work
5822          even after a server graceful restart, which is essential for
5823          a production server.
5824
5825         -Content-Length header is set again, if BufferingOn is set, and
5826          haven't $Response->Flush()'d.  This broke when I introduce
5827          the Script_OnEnd event handler.
5828
5829         +Optimized reloading of the GlobalPackage perl module upon changes,
5830          so that scripts and dynamic includes don't have to be recompiled.
5831          The global.asa will still have to be though.  Since we started
5832          compiling all routines into a package that can be named with
5833          GlobalPackage, we've been undeffing compiled scripts and includes
5834          when the real GlobalPackage changed on disk, as we do a full sweep
5835          through the namespace.  Now, we skip those subs that we know to
5836          be includes or scripts.
5837
5838         -Using Apache::Symbol::undef() to undefine precompiled scripts
5839          and includes when reloading those scripts.  Doing just an undef()
5840          would sometimes result in an "active subroutine undef" error.
5841          This bug came out when I started thrashing the StatINC system
5842          for production use.
5843
5844         +StatINCMatch setting created for production use reloading of
5845          perl modules.  StatINCMatch allows StatINC reloading of a
5846          subset of all the modules defined in %INC, those that match
5847          $module =~ /$StatINCMatch/, where module is some module name
5848          like Class/Struct.pm
5849
5850         +Reoptimized pod comment parsing.  I slowed it down to sync
5851          lines numbers in the last version, but found another corner I could cut.
5852
5853    $VERSION = 0.10; $DATE="05/24/1999";
5854         += improvement; - = bug fix
5855
5856         +Added index.html file to ./eg to help people wade through
5857          the examples.  This one has been long overdue.
5858
5859         +Clean config option, or setting $Response->{Clean} to 1 - 9,
5860          uses HTML::Clean to compress text/html output of ASP scripts.
5861          I like the Clean 1 setting which is lightweight, stripping
5862          white space for about 10% compression, at a cost of less than
5863          a 5% performance penalty.
5864
5865         +Using pod style commenting no longer confuses the line
5866          numbering.  ASP script line numbers are almost exactly match
5867          their compiled perl version, except that normal inline includes
5868          (not dynamic) insert extra text which can confuse line numbering.
5869          If you want perl error line numbers to entirely sync with your
5870          ASP scripts, I would suggest learning how to use dynamic includes,
5871          as opposed to inline includes.
5872
5873         -Wrapped StatINC reloading of libs in an eval, and capturing
5874          error for Debug 2 setting.  This makes changing libs with StatINC
5875          on a little more friendly when there are errors.
5876
5877         -$Request->QueryString() now stores multiple values for the
5878          same key, just as $Request->Form() has since v.07.  In
5879          wantarray() context like @vals = $Request->QueryString('dupkey'),
5880          @vals will store whatever values where associated with dupkey
5881          in the query string like (1,2) from: ?dupkey=1&dupkey=2
5882
5883         +The GlobalPackage config directive may be defined
5884          to explicitly set the perl module that all scripts and global.asa
5885          are compiled into.
5886
5887         -Dynamic includes may be in the Global directory, just like
5888          normal includes.
5889
5890         +Perl script generated from asp scripts should match line
5891          for line, seen in errors, except when using inline (default)
5892          includes, pod comments, or <% #comment %> perl comments, which
5893          will throw off the line counts by adding text, removing
5894          text, or having an extra newline added, respectively.
5895
5896         -Script_OnEnd may now send output to the browser.  Before
5897          $main::Response->End() was being called at the end of the
5898          main script preventing further output.
5899
5900        ++All scripts are compiled as routines in a namespace uniquely defined
5901        by the global.asa of the ASP application. Thus, scripts, includes, and
5902        global.asa routines will share all globals defined in the global.asa
5903        namespace. This means that globals between scripts will be shared, and
5904        globals defined in a global.asa will be available to scripts.
5905
5906          Scripts used to have their own namespace, thus globals
5907          were not shared between them.
5908
5909         +a -o $output_dir switch on the ./cgi/asp script allows
5910          it to execute scripts and write their output to an output
5911          directory.  Useful for building static html sites, based on
5912          asp scripts.  An example use would be:
5913
5914            asp -b -o out *.asp
5915
5916          Without an output directory, script output is written to STDOUT
5917
5918    $VERSION = 0.09; $DATE="04/22/1999";
5919         +Updated Makefile.PL optional modules output for CGI & DB_File
5920
5921         +Improved docs on $Response->Cookies() and $Request->Cookies()
5922
5923         +Added PERFORMANCE doc to main README, and added sub section
5924          on precompiling scripts with Apache::ASP->Loader()
5925
5926         +Naming of CompileIncludes switched over to DynamicIncludes
5927          for greater clarity.
5928
5929         +Dynamic includes can now reference ASP objects like $Session
5930          w/o the $main::* syntax.  These subs are no longer anonymous
5931          subs, and are now compiled into the namespace of the global.asa package.
5932
5933         +Apache::ASP->Loader() precompiles dynamic includes too. Making this work
5934          required fixing some subtle bugs / dependencies in the compiling process.
5935
5936         +Added Apache::ASP->Loader() similar to Apache::RegistryLoader for
5937          precompiling ASP scripts.  Precompile a whole site at server
5938          startup with one function call.
5939
5940         +Prettied the error messaging with Debug 2.
5941
5942         +$Response->Debug(@args) debugging extension, which
5943          allows a developer to hook into the module's debugging,
5944          and only have @args be written to error_log when Debug is greater
5945          than 0.
5946
5947         -Put write locking code around State writes, like $Session
5948          and $Application.  I thought I fixed this bug a while ago.
5949
5950         -API change: converted $Session->Timeout() and $Session->SessionID()
5951          methods into $Session->{Timeout} and $Session->{SessionID} properties.
5952          The use of these properties as methods is deprecated, but
5953          backwards compatibility will remain.  Updated ./eg/session.asp
5954          to use these new properties.
5955
5956         +Implemented $Response->{PICS} which if set sends out a PICS-Label
5957          HTTP header, useful for ratings.
5958
5959         +Implemented $Response->{CacheControl} and $Response->{Charset} members.
5960          By default, CacheControl is 'private', and this value gets sent out
5961          every request as HTTP header Cache-Control.  Charset appends itself
5962          onto the content type header.
5963
5964         +Implemented $Request->BinaryRead(), $Request->{TotalBytes},
5965          documented them, and updated ./eg/form.asp for an example usage.
5966
5967         +Implemented $Response->BinaryWrite(), documented, and created
5968          and example in ./eg/binary_write.htm
5969
5970         +Implemented $Server->MapPath() and created example of its use
5971          in ./eg/server.htm
5972
5973         -$Request->Form() now reads file uploads correctly with
5974          the latest CGI.pm, where $Request->Form('file_field') returns
5975          the actual file name uploaded, which can be used as a file handle
5976          to read in the data.  Before, $Request->Form('file_field') would
5977          return a glob that looks like *Fh::filename, so to get the file
5978          name, you would have to parse it like =~ s/^\*Fh\:\://,
5979          which you no longer have to do.  As long as parsing was done as
5980          mentioned, the change should be backwards compatible.
5981
5982         +Updated  +enhanced documentation on file uploads.  Created extra
5983          comments about it as an FAQ, and under $Response->Form(), the latter
5984          being an obvious place for a developer to look for it.
5985
5986         +Updated ./eg/file_upload.asp to show use of non file form data,
5987          with which we had a bug before.
5988
5989         +Finished retieing *STDIN to cached STDIN contents, so that
5990          CGI input routines may be used transparently, along side with
5991          use of $Request->Form()
5992
5993         +Cleaned up and optimized $Request code
5994
5995         +Updated documentation for CGI input & file uploads.  Created
5996          file upload FAQ.
5997
5998         +Reworked ./eg/cgi.htm example to use CGI input routines
5999          after doing a native read of STDIN.
6000
6001         ++Added dynamic includes with <!--include file=file args=@args-->
6002          extension.  This style of include is compiled as an anonymous sub &
6003          cached, and then executed with @args passed to the subroutine for
6004          execution.  This is include may also be rewritten as a new API
6005          extension: $Response->Include('file', @args)
6006
6007         +Added ./eg/compiled_includes.htm example documenting new dynamic includes.
6008
6009         +Documented SSI: native file includes, and the rest with filtering
6010          to Apache::SSI
6011
6012         +Turned the documentation of Filter config to value of Off so
6013          people won't cut and paste the On config by default.
6014
6015         +Added SecureSession config option, which forces session cookie to
6016          be sent only under https secured www page requests.
6017
6018         +Added StateDB config option allows use of DB_File for $Session, since
6019          default use of SDBM_File is limited.  See StateDB in README.
6020
6021         +file include syntax w/o quotes supported like <!--#include file=test.inc-->
6022
6023         +Nested includes are supported, with includes including each other.
6024          Recursive includes are detected and errors out when an include has been
6025          included 100 times for a script.  Better to quit early than
6026          have a process spin out of control. (PORTABLE ? probably not)
6027
6028         +Allow <!--include file=file.inc--> notation w/o quotes around file names
6029
6030         -PerlSetEnv apache conf setting now get passed through to
6031          $Request->ServerVariables. This update has ServerVariables
6032          getting data from %ENV instead of $r->cgi_env
6033
6034         +README FAQ for PerlHandler errors
6035
6036    $VERSION = 0.08; $DATE="02/06/1999";
6037         ++SSI with Apache::Filter & Apache::SSI, see config options & ./eg files
6038          Currently filtering only works in the direction Apache::ASP -> Apache::SSI,
6039          will not work the other way around, as SSI must come last in a set of filters
6040
6041         +SSI file includes may reference files in the Global directory, better
6042          code sharing
6043
6044         - <% @array... %> no longer dropped from code.
6045
6046         +perl =pod comments are stripped from script before compiling, and associated
6047          PodComments configuration options.
6048
6049         +Command line cgi/asp script takes various options, and allows execution
6050          of multiple asp scripts at one time.  This script should be used for
6051          command line debugging.  This is also the beginning of building
6052          a static site from asp scripts with the -b option, suppressing headers.
6053
6054         +$Response->AddHeader('Set-Cookie') works for multiple cookies.
6055
6056         -$Response->Cookies('foo', '0') works, was dropping 0 because of boolean test
6057
6058         -Fixed up some config doc errors.
6059
6060    $VERSION = 0.07; $DATE="01/20/1999";
6061         -removed SIG{__WARN__} handler, it was a bad idea.
6062
6063         -fixes file locking on QNX, work around poor flock porting
6064
6065         +removed message about Win32::OLE on UNIX platforms from Makefile.PL
6066
6067         -Better lock garbage collection.  Works with StatINC seamlessly.
6068
6069         -Multiple select forms now work in array context with $Response->Form()
6070                @values = $Response->Form('multi');
6071
6072         -Better CGI.pm compatibility with $r->header_out('Content-type'),
6073          improved garbage collection under modperl, esp. w/ file uploads
6074
6075    $VERSION = 0.06; $DATE="12/21/1998";
6076         +Application_OnStart & Application_OnEnd event handlers support.
6077
6078         -Compatible with CGI.pm 2.46 headers()
6079
6080         -Compatible with CGI.pm $q = new CGI({}), caveat: does not set params
6081
6082         +use strict; followed by use of objects like $Session is fine.
6083
6084         -Multiple cookies may be set per script execution.
6085
6086         +file upload implemented via CGI.pm
6087
6088         ++global.asa implemented with events Session_OnStart and Session_OnEnd
6089          working appropriately.
6090
6091         +StateDir configuration directive implemented.
6092          StateDir allows the session state directory to be specified separately
6093          from the Global directory, useful for operating systems with caching file
6094          systems.
6095
6096         +StateManager config directive.  StateManager specifies how frequently
6097          Sessions are cleaned up, with 10 (default) meaning that old Sessions
6098          will be cleaned up 10 times per SessionTimeout period (default 20 minutes).
6099
6100         +$Application->SessionCount() implemented, non-portable method.
6101                : returns the number of currently active sessions
6102
6103         -STOP button fix.  Users may hit STOP button during script
6104          execution, and Apache::ASP will cleanup with a routine registered
6105          in Apache's $r->register_cleanup.  Works well supposedly.
6106
6107         +PerlScript compatibility work, trying to make ports smoother.
6108                : Collection emulator, no ->{Count} property
6109                : $.*(.*)->{Item} parsed automatically,
6110                  shedding the ->{Item} for Collection support (? better way ?)
6111                : No VBScript dates support, just HTTP RFC dates with HTTP::Date
6112                : Win32::OLE::in not supported, just use "keys %{$Collection}"
6113
6114         +./cgi/asp script for testing scripts from the command line
6115                : will be upgraded to CGI method of doing asp
6116                : is not "correct" in anyway, so not documented for now
6117                  but still useful
6118
6119         +strips DOS carriage returns from scripts automatically, so that
6120          programs like FrontPage can upload pages to UNIX servers
6121          without perl choking on the extra \r characters.
6122
6123    $VERSION = 0.05; $DATE="10/19/1998";
6124         +Added PERFORMANCE doc, which includes benchmarks  +hints.
6125
6126         +Better installation warnings and errors for other modules required.
6127
6128         -Turned off StatINC in eg/.htaccess, as not everyone installs Devel::Symdump
6129
6130         -Fixed AUTOLOAD state bug, which wouldn't let you each through state
6131          objects, like %{$Session}, or each %$Session, (bug introduced in v.04)
6132
6133         +Parses ASP white space better.  HTML output matches author's intent
6134          by better dealing with white space surrounding <% perl blocks %>
6135
6136         -Scalar insertion code <%=$foo%> can now span many lines.
6137
6138         +Added include.t test script for includes.
6139
6140         +Script recompiles when included files change.
6141
6142         +Files can be included in script with
6143          SSI <!--#include file="filename"--> syntax, needs to be
6144          done in ASP module to allow compilation of included code and html
6145          into script.  Future chaining with Apache::SSI will allow static
6146          html includes, and other SSI directives
6147
6148    $VERSION = 0.04; $DATE="10/14/1998";
6149         +Example script eg/cgi.htm demonstrating CGI.pm use for output.
6150
6151         +Optimized ASP parsing, faster and more legible executing code
6152                : try 'die();' in code with setting PerlSetVar Debug 2
6153
6154         +Cleaned up code for running with 'use strict'
6155
6156         -Fixed directory handle leak on Solaris, from not closing after opendir()
6157
6158         +StatINC overhaul.  StatINC setting now works as it should, with
6159          the caveat that exported functions will not be refreshed.
6160
6161         +NoState setting optimization, disallows $Application & $Session
6162
6163         +$Application->*Lock() functions implemented
6164
6165         -SoftRedirect setting for those who want scripts to keep running
6166          after a Redirect()
6167
6168         +SessionSerialize setting to lock session while script is running
6169                : Microsoft ASP style session locking
6170                : For a session, scripts execute one at a time
6171                : NOT recommended use, please see note.
6172
6173         -MLDBM can be used for other things without messing up internal use
6174                : before if it was used with different DB's and serializers,
6175                  internal state could be lost.
6176
6177         --State file locking.  Corruption worries, and loss of data no more.
6178
6179         +CGI header support, developer can use CGI.pm for *output*, or just print()
6180                : print "Set-Cookie: test=cookie\n", and things will just work
6181                : use CGI.pm for output
6182                : utilizes $r->send_cgi_header(), thanks Doug!
6183
6184         +Improved Cookie implementation, more flexible and complete
6185                - Domain cookie key now works
6186                : Expire times now taken from time(), and relative time in sec
6187                : Request->Cookies() reading more flexible, with wantarray()
6188                  on hash cookie values, %hash = $Request->Cookie('test');
6189
6190         -make test module naming correction, was t.pm, now T.pm for Unix
6191
6192         +POD / README cleanup, formatting and HTML friendly.
6193
6194    $VERSION = 0.03; $DATE="09/14/1998";
6195         +Installation 'make test' now works
6196
6197         +ActiveX objects on Win32 implemented with $Server->CreateObject()
6198
6199         +Cookies implemented: $Response->Cookies() & $Request->Cookies()
6200
6201         -Fixed $Response object API, converting some methods to object members.
6202          Deprecated methods, but backwards compatible.
6203
6204         +Improved error messaging, debug output
6205
6206         +$, influences $Response->Write(@strings) behavior
6207
6208         +perl print() works, sending output to $Response object
6209
6210         +$Response->Write() prints scalars, arrays, and hashes.  Before only scalars.
6211
6212         +Begin implementation of $Server object.
6213
6214         +Implemented $Response->{Expires} and $Response->{ExpiresAbsolute}
6215
6216         +Added "PerlSetVar StatINC" config option
6217
6218         +$0 is aliased to current script filename
6219
6220         +ASP Objects ($Response, etc.) are set in main package
6221          Thus notation like $main::Response->Write() can be used anywhere.
6222
6223    $VERSION = 0.02; $DATE="07/12/1998";
6224         ++Session Manager, won't break under denial of service attack
6225
6226         +Fleshed out $Response, $Session objects, almost full implementation.
6227
6228         +Enormously more documentation.
6229
6230         -Fixed error handling with Debug = 2.
6231
6232         -Documentation fixed for pod2man support.  README now more man-like.
6233
6234         -Stripped \r\n dos characters from installation files
6235
6236         -755 mode set for session state directory when created
6237
6238         -Loads Win32/OLE properly, won't break with UNIX
6239
6240    $VERSION = 0.01; $DATE="06/26/1998";
6241         Syntax Support
6242         --------------
6243         Initial release, could be considered alpha software.
6244         Allows developers to embed perl in html ASP style.
6245
6246         <!-- sample here -->
6247         <html>
6248         <body>
6249         <% for(1..10) { %>
6250                counting: <%=$_%> <br>
6251         <% } %>
6252         </body>
6253         </html>
6254
6255         ASP Objects
6256         -----------
6257         $Session, $Application, $Response, $Request objects available
6258         for use in asp pages.
6259
6260         $Session & $Application data is preserved using SDBM files.
6261
6262         $Session id's are tracked through the use of cookies.
6263
6264         Security
6265         --------
6266         Timeouts any attempt to use a session id that doesn't already
6267         exist.  Should stop hackers, since there is no wire speed guessing
6268         cookies.
6269
6270LICENSE
6271    Copyright (c) 1998-2018, Josh Chamas
6272
6273    All rights reserved. This program is free software; you can redistribute it
6274    and/or modify it under the same terms as Perl itself.
6275
6276    Apache::ASP is a perl native port of Active Server Pages for Apache and
6277    mod_perl.
6278
6279