2_0_13 release branch git-svn-id: https://svn.apache.org/repos/asf/perl/modperl/branches/release@1913168 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/2_0_13/BRANCHING b/2_0_13/BRANCHING new file mode 100644 index 0000000..ccb962f --- /dev/null +++ b/2_0_13/BRANCHING
@@ -0,0 +1,81 @@ +This doc explains how to create/work/re-merge svn branches + +####################################### +### PREREQUISITE ### +####################################### + +You need to have svnmerge installed and working +before you can proceed with rest of the instructions. + +You can find it here: + +http://www.orcaware.com/svn/wiki/Svnmerge.py + +####################################### +### make a new branch ### +####################################### + +we will create a branch mybranch + +branch: + + svn copy https://svn.apache.org/repos/asf/perl/modperl/trunk \ + https://svn.apache.org/repos/asf/perl/modperl/branches/mybranch \ + -m "creating mybranch" + +check out: + + svn co https://svn.apache.org/repos/asf/perl/modperl/branches/mybranch + +change externals to point to the new A-T branch (if one was done) + + svn propedit svn:externals . + +initialize svnmerge tracking in the branch (if you plan to pull trunk/ changes into the branch) + +mybranch/ $> svnmerge init +property 'svnmerge-integrated' set on '.' +mybranch/ $> svn ci -F svnmerge-commit-message.txt + + +initialize svnmerge tracking on the trunk: + +trunk/ $> svnmerge init https://svn.apache.org/repos/asf/perl/modperl/branches/mybranch +property 'svnmerge-integrated' set on '.' +mybranch/ $> svn ci -F svnmerge-commit-message.txt + + +############################################## +### merging changes from branch to brahch ### +############################################## + +Work from a clean checkout of the branch you want to merge *to* + +Check on the availability of changes to merge + +$> svnmerge avail -b -l + +------------------------------------------------------------------------ +r584362 | gozer | 2007-10-12 21:00:47 -0700 (Fri, 12 Oct 2007) | 1 line +Changed paths: + A /perl/modperl/branches/mybranch (from /perl/modperl/trunk:584361) + +creating mybranch +------------------------------------------------------------------------ +r584363 | gozer | 2007-10-12 21:05:32 -0700 (Fri, 12 Oct 2007) | 3 lines +Changed paths: + M /perl/modperl/branches/mybranch + +Initialized merge tracking via "svnmerge" with revisions "1-584361" from +https://svn.apache.org/repos/asf/perl/modperl/trunk + +Then merge the ones you want to merge + +$> svnmerge -r 584362-584363 + +review the changes, fix conflicts, etc + +Check in the merged version + +$> svn ci -F svnmerge-commit-message.txt +
diff --git a/2_0_13/CONTRIBUTING.md b/2_0_13/CONTRIBUTING.md new file mode 100644 index 0000000..b507419 --- /dev/null +++ b/2_0_13/CONTRIBUTING.md
@@ -0,0 +1,59 @@ +# How to Contribute + +Help with mod_perl is always welcome. You do not have to know any code +to help out - we also need help testing, answering questions, improving +documentation, etc. + + +## Issues + +Bugs and problems can be reported at: + +https://rt.cpan.org/Dist/Display.html?Name=mod_perl + +which can be accessed from the "Issues" link in the left-hand menu on +the metacpan.org page, https://metacpan.org/pod/mod_perl2 . + +(Note: You will need to log in to https://rt.cpan.org in order to get +the "Report a new bug" button on the bug tracker page.) + + +### Discussions + +There is a low-volume mailing list for mod_perl users and developers to +share ideas, solve problems and discuss things related to mod_perl and +the Apache::* modules. + +Send an email to <modperl@perl.apache.org>. Before doing so, you should +subscribe by sending an email to <modperl-subscribe@perl.apache.org>. +Send an email to <modperl-unsubscribe@perl.apache.org> to unsubscribe. + +There is also a low-volume mailing list for discussions about the +development of the core mod_perl. + +Send an email to <dev@perl.apache.org>. Before doing so, you should +subscribe by sending an email to <dev-subscribe@perl.apache.org>. +Send an email to <dev-unsubscribe@perl.apache.org> to unsubscribe. + + +## Testing + +You can help by testing mod_perl as widely as possible. Running the +tests on a wide variety of platforms, Apache httpd versions, Perl +versions and other factors is a great help in uncovering problems and +improving mod_perl. + + +## Code development + +Development happens in a Subversion repo. The canonical location is +currently at: + +https://svn.apache.org/repos/asf/perl/ + +The current mod_perl 2.0 development branch is at modperl/trunk under +the above URL. + +Create your own copy of that branch by running: + +svn co https://svn.apache.org/repos/asf/perl/modperl/trunk/ mod_perl2
diff --git a/2_0_13/Changes b/2_0_13/Changes new file mode 100644 index 0000000..19bfa2d --- /dev/null +++ b/2_0_13/Changes
@@ -0,0 +1,3007 @@ +=encoding utf8 + +=head1 NAME + +Changes - Apache mod_perl changes logfile + +=head1 CHANGES + +all changes without author attribution are by Doug MacEachern + +Also refer to the Apache::Test changes log file, at Apache-Test/Changes + +=over 3 + +=item 2.0.13 October 21, 2023 + +Use get_server_banner() instead of deprecated get_server_version() in +Apache2::Status. [Petr Písař <ppisar@redhat.com] + +Avoid generating APR precompiled headers. [Sam James <sam@gentoo.org>] + +Fix build for perl >= 5.37.1. [Jitka Plesnikova <jplesnik@redhat.com>] + +=item 2.0.12 January 30, 2022 + +Add bug tracker information to README, and add CONTRIBUTING.md. [Steve Hay] + +Fix detection of APR's threading support on RHEL 8. [Petr Písař +<ppisar@redhat.com>] + +Fix build for perl >= 5.33.7. [Leon Timmermans <fawaka@gmail.com>] + +Fix SIGSEGV crash due to wrong use of perl_parse(). [Charles Pigott +<cpigott@rapitasystems.com>] + +Improve installation instructions for AIX. [Rainer Tammer +<rainer.tammer@schulergroup.com>] + +=item 2.0.11 October 5, 2019 + +Fix t/modules/apache_resource.t failures [Steve Hay] + +Fix [CVE-2011-2767] Arbitrary Perl code execution in the context of the user +account via a user-owned .htaccess. Patch from bugs.debian.org #644169. [Jan +Ingvoldstad <jani+debian-2011+@ifi.uio.no>] + +Fix potential test suite hangs due to pipelined response deadlocks. Patch +from rt.cpan.org #82409. [Zefram <zefram@fysh.org>] + +Fix t/compat/request.t failures [Steve Hay] + +Fix use-after-free segfault in ap_server_config_defines seen on start-up on +OpenBSD. [Found/fixed by Sam Vaughan/Joe Orton] + +Fix build with Perls earlier than 5.13.6. [Rainer Jung +<rainer.jung@kippdata.de>] + +Fix filter/in_bbs_inject_header.t test failure with Apache 2.4.25+. [Stefan +Fritsch <sf@sfritsch.de>] + +Fix apache/read.t test failure with Apache 2.4.25+. [Niko Tyni +<ntyni@debian.org>] + +=item 2.0.10 October 27, 2016 + +Declare MP_vtbl_env and MP_vtbl_envelem as 'extern' to fix linker errors on +OSX/Darwin. [Michael Schout <mschout@gkg.net>] + +Automatically select the appropriate c89 option when modperl is being +built with either gcc 5 or clang. [Klaus S. Madsen <ksm@jobindex.dk>] + +Fix non-threaded Perl 5.22.x build and tests. [Klaus S. Madsen +<ksm@jobindex.dk>] + +Add support for Perl 5.22.x. [Niko Tyni <ntyni@iki.fi>, Steve Hay] + +=item 2.0.9 June 18, 2015 + +Add note to README about MP_INLINE problem when building with GCC 5. +[Niko Tyni <ntyni@debian.org>] + +Fix t/api/aplog.t for apr-1.5.2. [Steve Hay] + +Note that Perl 5.22.x is currently not supported. This is logged as +CPAN RT#101962 and will hopefully be addressed in 2.0.10. [Steve Hay] + +Fix unthreaded build, which was broken in 2.0.9-rc2. [Steve Hay] + +Remove PerlInterpScope. This has not been working properly with threaded +MPMs with httpd-2.4.x and the use-case of this directive was questionable. +[Jan Kaluza] + +Allow running the test suite with httpd-2.4.x when mod_access_compat is not +loaded. [Steve Hay] + +Add support for Apache httpd-2.4.x. [Torsten Foertsch, Jan Kaluza, +Steve Hay, Gozer] + +Don't call modperl_threaded_mpm() et al. from XS code. Fixes Debian Bug +#765174. [Niko Tyni <ntyni@debian.org>] + +Make sure modperl_interp_select uses r->server rather than the passed s +parameter to find the interpreter pool to pull an interpreter from. This +fixes an issue with vhosts with a separate interpreter pool and runtime +dir-config merges that used to pull the interpreter from the wrong pool. +[Torsten Foertsch] + +PerlInterpScope is now more advisory. Using $(c|r)->pnotes will bind +the current interpreter to that object for it's lifetime. +$(c|r)->pnotes_kill() can be used to prematurely drop pnotes and +remove this binding. [Torsten Foertsch] + +Now correctly invokes PerlCleanupHandlers, even if they are the only +handler type configured for that request [Torsten Foertsch] + +For threaded MPMs, change interpreter managment to a new, reference-counted +allocation model. [Torsten Foertsch] + +Expose modperl_interp_pool_t via ModPerl::InterpPool, modperl_tipool_t +via ModPerl::TiPool and modperl_tipool_config_t via ModPerl::TiPoolConfig +[Torsten Foertsch] + +Expose modperl_interp_t via ModPerl::Interpreter [Torsten Foertsch] + +Fix t/compat/apache_file.t on Windows. Apache::File->tmpfile() wants TMPDIR +or TEMP from the environment, or else defaults to /tmp. The latter is no +good on Windows, so make sure the environment variables are passed through. +(TEMP should be set to something suitable on Windows.) [Steve Hay] + +Fix t/api/err_headers_out.t with HTTP::Headers > 6.00. [Rolando +<rolosworld@gmail.com>] + +Fix the build with VC++ and dmake (rather than nmake) on Windows. The +Makefile generated by Apache2::Build uses shell commands for the manifest +file, but neglected to tell dmake to use the shell. [Steve Hay] + +Don't write an 'rpm' target into the Makefile on Windows. It isn't relevant +on Windows, and the (hard-coded, not MakeMaker-generated) recipe group has +syntax which dmake doesn't understand. [Steve Hay] + +=item 2.0.8 April 17, 2013 + +Perl 5.16.3's fix for a rehash-based DoS makes it more difficult to invoke +the workaround for the old hash collision attack, which breaks mod_perl's +t/perl/hash_attack.t. Patch from rt.cpan.org #83916 improves the fix +previously applied as revision 1455340. [Zefram] + +On Perl 5.17.6 and above, hash seeding has changed, and HvREHASH has +disappeared. Patch to update mod_perl accordingly from rt.cpan.org #83921. +[Zefram] + +Restore build with Perl 5.8.1, 5.8.2 etc: take care to use +$Config{useithreads} rather than $Config{usethreads}, and supply definitions +of Newx and Newxz as necessary. [Steve Hay] + +On Perl 5.17.9, t/apache/read2.t fails because an "uninitialized value" +warning is generated for the buffer being autovivified. This is because +the sv_setpvn() that's meant to vivify the buffer doesn't perform set +magic; the warning is generated by the immediately following SvPV_force(). +Patch to fix this from rt.cpan.org #83922. [Zefram] + +Fix t/perl/hash_attack.t to work with Perl 5.14.4, 5.16.3 etc, which +contain a fix for CVE-2013-1667 (memory exhaustion with arbitrary hash +keys). This resolves rt.perl.org #116863, from where the patch was taken. +[Hugo van der Sanden] + +use APR::Finfo instead of Perl's stat() in ModPerl::RegistryCooker to +generate HTTP code 404 even if the requested filename contains newlines +[Torsten] + +Remove all uses of deprecated core perl symbols. [Steve Hay] + +Add branch release tag to 'make tag' target. [Phred] + +=item 2.0.7 June 5, 2012 + +Fix breakage caused by removal of PL_uid et al from perl 5.16.0. Patch from +rt.cpan.org #77129. [Zefram] + +=item 2.0.6 April 24, 2012 + +Preserve 5.8 compatibility surrounding use of MUTABLE_CV [Adam Prime] + +Move code after declarations to keep MSVC++ compiler happy. [Steve Hay] + +Adopt modperl_pcw.c changes from httpd24 branch. [Torsten Foertsch] + +Pool cleanup functions must not longjmp. Catch these exceptions and turn +them into warnings. [Torsten Foertsch] + +Fix a race condition in our tipool management. +See http://www.gossamer-threads.com/lists/modperl/dev/104026 +Patch submitted by: SalusaSecondus <salusa@nationstates.net> +Reviewed by: Torsten Foertsch + +Ensure that MP_APXS is set when building on Win32 with MP_AP_PREFIX, +otherwise the bundled Reload and SizeLimit builds will fail to find a +properly configured Test environment. +[Steve Hay] + +Fix a few REFCNT bugs. +Patch submitted by: Niko Tyni <ntyni@debian.org> +Reviewed by: Torsten Foertsch + +Correct the initialization of the build config in ModPerl::MM. The global +variable was only being set once on loading the module, which was before +Apache2::BuildConfig.pm had been written, leading to cwd and MP_LIBNAME +being unset when writing the Reload and SizeLimit makefiles. +[Steve Hay] + +Discover apr-2-config from Apache 2.4 onwards. [Gozer] + +Apache 2.4 and onwards doesn't require linking the MPM module directly in +the httpd binary anymore. APXS lost the MPM_NAME query, so we can't assume +a given MPM anymore. Introduce a fake MPM 'dynamic' to represent this. +[Torsten Foertsch, Gozer] + +Perl 5.14 brought a few changes in Perl_sv_dup() that made a threaded apache +segfault while cloning interpreters. +[Torsten Foertsch] + +PerlIOApache_flush() and mpxs_Apache2__RequestRec_rflush() now no longer throw +exceptions when modperl_wbucket_flush() fails if the failure was just a reset +connection or an aborted connection. The failure is simply logged to the error +log instead. This should fix cases of httpd.exe crashing when users press the +Stop button in their web browsers. +[Steve Hay] + +Fixed a few issues that came up with LWP 6.00: +- t/response/TestAPI/request_rec.pm assumes HTTP/1.0 but LWP 6 uses 1.1 +- t/api/err_headers_out.t fails due to a bug somewhere in LWP 6 +- t/filter/TestFilter/out_str_reverse.pm sends the wrong content-length header +[Torsten Foertsch] + +Bugfix: Apache2::ServerUtil::get_server{description,banner,version} cannot +be declared as perl constants or they won't reflect added version components +if Apache2::ServerUtil is loaded before the PostConfig phase. Now, they +are ordinary perl functions. [Torsten Foertsch] + +Check for the right ExtUtils::Embed version during build [Torsten Foertsch] + +Take a lesson from rt.cpan.org #66085 and pass LD_LIBRARY_PATH if mod_env +is present. Should prevent test failures on some platforms. +[Fred Moyer] + + +=item 2.0.5 February 7, 2011 + +The mod_perl PMC dedicates this release of mod_perl to Randy Kobes, who +passed away in September 2010. Randy was a member of the mod_perl project +management committee and a co-author of the mod_perl Developer's Cookbook. +His work helped many Windows mod_perl users. His work with ppm files, and +Win32 perl users will be sorely missed. He was kind, bright, and always +willing to lend a hand on the mod_perl user's list. + +Prepare modperl for the upcoming perl 5.14 [Torsten Foertsch] + +Add lib/ModPerl/MethodLookup.pm to MANIFEST via lib/ModPerl/Manifest.pm +RT #48103 reported by MARKLE@cpan.org +[Fred Moyer] + +PerlIOApache_write() now throws an APR::Error object, rather than just a string +error, if modperl_wbucket_write() fails. +[Steve Hay] + +Authentication tests fail with LWP 5.815 and later +[Doug Schrag] + +Concise test won't perform unless StatusTerse is set to ON +[Doug Schrag] + +Look for a usable apxs in $ENV{PATH} if all other options fail, then prompt the user for one. +[Phred] + +Work around bootstrap warnings when Apache2::BuildConfig has not been created yet. +[Phred] + +Remove Apache::test compatibility (part of mod_perl 1.2.7), that code causes build issues and is 4 versions out of date. +[Phred] + +Make sure perl is built either with multiplicity and ithreads or without +both [Theory, Torsten] + +Support for "install_vendor" and "install_site" make targets [Torsten] + +Run tests on bundled pure perl Apache::* modules [Gozer, Phred] + +Implement a mini-preprocess language for map-files in xs/maps. +[Torsten Foertsch] + +Implement APR::Socket::fileno [Torsten Foertsch] + +Export PROXYREQ_RESPONSE, a missing PROXYREQ_* constant [Gozer] + +Make sure standard file descriptors are preserved by the perl-script +handler [Torsten Foertsch] + +Fix the filter init handler attribute check in +modperl_filter_resolve_init_handler() [Torsten Foertsch] + +Make sure buffer is a valid SV in modperl_filter_read() [Torsten Foertsch] + +Move modperl_response_finish() out of modperl_response_handler_run in +mod_perl.c [Torsten Foertsch] + +"MODPERL_INC= now correctly supported as an argument to Makefile.PL" +[Torsten Foertsch] + +Fix an XSS issue in Apache2::Status reported by Richard J. Brain +<richard@procheckup.com>. [Torsten Foertsch] + +Add NOTICE file to the distribution. [Joe Schaefer] + +Make sure Apache2::RequestIO::read doesn't clear the buffer on end of +file and handle negative offsets and offsets that are larger than +the current string length. [Torsten Foertsch] + +Fix a problem that could make APR::XSLoader and Apache2::XSLoader +load the wrong shared library. [Torsten Foertsch] + +Fix compilation when using a non-threaded APR. +[Gozer, Philip M. Gollucci] + +Make sure mod_perl's own ChildInitHandlers are run before user +supplied ones. This fixes the incorrectly reported value of $$ +at ChildInit time [Gozer] + +=item 2.0.4 April 16, 2008 + +Fix $r->location corruption under certain conditions +[Gozer] + +Fix a crash when spawning Perl threads under Perl 5.10 +[Gozer] + +Fix erratic behaviour when filters were used with Perl 5.10 +[Gozer] + +Fix problems with redefinitions of perl_free as free and perl_malloc +as malloc on Win32, as described at + http://marc.info/?l=apache-modperl&m=119896407510526&w=2 +[Tom Donovan] + +Fix a crash when running a sub-request from within a filter where +mod_perl was not the content handler. [Gozer] + +Refactor tests to use keepalives instead of same_interp [Gozer, Phred] + +Apache2::Reload has been moved to an externally maintained +CPAN distribution [Fred Moyer <fred@redhotpenguin.com>] + +PerlCleanupHandler are now registered with a subpool of $r->pool, +instead of $r->pool itself, ensuring they run _before_ any other +$r->pool cleanups [Torsten Foertsch] + +Fix a bug that would prevent pnotes from being cleaned up properly +at the end of the request [Torsten Foertsch] + +On Win32, embed the manifest file, if present, in mod_perl.so, +so as to work with VC 8 [Steve Hay, Randy Kobes] + +Expose apr_thread_rwlock_t with the APR::ThreadRWLock module +[Torsten Foertsch] + +Don't waste an extra interpreter anymore under threaded MPMs when using a +modperl handler [Torsten Foertsch] + +Fix a bug that could cause a crash when using $r->push_handlers() multiple +times for a phase that has no configured handlers [Torsten Foertsch] + +Catch up with some httpd API changes + 2.2.4: + The full server version information is now included in the error log at +startup as well as server status reports, irrespective of the setting +of the ServerTokens directive. ap_get_server_version() is now +deprecated, and is replaced by ap_get_server_banner() and +ap_get_server_description(). [Jeff Trawick] + + 2.3.0: +ap_get_server_version() has been removed. Third-party modules must +now use ap_get_server_banner() or ap_get_server_description(). +[Gozer] + +fixed Apache2::compat Apache2::ServerUtil::server_root() resolution +issues [Joshua Hoblitt] + +*) SECURITY: CVE-2007-1349 (cve.mitre.org) +fix unescaped variable interprolation in regular expression +[Randal L. Schwartz <merlyn@stonehenge.com>, Fred Moyer <fred@redhotpenguin.com>] + +Make $r->the_request() writeable +[Fred Moyer <fred@redhotpenguin.com>] + +fix ModPerl::RegistryCooker::read_script to handle all possible +errors, previously there was a case where Apache2::Const::OK was +returned on an error. [Eivind Eklund <eeklund@gmail.com>] + +a minor compilation warning resolved in modperl_handler_new_from_sv +[Stas] + +a minor compilation warning resolved in modperl_gtop_size_string +[Stas] + +Prevent direct use of _deprecated_ Apache2::ReadConfig in +<Perl> sections with httpd Alias directives from +incorrectly generating +'The Alias directive in xxxxx at line y will probably never match' +messages. +[Philip M. Gollucci <pgollucci@p6m78g.com>] + +Prevent Apache2::PerSections::symdump() from returning invalid +httpd.conf snippets like 'Alias undef' +[Philip M. Gollucci <pgollucci@p6m78g.com>] + +Require B-Size 0.9 for Apache2::Status which fixes +Can't call method "script_name" on an undefined value +[Philip M. Gollucci <pgollucci@p6m78g.com>] + +-march=pentium4 or anything with an = in it in CCFLAGS or @ARGV +that gets passed to xs/APR/APR/Makefile.PL broke the @ARGV +parsing. I.E. FreeBSD port builds when users had CPUTYPE +set in /etc/make.conf. +[Philip M. Gollucci <pgollucci@p6m7g8.com>] + +Fixes to get bleed-ithread (5.9.5+) to comile again. +[Philip M. Gollucci <pgollucci@p6m7g8.com>] + +=item 2.0.3 November 28, 2006 + +Prevent things in %INC that are not stat() able +from breaking Apache2::Status 'Loaded Modules' +under fatal warnings. +[Philip M. Gollucci <pgollucci@p6m7g8.com>] + +When using MP_AP_PREFIX on WIN32 make sure that its +a valid directory. +[Nikolay Ananiev <ananiev@thegdb.com>] + +Fix bug concerning 'error-notes' having no value on +errordocument redirect. +[Guy Albertelli II <guy@albertelli.com>] + +Multi-line $PerlConfig is now working [Gozer] + +PerlOptions None was previously incorrectly reported as invalid +inside <VirtualHost> or <Directory> blocks. +[Philip M. Gollucci] + +Require B::Size 0.07 and B::TerseSize 0.07 for Apache2::Status +[Philip M. Gollucci] + +Apache2::Status was expecting B::TerseSize to return +an op count for things that it didn't causing +requests like http://localhost/perl-status/main?noh_b_package_size +to cause 405s +[Philip M. Gollucci] + +Updates for Win32 to allow building and testing on Apache/2.2: +- use httpd.exe as the Apache binary name when installing apxs +- use new apr library names (libapr-1.lib and libaprutil-1.lib) +[Randy Kobes] + +Make sure that additional library paths are included in the build flags +so that mod_perl will use the same versions of libraries that APR does. +[Mike Smith <mike@mailchannels.com>] + +Added $r->connection->pnotes, identical to $r->pnotes, but +for the entire lifetime of the connection +[Geoffrey Young, Gozer] + +Fixed problems with add_config() and thread-safety: [Gozer] +- $s->add_config is not allowed anymore after server startup +- $r->add_config can only affect configuration for the current + request, just like .htaccess files do + +Make sure that LIBS and other MakeMaker command line flags are not +ignored by the top level Makefile.PL and xs/APR/APR/Makefile.PL [Stas] + +Corrected a typo that would cause the corruption of $), the +effective group id as Perl sees it [Gozer] + +Added support for httpd-2.2's new override_opts in Apache2::Access. +Calls to add_config() now accept an override_opts value as the 4th +argument. [Torsten Foertsch <torsten.foertsch@gmx.net>, Gozer] + +Fix 'PerlSwitches +inherit' that got broken somewhere along +the way to 2.0. You can also use 'PerlOptions +InheritSwitches' +for the same result. [Gozer] + +Add perl API corresponding to User and Group directives in httpd.conf: +Apache2::ServerUtil->user_id and Apache2::ServerUtil->group_id +[Stas] + +Apache2::Reload now first unloads all modified modules before +trying to reload them. This way, inter-module dependencies +are more likely to be correctly satisfied when reloaded +[Javier Uruen Val <juruen@warp.es>, Gozer] + +$r->add_config() can now take an optionnal 3rd argument that +specifies what pseudo <Location $path> the configuration is +evaluated into [Torsten Foertsch <torsten.foertsch@gmx.net>] + +remove -DAP_HAVE_DESIGNATED_INITIALIZER and -DAP_DEBUG from +MP_MAINTAINER mode to avoid collisions [Joe Orton] + +Back out r280262 which was causing Apache2::Reload to misbehave. +[JT Smith <jt@plainblack.com>] + +Perl_do_open/close fixes to make mod_perl 2.0 compile with +blead-perl@25889+ (5.9.3+) [Stas] + +Added Apache2::PerlSections->server, returning the server +into which the <Perl> section is defined [Gozer] + +Require B::Size and B::TerseSize v0.06 for Apache2::Status +options StatusTerse and StatusTerseSize which has now been +updated to support the new mod_perl2 api post RC5. +[Philip M. Gollucci] + +When using Apache2::PerlSections->dump, the configuration +would print out in the correct order, but when the configuration was +passed off to Apache the ordering was lost. +[Scott Wessels <swessels@usgn.net>] + +=item 2.0.2 - October 20, 2005 + +add :proxy import tag to Apache2::Const which exposes new +constants PROXYREQ_NONE, PROXYREQ_PROXY, and PROXYREQ_REVERSE +[Geoffrey Young] + +$0 Fixes : [Gozer] +- Setting $0 works on Linux again +- HP-UX and *BSDes show the correct process name instead of '-e' + +Fix a critical but trivial bug that would cause MP_MAINTAINER=1 +or MP_TRACE=1 builds to fail if not building against a threaded APR. +Functions such as apr_os_thread_current() would not be linked in, +but were expected to be. +[Philip M. Gollucci] + +Add the output of ldd(unix/cygwin) and otool -L (darwin) +for httpd to the mp2bug report script. +[Philip M. Gollucci] + +Prevent tools such as Apache2::Status's Loaded Modules screen +from displaying erroneous information about mod_perl.pm being loaded. +[Stas, Philip M. Gollucci] + +Correctly set the version of ModPerl::MethodLookup, previously, +it was not set because of the way it was Generating via ModPerl::WrapXS. +[Philip M. Gollucci] + +Improve the detection of whether or not we are in an mp2 build tree. +This allows usage of ExtUtils::MakeMaker options such as PREFIX to +not break the probe of mp2 build trees. +[Stas, Philip M. Gollucci] + +Add support for the newer Smaps (/proc/self/statm) on Linux +systems that support it (i.e. linux-2.6.13-rc4-mm1) +to accurately count the amount of shared memory. +[Torsten Foertsch <torsten.foertsch gmx.net>] + +On cygwin some dlls might happen to be with identical base addresses +and if you try to load both of them you'll get an error and you'll +have to use the rebase utility to fix them. this fix should prevent +this. [Nikolay Ananiev <ananiev@thegdb.com>] + +Fix an undefined warning in DSO builds when not using MP_APXS. +[Nikolay Ananiev <ananiev@thegdb.com>] + +When running Makefile.PL with the MP_MAINTAINER=1 option +add -Wdeclaration-after-statement if we are using gcc +version 3.3.2 or higher and its not already part of the ccopts. +[Philip M. Gollucci, Gozer] + +Several fixes to Apache2::Status +[Philip M. Gollucci] + +When using Apache2::Reload and ReloadDebug is set to 'On', +sort the output alphabetically [Philip M. Gollucci] + +croak in case a filter returns DECLINED after calling $f->read (as it +is not supposed to happen) [Stas] + +another round of cygwin fixes [Nikolay Ananiev <ananiev@thegdb.com>] + +Multiple fixes to make mod_perl 2.0 work with blead-perl (5.9.3+) +[Stas] + +t/modules/reload.t would fail if run more than 3 times, breaking +smokes [Gozer] + +filter flushing now doesn't croak on connection reset +(ECONNRESET/ECONNABORTED), but just logs the event on the 'info' +level. [Stas] + +RPM Friendly builds : [Gozer] +- make dist tarballs can now be built directly into RPMs with rpmbuild +- Added a new target 'make rpm' to directly build rpms from a checkout + + + +=item 2.0.1 - June 17, 2005 + +B::Terse has problems with XS code, so adjust Apache::Status to eval +{} the code doing Syntax Tree Dump: syntax and execution order options +[Stas] + +Fix a broken regexp in Apache2::Build::dir() on win32 that would +incorrectly attempt to fully-qualify paths like c:/some/path +[Nikolay Ananiev <ananiev@thegdb.com>] + +Fix the "No library found" warnings when building on win32 without +apxs and MP_AP_PREFIX [Nikolay Ananiev <ananiev@thegdb.com>] + +The pure-perl ModPerl::Util::unload_package implementation was +accidently deleting sub-stashes [Gozer] + +If running Makefile.PL unnatended (STDIN isn't a terminal or +MP_PROMPT_DEFAULT=1), break out of potentially infinite prompt +loops [Gozer] + +fix ModPerl::TestReport used by t/REPORT and mp2bug to use +ExtUtils::MakeMaker's MM->parse_version to get the interesting +packages version number, w/o trying to load them (which may fail if +the environment is not right) [Stas] + +fix a bug in ModPerl::RegistryCooker: now stripping __(END|DATA)__ +only at the beginning of the line [Stas] + +APR::Base64 : [Torsten Foertsch <torsten.foertsch@gmx.net>] +- fix encode_len() to return the length without accounting for the +terminating '\0' as the C API does. +- fix encode() to create the string of the correct length (previously +was creating one too many) + +in mod_perl callbacks merge error-notes entries rather than store just +the newest error [Mark <mark@immermail.com>] + +Expose Apache2::Const::EXEC_ON_READ (added to the :override group) +[Stas] + +Fix a bug in custom directive implementation, where the code called +from modperl_module_config_merge() was setting the global context +after selecting the new interpreter which was leading to a segfault in +any handler called thereafter, whose context was different +beforehand. [Stas] + + + +=item 2.0.0 - May 20, 2005 + +fix global anon_cnt double-initialization bug that was causing +startup segfaults on OSX. [Gozer] + +fix the ap_install target in the top-level Makefile (used for static +build) [Stas] + +Reintroduce a pure-Perl version of ModPerl::Util::unload_package() +The problematic XS version is now called unload_package_xs() and +not used by default [Gozer] + +More APR::Status wrappers: [Stas, Randy Kobes] +- is_EOF +- is_ECONNABORTED +- is_ECONNRESET +- is_TIMEUP + +make sure that the build picks up the include directories based on the +apxs queries and only search the httpd source if $self->{MP_AP_PREFIX} +was set. Earlier it was always picking the headers from the httpd +source if it was available, which was resulting in the wrong headers +if the installed httpd was different than the source that was found +[Stas] + +introduce ModPerl::RegistryPrefork and ModPerl::PerlRunPrefork, which +behave the same as ModPerl::Registry and ModPerl::PerlRun, +respectively, but chdir to the script's directory like mod_cgi +does. These two new handlers will refuse to load under threaded MPMs +where chdir can't be used as it will affect all running threads [Stas] + +ModPerl::RegistryCooker::chdir_file_normal() now chdirs to the current +script's directory or the specified directory as an argument, as it +was planned in first place. Therefore switch ModPerl::Registry and +ModPerl::PerlRun to us NOP for this method call. If chdir_file is +mapped to chdir_file_normal(), then run() and +convert_script_to_compiled_handler() now call chdir to the script's +directory and at before returning go back to the server root. [Stas] + +prevent undef warnings in catfile() calls in Apache2::Build when +called from the ModPerl-Registry tree [Stas] + +fix modperl_brigade_dump to use apr_file_printf() instead of +fprintf(), which doesn't work everywhere [Stas] + +Fix a warning triggered by `ln` on Cygwin, when running perl +Makefile.PL for a second time without previously running make +clean. [Nikolay Ananiev <ananiev@thegdb.com>] + +When compiling a static mod_perl and +MP_AP_CONFIGURE="--with-apr=/some/path" argument is given, Apache will +use the apr-config at the given path, but mod_perl was using the +default at "srclib/apr/.libs". Fix that [Nikolay Ananiev <ananiev@thegdb.com>] + +Show MP_APU_CONFIG as an argument to Makefile.PL in the Usage +menu. [Nikolay Ananiev <ananiev@thegdb.com>] + +Makefile.PL: fix the pre-rename mp2 install diagnostics code, to use +the mp version of 1.999xx and not 1.999_xx, as the latter is +unsuitable for numerical comparison, also fix the name of the reported +conflicting directory [Stas]. + +add APR::Status::is_(EACCES|ENOENT), and use in ModPerl::RegistryCooker +to return, as appropriate, Apache2::Const::(FORBIDDEN|NOT_FOUND), +based on $@. Also remove a check in modperl_slurp_filename +of src/modules/perl/modperl_util.c to enable $@ to be set when +opening or reading a file fails. This fixes a bug on Win32, revealed +in 404.t and redirect.t of the ModPerl-Registry tests, as reported +by Steve Hay and Markus Wichitill [Stas, Randy Kobes] + +link Apache2::* and ModPerl::* to mod_perl.a and DynaLoader.a, but +-lmod_perl and -lDynaLoader don't work, and we can't supply the full +paths, because MakeMaker doesn't allow this. I workaround this by +making a symlink to mod_perl.a (called libmod_perl.a) and copy +DynaLoader.a to libDynaLoader.a (I don't create a symlink, because, +when running make clean, the real DynaLoader.a may get deleted). The +APR::* extensions are not affected, because in both cases we link them +against aprext. Also other small fixes are added. [Nikolay Ananiev +<ananiev@thegdb.com>] + + + + +=item 1.999_23 - May 3, 2005 + +fix Apache2::Build::dynamic_link_MSWin32 to generate a new line after +dynamic_link code in Makefile [Nikolay Ananiev <ananiev@thegdb.com>] + +fix a warning in Apache2::Build::build_config() when building +with MP_STATIC_EXTS=1 [Nikolay Ananiev <ananiev@thegdb.com>] + +improving DSO support on cygwin. The problem with cygwin is that it +behaves like windows (it's a posix layer over windows after +all). That's why we need to supply all symbols during linking time +just like on win32, by adding -lapr-0 -laprutil-0 and -lhttpd. On +windows, Apache supplies all the three libraries and it's easy to +link, but on cygwin apache doesn't play nice and doesn't supply +libhttpd. This change adds libapr and libaprutil. [Nikolay Ananiev +<ananiev@thegdb.com>] + +improve the diagnostics when detecting mp2 < 1.999022, tell the user +which files and/or dirs need to be removed [Stas] + +restore the DESTDIR support partially nuked by the apache2 rename +branch [Torsten Förtsch <torsten.foertsch gmx.net>] + +add APR::Status to provide functions corresponding to the +APR_STATUS_IS_* macros of apr_errno.h, especially those composites +like APR_STATUS_IS_EAGAIN(s) which are satisfied by more than one +specific error condition. Presently only APR_STATUS_IS_EAGAIN is +provided [Randy Kobes] + +fix the generation of the manpages for .pm files from sub-projects +like ModPerl-Registry (previously was creating manpage files like +.::ModPerl::PerlRun.3) [Stas] + +fix the pod2man'ification part of 'make install' (using POD2MAN_EXE +instead of POD2MAN Makefile macro) [Stas] + + +=item 1.999_22 - April 14, 2005 + + ******************** IMPORTANT ******************** + this version of mod_perl is completely incompatible + with prior versions of mod_perl, both 1.XX and + 1.99_XX. Please read the below changes carefully. + *************************************************** + +remove MP_INST_APACHE2 installation option and Apache2.pm - all +mod_perl related files will now be installed so they are visible +via standard @INC. also, refuse to install over mod_perl 2 versions +less than 1.999_22. [Geoffrey Young] + +s/Apache::/Apache2::/g and s/mod_perl/mod_perl2/g in all module +APIs. so, Apache::RequestRec is now Apache2::RequestRec, +Apache::compat is now Apache2::compat, and so on. [joes] + +move all Apache:: constants to Apache2::Const and all APR:: constants +to APR::Const. for example, Apache:OK is now Apache2::Const::OK and +APR::SUCCESS is now APR::Const::SUCCESS. [Geoffrey Young] + +add $ENV{MOD_PERL_API_VERSION} as something that clearly distinguishes +which mod_perl version is being used at request time. [Geoffrey Young] + +rename Apache->request() to Apache2::RequestUtil->request(), and +Apache->server() to Apache2::ServerUtil->server() +[Geoffrey Young] + +fix Apache2::Status which was bailing out on trying to load modules +with dev versions like 2.121_02 [Stas] + +When parsing Makefile.PL MP_* options, handle correctly the MP_FOO=0 +entries [Philip M. Gollucci <pgollucci@p6m7g8.com>] + +init the anonsub hash for base perl and each vhost +Parent (previously +was init'ed only for the base perl) [Stas] + +fix a bug when a non-threaded perl is used and anonymous sub is pushed +at the server startup (the CV wasn't surviving) [Stas] + +Make sure that CPAN shell doesn't triple over usage of +$ExtUtils::MakeMaker::VERSION [Randy Kobes] + +Apache2::RequestRec->new now sets $r->request_time [Stas] + +remove CGI.pm and Apache::Request dependencies from Apache2::Status +since they weren't used at all [Geoffrey Young] + +Fixes for Apache2::Reload's touchfile feature (return Apache2::Const::OK +instead of 1) [Chris Warren <chwarren@cisco.com>] + +cygwin fixes: [Nikolay Ananiev <ananiev@thegdb.com>] +- doesn't like XS wrapper starting with 'static' +- need to compile everything with -DCYGWIN + +ModPerl::RegistryCooker API change: s/rewrite_shebang/shebang_to_perl/ +the new API now returns the string to prepend before the rest of the +script, instead of rewriting the content, which is both faster and +doesn't mislead the perl debugger [Dominique Quatravaux +<dom@idealx.com>] + +Starting from ExtUtils::MakeMaker 6.26 went back to pm_to_blib target +from pm_to_blib.ts introduced in 6.22, so needed to fix the glue_pod +target, so install will work correctly [Stas] + +Syntax errors in <Perl> sections were not correctly caught and +reported. [Gozer] + +when building mp2 EU::MM looks into Apache-Test/MANIFEST and complains +about the missing Apache-Test/META.yml (which is indeed not included +in the modperl package due to the PAUSE problems of dealing with more +than one META.yml. Solution: Exclude Apache-Test/MANIFEST from +mod_perl distribution package. [Stas] + +ModPerl::Registry no longer checks for -x bit (we don't executed +scripts anyway), and thus works on acl-based filesystems. Also +replaced the -r check with a proper error handling when the file is +read in. [Damon Buckwalter <buckwad@gmail.com>] + +Apache2::RequestUtil::slurp_filename now throws an APR::Error exception +object (before it was just croaking). [Stas] + +fix APR::Error's overload of '==' (it was always returning true +before), and add the corresponding '!=' [Stas] + +if $r->document_root was modified, restore it at the end of request +[joes] + +Apache2::ServerRec method which set the non-integer fields in the +server_rec, now copy the value from the perl scalar, so if it changes +or goes out of scope the C struct is not affected. Using internal perl +variables to preserve the value, since using the server pool to +allocate the memory will mean a memory leak [Stas] + +add the escape_url entry in the ModPerl::MethodLookup knowledgebase +[Stas] + +Apache2::SubProcess::spawn_proc_prog now can be called in a void +context, in which case all the communication std pipes will be closed +[Stas] + +fix a bug in $r->document_root, which previously weren't copying the +new string away [Stas] + +introduce a new build option MP_AP_DESTDIR to aid package builders +direct the Apache-specific files to the right place. [Cory Omand +<Cory.Omand@Sun.COM>] + +Fix bug in modperl_package_clear_stash() segfaulting when +encountering declared but not yet defined subroutines. +[Steve Hay <steve.hay@uk.radan.com>, Gozer] + +win32 needs PERL_SYS_INIT3/PERL_SYS_TERM calls [Steve Hay +<steve.hay@uk.radan.com>] + +Fix broken MP_STATIC_EXTS=1 build. [Gozer] + +Perl -Duse64bit fix. Pointers can't just be generically +casted from/to IVs. Use PTR2IV/INT2PTR instead. [Gozer] + +Perl -Duse64bit fix. apr_size_t pointers can't just be generically +casted from/to UVs. Use PTR2UV/INT2PTR instead. [Gozer] + +fix a bug in Apache2::Build::dir: If the right directory isn't found in +the for loop $dir still contains a > value, so the ||= has no +effect. [Nick Wellnhofer <wellnhofer@aevum.de>] + + + +=item 1.999_21 - January 22, 2005 + +PerlPostConfigRequire was trying to detect missing files early on, +but without searching thru @INC, causing false negatives. Better off +skipping that check and leave it to modperl_require_file() to report +problems with finding the file. [Patrick LeBoutillier +<patrick.leboutillier@gmail.com>, Gozer] + +add a perl bug workaround: with USE_ITHREADS perl leaks pthread_key_t +on every reload of libperl.{a,so} (it's allocated on the very first +perl_alloc() and never freed). This becomes a problem on apache +restart: if the OS limit is 1024, 1024 restarts later things will +start crashing [Gisle Aas <gisle@ActiveState.com>, Stas] + +on Irix mod_perl.so needs to see the libperl.so symbols, which +requires the -exports option immediately before -lperl. [Gordon Lack +<gml4410@ggr.co.uk>] + +pool arguments to startup and connection callbacks must be blessed +into APR::Pool and not Apache::Pool class [joes] + +Make PerlSetEnv, PerlPassEnv and %ENV in PerlRequre, PerlModule, +PerlConfigRequire and PerlPostConfigRequire affect each other, so a +change in one of these is immediately seen in the others. [Pratik +<pratiknaik gmail.com>, Stas] + + + +=item 1.999_20 - January 5, 2005 + +the autogenerated modules (and some implemented in xs/ modules) are +now getting the same version number as $mod_perl::VERSION (the +exception are APR modules which get 0.009_000 for now). [Stas] + +until we figure out how to tell PAUSE index about versions of the +autogenerated modules, create a fake module which lists all the +autogenerated modules and their versions and include that in the +distro. [Stas] + +moving to the triplet version notation, which requires us to bump 1.99 +=> 1.999 so 1.999020 (mp2) > 1.29 (mp1). [Stas] +Now we are gong to have: + $mod_perl::VERSION : "1.099020" + int $mod_perl::VERSION : 1.09902 + $mod_perl::VERSION_TRIPLET: 1.99.20 + +<Perl> and PerlPostConfigRequires were leaking some memory at +startup. Use parms->temp_pool instead of parms->pool for temporary +memory allocations. [Gozer] + +deal with a situation where an object is used to construct another +object, but it's then auto-DESTROYed by perl rendering the object that +used it corrupted. the solution is to make the newly created objects +refer to the underlying object via magic attachment. only objects +using objects that have DESTROY are effected. This concerns some of +the methods accepting the custom APR::Pool object (not native pools +like $r->pool). [Stas] +Adjusted: +- APR::Brigade: new +- APR::Finfo: stat +- APR::IpSubnet: new +- APR::Table: copy, overlay, make +- APR::ThreadMutex: new +- APR::URI: parse +- Apache::RequestUtil: new +- APR::Pool: new +- APR::BucketAlloc: new + +APR::Bucket::alloc_create moved to APR::BucketAlloc::new +APR::Bucket::alloc_destroy moved to APR::BucketAlloc::destroy [Stas] + +prefork handlers optimisation: don't dup the handler struct unless +this is a threaded-mpm [Stas] + +speed up the 'perl Makefile.PL' stage [Randy Kobes]: + - reduce the number of calls to build_config() of + Apache::Build within ModPerl::BuildMM + - cache the results of the calls to apxs_cflags, apxs_extra_cflags, + and apxs_extra_cppflags in Apache::Build + - in apxs of Apache::Build, return a cached result only when defined + +move ModPerl::Util::exit() into mod_perl.so, since it needs to work, +even if ModPerl::Util wasn't loaded [Stas] + + + +=item 1.99_19 - December 23, 2004 + +$r->hostname is now writable [Gozer] + +Static build with a Perl without ithreads and a non-threaded MPM +would segfault on startup. Caused by a bug in perl's perl_shutdown() +code. Fixed in Perl 5.8.2, so it's now a build requirement [Gozer] + +replace the added in 1.99_17 code on resetting/restoring PL_tainted, +with explicit reset before and after each each callback. This solves a +complicated tainting issues caused when perl exception object is +thrown. rgs suggested that it should be safe, similar to perl's own +pp_nextstate which says: /* Each statement is presumed innocent */ +[Stas] + +New configuration directives: [Gozer] + - PerlConfigRequire + Just like PerlRequire, but _always_ triggers an immediate + interpreter startup + - PerlPostConfigRequire + A delayed form of PerlRequire, that waits until the post_config + phase before require'ing files + +fix a warning in Apache::Status [John Williams <williams tni.com>] + +Ignore Apache-Test/META.yml in distribution tarballs until PAUSE +is capable of handling multiple META.yml files in one distro [Gozer] + +modperl_exports.c now wraps all exported functions in a #ifndef +function_name wrapper to help in weeding out functions that only make +sense for certain Perl configurations (perlio, threads) (which also +fixes static build against perlio-disabled perls, like 5.6.x) [Gozer] + +for make test, skip configuring fastcgi if it's found in the global +httpd.conf, as it causes crashes in the test suite [Stas] + +fix Makefile.PL arguments parser to support more than one MP_foo +option on the same line (including .makepl_args.mod_perl2 file) [Stas] + +fix compilation issues in ModPerl::Util::current_perl_id (on some +builds newSVpvf can't be resolved but Perl_newSVpvf works just +fine). [Stas, Markus Wichitill <mawic@gmx.de>] + +fix APR::Error::str to return a lexical variable, rather than a +string. This function is called by SvTRUE in modperl_errsv() via +overload and on win32 (and randomly on linux) causes crashes via: +"Attempt to free temp prematurely" warning, where this 'temp' is the +string returned by this function. Making it a lexical variable before +returning it, resolves the problem. [Steve Hay] + +fix META.yaml s/private/no_index/ (to hide the bundled Apache-Test +from PAUSE indexer) [Randy Kobes] + + + +=item 1.99_18 - December 12, 2004 + +Fix x86_64 warnings in modperl_restart_count_*, due to casting between +integers and pointer types [Joe Orton] + +open_logs and post_config handlers require the Apache::OK return code +or the server aborts, so we need to log an error in case the handler +didn't fail but returned something different from Apache::OK [Stas] + +new function ModPerl::Util::current_perl_id() which returns something +like (.e.g 0x92ac760) (aTHX) under threaded mpm and 0 under +non-threaded perl (0x0). Useful for debugging modperl under threaded +perls. [Stas] + +make sure that modperl's internal post_config callback, which amongst +other things, cloning perl interpreters is running as +modperl_hook_post_config_last APR_HOOK_REALLY_LAST, which ensures that +user's post_config callbacks are run before the cloning. now the code +from config phase's startup.pl can be safely moved to the post_config +phase's equivalent. [Stas] + +Further sync with libapr constants changes: [Stas] +- the constants + APR::(READ|WRITE|CREATE|APPEND|TRUNCATE|BINARY|EXCL|BUFFERED|DELONCLOSE) + now have a prefix APR::FOPEN_ and moved group s/filemode/fopen/ +- constants from the fileprot group moved to the fprot group and the + prefix has changed: from APR::FILEPROT_ to APR::FPROT_ +- this also fixes the import of APR_EXCL as an error constant + +$r->print() and tied print() now return 0E0 (zero but true) when the +call was successful but for zero bytes. [Geoffrey Young] + +a new function Apache::ServerUtil::server_shutdown_cleanup_register to +register cleanups to be run at server shutdown. [Stas] + +$bb->cleanup is no more segfaulting (was segfaulting due to a broken +prototype in APR, and consequently invalid XS glue code) [Randy Kobes, +Stas] + +make sure that ABSPERLRUN and ABSPERLRUN are defined in +src/modules/perl/Makefile (needed by win32 build) [Stas] + +For static builds, mod_perl header files were being installed +into apache's source tree instead of where apache installed it's +own headers [Gozer] + +modperl_threads_started() wasn't working under static worker build, +due to MP_threads_started static variable not being reset on +restart. Now resetting it. [Stas] + +@INC shrinking efforts: [Stas] +1) when adding $ServerRoot don't add the trailing / (as it ends up +twice when added by A-T w/o trailing /) +2) add $ServerRoot/lib/perl only if it actually exists + +For static builds, we now run 'make clean' in httpd's source +tree before running ./configure if the source tree has been +configured before [Gozer] + +Apache::SizeLimit ported [Perrin Harkins <perrin elem.com>] + +create a new subpool modperl_server_user_pool (from +modperl_server_pool), which is used internally by +Apache::ServerUtil::server_restart_register. This ensures that +user-registered cleanups are run *before* perl's internals cleanups +are run. (previously there was a problem with non-threaded perls which +were segfaulting on user cleanups, since perl was already gone by that +time). [Stas] + +Starting from ExtUtils::MakeMaker 6.22 it no longer generates +pm_to_blib target, but pm_to_blib.ts, so needed to fix the glue_pod +target, so install will work correctly [Stas] + +Apache::RequestUtil : $r->child_terminate() implemented for +non-threaded MPMs. [Gozer] + +new API Apache::ServerUtil::restart_count() which can be used to tell +whether the server is starting/restarting/gracefully +restarting/etc. Based on this feature implement +$Apache::Server::Starting and $Apache::Server::ReStarting in +Apache::compat [Stas] + +Apache::Resource ported to mp2 [Stas] + +If none of MP_APXS, MP_AP_PREFIX and MP_USE_STATIC were specified when +configuring Makefile.PL, we now prompt for APXS path first and only if +that fails ask for MP_AP_PREFIX. This is a requirement to get 'make +test' find httpd. [Stas] + +Dynamically prompt and add MP_INST_APACHE2=1 when installing on +systems with mod_perl 1 preinstalled. [Stas] + +fix the logging call in RegistryCooker [Lars Eggert <lars.eggert +netlab.nec.de>] + +fix $r->filename in Apache::compat to update the finfo struct (which +is how it worked in mp1) [Stas] + +enclose all occurences of eval_* with ENTER;SAVETMPS; +... FREETMPS;LEAVE; previously things just happened to work, due to +external scopes which was not very reliable and some change could +introduce obsure bugs. [Stas] + +in case a native apache response filter is configured outside the +<Location> block with PerlSet*Filter directive, make sure that +mod_perl doesn't try to add it as connection filter (previously was +logging an error like: [error] a content filter was added without a +request: includes) [Stas] + +replace the slow implementation of anon handlers using B::Deparse, +with per-interpreter cache of compiled CODE refs (sort of emulating +named subroutines for anonymous handlers) [Stas]. + +avoid segfaults when a bogus $r object is used [Stas] + +Remove magicness of PerlLoadModule and implement Apache::Module::add() +for modules that implement their own configuration directives [Gozer] + +Apache::Connection::remote_ip is now settable (needed to set the +remote_ip record based on proxy's X-Forwarded-For header) [Stas] + +Fix Modperl::Util::unload_package() [Gozer] + - Mistakenly skipping small entries of size 2 and less + - Leave entries from other packages alone + +$filter->remove now works with native (non-modperl) filters + test +[Torsten Förtsch <torsten.foertsch gmx.net>] + + + +=item 1.99_17 - October 22, 2004 + +Implement Apache->unescape_url_info in Apache::compat and drop it +from the official API for CGI::Util::unescape() as a suggested +replacement [Gozer] + +fix xs_generate to croak on duplicate entries in xs/maps files +[Christian Krause <chkr plauener.de>] + +Workaround a possible bug in Perl_load_module() [Gozer] + +Fix a problem building with non-GNU make (can't make target dynamic +in xs/APR/aprext) [Gozer] + +escape HTML in dumped variables by Apache::Status [Markus Wichitill +<mawic@gmx.de>] + +$r->document_root can now be changed when safe to do so [Gozer] + +APR::Bucket->new now requires an APR::BucketAlloc as its first argument. +New subs added: APR::Bucket::setaside, APR::Bucket::alloc_create, +APR::Bucket::alloc_destroy, APR::Brigade::bucket_alloc. [joes] + +reimplement APR::Pool life-scope handling, (the previous +implementation had problems) [joes] + +make sure that Apache::Filter::read, APR::Socket::recv, +Apache::RequestIO::read, APR::Brigade::flatten, and APR::Bucket::read +all return tainted data under -T [Stas] + +tag the custom pools created by mod_perl for easier pools debug [Joe +Orton] + +fix a bug in non-ithreaded-perl implementation where the cached +compiled CODE refs of httpd.conf-inlined one-liner handlers like: +PerlFixupHandler 'sub { use Apache::Const qw(DECLINED); DECLINED }' +didn't have the reference count right. [Stas] + +per-server PerlSetEnv and PerlPassEnv values are properly added +to %ENV when only a per-directory handler is configured. +[Geoffrey Young] + +resolve several 'Use of uninitialized value in...' warnings in +Apache::Status [Stas]. + +make install and static build now correctly installs mod_perl as +well as the statically built apache [Gozer] + +if some code changes the current interpreter's tainted state to on, +the return value from the handler callback will be tainted, and we +fail to deal with that. So revert to coercing any return value, but +undef (a special case for exit()). to IV, so that tainted values are +handled correctly as well. [Stas] + +make sure that each handler callback starts with a pristine +tainted-ness state, so that previous callback calls won't affect the +consequent ones. Without this change any handler triggering eval or +another function call, that checks TAINT_PROPER, will crash mod_perl +with: "Insecure dependency in eval while running setgid. Callback +called exit." farewell message [Stas] + +make sure that 'make distclean' cleans all the autogenerated files +[Stas] + +$r->log_reason has been ported and moved out of Apache::compat +[Gozer] + +APR::OS::thread_current renamed APR::OS::current_thread_id and +now returns the actual thread_id instead of an object that +needed to be dereferenced to get at the thread_id [Gozer] + +change a bunch of the APR:: constants to have a better prefix +(APR::FILETYPE_* and APR::FILEPROT_). libapr will be changed soon too +[Stas] + +Generate modperl_exports.c for static builds to prevent the +linker from stripping needed but unused symbols [Gozer] + +Add .libs/ as part of the library search path when building +against httpd's source tree [Gozer] + +In the static build, run make in httpd's srclib/ early to have +generated files present at mod_perl configure time [Gozer] + +When searching for ap(r|u)-config in httpd's source tree, search +into srclib/apr-util as well as srclib/apr [Gozer] + +Remove APR::Finfo::pool as it has no use to us [Stas] + +get PerlSetVar and PerlAddVar multi-level merges to (finally) work +properly. [Rici Lake <rici ricilake.net>] + +MP_AP_BUILD configure option removed. Now implicit when MP_USE_STATIC +is specified [Gozer] + +Apache::Module $mod->version() and $mod->minor_version() renamed +to $mod->ap_api_major_version() and $mod->ap_api_minor_version +for clarity [Gozer] + +Apache::Log changes: [Stas] + - moved to compat: Apache::warn, Apache->warn, Apache::Server->warn, + Apache::Server::warn + - re-enabled $r->warn + - removed support for Apache::ServerRec->warn + (Apache::ServerRec::warn is still there) + +Apache::Directive conftree() changed from class method to +regular subroutine [Gozer] + +Apache::Module top_module() and get_config() as class methods +added to Apache::compat for backwards compatibility [Gozer] + +Apache::Module top_module() and get_config() changed from class +methods to regular subroutines [Gozer] + +Added Apache::CmdParms::add_config() to work around a memory +leak discovered with <Perl> sections in .htaccess files [Gozer] + +Added ModPerl::Util::unload_package() to remove a loaded package +as thoroughly as possible by clearing it's stash. [Gozer] + +fix Apache->request($r) to be set-able even w/: PerlOptions +-GlobalRequest [Stas] + +Add Apache::Reload->unregister_module() to explicitely remove a +module from Apache::Reload's monitoring list [Gozer] + +introduce a custom modperl error message for failing filter handlers +(previously 'unknown error' coming from rc=500 was logged) [Stas] + +Fix Apache::Log methods/functions to log into the vhost's error_log +file (if there is one). ( $s->log->*, $s->log_error, $s->log_serror, +Apache::ServerRec::warn, etc.). Apache::ServerRec can now export its +warn function to override CORE::warn [Stas] + +Fix $s->log->*, $s->log_error and $s->log_serror to again log into the +vhost's error_log file (if there is one). [Stas] + +$s->log->warn and other $s->log->foo are now logging to the right +vhost server and not the global one. modperl_sv2server_rec was +broken. [Stas] + +Fix a glue_pod make target bug, when .pm file doesn't exist, +e.g. ThreadMutex.pm is not created on unless +$apr_config->{HAS_THREADS} [Stas] + +Introduce APR::Socket::poll to poll a non-blocking socket [Ken Simpson +<ksimpson@larch.mailchannels.com>] + +Fix the error message when the minimal required httpd version is not +satisfied [Pratik <pratiknaik@gmail.com>] + +Fix interactive prompting at perl Makefile.PL, when no APXS or +MP_AP_PREFIX were provided. now asking for an alternative location if +the suggested choices weren't selected. [Stas] + +Added APR::URI->rpath method. Returns the path of an uri minus +path_info, if any. [Gozer] + +moved Apache::current_callback() to ModPerl::Util::current_callback +where it belongs [Gozer] + +modperl_perl_module_loaded() fixed to use %INC to determine if a module +is loaded instead of checking for the existence of a stash [Gozer] + +fix the modperl build, where httpd has been built against separate +installations of apr-util and apr, where apr-util has been installed +with a different includedir to apr. [Joe Orton] + +$Apache::Server::SaveConfig is now $Apache::PerlSections::Save +[Geoffrey Young] + + + +=item 1.99_16 - Aug 22, 2004 + +Fix a compilation problem breaking 1.99_15 (sv_copypv was added in +perl 5.7.3) [Jason Woodward <woodwardj@jaos.org>] + +Added $r->content_languages in Apache::RequestRec [Gozer] + +APR::Bucket: add delete() and destroy() methods [Stas] + + + +=item 1.99_15 - Aug 20, 2004 + +replace the memory allocation for modperl filter handlers to use a +temporary subpool of the ap_filter_t object. previously using perl's +safemalloc had problems on win32 (randomly my_perl == NULL) [Stas] + +Disable Apache::HookRun::run_create_request -- it's already run +internally by Apache::RequestRec->new [Stas] + +Update Apache::RequestRec->new() to initialize members of request_rec +which were added some time ago (without it we were getting segfaults +in the new pseudo_http test. [Stas] + +Apache::CmdParms->limited member replaced by is_method_limited() +method [Gozer] + +Apache::Module changes [Gozer] +- readwrite => readonly: + cmds, next, name, module_index, minor_version, version +- removed: remove_module + +ensure that a sub-dir Apache-Test exists in the source distro (this is +a requirement, since the test suite relies on the particular +Apache-Test version distributed with the mod_perl source) [Stas] + +combine handler resolving failure error with the actual error, so +there is only one logged entry [Stas] + +pod manpages are now glued to all .pm files for which .pod exists at +'make install' phase [Stas] + +Apache::RequestIO::sendfile() now indicates which file it has failed +to open on failure. [Stas] + +fix Apache::SubRequest's methods: lookup_file, lookup_uri, +lookup_method_uri to default the last argument to +r->proto_output_filters (no request filters for the subrequest) and +not r->output_filters->next as it was before (one filter was getting +skipped and the rest of the filters were applied *twice*). [Stas] + +Apache::CmdParms changes [Gozer] +- readwrite => readonly: + override, limited, directive, pool, temp_pool, server, path, + cmd, context, err_directive + +- removed: limited_xmethods, xlimited, config_file, err_directive + +Fix a bug in APR::Bucket->new when a passed argument was of type +PADTMP [Stas] + +Apache::Connection changes [Stas, "Fred Moyer" <fred /about/ +taperfriendlymusic.org>] +- readwrite => readonly: + + pool, base_server, local_addr, remote_addr, remote_ip, remote_host, + aborted, local_ip, local_host, id, conn_config, sbh, bucket_alloc + +- removed: logname + +Move check_cmd_context from Apache::Command to Apache::CmdParms. +[Gozer] + +Add :context group of constants for check_cmd_context(). +NOT_IN_VIRTUALHOST, NOT_IN_LIMIT, NOT_IN_DIRECTORY, NOT_IN_LOCATION, +NOT_IN_FILES, NOT_IN_DIR_LOC_FILE & GLOBAL_ONLY [Gozer] + +Removed Apache::Command method soak_end_container [Gozer] + +Removed Apache::Module methods (dynamic_load_handle and +find_module_name) [Gozer] + +All Apache::Command methods are now read-only [Gozer] + +Removed Apache::Command methods (func and cmd_data) [Gozer] + +Removed Apache::Directive methods (data & walk_config) [Gozer] + +All Apache::Directive methods are now read-only [Gozer] + +Filters should not reset $@ if it was already set before +invocation [Gozer] + +Apache::compat server_root_relative now correctly handles absolute +paths like ap_server_root_relative does [Gozer] + +Fix a bug in <Perl> sections with multiple aliases in a +virtualhost container. [Gozer] + +PerlModule, PerlRequire, Perl and <Perl> is now supported in +.htaccess. They will run for each request. [Gozer] + +removed support for httpd 2.0.46. httpd 2.0.47 is now the minimum +supported version. [Geoffrey Young] + +Static builds for httpd >= 2.0.51 available. With the new MP_AP_BUILD +option, configure and compile an httpd with mod_perl statically linked +in [Gozer] + +Apache::RequestRec methods changes [Stas] +- readwrite => readonly: + + connection, canonical_filename, header_only, main, next, prev, + pool, per_dir_config, request_config, proto_num, protocol, + request_time, server, the_request, unparsed_uri + +- removed: + + remaining - this method is not needed if the deprecated + $r->client_block methods aren't used, (use $r->read + $r->instead) + canonical_filename - it's a private member + +The func Apache::SubProcess::spawn_proc_prog is now a method: +$r->spawn_proc_prog [Stas] + +Apache::Process methods (pool, pconf and short_name) are now read-only +[Stas] + +($r|$c|$s)->server_root_relative were removed. Now only an explicit +and somewhat deprecated function API remains: +Apache::ServerUtil::server_root_relative($pool, $path); it's too easy +to cause memory leak with this method, and it's inefficient as it +duplicates the return value, to avoid potential segfaults if the pool +it was allocated from gets destroyed and the value is attempted to be +used. Instead of this method use the equivalent: +File::Spec->catfile(Apache::ServerUtil::server_root, $fname); [Stas] + +$r->psignature now lives in the package it belongs to: +Apache::RequestUtil (previously lived in Apache::ServerUtil). [Stas] + +A few functions moved namespace from Apache:: to Apache::ServerUtil:: +(to make it easier to find the container of the function): [Stas] + - exists_config_define + - server_root + - get_server_built + - get_server_version + +fix an old outstanding bug in the APR::Table's TIE interface with +each()/values() over tables with multi-values keys. Now the produced +order is correct and consistent with keys(). Though, values() works +correctly only with perl 5.8.x and higher. [Joe Schaefer] + +require Perl 5.6.1, 5.6.0 isn't supported for a long time, but we +weren't aborting at the Makefile.PL stage [Stas] + +Apache::RequestUtil::method_register($s->process->pconf, 'FOO'); is +now $s->method_register('FOO'). +Apache::RequestUtil::add_version_component($s->process->pconf, 'BAR/0.1'); +is now $s->add_version_component('BAR/0.1'). [Stas] + +Remove $Apache::Server::StrictPerlSections. Now, all <Perl> +sections errors are fatal by default and cause server startup to +abort on error. [Gozer] + +Fix ($r|$filter|$bucket)->read() functions to run the set magic logic, +to handle cases when a passed buffer to fill is not a regular +scalar. [Stas] + +Apache::ServerRec accessors changes: [Stas] +- readonly accessors: + + process, next, is_virtual, module_config, lookup_defaults and + addrs + +- readwrite accessors with the exception of threaded mpms, where the + accessors are writable only before the child_init phase (i.e. before + threads are spawned): + + server_admin, server_hostname, port, error_fname, error_log, + loglevel, timeout, keep_alive_timeout, keep_alive_max, keep_alive, + names, wild_names, limit_req_line, limit_req_fieldsize, + limit_req_fields, and path + +supports a new type of struct accessor, which is just like read/write +one, but doesn't allow write access starting at the ChildInit phase +under threaded mpm (to avoid thread-safely issues) [Stas] + +In order to be consistent with Apache::RequestRec, Apache::Server is +now Apache::ServerRec and all methods/functions from Apache::Server +now live in Apache::ServerRec. [Stas] + +Use a context-specific Perl_load_module() instead of load_module(), to +avoid the problem with 'load_module' symbol resolution on certain +platforms, where for some reason it doesn't get resolved at compile +time to Perl_load_module_nocontext [Stas] + +Make it possible to disable mod_perl for the base server, but enable +it for the virtual hosts [Stas] + +Removed the deprecated path argument to $r->add_config() [Gozer] + +Created a META.yml for CPAN and friends, including Apache-Test as +a private resource to keep CPAN from installing mod_perl when a +user just wants Apache::Test [Gozer] + +Moving HTTP specific functions get_status_line, method_register from +Apache:: to Apache::RequestUtil:: to match their container [Stas] + +Adjust the list of mod_perl header files installed into the Apache2 +include/ directory, made necessary from the renaming and refactoring +arising from the decoupling of APR and APR::* from mod_perl.so. +Also include modperl_apr_perlio.h under xs/APR/PerlIO/ in +the list of such files installed [Stas, Randy Kobes] + +$r->read()/READ now throw exceptions [Stas] + +$r->rflush now returns nothing (was always returning APR::SUCCESS +before) [Stas] + +bug reports generating code: [Stas] +- add (apr|apu)-config linking info +- show the full path to the config file used to get the data for the + report + +The APR and APR::* family of modules can now be used without having +to load mod_perl.so. On *nix, this is done by compiling the needed +functions from the appropriate sources used to build mod_perl.so +into APR.so, and then arranging for APR::* to 'use APR ()'. On Win32, +a static library of needed functions is built, and APR/APR::* +then link into this library [Stas, Joe Schaefer, Randy Kobes] + +APR::RequestIO::sendfile() now flushes any buffered output before +sending the file contents out. If the return status is not checked and +an error happens it'll throw an exception. Fix offset handling. [Stas] + +Registry: remove the misleading prefix "$$: $class:" in the logged +error message, since not only registry errors will get logged if $@ is +set [Stas] + +change t/REPORT to suggest to post bug reports to the modperl users +list, to be consistent with the documentation [Stas] + +amd64 fixes [Joe Schaefer <joe+gmane@sunstarsys.com>] + - use IV insteaf of int where a pointer is used + - mpxs_APR__Bucket_new needs to use apr_size_t/off_set_t types + +APR::Socket::recv() now returns the length of the read data [Stas] + +APR::Bucket's read() returns "" instead of undef when there is no data +to read. [Stas] + +fix a bug in Registry handlers, where the same error was logged twice +and potentially a wrong error code returned [Stas] + +Apache::RequestIO: print(), printf(), puts(), write(), rflush() throw +an exception on failure [Stas] + +Apache::SubRequest: run() throw an exception on failure [Stas] + +Apache::Filter: [Stas] + - remove unneeded methods: remove_input_filter() and + remove_output_filter(), fputs() + - frec() accessor is made read-only + - fflush(), get_brigade() and pass_brigade() now throw exceptions if + called in the void context + - read, print() and puts() throw an exception on failure + +Apache::FilterRec: [Stas] + - remove the next() accessor since it's not used by Apache at the + moment + - name() is made read-only + +APR::URI: [Stas] + - removed accessors + o is_initialized() (internal apr_uri flag) + o dns_looked_up() and dns_resolved() (they are not + used by apache/apr) + - all remaining accessors now accept undef value, which unsets the + field + +Extended WrapXS code to support a new type of accessor: char * which +accepts undef to set the C pointer to NULL and as such unset the +member of the struct. [Stas] + +Exception error messages now include the error id along with the error +message (as they did in first place). [Stas] + +$r->finfo now accepts APR::Finfo object as an optional +argument. [Stas] + +APR::Finfo [Stas] + - change stat() to return finfo + - make all field accessors readonly + +ARP::password_validate is now ARP::Util::password_validate [Stas] + +APR::IpSubnet::new() now throws APR::Error exception (not returning +rc) [Stas] + +rename package APR::NetLib -> APR::IpSubnet to match the class name +[Stas] + +APR::BucketType: [Stas] + - name is readonly + +APR::Brigade [Stas] + - destroy() now throws APR::Error exception (not returning rc) + - rename empty => is_empty + - added the method cleanup() + - flatten() now returns the number of bytes read (and passed the + buffer by the argument) and throws APR::Error exception + +APR::Bucket: [Stas] + - read() now returns the length of the read data and throws + APR::Error exception (not returning rc). The returned scalar is + now TAINTED. + - type->name now has a module APR::BucketType + - type(), length(), start(), data() are now all readonly + - new() fix a bug in offset handling + + + +=item 1.99_14 - May 21, 2004 + +APR::SockAddr::port() accessor is now read-only [Stas] + +APR::Pool now has destroy() and clear() available [Stas] + +now logging the errors happening in pool cleanup callbacks [Stas] + +use the new Apache-Test attribute -minclient in the test suites. Now +along with the default maxclients = minclients+1, we no longer should +get 'server reached MaxClients setting' errors. [Stas] + +new API for APR::Socket recv() and send() + updated tests [Stas] + +add infrastructure for new ModPerl::Const constants and the first +constant ModPerl::EXIT. [Stas] + +re-implement ModPerl::Util::exit to use exception objects, so it's +possible to detect exit called in eval context and call it again +outside the eval context. [Stas] + +add the perl interface for the new exception handling code (mod_perl, +apache and apr methods will now throw exceptions with $@ being an +object). New class APR::Error was added, to handle the exception +objects with overload methods. Also added confess and croak +equivalents of Carp's methods, since at the moment the Carp's ones +don't work as is. The following perl and C methods have been renamed: + modperl_apr_strerror => modperl_error_strerror + APR::strerror => APR::Error::strerr +[Stas] + +set the 'error-notes' table to the error message on +HTTP_INTERNAL_SERVER_ERROR [Stas] + +fix the apxs build function to not handle empty lookups as errors +[Randy Kobes, Steve Hay] + +fix type casting problems in the io functions [Stas] + +add support for libgtop 2.5.0+ (maintenance mode) [Stas] + +APR::Socket::timeout_set now croaks on failure [Stas] + +significantly speedup the startup of threaded mpm test suite, by +configuring only the minimal number of perl interpreters to start +[Stas] + +make APR::Socket::opt_(set|get) working (and change the previous +behavior) [Stas] + +make sure that our protocol module tests that interact with the socket +use a blocking read [Joe Orton] + +Use a better approach to figure out whether we need to strip perl's +LargeFilesSource flag, by checking whether libapr was compiled with +-D_FILE_OFFSET_BITS=64 or not. Checking for APR_HAS_LARGE_FILES is +useless since it doesn't tell whether 32 vs 64 bits off_t and similar +types are used [Joe Orton] + +'SetHandler perl-script' no longer grabs any newly encountered END +blocks, and removes them from PL_endav, but only if they are +explicitly registered via ModPerl::Global::special_list_register(END +=> $package_name) (this is a new function). It's now possible to have +a complete control of when END blocks are run from the user space, not +only in the registry handlers [Stas] + +END blocks encountered by child processes and not hijacked by +ModPerl::Global::special_list_register() are now executed at the +server shutdown (previously they weren't executed at all). [Stas] + +Added test to ensure <Perl> sections can have things like %Location +tied [Gozer] + +Fix the installation on Win32 so that an appropriate Apache2 +subdirectory under the Perl tree is used when MP_INST_APACHE2 is +specified [Randy Kobes] + +Fix a redefined warning in Apache::Status [Stas] + +Fix Apache::Status, to lookup the Apache::Request version without +loading it. Only if a suitable (2.x) version is found -- load and use +it. Previously loading the 1.x version was affecting Apache::compat. +[Stas] + +Fix a bug in special blocks handling (like END), which until now was +dropping on the floor all blocks but the last one (mainly affecting +registry handlers). [Stas] + +The filter streaming API print() function, now correctly handles a +binary data [Stas] + +Fix Registry handlers, not to lose the execution errors, when they +include END blocks [Stas] + + + +=item 1.99_13 - March 8, 2004 + +respect $ENV{APACHE_TEST_STARTUP_TIMEOUT} settings if any [Stas] + +Added tests for issuing subrequests from filters [Geoffrey Young] + +Updated to the new Apache License Version 2.0 [Gozer] + +Drop the support for making GATEWAY_INTERFACE special. It's not needed +as $ENV{MOD_PERL}, available in both mod_perl generations, should be +used to test whether the code is running under mod_perl. [Stas] + +Handle correctly the situation when response HTTP headers are printed +from the handler and the response body starts with \000, which is the +case with some images like .ico. [Stas] + +Apache::PerlSections->dump() and store(filename) [Gozer] + +expose $c->keepalive related constants and $c->keepalives counter +[Stas] + +Perl handlers are now guaranteed to run before core C handlers for +all request phases. [Geoffrey Young] + +Fix the STDIN/OUT overriding process to handle gracefully cases, when +either or both are closed/bogus (the problem was only with useperlio +enabled perl) [Stas] + +copy apr_table_compress logic from later httpd versions in case mod_perl +is built against 2.0.46, as mod_perl now requires it internally. users +should be aware that 2.0.47 may become the oldest supported httpd version +in the near future. [Geoffrey Young] + +Fix the corruption of the httpd process argv[0], caused by $0 +manipulating [Stas] + +ModPerl::MethodLookup::lookup_method now handles sub-classed objects +[Stas] + +standard %ENV population with CGI variables and contents of the +subprocess_env table (such as SetEnv and PassEnv) has been delayed +until the last possible moment before content-generation runs. +PerlSetEnv and PerlPassEnv are each an exception to this and are +placed in both %ENV and the subprocess_env table immediately, +regardless of the current [+-]SetupEnv setting. +[Geoffrey Young] + +fix PerlAddVar configuration merging [Geoffrey Young] + +Anonymous subs are now supported in push_handlers, set_handlers, +add_input_filter, etc. A fast cached cv is used with non-ithreaded +perl. A slower deparse/eval approach (via B::Deparse) is used with +ithreads enabled perls. Further optimizations are planned for the +latter case. [Stas] + +ht_time w/o the pool is now available only via override/restore compat +API. format_time, has been renamed back to ht_time, and the default +values for fmt, time and gmt are now supported. [Stas] + +it's now possible to push new handlers into the same phase that is +running at the moment [Stas]. + +when $r->handler($new_handler) is called from a response phase, it now +checks that the response handler type is not switched (e.g. from +'modperl' to 'perl-script') from the currently used one [Stas] + +Since Apache::SubProcess is now part of the mp2 API, add +$r->cleanup_for_exec as a noop in Apache::compat. That function is no +longer needed in Apache2. [Stas] + +When 'perl Makefile.PL PREFIX=/foo/bar' is used and mod_perl 1 is +found, but at different prefix no longer require +MP_INST_APACHE2=1. [Stas] + +modperl_mgv_resolve now croaks when a module scheduled for autoloading +fails to load. AutoLoaded modules shouldn't silently fail. [Stas] + +Perl(Input|Output)FilterHandler handlers are now always AutoLoaded, as +if '+' prefix was used. This must be performed to get the access to +filter attributes long before the filter itself is executed. [Stas] + +APR/Pool.xs has been reimplemented. The problem with the previous +implementation is that a dead perl pool object could hijack a newly +created pool, which didn't belong to that object, but which happened +to be allocated at the same memory location. The problem is that +apr_pool_user_data_set/get has no mechanism to check whether the pool +has changed since it was last assigned to (it does but only in the +debug mode). It really needs some signature mechanism which can be +verified that the pool is still the same pool. Since apr_pool doesn't +have this feature, the reference counting has been reimplemented using +a plain sv reference. Several new (mainly hijacking) tests which badly +fail with the previous impelementation have been added. [Stas] + +fix calling $r->subprocess_env() in a void context so that it only +populates %ENV if also called with no arguments. also, make sure it +can be called more than once and still populate %ENV. +[Geoffrey Young] + +add APR::Brigade::pool() to allow access to the pool associated with +the brigade [Geoffrey Young] + +make 't/TEST -startup_timeout secs' working (previously user's value +was ignored) [Stas] + +ModPerl::Registry and friends now support non-parsed headers scripts, +whose filename =~ /^nph-/, identically to mod_cgi. + test [Stas] + +implement APR::Brigade::length() and APR::Brigade::flatten() (the +latter implements a wrapper for apr_brigade_flatten, but also includes +an emulation of apr_brigade_pflatten) as [Geoffrey Young] + +($r|$s)->add_config() now die if failed (previously returned the +error) [Stas] + +fix context problems in <perl> sections and +PerlModule/PerlLoadModule/PerlRequre under threaded mpms w/ +PerlOptions +Parent/+Clone in Vhosts + TestVhost::config test. [Stas] + +Implemented Apache::get_server_version and Apache::get_server_built +as constant subroutines [Geoffrey Young] + +Moved some functions out of the Apache:: namespace: + Apache::unescape_url() is now Apache::URI::unescape_url() + Apache::log_pid() is now Apache::Log::log_pid() + Apache::LOG_MARK() is now Apache::Log::LOG_MARK() +[Geoffrey Young] + +if MP_AP_PREFIX is used apxs and apr-config from the apache build tree +won't work, so it can't co-exist with MP_APXS and MP_APR_CONFIG build +options - ensure that this doesn't happen. [Stas] + +server_root_relative() now requires either a valid pool or an $r, $s, +or $c object as a first argument. also, the returned result is a +copy, protecting against cases where the pool would go out of scope +before the result. [Geoffrey Young] + +Check the success of sysopen in tmpfile() in compat [Geoffrey Young] + +make sure DynaLoader is loaded before XSLoader, not only with perl +5.6.1, but always because of the issues with <Perl> sections are +loaded from +Parent vhost [Stas] + +added ($r|$s)->is_perl_option_enabled($option_name), to test for +PerlOptions + tests [Stas] + +On Solaris add a workaround for xs/APR/APR/Makefile.PL to build +APR.so, correctly linked against apr and apr-util libs, by addding the +missing -R paths corresponding to -L flags. EU::MM was adding them via +LD_RUN_PATH instead of using -R, but since perl's lddflags may have -R +it overrides LD_RUN_PATH. So explicitly add anything that may go into +LD_RUN_PATH via -R. Also make sure that -R coming from Apache will +appear first. [Brad Lanam <bll@gentoo.com>] + +'make dist' now generates and picks Apache-Test/META.yml which was +always reported missing, as it was included in Apache-Test/MANIFEST +[Stas] + +fix the $r->read function to return undef on failure similar to the +core perl function and make $! available for those who test for read() +failures. [Stas] + +Make sure that pnotes are destroyed after PerlCleanup handlers are +finished and not before + test. [Stas] + + + +=item 1.99_12 - December 22, 2003 + +Restore a proper behavior of all Registry handlers, but PerlRun, not +to reset %INC to forget any .pl files required during the script's +execution. [Stas] + +<Perl> are now evaluating code into one distinct namespace per +container, similar to ModPerl::Registry scripts. [Philippe M. Chiasson] + +Fix ModPerl::MM::WriteMakefile to use the MODPERL_CCOPTS entry from +Apache::BuildConfig, as it contains some flags added by mod_perl, +which aren't in perl_ccopts and ap_ccopts. [Stas] + +Add the implementation of Apache::Connection::local_addr and +Apache::Connection::remote_addr to the Apache::compat overridable +functions. [Stas] + +Apache::compat's implementation of APR::URI::unparse, +Apache::RequestRec::finfo and Apache::RequestRec::notes is now +overridable and not enabled by default. [Stas] + +Apache::compat no longer enables functions which collide with mp2 API +by default. It provides two new functions: override_mp2_api and +restore_mp2_api to override and restore the original mp2 API. [Stas] + +For Win32, add a .bat extension to candidates for the apxs and +apr-config utilities used in Apache::Build, so that the -x file +test can potentially succeed [Randy Kobes] + +Plug a memory leak with 'perl-script' not cleaning up the temp vars +created during the override of STDIN/STDOUT to use the :Apache IO +layer [Stas] + +libgtop config (needed for enabling MOD_PERL_TRACE=m) is now searched +using the gnome packaging tools if available (pkg-config for gnome-2.x +and gnome-config for gnome-1.x) [Stas] + +Prevent a problem where an autovivified package (stash) prevents from +modperl_mgv to load the file with that package (until now it was +checking whether the stash existed already and skipped the loading if +that was the case). Now checking %INC and attempting to load the +module. Reporting the failure only if the module has failed to load +and the stash is not defined (so that it's possible to autovivify +packages without loading them from an external file). [Stas] + +MaxClients is now overridable from the t/TEST -maxclients command line +option (it was hardcoded before). [Stas] + +Postpone the allocation of the wbucket in filters till the moment it's +needed (if at all). Since non-streaming filters aren't going to use +that buffer, it's a waste to allocate/free it. [Stas] + +Extend the autogenerated bug report to include information about +installed modules of special interest (which may aid in understanding +the bug report), such as CGI.pm, Apache::Request, LWP, etc. [Stas] + +As the test suite keeps on growing, it takes longer time to +startup. Change the main test suite timeout to 180 secs for threaded +mpms and 120 secs for non-threaded ones. [Stas] + +use plain malloc/free to allocate filter structs, since they could be +invoked hundreds of times during a single request, causing huge memory +demands if the memory is allocated from the pool, which gets destroyed +only at the end of a request. [Stas] + +Fix a compilation error in APX.xs when MP_HAVE_APR_LIBS is not defined +[Fred Moyer <fred@taperfriendlymusic.org>] + +fix a memory leak when $filter->ctx is used [Stas] + +fix buglet on Win32 (and potentially other non-Unix platforms) +where not all files were being installed under a relative Apache2 +subdirectory when MP_INST_APACHE2 was specified [Randy Kobes]. + +deprecated APR::SockAddr::port_get()/APR::SockAddr::port_set() +replaced with direct access to the port record via +APR::SockAddr::port(). [Geoffrey Young, Stas] + +deprecated APR::URI::default_port_for_scheme() replaced with +APR::URI::port_of_scheme() [Geoffrey Young] + +deprecated APR::SockAddr::ip_set() and APR::NO_TIMEOUT removed. +[Geoffrey Young] + +Apache::MPM->is_threaded() replaces Apache::MPM_IS_THREADED +[Geoffrey Young] + +fix "PerlSetVar Foo 0" so that $r->dir_config('Foo') returns 0, not undef +[Geoffrey Young] + +add Apache::MPM class, along with show() and query() class methods +[Geoffrey Young] + +add :mpmq import tag to Apache::Const [Geoffrey Young] + +Fix ModPerl::Registry handlers family to modify $0 only for the +duration of the handler, by localizing it [Stas] + +Fix :Apache perlio's STDOUT to be reentrant + modules/include_subreq +test [Stas] + +fix slurp_filename to always open the file and not try to guess +whether filename has been already opened, as there is no reliable way +to accomplish that [Stas] + +Apache->can_stack_handlers is now in Apache::compat (mp2 always can +stack handlers) [Stas] + +add access to $r->finfo() and related APR::Finfo methods, +such as $r->finfo->size(), $r->finfo->mtime(), and +$r->finfo->stat() [Geoffrey Young] + +add :filetype import tag to APR::Const [Geoffrey Young] + +<Perl> sections now properly set $0 to the name of the configuration +file they are in. [Philippe M. Chiasson] + +Apache::Status: provide a workaround for Config::myconfig() which +fails under threads with (5.8.0 < perl < 5.8.3) [Elizabeth Mattijsen +<liz@dijkmat.nl>] + +Fix Apache::Status::handler to return 'Apache::OK' [Juanma Barranquero +<lektu@terra.es>] + +<Perl> sections now properly set filename and line number information, +making error messages report the correct location. [Philippe M. Chiasson] + + + +=item 1.99_11 - November 10, 2003 + +add a build/win32_fetch_apxs script (called within the top-level +Makefile.PL) to offer to fetch and install a Win32 development +version of apxs and (apr|apu)-config [Randy Kobes] + +rewrite $r->read() and perlio read functions to use the same function, +which completely satisfies the read request if possible, on the way +getting rid of get_client_block and its supporting functions which +have problems and will most likely will be removed from the httpd-API +in the future. Directly manipulate bucket brigades instead. [Stas] + +Since Apache2.pm pops /foo/Apache2 dirs to the top of @INC, it now +also takes care of keeping lib and blib dirs before the system dirs, +so that previously installed libraries won't get loaded instead of the +currently uninstalled libraries that are under test. [Stas] + +When 'make test' fails we now print the info on what to do next [Stas] + +At the end of 'make install' we now print the info how to proceed with +mod_perl and what to do in the case of post-install problems +[Geoffrey Young] + +Adjust the source to properly work with 5.8.2's new algorithm of +dynamic re-hashing of hashes on hash collision attack. [Nicholas Clark +<nick@ccl4.org>, Stas]. Add a test that mounts such an attack so we +can verify that we can survive this rehashing. [Scott A Crosby +<scrosby@cs.rice.edu>, Nicholas Clark <nick@ccl4.org>, Tels +<perl_dummy@bloodgate.com>, Mark Jason Dominus <mjd@plover.com>, Stas] + +Standardize the Apache::PerlSections package name to it's plural form for +clarity and so that the pod gets glued in it's proper place. +[Philippe M. Chiasson <gozer@cpan.org>] + +return value from Perl callbacks are now passed directly to Apache +without additional post-call manipulations (such as assuming HTTP_OK +should really be OK). [Geoffrey Young] + +perl 5.8.1 w/ ithreads has a bug where it reports the wrong parent pid +(as if the process was never forked), provide a local workaround (+ new +test). [Rafael Garcia-Suarez <rgarciasuarez@free.fr>] + +overridden STD* streams now can be further overridden and will be +properly restored, which allows functions like $r->internal_redirect +work (+add tests) [Stas] + +implement perlio's getarg hook, which now allows duping STD* streams +overloaded by modperl [Stas] + +Add PerlMapToStorageHandler [Geoffrey Young] + +callbacks are now expected to return a meaningful value +(OK, SERVER_ERROR, etc) or return via an official API +(exit, die, etc). relying on implicit returns from the +last call evaluated by a subroutine may result in server +errors. [Stas, Geoffrey Young] + +in the MP_MAINTAINER mode add the -Werror compilation flag when perl +v5.6.2 or higher is used, so that we don't miss compilation +warnings. [Stas] + +fix the Makefile.PL option parser to support overriding of certain +build options, in addition to appending to them (.e.g. now MP_LIBNAME +is overridable) [Andrew Wyllie <wyllie@dilex.net>] + +make sure that connection filters won't be inserted as request filters +[Stas] + +Prevent the 'Use of uninitialized value.' warning when +ModPerl::Util::exit is used. [Stas] + +To make the test-suite sandbox-friendly, which break when things try to +run off /tmp, use t/logs as the location of the mod_cgid socket and +TMPDIR env var [Haroon Rafique <haroon.rafique@utoronto.ca>] + + + +=item 1.99_10 - September 29, 2003 + +added Apache::CRLF, Apache::CR, and Apache::LF to +Apache::Const's :platform group [Geoffrey Young] + +make sure that the custom pools are destroyed only once and only when +all references went out of scope [Stas] + +($r|$c)->add_(input|output)_filter(\&handler) now verify that the +filter of the right kind is passed and will refuse to add a request +filter as a connection filter and vice versa. The request filter +handler is not required to have the FilterRequestHandler attribute as +long as it doesn't have any other attributes. The connection filter +handler is required to have the FilterConnectionHandler +attribute. [Stas] + +fix tracing with (PerlTrace/MOD_PERL_TRACE) on win32 (the error_log +filehandle was invalid after the open_logs phase) [Stas] + +fix a bug where %ENV vars set via subprocess_env persist across +requests. (e.g. a Cookie incoming header which ends up in +$ENV{HTTP_COOKIE} would persist to the next request which has no +Cookie header at all). Now we unset all the %ENV vars set from +subprocess_env. Improve and extend the tests to cover this bug. [Stas] + +it is invalid to return HTTP_INTERNAL_SERVER_ERROR or any other HTTP +response code from modperl_wbucket_pass, therefore set the error code +into r->status and return APR_SUCCESS. Until now response handler +with messed up response headers, were causing no response what so ever +to the client. LWP was assuming 500, and it was all fine, testing +without LWP has immediately revealed that there was a problem in the +handling of this case. [Stas] + +put the end to the 'Not a CODE reference' errors, instead provide an +intelligent error message, hopefully telling which function can't be +found. at the same time improve the tracing to include the pid/tid of +the server that has encountered this problem, to make it easier to +debug. [Stas] + +mod_perl handler must be duped for any mpm which runs within +USE_ITHREAD. Until now there was a big problem with prefork mpm if +any of its vhosts was using PerlOptions +(Parent|Clone) and happened +to load handlers before the main server. When that was happening the +main server will see that the handler was resolved (since it sees the +handler struct from the vhost that loaded this module, instead of its +own), which in fact it wasn't, causing the failure to run the handler +with the infamous 'Not a CODE reference' error. [Stas] + +Make sure that the static mod_perl library is built after the dynamic +(a requirement on win32) [Steve Hay <steve.hay@uk.radan.com>] + +Apache::Status now generates HTML 4.01 Strict (and in many cases, also +ISO-HTML) compliant output. Also add a simple CSS to make the reports +look nicer. [Ville Skyttä <ville.skytta@iki.fi>] + +APR::Pool::DESTROY implemented and tweaked to only +destroy pools created via APR::Pool->new() [Geoffrey Young] + +$r->slurp_filename is now implemented in C. [Stas] + +remove support for httpd 2.0.45/apr 0.9.3 and lower. +httpd 2.0.46 is now the minimum supported version. +[Geoffrey Young] + +APR::PerlIO now accepts the pool object instead of a request/server +objects, so it can be used anywhere, including outside mod_perl [Stas] + +when perl is built with perlio enabled (5.8+) the new PerlIO Apache +layer is used, so now one can push layers onto STDIN, STDOUT handles +e.g. binmode(STDOUT, ':utf8'); [Stas] + +add ap_table_compress() to APR::Table [Geoffrey Young] + +alter stacked handler interface so that mod_perl follows Apache +as closely as possible with respect to VOID/RUN_FIRST/RUN_ALL +handler types. now, for phases where OK ends the Apache +call list (RUN_FIRST handlers, such as the PerlTransHandler), +mod_perl follows suit and leaves some handlers uncalled. +[Geoffrey Young] + +Apache::Build now tries to use the new APR_BINDIR query string to find +the location of apr-config. [Stas] + +new package Apache::porting to make it easier to port mp1 code to mp2 +[Stas] + +new Apache::Build methods: mpm_name(), mpm_is_threaded(). use them in +the top-level Makefile.PL to require 5.8.0/ithreads if mpm requires +threads. [Stas] + +add the missing XS methods to ModPerl::MethodLookup, add support for +mp1 methods that are no longer in the mod_perl 2.0 API. [Stas] + +mod_perl now refuses to build against threaded mpms (non-prefork) +unless perl 5.8+ w/ithreads is used [Stas] + +don't try to read PERL_HASH_SEED env var, where apr_env_get is not +available (apr < 0.9.3) [Stas] + +APR.so now can be loaded and used outside mod_perl (all the way back +to httpd 2.0.36) [Stas] + +perl 5.8.1 randomizes the hash seed, because we precalculate the hash +values of mgv elements the hash seed has to be the same across all +perl interpreters. So mod_perl now intercepts cases where perl would +have randomize it, do the seed randomization by itself and tell perl +to use that value. [Stas] + +fix APR::PerlIO layer to pop itself if open() has failed. [Stas] + +move the definition of DEFINE='-DMP_HAVE_APR_LIBS' to the top level +Makefile.PL, since it overrides MY::pasthru target which makes it +impossible to define local DEFINE in subdirs. [Stas] + +make APR perl functions work outside mod_perl: several libraries +weren't linked. Also LIBS needs to receive all libs in one +string. [Stas] + +Apache::compat: $r->cgi_env, $r->cgi_var are now aliases to +$r->subprocess_env [Stas] + +For Win32, generate .pdb files for debugging when built with +MP_DEBUG. These will get installed into the same directory as +the associated dll/so libs. As well, install mod_perl.lib +into MP_AP_PREFIX/lib/ for use by 3rd party modules [Randy Kobes]. + +Apache2.pm is now autogenerated and will adjust @INC to include +Apache2/ subdirs only if built with MP_INST_APACHE2=1 [Stas] + +Change the default value for the argument 'readbytes' for +ap_get_brigade(), from 0 to 8192. other than being useless, 0 always +triggers an assert in httpd internal filters and 8192 is a good +default. [Stas] + +Fix DynaLoader breakage when using DL_GLOBAL on OpenBSD +[Philippe M. Chiasson <gozer@cpan.org>] + +renamed the private modperl_module_config_get_obj function to +modperl_module_config_create_obj, since the logic creates +the object but doesn't dig it out if it already exists. then, +moved logic from mpxs_Apache__Module_get_config into a new public +C function that reused the old name, modperl_module_config_get_obj. +while Apache::Module->get_config exists as a wrapper to return the +object to Perl space, now C/XS folks can also access the object +directly with the public function. +[Geoffrey Young] + +Apache::Reload: add a new config variable: +ReloadConstantRedefineWarnings to optionally shut off the constant sub +redefine warnings [Stas] + +implement $parms->info. directive handlers should now be complete. +[Geoffrey Young] + +MP_GTOP now works with modern GCC +[Philippe M. Chiasson <gozer@cpan.org] + +add missing dependencies to Apache::PerlSections +[Geoffrey Young] + +$r->get_client_block is bogus in httpd-2.0.45 (and ealier), as it +can't handle EOS buckets arriving in the same bucket brigade with +data. so rewrite ModPerl::Test::read_post to use an explicit read +through all bucket brigades till it sees eos and then it stops. The +code is longer but it works correctly. [Stas] + +an attempt to resolve the binary compatibility problem in +PerlIOAPR_seek API when APR_HAS_LARGE_FILES=0 [Stas] + +perl 5.8.0 forgets to export PerlIOBase_noop_fail, causing problems on +win32 and aix. reimplement this function locally to solve the +problem. APR::PerlIO should now be useful on win32 and aix [Stas] + +implement DECLINE_CMD and DIR_MAGIC_TYPE constants +[Geoffrey Young] + +allow init filter handlers to call other methods than just $f->ctx [Stas] + +Fix Apache::Reload to gracefully handle the case with empty Touchfiles +[Dmitri Tikhonov <dmitri@netilla.com>] + +PerlRequire entried should be executed before PerlModule entries in +VirtualHost containers, just like in the base server [Stas] + + + +=item 1.99_09 - April 28, 2003 + +$filter->seen_eos() now accepts 1/0 to set/unset the flag so streaming +filters can control the sending of EOS. [Stas] + +support systems where apr header files are installed separately from +httpd header files ["Andres Salomon" <dilinger@voxel.net>] + +implement init filter handlers + tests [Stas] + +improving ModPerl::MethodLookup to: +- handle more aliased perl XS functions +- sort the methods map struct so one can use the autogenerated map as is +- add lookup_module, tells which methods are defined by a given module +- add lookup_object, tells which methods can be called on a given object +- provide autoexported wrappers print_method, print_module and + print_object for easy deployment from the command line +[Stas] + +add Perl glue for functions: APR::Socket::timeout_get +APR::Socket::timeout_set [Stas] + +similar to SetEnv, upcase the env keys for PassEnv on platforms with +caseless env (e.g. win32) [steve.sparling@ps.ge.com] + +Add a backcompat wrapper for $r->notes (mp2 supports only the +APR::Table API) [Stas] + +Add a script mp2bug and a target 'make bugreport', so people can use +bugreporting during the build and after modperl is installed. [Stas] + +Add a script mp2doc as a replacement for perldoc (due to 2.0 modules +living under Apache2, which won't be looked at by perldoc). [Stas] + +Add a constant APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED and use it in +tests [Stas] + +Require perl 5.8 or higher when building mod_perl on OSes requiring +ithreads (e.g., win32), since 5.6.x ithreads aren't good. [Stas] + +MP_COMPAT_1X=0 now can be passed to Makefile.PL to disable +mp1-back-compat compile-time features + adjust tests. [Stas] + +<SERVER_ROOT> and <SERVER_ROOT>/lib/perl are now added to @INC, just +like mod_perl 1.0 with MP_COMPAT_1X=1 (currently enabled by +default). [Stas] + +The Perl-5.8.0 crypt() workaround is now used only if 5.8.0 is used, +since 5.8.1-tobe/5.9.0-tobe(blead-perl) won't compile with +it. [Geoffrey Young] + +new directives PerlSetInputFilter and PerlSetOutputFilter, which are +the same as SetInputFilter and SetOutputFilter respectively, but allow +to insert non-mod_perl filters before, between or after mod_perl +filters. + tests [Stas] + +improved filters debug tracing [Stas] + +implement $filter->remove (filter self-removal) + tests [Stas] + +remove the second-guessing code that was trying to guess the package +name to load from the handler configuration (by stripping ::string and +trying to load the package). fall back to using explicit PerlModule to +load modules whose handler sub name is not called 'handler' + adjust +tests. [Stas] + +set the magic taint flags before modules are required [Stas] + +make sure to set base server's mip before any of the +PerlRequire/PerlModule directives are called, since they may add +add_config(), which in turn runs Perl sections or PerlLoadModule, +which may need the scfg->mip to be set. [Stas] + +ModPerl::MM is now ready to be used in Makefile.PL of 3rd party +mod_perl modules [Stas and Geoff] + +fix a segfault caused by PerlModule in $s->add_config, due to setting +the MP_init_done flag before init was done + add test [Stas] + +adjust the generated Makefile's to properly build on aix (tested on +powerpc-ibm-aix5.1.0.0) [Stas] + +the build now automatically glues the .pod files to the respective .pm +files, so one can use perldoc on .pm files to read the +documentation. [Stas] + +provide a workaround for ExtUtils::MakeMaker::mv_all_methods, so +ModPerl::BuildMM and ModPerl::MM can override EU::MM methods behind +the scenes. [Stas] + +adding ModPerl::BuildMM, which is now used for building mod_perl. +ModPerl::MM will be used for 3rd party modules. ModPerl::BuildMM +reuses ModPerl::MM where possible. [Stas] + +drop the glue code for apr_generate_random_bytes, since it's not +available on all platforms. [Stas] + +Since non-threaded mpms don't use tipools in mips, don't create and +destroy them. [Stas] + +re-use the workaround for glibc/Perl-5.8.0 crypt() bug for the +main/vhost base perl interpreters as well. This solves the problem for +the buggy glibc on RH8.0. [Stas] + +send_cgi_header now turns the header parsing off and can send any data +attached after the response headers as a response body. [Stas] + +move the check that print/printf/puts/write/etc are called in the +response phase into the functions themselves so 1) we can print a more +useful error message 2) this check is not always needed in +modperl_wbucket_write, when called internally, so we save some cycles. +[Stas] + +add checks that print/printf/puts/write/etc are called in the response +phase. move the check into the functions themselves so we can print a +more useful error message [Stas] + +'make install' now installs mod_perl*h files under httpd's include +tree [Stas] + +When PerlOptions +ParseHeaders is an effect, the CGI headers parsing +won't be done if any *mod_perl* handler before and including the +response phase, sets $r->content_type. (similar behavior to mp1's +send_http_header() [Stas] + +Registry: make sure that $r is not in the scope when the script is +compiled [Stas] + +$Apache::Server::SaveConfig added. When set to a true value, +will not clear the content of Apache::ReadConfig:: once <Perl > +sections are processed. [Philippe M. Chiasson <gozer@cpan.org] + +Apache::compat: support 1.0's Apache->push_handlers, +Apache->set_handlers and Apache->get_handlers [Stas] + +revamp the code handling output flushing and flush bucket +sending. Namelly modperl_wbucket_flush and modperl_wbucket_pass now +can be told to send a flush bucket by themselves, attaching it to the +data bb they are already sending. This halfs the number of output +filter invocations when the response handler flushes output via $| or +rflush. adjust tests, which were counting the number of invocations. +[Stas] + +move ModPerl::RegistryCooker to use a hash as object (similar to mp1), +to make it easier to subclass. [Nathan Byrd <nathan@byrd.net>] + +$r->rflush has to flush internal modperl buffer before calling +ap_rflush, so implement rflush, instead of autogenerating the xs code +for it. [Stas] + +fix the input filters handling of DECLINED handlers (consume the data, +on behalf of the handler) + tests [Stas] + +fix the code that autogenerates modperl_largefiles.h not to define +macros matching m/^-/ (was a problem on aix-4.3.3) [Stas] + +$Apache::Server::StrictPerlSections added. When set to a true +value, will abort server startup if there are syntax errors +in <Perl > sections [Philippe M. Chiasson <gozer@cpan.org] + +Use Win32::GetShortPathName for Win32 to handle cases when +the supplied MP_AP_PREFIX contains spaces. [Randy Kobes] + +Bump up ThreadsPerChild for mpm_winnt in httpd.conf, which seems +to help avoid server startup problems when running the tests. +[Randy Kobes] + +implement a new helper module ModPerl::MethodLookup to help figure out +which module should be loaded when a certain method is reported to be +missing. [Stas] + +fix a bug for apr < 0.9.3, where it segfaults in apr_uri_unparse, if +hostname is set, but not the scheme. In case the hostname is defined +but scheme is not Apache::compat will default to the 'http' scheme, +whereas APR::URI::unparse provides no default [Stas] + +move $r->send_http_header implementation to Apache::compat. This +allows the 1.0 code to run unmodified if $r->send_http_header is +called before the response change. we already handle the check whether +content_type was set, when deciding whether the headers are to be +parsed inside modperl_wbucket_pass(). [Stas] + +fixes to Apache::compat. make $r->connection->auth_type interface +with r->ap_auth_type. make both $r->connection->auth_type and +$r->connection->user writable. [Geoffrey Young] + +Open up r->ap_auth_type, making it possible to write custom +authen handlers that don't rely on Basic authentication or +it's associated ap_* functions. +[Geoffrey Young] + +add Apache::Bundle2 [Stas] + +Apache::Reload now supports the PerlPreConnectionHandler invocation +mode, so connection filter and protocol modules can be automatically +reloaded on change. [Stas] + +implement Apache::current_callback + $r->current_callback goes into +Apache::compat, since now we have a way too many callbacks unrelated +to $r [Stas] + +Add Apache::compat methods: $r->connection->auth_type and +$r->connection->user (requires 'PerlOptions +GlobalRequest') + tests +[Stas] + +Several issues resolved with parsing headers, including making work +the handlers calling $r->content_type() and not sending raw headers, +when the headers scanning is turned on. Lots of tests added to +exercise different situations. [Stas] + +warn on using -T in ModPerl::Registry scripts when mod_perl is not +running with -T [Stas] + +perl 5.7.3+ has a built-in ${^TAINT} to test whether it's running +under -(T|t). Backport ${^TAINT} for mod_perl running under +5.6.0-5.7.3, (what used to be $Apache::__T. $Apache::__T is available +too, but deprecated. [Stas] + +add PerlChildExitHandler implementation [Stas] + +add PerlCleanupHandler implementation + test [Stas] + +die when Apache->request returns nothing ('PerlOptions -GlobalRequest' +or 'SetHandler modperl') [Stas] + +New Apache::Directive methods: as_hash(), lookup() + tests + docs +[Philippe M. Chiasson <gozer@cpan.org>] + +Stacked handlers chain execution is now aborted when a handler returns +something other than OK or DECLINED [Stas] + +make $filter->read() in input streaming filters, use the same number +of arguments as read() in the output filters. [Stas] + +Implement $r->add_input_filter and $r->add_output_filter + $c->add_input_filter and $c->add_output_filter +and add tests [Stas] + +Skip the handler package::func resolving error, only when the error +message matches "Can't locate .*? in @INC", rather than just "Can't +locate", since there are many other errors that start with that +string. [Stas] + +the top level 'make test' now descends into the ModPerl-Registry dir +to run 'make test' there [Stas] + +All response functions are now returning status and the callers check +and croak on failure or progate them further. [Stas] + +OPEN, CLOSE and FILENO implementation for Apache::RequestRec [Stas] + +Another fix for the handling of the return status in +ModPerl::RegistryCooker: reset the status to the original one only if +it was changed by the script, otherwise return the execution status +[Stas] + +prevent segfault in $r->print / $filter->print (in output filter) and +related functions when they are called before the response phase +[Stas] + +prevent segfault in send_http_header when it's called before the +response phase [Stas] + +input stream filtering support was added + tests (plus renaming filter +tests so we can know from the test name what kind of filter is tested) +[Stas] + +Add proper support for mis-behaved feeding filters that send more than +one EOS bucket in streaming filters + test. [Stas] + +prevent a segfault when push_handlers are used to push a handler into +the currently phase and switching the handler (perl-script/modperl) + +tests [Stas] + +Add $filter->seen_eos to the streaming filter api to know when eos has +been seen, so special signatures can be passed and any data stored in +the context flushed + tests. [Stas] + +Add $filter->ctx to maintain state between filter invocation + tests +[Stas] + +Request input and output filters are now getting the EOS bucket, which +wasn't passed through before. Now the context can be flushed on +EOS. [Stas] + + + +=item 1.99_08 - January 10, 2003 + +Correct ModPerl::RegistryCooker to reset %INC, after compile for .pl +files which don't declare the package + add tests to check that [Stas] + +Log the real error message when Foo::Bar::sub_name fails to resolve, +because of a problem in Foo::Bar, when Foo::Bar *was* found [Stas] + +Add PerlPreConnectionHandler support in Apache::Test [Stas] + +Enable PerlPreConnectionHandler [Stas] + +Support the Host: request header in Apache::TestClient [Stas] + +restore the ModPerl::RegistryLoader::new() method for backwards +compatibility [Stas] + +port the support for NameWithVirtualHost in ModPerl::RegistryCooker +and ModPerl::RegistryLoader [Stas] + +fix the handling of the return status in ModPerl::RegistryCooker, add +a test to verify that [Stas] + +under non-threaded perl need to check whether mod_perl is running, +when modperl_vhost_is_running check is done. [Stas] + +fix $r->read to read all the requested amount of data if possible, +adjust the test TestApache::read to verify that [Stas] + +fix the method content() in Apache::compat to read a whole request +body. same for ModPerl::Test::read_post. add tests. [Stas] + +Adjust the reverse filter test to work on win32 (remove trailing \r) +[Randy Kobes <randy@theoryx5.uwinnipeg.ca>] + +Strongly suggest win32 users to upgrade to 5.8.0, if they run 5.6.x +[Randy Kobes <randy@theoryx5.uwinnipeg.ca>] + +When installing the mod_perl shared object, first need to check +whether the directory 'modules' already exists, and create it if not. +[Randy Kobes <randy@theoryx5.uwinnipeg.ca>] + +Add a capability to tune the test configuration sections ordering +in Apache::TestConfigPerl [Stas Bekman] + +fix the complaining code about late PerlSwitches when PerlLoadModule +is used before it [Stas Bekman] + +add various tests that exercise PerlLoadModule and vhosts +[Stas Bekman] + +handle correctly PerlLoadModules (directives) with vhosts: + - handle gracefully cases when things are undef/NULL + - handle the case when scfg==NULL, by stealing the base_servers's config +[Stas Bekman] + +make mod_perl work with vhosts when the server is started prior to + post_config(): + - call modperl_init_globals as early as possible, because the main server + record is needed during the configuration parsing, for perlloadmodule + and vhosts + - also make sure that we are using a real base_server, when dealing + with modperl_init, and if not retrieve it from the global record +[Stas Bekman] + +prevent segfaults, when scfg is NULL in Apache::Module->get_config(); +[Stas Bekman] + +ensure that a core file is a file indeed, before complaining [Philippe +M. Chiasson <gozer@cpan.org>] + +add $r->as_string [Geoffrey Young] + +add backcompat vars: $Apache::Server::CWD and +$Apache::Server::AddPerlVersion [Stas Bekman] + +env var MOD_PERL_TRACE is working again [Stas Bekman] + +add a new test TestDirective::perlloadmodule2, which performs a more +evolved merging. [Stas Bekman] + +fix Apache::TestConfigPerl under mod_perl 1.0, need to require +mod_perl.pm before using $mod_perl::VERSION [Geoffrey Young] + +add an Apache::SIG backcompat stub to Apache::compat [Stas Bekman] + +fix the Apache::TestConfigPerl's run_apache_test_config() function +where test packages are scanned for the magic APACHE_TEST_CONFIGURE +and if found get require()'d. Apache2 needs to be run for mod_perl +2.0. [Stas Bekman] + +move the custom mod_perl 2.0 configuration bits out of the +ModPerl::TestRun, where they don't belong, into a special config file +which is included at the very end of httpd.conf [Stas Bekman] + +extend Apache::Test to allow extra configuration files to be included +at the very end of httpd.conf, when everything was loaded and +configured [Stas Bekman] + +resolve a segfault in Apache::Module::get_config() for the edge case +when the package name is bogus. [Stas Bekman] + +Apache::Reload: add support for watching and reloading modules only in +specified sub-dirs [Harry Danilevsky <harry@deerfieldcapital.com>] + +enable APR.pm's linking for apr 0.9.2 and higher, which uses a new lib +naming scheme, such as libapr-0.so.0.9.2, only if apr-config and +apu-config scripts exist. [Stas Bekman] + +define IoTYPE_RDONLY/IoTYPE_WRONLY for perl-5.6.0 so the project +compiles again under 5.6.0 [Stas Bekman] + +allow output streaming filters to append data to the end of the stream +[Stas Bekman] + +fixes to compile with ActivePerl 5.8 beta +[Randy Kobes <randy@theoryx5.uwinnipeg.ca>] + +fix for directive handlers within vhosts using threaded MPMs +[Stephen Clouse <stephenc@theiqgroup.com>] + +fix <IfDefine MODPERL2> support + +default AuthType to Basic if not set in $r->get_basic_auth_pw() +[Philippe M. Chiasson <gozer@cpan.org>] + +workaround glibc/Perl-5.8.0 crypt() bug (seen with threaded MPMs) + +fix delete $ENV{$key} bug + +fix parse_args compat method to support non-ascii characters and tr/+/ / +[Walery Studennikov <despair@sama.ru>] + +fix post_connection compat method to behave as it did in 1.x +[Geoffrey Young] + +add support for setting $r->auth_name and $r->auth_type +[Philippe M. Chiasson <gozer@cpan.org>] + +add Apache->httpd_conf compat method +[Philippe M. Chiasson <gozer@cpan.org>] + +add default <Perl> handler Apache::PerlSection. +make <Perl> blocks to be EXEC_ON_READ so apache does not parse the contents. +add "Perl" directive for general use and for which <Perl> sections are +stuffed into. +[Philippe M. Chiasson <gozer@cpan.org>] + +rename overloaded LoadModule directive to PerlLoadModule and adjust +the test naming + + + +=item 1.99_07 - September 25, 2002 + +fix =pod directive test config problem +[Philippe M. Chiasson <gozer@cpan.org>] + + + +=item 1.99_06 - September 25, 2002 + +add support for pod directives (=pod,=back,=cut) and __END__ directive +[Philippe M. Chiasson <gozer@cpan.org>] + +tweaks to support Test.pm 1.21 [Philippe M. Chiasson <gozer@cpan.org>] + +add $r->add_config method to add dynamic configuration at request time + +add Apache::DIR_MAGIC_TYPE constant + +add support for directive handlers + +fix source_scan to run with current httpd/apr + +add Apache::Server->add_config method to add dynamic configuration at +server startup time + +add Apache::Directive->to_string method + +add support for pluggable <Perl> sections + +fix compilation probs with get_remote_host() that had a wrong +prototype [Stas Bekman] + +Apache::SubProcess now has a manpage [Stas Bekman] + +fix the Apache::SubProcess tests to work with perlio-disabled Perl +[Stas Bekman] + +fix the filehandle leak in APR::PerlIO (both perlio-disabled and +perlio-enabled Perl) [Stas Bekman] + +remove dup() when converting filehandles from apr_file_t to FILE* +under perlio-disabled Perl (APR::PerlIO) [Stas Bekman] + +fix compilation if apache/apr do not have thread support + + + +=item 1.99_05 - August 20, 2002 + +fix PerlOptions +ParseHeaders to only parse once per-request + +add external redirects Registry tests [Stas Bekman] + +get rid of the compat layer in ModPerl-Registry [Stas Bekman] + +ModPerl::RegistryLoader is now fully operational and tested [Stas Bekman] + +Registry method handlers are now working [Stas Bekman] + +core Registry packages all compile the scripts into +ModPerl::RegistryROOT:: namespace and cache them in +%ModPerl::RegistryCache. Both overridable by the sub-classes. [Stas Bekman] + +compat tests were split into groups by functionality, send_fd test +moved to compat. [Stas Bekman] + +added $c->get_remote_host and a compat wrapper $r->get_remote_host + +tests [Stas Bekman] + +adjust the build system to support mod_perl build from the source +tree. [Stas Bekman] + +ModPerl::RegistryCooker syncs with mod_perl 1.0's registry: + - prototypes defined checks in flush_namespace + [Yair Lenga <yair.lenga@citigroup.com>] + - set error-notes on error [Geoffrey Young] + - preserve status in Registry scripts [Geoffrey Young] + +apr_table_t is now an opaque type, use apr_table_elts() to get the array +record [Stas Bekman] + +add support for redirects with PerlOptions +ParseHeaders + +backport to 2.0.35 + +adjust to filter register api change + +added APR::ThreadMutex module + + + +=item 1.99_04 - June 21, 2002 + +various APR PerlIO updates [Stas Bekman] + +stop using an apr_pool_t to allocate items for the interpreter pool, +safer for threaded MPMs and prevents "leaks" when interpreters are +removed from due to PerlInterpMax{Requests,Spare} + +implement modperl_sys_dlclose() to avoid apr/pool overhead/thread issues + +get the -DPERL_CORE optimization working again + +PERL_SET_CONTEXT to the parent interpreter when cloning interpreters at +request time, else dTHX might be NULL during clone in the given thread, +which would crash the server. + + + +=item 1.99_03 - June 15, 2002 + +win32 fix for the global Apache->request object to make sure it uses +the thread local storage mechanism + +add a reference count mechanism to interpreters for use in threaded MPMs, +so if APR::Pool cleanups have been registered the interpreter is not +putback into the interpreter pool until all cleanups have run. + +unbuffer STDERR (by turning on autoflush by default) + +add support for Perl*Handler +Apache::Foo + +fix open_logs,post_config,child_init hooks to run in the proper order + +adjust to apr_bucket_type_t changes in 2.0.37-dev +[Mladen Turk <mturk@mappingsoft.com>] + +add MODPERL2 config define, as if the server had been started with -DMODPERL2 + +compat additions and fixes: $r->lookup_{file,uri}, $r->is_main, Apache->define + +added compat for Apache::log_error [Stas Bekman] + + + +=item 1.99_02 - June 1, 2002 + +pass the PATH and TZ environment variables at startup by default as 1.xx did + +fix ModPerl::Util::exit segv with 5.6.0 + +no longer support 5.7.x perl development versions + +added compat for Apache::Table->new + +various fixes to compile/run on darwin + +server-scope Perl{Set,Pass}Env config now propagated to %ENV at startup + +use SvOK(sv) instead of sv == &PL_sv_undef to detect undef values in xs +[Stephen Clouse <stephenc@theiqgroup.com>] + +complete Apache::Util 1.x compat + +added Apache::MPM_IS_THREADED constant + +added compat function for Apache::Constants::SERVER_VERSION + +added Apache::Constants::export stub for compat + +added noop stubs for timeout functions removed from 2.0: +$r->{soft,hard,reset,kill}_timeout + +turned on PerlOptions +GlobalRequest by default for perl-script handler +unless it is explicitly turned off with PerlOptions -GlobalRequest + +added APR::OS::thread_current function + +added support for 1.x $r->subprocess_env functionality + +added support for $r->push_handlers(PerlHandler => ...) + +added support for $r->proxyreq to detect proxy requests + +$r->content_type($val) now calls ap_set_content_type underneath + +add the err_header_out() wrapper to Apache::compat + corresponding tests +[Stas Bekman] + +fix $r->dir_config lookup of values set in the server context + +added Apache::REDIRECT shortcut constant + +various fixes for method handlers + +use Apache::ServerUtil in Apache::compat so Apache->server works in compat +mode [Dave Rolsky <autarch@urth.org>] + +add Apache::Util::unescape_uri alias to Apache::unescape_url in Apache::compat + +change Apache::unescape_url to return the escaped url as 1.x does + +disabled term coloring by default (enable with env var APACHE_TEST_COLOR=1) + +fix for APR::IpSubnet->new to check return status apr_ipsubnet_create + +enabled APR::SockAddr module + +turn on binmode for filehandle used in $r->send_fd + +get MP_{TRACE,DEBUG} Makefile.PL options working on win32 + +various fixes to build/run with bleedperl + +various fixes for win32 to get make test passing + +moved constuct_{url,server} methods to Apache::URI module + +implement Apache::URI::parse in Apache::compat + +give Perl*Handlers precedence over other handlers by using APR_HOOK_FIRST +rather than APR_HOOK_LAST + +workaround bug in 5.6.1 when XSLoader loads DynaLoader, wiping out any +dl handles it had been keeping track of. + +tidy up test to run standalone (without modperl test config) +[Stas Bekman] + +override T_PTROBJ INPUT typemap to croak if object is not a blessed +reference, to prevent possible segv from e.g. Apache::Server->process + +apr_lock.h is gone; disable APR::Lock for the moment + +enabled the Apache::Process module + +fix ModPerl::Util::exit to clear $@ before calling Perl_croak + +cut down on some build noise + +fix 'PerlOptions +GlobalRequest' when used within subrequests + +get rid of some "subroutine redefined" warnings in ModPerl::MM that +show up with newer bleedperls. + +a few fixes for Apache::compat [Dave Rolsky <autarch@urth.org>] + + + +=item 1.99_01 - April 6, 2002 + +First public release of mod_perl-2.0-tobe. + +=back + +=cut
diff --git a/2_0_13/INSTALL b/2_0_13/INSTALL new file mode 100644 index 0000000..e8c110b --- /dev/null +++ b/2_0_13/INSTALL
@@ -0,0 +1,40 @@ +Simple install: + + % perl Makefile.PL MP_APXS=/usr/local/apache2/bin/apxs + % make && make test + % make install + +Simple install on AIX: + + You will need GNU make to compile mod_perl. The AIX make does not work. + If you have installed GNU make from the AIX Toolbox: + + % export MAKE="/opt/freeware/bin/gmake" + % perl Makefile.PL MP_APXS=/usr/local/apache2/bin/apxs + % gmake && gmake test + % gmake install + +Simple config: + + LoadModule perl_module modules/mod_perl.so + #PerlModule Apache::compat + # your config comes here + +For a more detailed version (including more options) refer to: + + docs/user/intro/start_fast.pod + +or online: + + http://perl.apache.org/docs/2.0/user/intro/start_fast.html + +For an even more detailed documentation refer to: + + docs/user/install/install.pod + docs/user/config/config.pod + +or online: + + http://perl.apache.org/docs/2.0/user/install/install.pod + http://perl.apache.org/docs/2.0/user/config/config.pod +
diff --git a/2_0_13/LICENSE b/2_0_13/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/2_0_13/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/2_0_13/META.yml b/2_0_13/META.yml new file mode 100644 index 0000000..d652de7 --- /dev/null +++ b/2_0_13/META.yml
@@ -0,0 +1,24 @@ +name: mod_perl +version: 2.0.13 +installdirs: site +distribution_type: module +no_index: + directory: + # A-T and others have their own CPAN distros + - Apache-Test + - Apache-Reload + - Apache-SizeLimit + package: + # Internally redefined module + - C::Preprocessed + # Fake packages + - Apache::Status::_version + - perlrun_decl + # Apache::compat redefines + - Apache + - Apache::Constants + - Apache::File + - Apache::SIG + - Apache::Server + - Apache::Table + - Apache::Util
diff --git a/2_0_13/Makefile.PL b/2_0_13/Makefile.PL new file mode 100644 index 0000000..2ceb943 --- /dev/null +++ b/2_0_13/Makefile.PL
@@ -0,0 +1,947 @@ +use 5.006; +use strict; +use warnings FATAL => 'all'; + +# useful for sub-Makefile.PL's to know whether they are invoked +# directly or via the top level Makefile.PL +$ENV{MOD_PERL_2_BUILD} = 1; + +use constant MIN_HTTPD_VERSION_DYNAMIC => '2.0.47'; +use constant MIN_HTTPD_VERSION_STATIC => '2.0.51'; +use constant MIN_HTTPD_24_VERSION => '2.4.0'; + +my($old_modperl_version, $old_modperl_pm, $old_Apache2_pm); + +BEGIN { + eval { + my $old_mp2 = eval { require Apache2 }; + require mod_perl; + if ($mod_perl::VERSION < 1.999_22 && $old_mp2) { + $old_modperl_version = $mod_perl::VERSION; + $old_modperl_pm = delete $INC{'mod_perl.pm'}; + $old_Apache2_pm = delete $INC{'Apache2.pm'}; + } + }; + +} + +use lib qw(lib Apache-Test/lib); + +use Config; +use File::Spec::Functions; +use File::Spec; +use DirHandle (); +use File::Copy 'cp'; +use File::Basename qw(basename dirname); +use File::Find (); + +use Apache2::Build (); +use Apache::TestSmokePerl (); +use Apache::TestTrace; +use ModPerl::TestReport (); +use ModPerl::TestRun (); +use ModPerl::Code (); +use ModPerl::BuildMM (); + +use constant WIN32 => Apache2::Build::WIN32; +use constant BUILD_APREXT => Apache2::Build::BUILD_APREXT; + +our $VERSION; + +my $build = Apache2::Build->new(init => 1); +my $code = ModPerl::Code->new; + +sub UNATTENDED() { $build->{MP_PROMPT_DEFAULT} || ! -t STDIN } + +# may populate $build->{MP_APXS} +win32_fetch_apxs() if WIN32; + +configure(); +perl_version_check($build); + +local %ModPerl::BuildMM::PM = ( + 'lib/typemap' => 'blib/lib/Apache2/typemap', +); + +# these h files need to be installed system-wide so 3rd party XS +# extensions can use them +my @xs_h_files = map catfile("xs", $_), + qw(modperl_xs_sv_convert.h modperl_xs_typedefs.h modperl_xs_util.h + APR/PerlIO/modperl_apr_perlio.h); +my @exe_files = map "bin/$_", qw(mp2bug); + +ModPerl::BuildMM::WriteMakefile( + NAME => 'mod_perl2', + VERSION => $VERSION, + DISTNAME => 'mod_perl', + NO_META => 1, + ABSTRACT_FROM => 'lib/mod_perl2.pm', + EXE_FILES => \@exe_files, + DEFINE => get_DEFINE(), + macro => { + MODPERL_SRC => $code->path, + MODPERL_MAKEFILE => basename($build->default_file('makefile')), + PERL => $build->perl_config('perlpath'), + MOD_INSTALL => ModPerl::BuildMM::mod_install(), + MODPERL_AP_INCLUDEDIR => + $build->ap_destdir($build->install_headers_dir), + MODPERL_XS_H_FILES => join(" \\\n\t", @xs_h_files), + }, + clean => { + FILES => "@{ clean_files() }", + }, + dist => { + DIST_DEFAULT => 'mydist', + COMPRESS => 'gzip -9f', SUFFIX=>'gz', + PREOP => 'find $(DISTVNAME) -type d -print|xargs chmod 0755 && ' . + 'find $(DISTVNAME) -type f -print|xargs chmod 0644', + TO_UNIX => 'find $(DISTVNAME) -type f -print|xargs dos2unix' + }, +); + +post_configure(); + +sub get_DEFINE { + + my $opt_define = ''; + + # do we have apr libs? + # XXX: this define is really needed in xs/APR/APR/Makefile.PL, but this + # top-level Makefile.PL overrides MY::pasthru, and defines DEFINE= which + # overrides any local definition, not sure what's the right fix, for + # now just define it here (should it define PASTHRU_DEFINE instead?) + $opt_define = '-DMP_HAVE_APR_LIBS' if $build->apru_link_flags; + + # preserve any DEFINE opts from outside and combine them with our + # local DEFINE + @ARGV = grep defined, + map { (/^DEFINE=(.*)/ && ($opt_define .= " $1")) ? undef : $_ } @ARGV; + + return $opt_define; +} + +sub configure { + + # mod_perl test suite relies on having Apache-Test bundled with + # the mod_perl source, since any pre-installed version may not do + # the right thing + unless (-d "Apache-Test") { + error "Can't find a sub-directory Apache-Test. " . + "Make sure that you are using a complete source distribution"; + exit 1; + } + + set_modperl_version(); + + if ($old_modperl_version) { + (my $old_modperl_version_str = $old_modperl_version) + =~ s/(\d\d\d?)(\d\d)/$1_$2/; + my $vstring = "mod_perl/$old_modperl_version_str"; + print "$vstring installation detected..."; + + my $prefix; + /^PREFIX=(.*)/ && $1 && ($prefix = canonpath glob($1)) for @ARGV; + + # check that it's a full path + my $path = canonpath $old_modperl_pm; + # XXX: doesn't handle relative paths yet + # if PREFIX=/foo/bar is used, and it's not the same as the + # path where mod_perl < 1.999_22 is installed + if ($prefix && $path !~ /^$prefix/) { + print "ok (will install mod_perl/$VERSION into PREFIX=$prefix, " . + "no collision)\n"; + } + else { + my $note = ''; + if ($old_Apache2_pm) { + $note .= "Conflicting file: $old_Apache2_pm\n"; + } + if ($path =~ /Apache2/ or $old_modperl_version > 1.99) { + my $dir = dirname $path; + # was it installed into the top-level? + $dir = catdir $dir, 'Apache' unless $path =~ /Apache2/; + $note .= "Conflicting dir: $dir\n" if -d $dir; + } + + print " not ok\n\n"; + print <<EOI; +Cannot install mod_perl/$VERSION on top of $vstring +due to a major API change between mod_perl 1.999_21 and 1.999_22. + +$note +Please nuke the prior mod_perl installation from your site_lib, +use a different perl to run the installation process, or use the +PREFIX option when creating your Makefile. See: + + http://perl.apache.org/docs/2.0/rename.html + +for more details. + +aborting... +EOI + exit 1; + } + } + else { + print "no conflicting prior mod_perl version found - good.\n"; + + } + + # On Win32, in order to decouple APR::* from mod_perl.so, we + # make up a static library MP_APR_LIB of the symbols required from + # src/modules/perl/*.c (see xs/APR/aprext/Makefile.PL), and + # then link APR/APR::* against this library. The reason for + # this is that, unlike Unix, if we had linked APR/APR::* against + # the mod_perl lib, then use of APR/APR::* would demand mod_perl.so + # be available, even if these symbols are supplied by another + # loaded library (which is done for unix by APR.so - see + # xs/APR/APR/Makefile.PL). This also means we must ensure the + # MP_APR_LIB lib is built before any of the APR/APR::* modules + # (see the aprext target in the MY::top_targets sub below), as + # symbols must get resolved at link time. + + if (BUILD_APREXT()) { + require File::Path; + #Makefile.PL's in WrapXS/ just need to pass the -e mod_perl.lib test + #the real mod_perl.lib will be in place when WrapXS/ dll's are + #actually linked + # this must also be done for aprext.lib, build in xs/APR/aprext/; + # we must create a dummy aprext.lib to pass the -e test. + my $lib1 = catfile qw(src modules perl), + $build->{MP_LIBNAME} . $Config{lib_ext}; + my ($apr_blib, $full_libname) = $build->mp_apr_blib(); + my $lib2 = catfile $apr_blib, $full_libname; + unless (-d $apr_blib) { + File::Path::mkpath($apr_blib) or die "mkdir $apr_blib failed: $!"; + } + foreach my $lib ($lib1, $lib2) { + unless (-e $lib) { + open my $fh, '>', $lib or die "open $lib: $!"; + print $fh "#this is a dummy file to trick MakeMaker"; + close $fh; + } + } + } + + system_sanity_check(); + + my $min_httpd_version = $build->should_build_apache + ? MIN_HTTPD_VERSION_STATIC + : MIN_HTTPD_VERSION_DYNAMIC; + + if ($build->{MP_APXS}) { + print "Using APXS => $build->{MP_APXS}\n"; + } + elsif ($build->{MP_AP_PREFIX}) { + if (my $reason = $build->ap_prefix_invalid) { + error "invalid MP_AP_PREFIX: $reason"; + exit 1; + } + print "Using Apache prefix => $build->{MP_AP_PREFIX}\n"; + } + else { + unless ($build->{MP_USE_STATIC}) { + # may populate $build->{MP_APXS} + prompt_for_apxs($build); + } + } + + $build->{$_} and $ENV{$_} = $build->{$_} for (qw/MP_APXS MP_AP_PREFIX/); + + unless ($build->{MP_APXS} or $build->{MP_AP_PREFIX}) { + my $ok = 0; + for my $path ($build->find) { + $build->dir($path); + my $mmn = $build->module_magic_number; + my $v = $build->httpd_version; + next unless $v; + next if $v lt $min_httpd_version; + $ok++ if $build->prompt_y("Configure mod_perl with $path?"); + last if $ok; + } + until ($ok) { + my $ask = "Please provide the location of the Apache directory:"; + my $ans = $build->prompt($ask) || ""; + # strip leading/closing spaces + $ans =~ s/^\s*|\s*$//g; + if (defined $ans and -d $ans) { + $build->dir($ans); + $ok++; + } + else { + error "Can't find dir '$ans'"; + last if UNATTENDED; + } + } + } + + if ($build->should_build_apache) { + $build->configure_apache(); + } + + my $httpd_version = $build->httpd_version; + unless ($httpd_version) { + error 'Unable to determine server version, aborting.'; + if ($build->{MP_APXS} || $build->{MP_AP_PREFIX}) { + my $what = $build->{MP_APXS} ? 'MP_APXS' : 'MP_AP_PREFIX'; + error "Invalid $what specified?"; + } + else { + error 'Please specify MP_APXS or MP_AP_PREFIX.'; + } + exit(1); + } + + if ($httpd_version lt $min_httpd_version) { + error "Apache/$httpd_version not supported, " . + "$min_httpd_version or higher is required"; + exit(1); + } + + printf "Configuring Apache/%s mod_perl/%s Perl/v%vd\n", + $httpd_version, $VERSION, $^V; + + my $apr_config = $build->get_apr_config; #cache it + + # we need to know where apr-config and apu-configs are + # which sometimes aren't placed into the same dir with apxs/httpd + # XXX: need to fix that for WIN32 + # XXX: when the source tree is used, there is not much use for apr-config + unless (WIN32 || $build->apr_config_path || $build->httpd_is_source_tree) { + error "can't find 'apr-config', please pass " . + "MP_APR_CONFIG=/full/path/to/apr-config to 'perl Makefile.PL'"; + exit 1; + } + + for (@{ clean_files() }) { + debug "unlink...$_" if -e $_ && unlink; + } + + #ModPerl::BuildMM will use Apache2::BuildConfig in subdir/Makefile.PL's + $build->save; + + ModPerl::TestRun->generate_script; + ModPerl::TestReport->generate_script; + Apache::TestSmokePerl->generate_script; + + my $tables_dir = tables_dir($httpd_version); + + unshift @INC, $tables_dir; + + if ($build->{MP_GENERATE_XS}) { + debug "generating XS code using $tables_dir..."; + xs_generate($httpd_version); + } + + install_typemap(); +} + +sub prompt_for_apxs { + my $build = shift; + + print <<EOI; + +Next we need to know where the 'apxs' script is located. This script +provides a lot of information about the Apache installation, and makes +it easier to find things on your system. Normally it's located in the +same directory as the 'httpd' executable. + +If you don't yet have Apache installed you can build Apache against +the Apache source code, but you won't be able to run the test suite (a +very important step). Therefore you may want to install Apache before +proceeding. + +EOI + + my $prompt = "\nPlease provide a full path to 'apxs' executable\n" . + "(press Enter if you don't have it installed):"; + while (1) { + my $ans = $build->prompt($prompt) || ""; + + print "\n\n"; + + # strip leading/closing spaces + $ans =~ s/^\s*|\s*$//g; + + last unless length $ans; # skip + + unless (File::Spec->file_name_is_absolute($ans)) { + warn "The path '$ans' is not an absolute path. " . + "Please specify an absolute path.\n"; + next; + } + + warn("'$ans' doesn't exist.\n"), next unless -e $ans; + warn("'$ans' is not a file.\n"), next unless -f _; + warn("'$ans' is not executable.\n"), next unless -x _; + + $build->{MP_APXS} = $ans; + last; + } +} + +sub post_configure { + + #now have any data subdir/Makefile.PL's save, e.g. XS + $build = Apache2::Build->build_config; + + $build->write_src_makefile; + $build->save_ldopts; + + $code->generate($build); + + for my $type (qw(DSO STATIC)) { + next unless $build->{"MP_USE_$type"}; + warning "mod_perl \L$type\E library will be built as ". + $build->{"MODPERL_LIB_$type"}; + } + + if ($build->is_dynamic) { + warning + "You'll need to add the following to httpd.conf:", "", + " LoadModule perl_module modules/$build->{MODPERL_LIB_DSO}", "", + "depending on your build, mod_perl might not live in", + "the modules/ directory.\n"; + if ($build->{MP_APXS}) { + warning + "Check the results of", "", + " \$ $build->{MP_APXS} -q LIBEXECDIR", "", + "and adjust the LoadModule directive accordingly.\n"; + } + } + + $build->save; +} + +sub tables_dir { + my $httpd_version = shift; + + my $tables_version=''; + if ($httpd_version lt MIN_HTTPD_24_VERSION) { + $tables_version='current'; + } + else { + $tables_version='current24'; + } + + my $tables_dir = "xs/tables/$tables_version"; +} + +sub xs_generate { + require ModPerl::WrapXS; + + my $xs = ModPerl::WrapXS->new; + + $xs->generate; + + #shift @INC; #ModPerl::Code needs this path too +} + +sub install_typemap { + my $to_file = 'lib/typemap'; + + open my $to_fh, ">$to_file" or die "open $to_file: $!"; + + for my $from_file (qw(WrapXS/typemap xs/typemap)) { + open my $from_fh, $from_file or die "open $from_file: $!"; + cp $from_fh, $to_fh; + close $from_fh; + } + + close $to_fh or die "close $to_file: $!"; +} + +sub echo_cmd { + my $cmd = shift; + print "$cmd\n"; + system($cmd) == 0 or exit(1); +} + +sub clean_files { + my $path = $code->path; + + my @files = (); + File::Find::find(sub { push @files, "$File::Find::dir/$_" if -f $_}, + "WrapXS") if -d "WrapXS"; + + push @files, map { "xs/$_.h" } + qw(modperl_xs_typedefs modperl_xs_sv_convert); + + return [@{ $build->clean_files }, + @files, + qw(lib/typemap + lib/ModPerl/MethodLookup.pm + lib/ModPerl/DummyVersions.pm + t/htdocs/vhost/error_log + t/SMOKE + t/TEST + t/REPORT + ), + <t/htdocs/hooks/startup/open_logs*>, + <t/htdocs/hooks/startup/post_config*>, + <xs/*.exp>, + <xs/*.def>, + map { "$path/$_"} @{ $code->clean_files } + ]; +} + +sub set_modperl_version { + require './lib/mod_perl2.pm'; + + $VERSION = $mod_perl2::VERSION_TRIPLET; + + open my $fh, 'Changes'; + while (<$fh>) { + if (/^=item\s+\Q$VERSION\E-(dev|rc\d+)/) { + $VERSION .= "-$1"; + last; + } + last if /^=item/; + } + close $fh; + + $build->{VERSION} = $VERSION; + $build->{API_VERSION} = $mod_perl2::API_VERSION; +} + +# needs to be run after configure() when apxs is setup +sub perl_version_check { + my $build = shift; + + my $perl_version = $]; + $perl_version =~ s/5.00(\d)(?:00(\d))?/"5.$1." . ($2||0)/e; + my $perl_threads = Apache2::Build::PERL_HAS_ITHREADS ? "w/" : "w/o"; + my $perl_string = "Using Perl $perl_version $perl_threads ithreads"; + my $httpd_version = $build->httpd_version; + my $mpm = ""; + my $build_threaded = 0; + + # For httpd-2.4, we can't use mpm_is_threaded(), because MPMs are loadable + # modules. We therefore treat httpd as a whole project as threaded. It is + # still possible to disable threading by using MP_NO_THREADS=1 + if ($httpd_version lt MIN_HTTPD_24_VERSION) { + $build_threaded = $build->mpm_is_threaded(); + $mpm = $build->mpm_name(); + } + else { + if ($build->{MP_NO_THREADS}) { + $build_threaded = 0; + } + else { + $build_threaded = 1; + } + } + + # certain mpms require perl 5.8.0+ w/ithreads + if ($build_threaded) { + my @fail; + push @fail, "Perl 5.8 or higher" + unless $] >= 5.008; + push @fail, "Perl built with ithreads (build perl with -Duseithreads)" + unless Apache2::Build::PERL_HAS_ITHREADS(); + if (@fail) { + if ($httpd_version lt MIN_HTTPD_24_VERSION) { + error "$perl_string and '$mpm' mpm httpd.", + "Failed requirements:", + join "", map {" - $_\n"} @fail; + } + else { + error "$perl_string and httpd-2.4.", + "Failed requirements:", + join "", map {" - $_\n"} @fail; + } + exit 1; + } + } + else { + # before 5.8.2, perl_shutdown is incomplete (in the case of ithreads + # each PerlInterpreter * gets tossed so it works) + if ($build->should_build_apache && !Apache2::Build::PERL_HAS_ITHREADS) { + # before 5.8.2, perl_shutdown is incomplete + if ($] < 5.008_002) { + if ($httpd_version lt MIN_HTTPD_24_VERSION) { + error "static $mpm mpm requires a threaded ". + "perl 5.6.1-5.8.1 or any perl 5.8.2+"; + } + else { + error "httpd-2.4 requires a threaded ". + "perl 5.6.1-5.8.1 or any perl 5.8.2+"; + } + exit 1; + } + } + } + + if ($] < 5.006_001) { + error "$perl_string. You need at least Perl 5.6.1"; + exit 1; + } + + if ($] >= 5.007 and $] < 5.008) { + error "$perl_string.", + "5.7.x development versions of Perl are no longer supported", + "Upgrade to Perl 5.8.0 or higher"; + exit 1; + } + + if ($Config{usemultiplicity} xor $Config{useithreads}) { + error "mod_perl does not currently support multiplicity without ". + "ithreads."; + if ($build_threaded) { + error "Please recompile Perl with -Duseithreads and ". + "-Dusemultiplicity"; + } else { + error "Please recompile Perl with either -Duseithreads and ". + "-Dusemultiplicity or -Uuseithreads and -Uusemultiplicity"; + } + exit 1; + } +} + +sub system_sanity_check { + return if WIN32; + + my $ccflags = $build->perl_config('ccflags'); + for (split /\s+/, $ccflags) { + next unless s/^-I//; + my $header = "$_/ap_mmn.h"; + if (-e $header) { + $build->phat_warn(<<EOF); +Apache headers found in unexpected location: ``$_'', suggestions: + *) Remove via ``rpm -e apache'' + *) Remove by hand + *) Complain to your os vendor about their poor layout choice + *) Complain to your sysadmin about their poor layout choice +EOF + } + } + + $build->lib_check('gdbm'); + malloc_check(); + os_check(); +} + +sub malloc_check { + return unless $build->is_dynamic; + return unless $build->perl_config('usemymalloc') eq 'y'; + + my $abort = $^O eq 'solaris'; + + my $bincompat = $build->perl_config('bincompat5005'); + + if ($bincompat) { + $build->phat_warn(<<EOF, $abort); +Your current configuration will most likely trigger core dumps, suggestions: + *) Do not configure mod_perl as a DSO + *) Rebuild Perl without malloc pollution (Configure -Ubincompat5005) +EOF + } +} + +sub os_check { + my $check = \&{"os_check_$^O"}; + return unless defined &$check; + $check->() +} + +sub os_check_hpux { + my $ccflags = $build->perl_config('ccflags'); + my $ld = $build->perl_config('ld'); + + if ($build->is_dynamic and $ld eq 'ld') { + unless ($ccflags =~ /\+z/i) { + $build->phat_warn(<<EOF); +mod_perl is unlikely to link with your libperl, suggestions: + *) Rebuild Perl with Configure -Accflags=+Z ... +EOF + } + } +} + +sub win32_fetch_apxs { + return unless (my $prefix = $build->{MP_AP_PREFIX}); + my $script = catfile($build->{cwd}, 'build', 'win32_fetch_apxs'); + my @args = ($^X, $script, "--with-apache2=$prefix"); + system(@args) == 0 or die "system @args failed: $?"; + my $apxs = catfile($prefix, 'bin', 'apxs.bat'); + $build->{MP_APXS} = $apxs if -e $apxs; +} + + +package MY; + +use Config; +use constant WIN32 => $^O eq 'MSWin32'; +use constant BUILD_APREXT => Apache2::Build::BUILD_APREXT; + +sub MY::top_targets { + my $self = shift; + my $string = $self->ModPerl::BuildMM::MY::top_targets; + + if (BUILD_APREXT) { + ModPerl::MM::add_dep(\$string, pure_all => 'aprext'); + + # must not import File::Spec functions inside MY, it breaks + # 5.6.x builds + my ($apr_blib, $full_libname) = $build->mp_apr_blib(); + my $from = File::Spec->catfile($apr_blib, $full_libname); + (my $ap_lib = $build->ap_includedir()) =~ s{include$}{lib}; + my $to = File::Spec->catfile($ap_lib, $full_libname); + my $src_dir = File::Spec->catdir(qw(xs APR), 'aprext'); + $string .= <<"EOF"; + +aprext: + cd "$src_dir" && \$(MAKE) all \$(PASTHRU) LINKTYPE="static" + +aprext_install: + \@\$(MKPATH) "$ap_lib" + \$(CP) "$from" "$to" + +EOF + } + + if ($build->should_build_apache) { + ModPerl::MM::add_dep(\$string, pure_all => 'ap_build'); + $string .= <<"EOF"; +ap_build: modperl_lib + cd "$build->{MP_AP_PREFIX}" && make + +ap_install: ap_build + cd "$build->{MP_AP_PREFIX}" && make DESTDIR=\$(DESTDIR) install +EOF + } + + ModPerl::MM::add_dep(\$string, pure_all => 'modperl_lib'); + + $string .= <<'EOF'; + +source_scan: + $(PERL) build/source_scan.pl + +xs_generate: + $(PERL) build/xs_generate.pl + +bugreport: + $(PERL) bin/mp2bug + +etags: + $(SHELL) build/make_etags + +modperl_lib: + cd "$(MODPERL_SRC)" && $(MAKE) + +modperl_lib_install: + cd "$(MODPERL_SRC)" && $(MAKE) DESTDIR=$(DESTDIR) install + +modperl_xs_h_install: + @$(MKPATH) $(DESTDIR)$(MODPERL_AP_INCLUDEDIR) + $(CP) $(MODPERL_XS_H_FILES) $(DESTDIR)$(MODPERL_AP_INCLUDEDIR) + +modperl_src_clean: + cd "$(MODPERL_SRC)" && $(MAKE) clean + +EOF + + # $(ECHO) was broken before 6.10_01 + # XXX: if ever require 6.11 we can remove this workaround + require ExtUtils::MakeMaker; + (my $mm_ver = ExtUtils::MakeMaker->VERSION) =~ s/_\d+//; + my $say = $mm_ver > 6.10 + ? '@$(ECHO)' + : '@$(PERL) -le "print shift"'; + + $string .= <<"EOF"; +modperl_banner: + $say "+--------------------------------------------------------------+" + $say "| |" + $say "| For details on getting started with mod_perl 2, see: |" + $say "| |" + $say "| http://perl.apache.org/docs/2.0/user/intro/start_fast.html |" + $say "| |" + $say "| |" + $say "| Found a bug? File a bug report: |" + $say "| |" + $say "| http://perl.apache.org/bugs/ |" + $say "| |" + $say "+--------------------------------------------------------------+" + +EOF + + $string; +} + +sub MY::install { + my $self = shift; + my $string = $self->MM::install(@_); + + for my $kind ('', '_site', '_vendor') { + ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'ap_install') + if $build->should_build_apache; + ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'modperl_lib_install'); + ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'modperl_xs_h_install'); + # ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'aprext_install') + # if BUILD_APREXT; + + ModPerl::MM::add_dep_after(\$string, "install$kind", "doc${kind}_install", 'modperl_banner'); + + # glue_pods target must come first + ModPerl::MM::add_dep(\$string, "pure${kind}_install" => 'glue_pods'); + } + + $string; +} + +sub MY::clean { + my $self = shift; + my $string = $self->MM::clean(@_); + ModPerl::MM::add_dep(\$string, clean => 'modperl_src_clean'); + ModPerl::MM::add_dep(\$string, clean => 'test_clean'); + $string; +} + +sub MY::test { + + my $preamble; + if (Apache::TestConfig::WIN32) { + # need to add the location of Apache's dlls to the PATH + my $ap_bindir = $build->apr_bindir() || ''; + unless ($ap_bindir) { + $ap_bindir = File::Spec->catdir($build->{MP_AP_PREFIX}, 'bin') + if $build->{MP_AP_PREFIX}; + } + my $modperl_libexecdir = ''; + if ($build->is_dynamic) { + # need to add the location of mod_perl.so to the PATH + my $lib = $build->modperl_libpath() || ''; + if ($lib) { + $modperl_libexecdir = File::Basename::dirname($lib); + } + else { + $modperl_libexecdir = File::Spec->catdir($build->{cwd}, + 'src/modules/perl') + if $build->{cwd}; + } + } + my $extra_path = ''; + $extra_path .= ";$ap_bindir" if $ap_bindir; + $extra_path .= ";$modperl_libexecdir" if $modperl_libexecdir; + $preamble = <<EOF; +PATH = \$(PATH)$extra_path +EOF + } + else { + # PASSENV confuses the Win32 command-line build + my $env = Apache::TestConfig->passenv_makestr(); + $preamble = <<EOF; +PASSENV = $env +EOF + } + + $preamble .= <<'EOF'; +TEST_VERBOSE = 0 +TEST_FILES = + +test_clean : + $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \ + t/TEST -clean + +run_tests : test_clean + $(PASSENV) \ + $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \ + t/TEST -bugreport -verbose=$(TEST_VERBOSE) $(TEST_FILES) + +run_subtests :: + cd ModPerl-Registry && $(MAKE) test + +run_subtests :: + cd Apache-Reload && $(MAKE) test + +EOF + + $preamble .= <<'EOF' unless $build->mpm_is_threaded(); +run_subtests :: + cd Apache-SizeLimit && $(MAKE) test + +EOF + + $preamble .= <<'EOF'; +test :: pure_all run_tests run_subtests +EOF + + return $preamble; +} + +sub MY::postamble { + my $self = shift; + + my $string = $self->ModPerl::BuildMM::MY::postamble; + + if (!WIN32) { + $string .= <<'EOF'; +rpm: dist + @[ -d $(PWD)/rpm ] || mkdir $(PWD)/rpm + rpmbuild -ta --define "_rpmdir $(PWD)/rpm" \ + --define "_srcrpmdir $(PWD)/rpm" \ + $(DISTVNAME).tar.gz + @mv $(PWD)/rpm/*/*.rpm $(PWD)/rpm/ + @rm -rf $(PWD)/rpm/*/ + +EOF + } + + my $q = (WIN32 ? '"' : "'"); + + $string .= <<"EOF"; +mydist : Apache-Test/META.yml mod_perl.spec manifest tardist + +mod_perl.spec: build/make_rpm_spec + \$(PERL) build/make_rpm_spec + +Apache-Test/META.yml: + cd Apache-Test && make metafile + +tag : + svn copy -m $q\$(VERSION_SYM) release branch$q https://svn.apache.org/repos/asf/perl/modperl/trunk https://svn.apache.org/repos/asf/perl/modperl/branches/release/\$(VERSION_SYM) + svn copy -m $q\$(VERSION_SYM) tag$q https://svn.apache.org/repos/asf/perl/modperl/branches/release/\$(VERSION_SYM) https://svn.apache.org/repos/asf/perl/modperl/tags/\$(VERSION_SYM) + svn copy -m $q\$(VERSION_SYM) tag$q https://svn.apache.org/repos/asf/perl/modperl/docs/trunk https://svn.apache.org/repos/asf/perl/modperl/docs/tags/\$(VERSION_SYM) +EOF + + return $string; +} + +# this is a workaround so that ModPerl::MM will move MY::constants +# away, and Apache-Test/Makefile.PL which has its own MY::constants +# won't get complaints on MY::constants redefined +sub MY::constants { + shift->ModPerl::BuildMM::MY::constants; +} + +sub MY::tool_autosplit { + ''; +} + +sub MY::manifypods { + my $self = shift; + my $ver = $self->{VERSION} || ""; + local $_ = $self->MM::manifypods(@_); + s/pod2man\s*$/pod2man --release mod_perl-$ver/m; + $_; +} + +sub MY::pasthru { + my $self = shift; + chomp(my $str = $self->MM::pasthru); + join $/, "$str\\", + "\t".'PERL="$(PERL)"\\', + "\t".'DEFINE="$(DEFINE)"', + ""; +} + +sub MY::dist_basics { + my $self = shift; + my $str = $self->MM::dist_basics; + + $str =~ s/(\"?)-MExtUtils(::Manifest=mkmanifest)/-Ilib $1-MModPerl$2/; + + $str; +}
diff --git a/2_0_13/ModPerl-Registry/MANIFEST b/2_0_13/ModPerl-Registry/MANIFEST new file mode 100644 index 0000000..88a5ab6 --- /dev/null +++ b/2_0_13/ModPerl-Registry/MANIFEST
@@ -0,0 +1,19 @@ +MANIFEST This list of files +Makefile.PL +README +TODO +lib/ModPerl/PerlRun.pm +lib/ModPerl/Registry.pm +lib/ModPerl/RegistryBB.pm +lib/ModPerl/RegistryCooker.pm +t/TEST.PL +t/basic.t +t/closure.t +t/cgi-bin/basic.pl +t/cgi-bin/closure.pl +t/cgi-bin/env.pl +t/cgi-bin/local-conf.pl +t/cgi-bin/not_executable.pl +t/cgi-bin/require.pl +t/conf/extra.conf.in +
diff --git a/2_0_13/ModPerl-Registry/Makefile.PL b/2_0_13/ModPerl-Registry/Makefile.PL new file mode 100644 index 0000000..0184b4c --- /dev/null +++ b/2_0_13/ModPerl-Registry/Makefile.PL
@@ -0,0 +1,44 @@ +use strict; +use warnings FATAL => 'all'; +no warnings 'redefine'; + +use FindBin; +use lib grep { -d } map "$FindBin::Bin/../$_", qw(lib Apache-Test/lib); + +use ModPerl::BuildMM (); +use Apache::TestSmokePerl (); +use Apache2::Build (); + +# enable 'make test|clean' +use Apache::TestMM qw(test clean); + +# prerequisites +my %require = ( + "Apache::Test" => "0", # any version will do? +); + +my @scripts = qw(t/TEST t/SMOKE); + +# accept the configs from comman line +Apache::TestMM::filter_args(); + +my $build = Apache2::Build->build_config; +if ($build->should_build_apache) { + push @Apache::TestMM::Argv, ('httpd' => $build->{httpd}); +} +Apache::TestMM::generate_script('t/TEST'); + +# t/SMOKE +Apache::TestSmokePerl->generate_script; + +ModPerl::BuildMM::WriteMakefile( + NAME => 'ModPerl::Registry', + VERSION_FROM => 'lib/ModPerl/RegistryCooker.pm', + PREREQ_PM => \%require, + clean => { + FILES => "@{ clean_files() }", + }); + +sub clean_files { + return [@scripts, 'Makefile.old']; +}
diff --git a/2_0_13/ModPerl-Registry/README b/2_0_13/ModPerl-Registry/README new file mode 100644 index 0000000..a1ee07b --- /dev/null +++ b/2_0_13/ModPerl-Registry/README
@@ -0,0 +1 @@ +to be written
diff --git a/2_0_13/ModPerl-Registry/TODO b/2_0_13/ModPerl-Registry/TODO new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/2_0_13/ModPerl-Registry/TODO
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRun.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRun.pm new file mode 100644 index 0000000..9dc3ce9 --- /dev/null +++ b/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRun.pm
@@ -0,0 +1,79 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::PerlRun; + +use strict; +use warnings FATAL => 'all'; + +# we try to develop so we reload ourselves without die'ing on the warning +no warnings qw(redefine); # XXX, this should go away in production! + +our $VERSION = '1.99'; + +use base qw(ModPerl::RegistryCooker); + +sub handler : method { + my $class = (@_ >= 2) ? shift : __PACKAGE__; + my $r = shift; + return $class->new($r)->default_handler(); +} + +my $parent = 'ModPerl::RegistryCooker'; +# the following code: +# - specifies package's behavior different from default of $parent class +# - speeds things up by shortcutting @ISA search, so even if the +# default is used we still use the alias +my %aliases = ( + new => 'new', + init => 'init', + default_handler => 'default_handler', + run => 'run', + can_compile => 'can_compile', + make_namespace => 'make_namespace', + namespace_root => 'namespace_root', + namespace_from => 'namespace_from_filename', + is_cached => 'FALSE', + should_compile => 'TRUE', + flush_namespace => 'flush_namespace_normal', + cache_table => 'cache_table_common', + cache_it => 'NOP', + read_script => 'read_script', + shebang_to_perl => 'shebang_to_perl', + get_script_name => 'get_script_name', + chdir_file => 'NOP', + get_mark_line => 'get_mark_line', + compile => 'compile', + error_check => 'error_check', + should_reset_inc_hash => 'TRUE', + strip_end_data_segment => 'strip_end_data_segment', + convert_script_to_compiled_handler => 'convert_script_to_compiled_handler', +); + +# in this module, all the methods are inherited from the same parent +# class, so we fixup aliases instead of using the source package in +# first place. +$aliases{$_} = $parent . "::" . $aliases{$_} for keys %aliases; + +__PACKAGE__->install_aliases(\%aliases); + + + + + +1; +__END__ +
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRunPrefork.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRunPrefork.pm new file mode 100644 index 0000000..445e599 --- /dev/null +++ b/2_0_13/ModPerl-Registry/lib/ModPerl/PerlRunPrefork.pm
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package ModPerl::PerlRunPrefork; + +use strict; +use warnings FATAL => 'all'; + +our $VERSION = '0.01'; + +use base qw(ModPerl::PerlRun); + +if ($ENV{MOD_PERL}) { + require Apache2::MPM; + die "This package can't be used under threaded MPMs" + if Apache2::MPM->is_threaded; +} + +sub handler : method { + my $class = (@_ >= 2) ? shift : __PACKAGE__; + my $r = shift; + return $class->new($r)->default_handler(); +} + +*chdir_file = \&ModPerl::RegistryCooker::chdir_file_normal; + +1; +__END__
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/Registry.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/Registry.pm new file mode 100644 index 0000000..9d7904e --- /dev/null +++ b/2_0_13/ModPerl-Registry/lib/ModPerl/Registry.pm
@@ -0,0 +1,85 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::Registry; + +use strict; +use warnings FATAL => 'all'; + +# we try to develop so we reload ourselves without die'ing on the warning +no warnings qw(redefine); # XXX, this should go away in production! + +our $VERSION = '1.99'; + +use base qw(ModPerl::RegistryCooker); + +sub handler : method { + my $class = (@_ >= 2) ? shift : __PACKAGE__; + my $r = shift; + return $class->new($r)->default_handler(); +} + +my $parent = 'ModPerl::RegistryCooker'; +# the following code: +# - specifies package's behavior different from default of $parent class +# - speeds things up by shortcutting @ISA search, so even if the +# default is used we still use the alias +my %aliases = ( + new => 'new', + init => 'init', + default_handler => 'default_handler', + run => 'run', + can_compile => 'can_compile', + make_namespace => 'make_namespace', + namespace_root => 'namespace_root', + namespace_from => 'namespace_from_filename', + is_cached => 'is_cached', + should_compile => 'should_compile_if_modified', + flush_namespace => 'NOP', + cache_table => 'cache_table_common', + cache_it => 'cache_it', + read_script => 'read_script', + shebang_to_perl => 'shebang_to_perl', + get_script_name => 'get_script_name', + chdir_file => 'NOP', + get_mark_line => 'get_mark_line', + compile => 'compile', + error_check => 'error_check', + strip_end_data_segment => 'strip_end_data_segment', + convert_script_to_compiled_handler => 'convert_script_to_compiled_handler', +); + +# in this module, all the methods are inherited from the same parent +# class, so we fixup aliases instead of using the source package in +# first place. +$aliases{$_} = $parent . "::" . $aliases{$_} for keys %aliases; + +__PACKAGE__->install_aliases(\%aliases); + +# Note that you don't have to do the aliases if you use defaults, it +# just speeds things up the first time the sub runs, after that +# methods are cached. +# +# But it's still handy, since you explicitly specify which subs from +# the parent package you are using +# + +# META: if the ISA search results are cached on the first lookup, may +# be we need to alias only those methods that override the defaults? + + +1; +__END__
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryBB.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryBB.pm new file mode 100644 index 0000000..d3667a8 --- /dev/null +++ b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryBB.pm
@@ -0,0 +1,40 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::RegistryBB; + +use strict; +use warnings FATAL => 'all'; + +# we try to develop so we reload ourselves without die'ing on the warning +no warnings qw(redefine); # XXX, this should go away in production! + +our $VERSION = '1.99'; + +use base qw(ModPerl::RegistryCooker); + +sub handler : method { + my $class = (@_ >= 2) ? shift : __PACKAGE__; + my $r = shift; + return $class->new($r)->default_handler(); +} + +# currently all the methods are inherited through the normal ISA +# search may + +1; +__END__ +
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryCooker.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryCooker.pm new file mode 100644 index 0000000..cf50007 --- /dev/null +++ b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryCooker.pm
@@ -0,0 +1,788 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# VERY IMPORTANT: Be very careful modifying the defaults, since many +# VERY IMPORTANT: packages rely on them. In fact you should never +# VERY IMPORTANT: modify the defaults after the package gets released, +# VERY IMPORTANT: since they are a hardcoded part of this suite's API. + +package ModPerl::RegistryCooker; + +require 5.006; + +use strict; +use warnings FATAL => 'all'; + +our $VERSION = '1.99'; + +use Apache2::ServerUtil (); +use Apache2::Response (); +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use Apache2::RequestIO (); +use Apache2::Log (); +use Apache2::Access (); + +use APR::Table (); +use APR::Finfo (); +use APR::Status (); + +use ModPerl::Util (); +use ModPerl::Global (); + +use File::Spec::Functions (); +use File::Basename (); + +use Apache2::Const -compile => qw(:common &OPT_EXECCGI); +use APR::Const -compile => qw(FILETYPE_REG); +use ModPerl::Const -compile => 'EXIT'; + +unless (defined $ModPerl::Registry::MarkLine) { + $ModPerl::Registry::MarkLine = 1; +} + +######################################################################### +# debug constants +# +######################################################################### +use constant D_NONE => 0; +use constant D_ERROR => 1; +use constant D_WARN => 2; +use constant D_COMPILE => 4; +use constant D_NOISE => 8; + +# the debug level can be overriden on the main server level of +# httpd.conf with: +# PerlSetVar ModPerl::RegistryCooker::DEBUG 4 +use constant DEBUG => 0; +#XXX: below currently crashes the server on win32 +# defined Apache2->server->dir_config('ModPerl::RegistryCooker::DEBUG') +# ? Apache2->server->dir_config('ModPerl::RegistryCooker::DEBUG') +# : D_NONE; + +######################################################################### +# OS specific constants +# +######################################################################### +use constant IS_WIN32 => $^O eq "MSWin32"; + +######################################################################### +# constant subs +# +######################################################################### +use constant NOP => ''; +use constant TRUE => 1; +use constant FALSE => 0; + + +use constant NAMESPACE_ROOT => 'ModPerl::ROOT'; + + +######################################################################### + +unless (defined $ModPerl::RegistryCooker::NameWithVirtualHost) { + $ModPerl::RegistryCooker::NameWithVirtualHost = 1; +} + +######################################################################### +# func: new +# dflt: new +# args: $class - class to bless into +# $r - Apache2::RequestRec object +# desc: create the class's object and bless it +# rtrn: the newly created object +######################################################################### + +sub new { + my ($class, $r) = @_; + my $self = bless {}, $class; + $self->init($r); + return $self; +} + +######################################################################### +# func: init +# dflt: init +# desc: initializes the data object's fields: REQ FILENAME URI +# args: $r - Apache2::RequestRec object +# rtrn: nothing +######################################################################### + +sub init { + $_[0]->{REQ} = $_[1]; + $_[0]->{URI} = $_[1]->uri; + $_[0]->{FILENAME} = $_[1]->filename; +} + +######################################################################### +# func: handler +# dflt: handler +# desc: the handler() sub that is expected by Apache +# args: $class - handler's class +# $r - Apache2::RequestRec object +# (o)can be called as handler($r) as well (without leading $class) +# rtrn: handler's response status +# note: must be implemented in a sub-class unless configured as +# Apache2::Foo->handler in httpd.conf (because of the +# __PACKAGE__, which is tied to the file) +######################################################################### + +sub handler : method { + my $class = (@_ >= 2) ? shift : __PACKAGE__; + my $r = shift; + return $class->new($r)->default_handler(); +} + +######################################################################### +# func: default_handler +# dflt: META: see above +# desc: META: see above +# args: $self - registry blessed object +# rtrn: handler's response status +# note: that's what most sub-class handlers will call +######################################################################### + +sub default_handler { + my $self = shift; + + $self->make_namespace; + + if ($self->should_compile) { + my $rc = $self->can_compile; + return $rc unless $rc == Apache2::Const::OK; + $rc = $self->convert_script_to_compiled_handler; + return $rc unless $rc == Apache2::Const::OK; + } + + # handlers shouldn't set $r->status but return it, so we reset the + # status after running it + my $old_status = $self->{REQ}->status; + my $rc = $self->run; + my $new_status = $self->{REQ}->status($old_status); + return ($rc == Apache2::Const::OK && $old_status != $new_status) + ? $new_status + : $rc; +} + +######################################################################### +# func: run +# dflt: run +# desc: executes the compiled code +# args: $self - registry blessed object +# rtrn: execution status (Apache2::?) +######################################################################### + +sub run { + my $self = shift; + + my $r = $self->{REQ}; + my $package = $self->{PACKAGE}; + + $self->chdir_file; + + my $cv = \&{"$package\::handler"}; + + my %orig_inc; + if ($self->should_reset_inc_hash) { + %orig_inc = %INC; + } + + my $rc = Apache2::Const::OK; + { # run the code and preserve warnings setup when it's done + no warnings FATAL => 'all'; + #local $^W = 0; + eval { $cv->($r, @_) }; + + # log script's execution errors + $rc = $self->error_check; + + { + # there might be no END blocks to call, so $@ will be not + # reset + local $@; + ModPerl::Global::special_list_call(END => $package); + + # log script's END blocks execution errors + my $new_rc = $self->error_check; + + # use the END blocks return status if the script's execution + # was successful + $rc = $new_rc if $rc == Apache2::Const::OK; + } + + } + + if ($self->should_reset_inc_hash) { + # to avoid the bite of require'ing a file with no package delaration + # Apache2::PerlRun in mod_perl 1.15_01 started to localize %INC + # later on it has been adjusted to preserve loaded .pm files, + # which presumably contained the package declaration + for (keys %INC) { + next if $orig_inc{$_}; + next if /\.pm$/; + delete $INC{$_}; + } + } + + $self->flush_namespace; + + $self->chdir_file(Apache2::ServerUtil::server_root()); + + return $rc; +} + + + +######################################################################### +# func: can_compile +# dflt: can_compile +# desc: checks whether the script is allowed and can be compiled +# args: $self - registry blessed object +# rtrn: $rc - return status to forward +# efct: initializes the data object's fields: MTIME +######################################################################### + +sub can_compile { + my $self = shift; + my $r = $self->{REQ}; + + return Apache2::Const::DECLINED + unless $r->finfo->filetype==APR::Const::FILETYPE_REG; + + $self->{MTIME} = $r->finfo->mtime; + + if (!($r->allow_options & Apache2::Const::OPT_EXECCGI)) { + $r->log_error("Options ExecCGI is off in this directory", + $self->{FILENAME}); + return Apache2::Const::FORBIDDEN; + } + + $self->debug("can compile $self->{FILENAME}") if DEBUG & D_NOISE; + + return Apache2::Const::OK; + +} +######################################################################### +# func: namespace_root +# dflt: namespace_root +# desc: define the namespace root for storing compiled scripts +# args: $self - registry blessed object +# rtrn: the namespace root +######################################################################### + +sub namespace_root { + my $self = shift; + join '::', NAMESPACE_ROOT, ref($self); +} + +######################################################################### +# func: make_namespace +# dflt: make_namespace +# desc: prepares the namespace +# args: $self - registry blessed object +# rtrn: the namespace +# efct: initializes the field: PACKAGE +######################################################################### + +sub make_namespace { + my $self = shift; + + my $package = $self->namespace_from; + + # Escape everything into valid perl identifiers + $package =~ s/([^A-Za-z0-9_])/sprintf("_%2x", unpack("C", $1))/eg; + + # make sure that the sub-package doesn't start with a digit + $package =~ s/^(\d)/_$1/; + + # prepend root + $package = $self->namespace_root() . "::$package"; + + $self->{PACKAGE} = $package; + + return $package; +} + +######################################################################### +# func: namespace_from +# dflt: namespace_from_filename +# desc: returns a partial raw package name based on filename, uri, else +# args: $self - registry blessed object +# rtrn: a unique string +######################################################################### + +*namespace_from = \&namespace_from_filename; + +# return a package name based on $r->filename only +sub namespace_from_filename { + my $self = shift; + + my ($volume, $dirs, $file) = + File::Spec::Functions::splitpath($self->{FILENAME}); + my @dirs = File::Spec::Functions::splitdir($dirs); + return join '_', grep { defined && length } $volume, @dirs, $file; +} + +# return a package name based on $r->uri only +sub namespace_from_uri { + my $self = shift; + + my $path_info = $self->{REQ}->path_info; + my $script_name = $path_info && $self->{URI} =~ /\Q$path_info\E$/ + ? substr($self->{URI}, 0, length($self->{URI}) - length($path_info)) + : $self->{URI}; + + if ($ModPerl::RegistryCooker::NameWithVirtualHost && + $self->{REQ}->server->is_virtual) { + my $name = $self->{REQ}->get_server_name; + $script_name = join "", $name, $script_name if $name; + } + + $script_name =~ s:/+$:/__INDEX__:; + + return $script_name; +} + +######################################################################### +# func: convert_script_to_compiled_handler +# dflt: convert_script_to_compiled_handler +# desc: reads the script, converts into a handler and compiles it +# args: $self - registry blessed object +# rtrn: success/failure status +######################################################################### + +sub convert_script_to_compiled_handler { + my $self = shift; + + my $rc = Apache2::Const::OK; + + $self->debug("Adding package $self->{PACKAGE}") if DEBUG & D_NOISE; + + # get the script's source + $rc = $self->read_script; + return $rc unless $rc == Apache2::Const::OK; + + # convert the shebang line opts into perl code + my $shebang = $self->shebang_to_perl; + + # mod_cgi compat, should compile the code while in its dir, so + # relative require/open will work. + $self->chdir_file; + +# undef &{"$self->{PACKAGE}\::handler"}; unless DEBUG & D_NOISE; #avoid warnings +# $self->{PACKAGE}->can('undef_functions') && $self->{PACKAGE}->undef_functions; + + my $line = $self->get_mark_line; + + $self->strip_end_data_segment; + + # handle the non-parsed handlers ala mod_cgi (though mod_cgi does + # some tricks removing the header_out and other filters, here we + # just call assbackwards which has the same effect). + my $base = File::Basename::basename($self->{FILENAME}); + my $nph = substr($base, 0, 4) eq 'nph-' ? '$_[0]->assbackwards(1);' : ""; + my $script_name = $self->get_script_name || $0; + + my $eval = join '', + 'package ', + $self->{PACKAGE}, ";", + "sub handler {", + "local \$0 = '$script_name';", + $nph, + $shebang, + $line, + ${ $self->{CODE} }, + "\n}"; # last line comment without newline? + + $rc = $self->compile(\$eval); + return $rc unless $rc == Apache2::Const::OK; + $self->debug(qq{compiled package \"$self->{PACKAGE}\"}) if DEBUG & D_NOISE; + + $self->chdir_file(Apache2::ServerUtil::server_root()); + +# if(my $opt = $r->dir_config("PerlRunOnce")) { +# $r->child_terminate if lc($opt) eq "on"; +# } + + $self->cache_it; + + return $rc; +} + +######################################################################### +# func: cache_table +# dflt: cache_table_common +# desc: return a symbol table for caching compiled scripts in +# args: $self - registry blessed object (or the class name) +# rtrn: symbol table +######################################################################### + +*cache_table = \&cache_table_common; + +sub cache_table_common { + \%ModPerl::RegistryCache; +} + + +sub cache_table_local { + my $self = shift; + my $class = ref($self) || $self; + no strict 'refs'; + \%$class; +} + +######################################################################### +# func: cache_it +# dflt: cache_it +# desc: mark the package as cached by storing its modification time +# args: $self - registry blessed object +# rtrn: nothing +######################################################################### + +sub cache_it { + my $self = shift; + $self->cache_table->{ $self->{PACKAGE} }{mtime} = $self->{MTIME}; +} + + +######################################################################### +# func: is_cached +# dflt: is_cached +# desc: checks whether the package is already cached +# args: $self - registry blessed object +# rtrn: TRUE if cached, +# FALSE otherwise +######################################################################### + +sub is_cached { + my $self = shift; + exists $self->cache_table->{ $self->{PACKAGE} }{mtime}; +} + + +######################################################################### +# func: should_compile +# dflt: should_compile_once +# desc: decide whether code should be compiled or not +# args: $self - registry blessed object +# rtrn: TRUE if should compile +# FALSE otherwise +# efct: sets MTIME if it's not set yet +######################################################################### + +*should_compile = \&should_compile_once; + +# return false only if the package is cached and its source file +# wasn't modified +sub should_compile_if_modified { + my $self = shift; + $self->{MTIME} ||= $self->{REQ}->finfo->mtime; + !($self->is_cached && + $self->cache_table->{ $self->{PACKAGE} }{mtime} == $self->{MTIME}); +} + +# return false if the package is cached already +sub should_compile_once { + not shift->is_cached; +} + +######################################################################### +# func: should_reset_inc_hash +# dflt: FALSE +# desc: decide whether to localize %INC for required .pl files from the script +# args: $self - registry blessed object +# rtrn: TRUE if should reset +# FALSE otherwise +######################################################################### + +*should_reset_inc_hash = \&FALSE; + +######################################################################### +# func: flush_namespace +# dflt: NOP (don't flush) +# desc: flush the compiled package's namespace +# args: $self - registry blessed object +# rtrn: nothing +######################################################################### + +*flush_namespace = \&NOP; + +sub flush_namespace_normal { + my $self = shift; + + $self->debug("flushing namespace") if DEBUG & D_NOISE; + ModPerl::Util::unload_package($self->{PACKAGE}); +} + + +######################################################################### +# func: read_script +# dflt: read_script +# desc: reads the script in +# args: $self - registry blessed object +# rtrn: Apache2::Const::OK on success, some other code on failure +# efct: initializes the CODE field with the source script +######################################################################### + +# reads the contents of the file +sub read_script { + my $self = shift; + + $self->debug("reading $self->{FILENAME}") if DEBUG & D_NOISE; + $self->{CODE} = eval { $self->{REQ}->slurp_filename(0) }; # untainted + if ($@) { + $self->log_error("$@"); + + if (ref $@ eq 'APR::Error') { + return Apache2::Const::FORBIDDEN if APR::Status::is_EACCES($@); + return Apache2::Const::NOT_FOUND if APR::Status::is_ENOENT($@); + } + + return Apache2::Const::SERVER_ERROR; + } + + return Apache2::Const::OK; +} + +######################################################################### +# func: shebang_to_perl +# dflt: shebang_to_perl +# desc: parse the shebang line and convert command line switches +# (defined in %switches) into a perl code. +# args: $self - registry blessed object +# rtrn: a Perl snippet to be put at the beginning of the CODE field +# by caller +######################################################################### + +my %switches = ( + 'T' => sub { + Apache2::ServerRec::warn("-T switch is ignored, enable " . + "with 'PerlSwitches -T' in httpd.conf\n") + unless ${^TAINT}; + ""; + }, + 'w' => sub { "use warnings;\n" }, +); + +sub shebang_to_perl { + my $self = shift; + my ($line) = ${ $self->{CODE} } =~ /^(.*)$/m; + my @cmdline = split /\s+/, $line; + return "" unless @cmdline; + return "" unless shift(@cmdline) =~ /^\#!/; + + my $prepend = ""; + for my $s (@cmdline) { + next unless $s =~ s/^-//; + last if substr($s,0,1) eq "-"; + for (split //, $s) { + next unless exists $switches{$_}; + $prepend .= $switches{$_}->(); + } + } + + return $prepend; +} + +######################################################################### +# func: get_script_name +# dflt: get_script_name +# desc: get the script's name to set into $0 +# args: $self - registry blessed object +# rtrn: path to the script's filename +######################################################################### + +sub get_script_name { + shift->{FILENAME}; +} + +######################################################################### +# func: chdir_file +# dflt: NOP +# desc: chdirs into $dir +# args: $self - registry blessed object +# $dir - a dir +# rtrn: nothing (?or success/failure?) +######################################################################### + +*chdir_file = \&NOP; + +sub chdir_file_normal { + my ($self, $dir) = @_; + $dir ||= File::Basename::dirname($self->{FILENAME}); + $self->debug("chdir $dir") if DEBUG & D_NOISE; + chdir $dir or die "Can't chdir to $dir: $!"; +} + +######################################################################### +# func: get_mark_line +# dflt: get_mark_line +# desc: generates the perl compiler #line directive +# args: $self - registry blessed object +# rtrn: returns the perl compiler #line directive +######################################################################### + +sub get_mark_line { + my $self = shift; + $ModPerl::Registry::MarkLine ? "\n#line 1 $self->{FILENAME}\n" : ""; +} + +######################################################################### +# func: strip_end_data_segment +# dflt: strip_end_data_segment +# desc: remove the trailing non-code from $self->{CODE} +# args: $self - registry blessed object +# rtrn: nothing +######################################################################### + +sub strip_end_data_segment { + ${ +shift->{CODE} } =~ s/^__(END|DATA)__(.*)//ms; +} + + + +######################################################################### +# func: compile +# dflt: compile +# desc: compile the code in $eval +# args: $self - registry blessed object +# $eval - a ref to a scalar with the code to compile +# rtrn: success/failure +# note: $r must not be in scope of compile(), scripts must do +# my $r = shift; to get it off the args stack +######################################################################### + +sub compile { + my ($self, $eval) = @_; + + $self->debug("compiling $self->{FILENAME}") if DEBUG && D_COMPILE; + + ModPerl::Global::special_list_register(END => $self->{PACKAGE}); + ModPerl::Global::special_list_clear( END => $self->{PACKAGE}); + + { + # let the code define its own warn and strict level + no strict; + no warnings FATAL => 'all'; # because we use FATAL + eval $$eval; + } + + return $self->error_check; +} + +######################################################################### +# func: error_check +# dflt: error_check +# desc: checks $@ for errors +# args: $self - registry blessed object +# rtrn: Apache2::Const::SERVER_ERROR if $@ is set, Apache2::Const::OK otherwise +######################################################################### + +sub error_check { + my $self = shift; + + # ModPerl::Util::exit() throws an exception object whose rc is + # ModPerl::EXIT + # (see modperl_perl_exit() and modperl_errsv() C functions) + if ($@ && !(ref $@ eq 'APR::Error' && $@ == ModPerl::EXIT)) { + $self->log_error($@); + return Apache2::Const::SERVER_ERROR; + } + return Apache2::Const::OK; +} + + +######################################################################### +# func: install_aliases +# dflt: install_aliases +# desc: install the method aliases into $class +# args: $class - the class to install the methods into +# $rh_aliases - a ref to a hash with aliases mapping +# rtrn: nothing +######################################################################### + +sub install_aliases { + my ($class, $rh_aliases) = @_; + + no strict 'refs'; + while (my ($k,$v) = each %$rh_aliases) { + if (my $sub = *{$v}{CODE}){ + *{ $class . "::$k" } = $sub; + } + else { + die "$class: $k aliasing failed; sub $v doesn't exist"; + } + } +} + +### helper methods + +sub debug { + my $self = shift; + my $class = ref $self; + $self->{REQ}->log_error("$$: $class: " . join '', @_); +} + +sub log_error { + my ($self, $msg) = @_; + my $class = ref $self; + + $self->{REQ}->log_error($msg); + $self->{REQ}->notes->set('error-notes' => $msg); + $@{$self->{URI}} = $msg; +} + +######################################################################### +# func: uncache_myself +# dflt: uncache_myself +# desc: unmark the package as cached by forgetting its modification time +# args: none +# rtrn: nothing +# note: this is a function and not a method, it should be called from +# the registry script, and using the caller() method we figure +# out the package the script was compiled into + +######################################################################### + +# this is a function should be called from the registry script, and +# using the caller() method we figure out the package the script was +# compiled into and trying to uncache it. +# +# it's currently used only for testing purposes and not a part of the +# public interface. it expects to find the compiled package in the +# symbol table cache returned by cache_table_common(), if you override +# cache_table() to point to another function, this function will fail. +sub uncache_myself { + my $package = scalar caller; + my ($class) = __PACKAGE__->cache_table_common(); + + unless (defined $class) { + Apache2->warn("$$: cannot figure out cache symbol table for $package"); + return; + } + + if (exists $class->{$package} && exists $class->{$package}{mtime}) { + Apache2->warn("$$: uncaching $package\n") if DEBUG & D_COMPILE; + delete $class->{$package}{mtime}; + } + else { + Apache2->warn("$$: cannot find $package in cache"); + } +} + + +1; +__END__
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryLoader.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryLoader.pm new file mode 100644 index 0000000..5f03c94 --- /dev/null +++ b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryLoader.pm
@@ -0,0 +1,168 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::RegistryLoader; + +use strict; +use warnings; + +use ModPerl::RegistryCooker (); +use Apache2::ServerUtil (); +use Apache2::Log (); +use APR::Pool (); +use APR::Finfo (); +use APR::Const -compile=>qw(FINFO_MIN); + +use Carp; +use File::Spec (); + +use Apache2::Const -compile => qw(OK HTTP_OK OPT_EXECCGI); + +our @ISA = (); + +sub new { + my $class = shift; + my $self = bless {@_} => ref($class)||$class; + $self->{package} ||= 'ModPerl::Registry'; + $self->{pool} = APR::Pool->new(); + $self->load_package($self->{package}); + return $self; +} + +sub handler { + my ($self, $uri, $filename, $virthost) = @_; + + # set the inheritance rules at run time + @ISA = $self->{package}; + + unless (defined $uri) { + $self->warn("uri is a required argument"); + return; + } + + if (defined $filename) { + unless (-e $filename) { + $self->warn("Cannot find: $filename"); + return; + } + } + else { + # try to translate URI->filename + if (exists $self->{trans} and ref($self->{trans}) eq 'CODE') { + no strict 'refs'; + $filename = $self->{trans}->($uri); + unless (-e $filename) { + $self->warn("Cannot find a translated from uri: $filename"); + return; + } + } + else { + # try to guess + (my $guess = $uri) =~ s|^/||; + + $self->warn("Trying to guess filename based on uri") + if $self->{debug}; + + $filename = File::Spec->catfile(Apache2::ServerUtil::server_root, + $guess); + unless (-e $filename) { + $self->warn("Cannot find guessed file: $filename", + "provide \$filename or 'trans' sub"); + return; + } + } + } + + if ($self->{debug}) { + $self->warn("*** uri=$uri, filename=$filename"); + } + + my $rl = bless { + uri => $uri, + filename => $filename, + package => $self->{package}, + } => ref($self) || $self; + + $rl->{virthost} = $virthost if defined $virthost; + + # can't call SUPER::handler here, because it usually calls new() + # and then the ModPerlRegistryLoader::new() will get called, + # instead of the super class' new, so we implement the super + # class' handler here. Hopefully all other subclasses use the same + # handler. + __PACKAGE__->SUPER::new($rl)->default_handler(); + +} + +# XXX: s/my_// for qw(my_finfo my_slurp_filename); +# when when finfo() and slurp_filename() are ported to 2.0 and +# RegistryCooker is starting to use them + +sub get_server_name { return $_[0]->{virthost} if exists $_[0]->{virthost} } +sub filename { shift->{filename} } +sub status { Apache2::Const::HTTP_OK } +sub pool { shift->{pool}||=APR::Pool->new() } +sub finfo { $_[0]->{finfo}||=APR::Finfo::stat($_[0]->{filename}, + APR::Const::FINFO_MIN, + $_[0]->pool); } +sub uri { shift->{uri} } +sub path_info {} +sub allow_options { Apache2::Const::OPT_EXECCGI } #will be checked again at run-time +sub log_error { shift; die @_ if $@; warn @_; } +sub run { return Apache2::Const::OK } # don't run the script +sub server { shift } +sub is_virtual { exists shift->{virthost} } + +# the preloaded file needs to be precompiled into the package +# specified by the 'package' attribute, not RegistryLoader +sub namespace_root { + join '::', ModPerl::RegistryCooker::NAMESPACE_ROOT, + shift->{REQ}->{package}; +} + +# override Apache class methods called by Modperl::Registry*. normally +# only available at request-time via blessed request_rec pointer +sub slurp_filename { + my $r = shift; + my $tainted = @_ ? shift : 1; + my $filename = $r->filename; + open my $fh, $filename or die "can't open $filename: $!"; + local $/; + my $code = <$fh>; + unless ($tainted) { + ($code) = $code =~ /(.*)/s; # untaint + } + close $fh; + return \$code; +} + +sub load_package { + my ($self, $package) = @_; + + croak "package to load wasn't specified" unless defined $package; + + $package =~ s|::|/|g; + $package .= ".pm"; + require $package; +}; + +sub warn { + my $self = shift; + Apache2::Log->warn(__PACKAGE__ . ": @_\n"); +} + +1; +__END__
diff --git a/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryPrefork.pm b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryPrefork.pm new file mode 100644 index 0000000..9c41e77 --- /dev/null +++ b/2_0_13/ModPerl-Registry/lib/ModPerl/RegistryPrefork.pm
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package ModPerl::RegistryPrefork; + +use strict; +use warnings FATAL => 'all'; + +our $VERSION = '0.01'; + +use base qw(ModPerl::Registry); + +if ($ENV{MOD_PERL}) { + require Apache2::MPM; + die "This package can't be used under threaded MPMs" + if Apache2::MPM->is_threaded; +} + +sub handler : method { + my $class = (@_ >= 2) ? shift : __PACKAGE__; + my $r = shift; + return $class->new($r)->default_handler(); +} + +*chdir_file = \&ModPerl::RegistryCooker::chdir_file_normal; + +1; +__END__
diff --git a/2_0_13/ModPerl-Registry/t/206.t b/2_0_13/ModPerl-Registry/t/206.t new file mode 100644 index 0000000..7b72728 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/206.t
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET); + +plan tests => 2, need [qw(mod_alias.c HTML::HeadParser)]; + +my $url = "/registry/206.pl"; +my $res = GET($url); +my $body = '<?xml versi'; + +ok t_cmp( + $res->code, + 206, + "test partial_content: response code", +); + +ok t_cmp( + $res->content, + $body, + "test partial_content: response body", +);
diff --git a/2_0_13/ModPerl-Registry/t/304.t b/2_0_13/ModPerl-Registry/t/304.t new file mode 100644 index 0000000..dda87c9 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/304.t
@@ -0,0 +1,63 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET); + +plan tests => 10, need [qw(mod_alias.c HTML::HeadParser)]; + +my $url = "/registry/304.pl"; + +{ + # not modified + my $if_modified_since = 'Sun, 29 Oct 2000 15:55:00 GMT'; + my $res = GET($url, 'If-Modified-Since' => $if_modified_since); + + ok t_cmp( + $res->code, + 304, + "test HTTP_NOT_MODIFIED (304 status)", + ); + + ok t_cmp( + $res->content, + '', + "test HTTP_NOT_MODIFIED (null body)", + ); + + #t_debug $res->as_string; +} + +{ + # full response cases: + # 1) the resource has been modified since the If-Modified-Since date + # 2) bogus If-Modified-Since date => is considered as a + # non-If-Modified-Since require + # + my %dates = ( + 'Sun, 29 Oct 2000 15:43:28 GMT' => "the resource was modified since #1", + 'Sun, 28 Oct 2000 15:43:29 GMT' => "the resource was modified since #2", + 'Thu, 32 Jun 1999 24:59:59 MIT' => "bogus If-Modified-Since #1", + 'Thu Juk 99 00:00:00 9999 FUK' => "bogus If-Modified-Since #2", + ); + my $received = '<html><head></head><body>Test</body></html>'; + while ( my ($if_modified_since, $debug) = each %dates) { + my $res = GET($url, 'If-Modified-Since' => $if_modified_since); + t_debug "If-Modified-Since $if_modified_since"; + ok t_cmp( + $res->code, + 200, + "$debug (code)" + ); + + ok t_cmp( + $res->content, + $received, + "$debug (body)" + ); + + #t_debug $res->as_string; + } +}
diff --git a/2_0_13/ModPerl-Registry/t/404-filename-with-newline.t b/2_0_13/ModPerl-Registry/t/404-filename-with-newline.t new file mode 100644 index 0000000..f28710b --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/404-filename-with-newline.t
@@ -0,0 +1,20 @@ +#!perl + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET_RC); + +plan tests => 1, need 'mod_alias.c'; + +{ + # this used to result in 500 due to a combination of Perl warning about + # a newline in the filename passed to stat() and our + # use warnings FATAL=>'all' + + t_client_log_error_is_expected(); + my $url = '/registry/file%0dwith%0anl%0d%0aand%0a%0dcr'; + ok t_cmp GET_RC($url), 404, 'URL with \\r and \\n embedded'; +}
diff --git a/2_0_13/ModPerl-Registry/t/404.t b/2_0_13/ModPerl-Registry/t/404.t new file mode 100644 index 0000000..4b4271a --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/404.t
@@ -0,0 +1,31 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET_BODY GET); + +plan tests => 2, need [qw(mod_alias.c HTML::HeadParser)]; + +{ + t_client_log_error_is_expected(); + my $url = "/error_document/cannot_be_found"; + my $response = "Oops, can't find the requested doc"; + ok t_cmp( + GET_BODY($url), + $response, + "test ErrorDocument" + ); +} + + +{ + my $url = "/registry/status_change.pl"; + my $res = GET($url); + ok t_cmp( + $res->code, + 404, + "the script has changed the status to 404" + ); +}
diff --git a/2_0_13/ModPerl-Registry/t/500.t b/2_0_13/ModPerl-Registry/t/500.t new file mode 100644 index 0000000..a96e97f --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/500.t
@@ -0,0 +1,91 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET); + +plan tests => 7, need 'mod_alias.c'; + +{ + # the script changes the status before the run-time error happens, + # this status change should be ignored + my $url = "/registry/runtime_error_n_status_change.pl"; + my $res = GET($url); + #t_debug($res->content); + ok t_cmp( + $res->code, + 500, + "500 error on runtime error (when the script changes the status)", + ); +} + +{ + my $url = "/registry/syntax_error.pl"; + my $res = GET($url); + #t_debug($res->content); + ok t_cmp( + $res->code, + 500, + "500 compile time error (syntax error)", + ); +} + +{ + my $url = "/registry/use_error.pl"; + my $res = GET($url); + #t_debug($res->content); + ok t_cmp( + $res->code, + 500, + "500 compile error on use() failure", + ); +} + +{ + my $url = "/registry/missing_headers.pl"; + my $res = GET($url); + #t_debug($res->content); + ok t_cmp( + $res->code, + 500, + "500 error on missing HTTP headers", + ); +} + +{ + # since we have a runtime error before any body is sent, mod_perl + # has a chance to communicate the return status of the script to + # Apache before headers are sent, so we get the code 500 in the + # HTTP headers + my $url = "/registry/runtime_error.pl"; + my $res = GET($url); + #t_debug($res->content); + ok t_cmp( + $res->code, + 500, + "500 error on runtime error", + ); +} + +{ + # even though we have a runtime error here, the scripts succeeds + # to send some body before the error happens and since by that + # time Apache has already sent the headers, they will include + # 200 OK + my $url = "/registry/runtime_error_plus_body.pl"; + my $res = GET($url); + #t_debug($res->content); + ok t_cmp( + $res->code, + 200, + "200, followed by a runtime error", + ); + + # the error message is attached after the body + ok t_cmp($res->content, + qr/some body.*The server encountered an internal error/ms, + "200, followed by a runtime error", + ); +}
diff --git a/2_0_13/ModPerl-Registry/t/TEST.PL b/2_0_13/ModPerl-Registry/t/TEST.PL new file mode 100644 index 0000000..4f82f04 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/TEST.PL
@@ -0,0 +1,56 @@ +use strict; +use warnings FATAL => 'all'; + +use FindBin; +# test against the source lib for easier dev +use lib "$FindBin::Bin/../lib"; +use lib grep { -d } map "$FindBin::Bin/../../$_", qw(lib Apache-Test/lib); + +# pick the common test libs +use lib "$FindBin::Bin/../../t/lib"; + +MyTest->new->run(@ARGV); + + + +# sub-class Apache::TestRunPerl +package MyTest; + +use base qw(Apache::TestRunPerl); + +# redirect tests require 2 servers +use constant MIN_CLIENTS => 2; + +use File::Spec::Functions qw(catdir); +use File::Basename qw(dirname); + +use Apache2::Build; + +# default timeout in secs (threaded mpms are extremely slow to +# startup, due to a slow perl_clone operation) +use constant DEFAULT_STARTUP_TIMEOUT => + Apache2::Build->build_config->mpm_is_threaded() ? 180 : 90; + +# subclass new_test_config to add some config vars which will be +# replaced in generated httpd.conf +sub new_test_config { + my $self = shift; + + require Apache::Test; + my $mp2_root_dir = dirname Apache::Test::vars('top_dir'); + $self->{conf_opts}->{src_dir} = catdir $mp2_root_dir, + qw(src modules perl); + + $self->{conf_opts}->{startup_timeout} ||= + $ENV{APACHE_TEST_STARTUP_TIMEOUT} || + DEFAULT_STARTUP_TIMEOUT; + + $self->{conf_opts}->{minclients} ||= MIN_CLIENTS; + + return $self->SUPER::new_test_config; +} + +sub bug_report { + require ModPerl::TestRun; + shift->ModPerl::TestRun::bug_report(); +}
diff --git a/2_0_13/ModPerl-Registry/t/bad_scripts.t b/2_0_13/ModPerl-Registry/t/bad_scripts.t new file mode 100644 index 0000000..8135484 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/bad_scripts.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET); + +plan tests => 1, need 'mod_alias.c'; + +{ + t_client_log_error_is_expected(); + my $url = "/perlrun/r_inherited.pl"; + my $res = GET($url); + ok t_cmp( + $res->code, + 500, + "the script hasn't declared its private \$r", + ); +}
diff --git a/2_0_13/ModPerl-Registry/t/basic.t b/2_0_13/ModPerl-Registry/t/basic.t new file mode 100644 index 0000000..dcdc174 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/basic.t
@@ -0,0 +1,120 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil qw(t_cmp t_catfile_apache t_client_log_error_is_expected); +use Apache::TestRequest; +use Apache::TestConfig (); + +my %modules = ( + registry => 'ModPerl::Registry', + registry_bb => 'ModPerl::RegistryBB', + perlrun => 'ModPerl::PerlRun', +); + +my @aliases = sort keys %modules; + +plan tests => @aliases * 5 + 3, need 'mod_alias.c'; + +my $vars = Apache::Test::config()->{vars}; +my $script_file = t_catfile_apache $vars->{serverroot}, 'cgi-bin', 'basic.pl'; + +# very basic compilation/response test +for my $alias (@aliases) { + my $url = "/$alias/basic.pl"; + + ok t_cmp( + GET_BODY($url), + "ok $script_file", + "$modules{$alias} basic cgi test", + ); +} + +# test non-executable bit (it should be executed w/o a problem) +for my $alias (@aliases) { + if (Apache::TestConfig::WIN32) { + skip "non-executable bit test for Win32", 0; + next; + } + my $url = "/$alias/not_executable.pl"; + + t_client_log_error_is_expected(); + ok t_cmp( + HEAD($url)->code, + 200, + "$modules{$alias} non-executable file", + ); +} + +# test environment pre-set +for my $alias (@aliases) { + my $url = "/$alias/env.pl?foo=bar"; + + ok t_cmp( + GET_BODY($url), + "foo=bar", + "$modules{$alias} mod_cgi-like environment pre-set", + ); +} + +# require (actually chdir test) +for my $alias (@aliases) { + my $url = "/$alias/require.pl"; + + ok t_cmp( + GET_BODY($url), + "it works", + "$modules{$alias} mod_cgi-like environment pre-set", + ); +} + + +# exit +for my $alias (@aliases) { + my $url = "/$alias/exit.pl"; + + ok t_cmp( + GET_BODY_ASSERT($url), + "before exit", + "$modules{$alias} mod_cgi-like environment pre-set", + ); +} + + + +# test method handlers +{ + my $url = "/registry_oo_conf/env.pl?foo=bar"; + ok t_cmp( + GET_BODY($url), + "foo=bar", + "ModPerl::Registry->handler mod_cgi-like environment pre-set", + ); +} + +# test mod_perl api usage +{ + my $url = "/registry/content_type.pl"; + ok t_cmp( + GET_BODY($url), + "ok", + "\$r->content_type('text/plain')", + ); +} + + +# test that files with .html extension, which are configured to run as +# scripts get the headerparse stage working: the default mime handler +# sets $r->content_type for .html files, so we can't rely on +# content_type not being set in making the decision whether to parse +# headers or not +{ + my $url = "/registry/send_headers.html"; + my $res = GET $url; + ok t_cmp( + $res->content_type, + "text/plain", + "script's content-type", + ); +}
diff --git a/2_0_13/ModPerl-Registry/t/bin_resp.t b/2_0_13/ModPerl-Registry/t/bin_resp.t new file mode 100644 index 0000000..5ffd780 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/bin_resp.t
@@ -0,0 +1,31 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# testing various binary responses + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2, need 'mod_alias.c'; + +# 2 sub-tests +{ + # favicon.ico and other .ico image/x-icon images start with + # sequence: + my $expected = "\000\000\001\000"; + my $location = "/registry/bin_resp_start_0.pl"; + #my $location = "/cgi-bin/bin_resp_start_0.pl"; + + my $received = GET_BODY_ASSERT $location; + + #t_debug "$received"; + + ok t_cmp(length($received), length($expected), "image size"); + + t_debug "comparing the binary contents"; + ok $expected eq $received; +} + +
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/206.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/206.pl new file mode 100755 index 0000000..0aeac2b --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/206.pl
@@ -0,0 +1,11 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + print <<_OUT_; +Status: 206 Partial Content +Content-Type: text/html; charset=UTF-8 +Content-Length: 11 +Content-Range: bytes 0-10/1336 +Date: Fri, 31 Jan 2003 09:39:01 GMT +ETag: "xxxx" + +_OUT_ +print '<?xml versi';
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/304.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/304.pl new file mode 100755 index 0000000..8238112 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/304.pl
@@ -0,0 +1,50 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# manually handle 'If-Modified-Since' requests + +use APR::Date (); +use Apache2::Util (); +use Apache2::RequestRec (); + +use constant FMT => '%a, %d %b %Y %H:%M:%S %Z'; +use constant GMT => 1; +use Apache2::Const -compile => qw(HTTP_NOT_MODIFIED); + +my $last_modified = "Sun, 29 Oct 2000 15:43:29 GMT"; + +my $r = shift; + +my $if_modified_since = $r->headers_in->{'If-Modified-Since'}; + +my $status = 200; +my $body = '<html><head></head><body>Test</body></html>'; + +#APR::Date::parse_http may fail +my $if_modified_since_secs = + ($if_modified_since && APR::Date::parse_http($if_modified_since)) || 0; +my $last_modified_secs = APR::Date::parse_http($last_modified); + +#warn "If-Modified-Since $if_modified_since\n"; +#warn "last_modified_secs $last_modified_secs\n"; +#warn "if_modified_since_secs $if_modified_since_secs\n\n"; + +if ($last_modified_secs < $if_modified_since_secs) { + $status = Apache2::Const::HTTP_NOT_MODIFIED; + $body = ''; +} + +my $date = Apache2::Util::ht_time($r->pool, $r->request_time, FMT, GMT); + +print <<HEADERS; +Status: $status +Date: $date +Server: Apache/2.0.47 +Connection: close +Last-Modified: $last_modified +Content-Type: text/html; charset=iso-8859-1 + +HEADERS + +print $body if length $body;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/404.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/404.pl new file mode 100755 index 0000000..ec1314f --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/404.pl
@@ -0,0 +1,7 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings; + +my $r = shift; +$r->content_type('text/plain'); +print "Oops, can't find the requested doc";
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/basic.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/basic.pl new file mode 100755 index 0000000..2176f3c --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/basic.pl
@@ -0,0 +1,16 @@ +#!perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +# test all the basic functionality + +print "Content-type: text/plain\n\n"; + +# test that __END__ can appear in a comment w/o cutting data after it + +print "ok $0"; + +# test that __END__ starting at the beginning of the line makes +# everything following it, stripped +__END__ + +this is some irrelevant data
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/bin_resp_start_0.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/bin_resp_start_0.pl new file mode 100755 index 0000000..4734b84 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/bin_resp_start_0.pl
@@ -0,0 +1,14 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; + +# favicon.ico and other .ico image/x-icon images start with this sequence +my $response = "\000\000\001\000"; + +# test here that the cgi header parser doesn't get confused and decide +# that there is no response body if it starts with \000 sequence + +print "Content-type: image/x-icon\n\n"; +print $response;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/cgi.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/cgi.pl new file mode 100755 index 0000000..ef4941c --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/cgi.pl
@@ -0,0 +1,5 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use CGI qw/:standard :html3/; + +print header(-type=>'text/html'); +print b("done");
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/closure.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/closure.pl new file mode 100755 index 0000000..495dd7a --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/closure.pl
@@ -0,0 +1,23 @@ +#!perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +BEGIN { + use Apache::TestUtil qw/t_server_log_warn_is_expected/; + t_server_log_warn_is_expected(); +} + +# this script will suffer from a closure problem under registry +# should see it under ::Registry +# should not see it under ::PerlRun + +print "Content-type: text/plain\n\n"; + +# this is a closure (when compiled inside handler()): +my $counter = 0; +counter(); + +sub counter { + #warn "$$: counter=$counter"; + print ++$counter; +} +
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/content_type.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/content_type.pl new file mode 100755 index 0000000..ceb3678 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/content_type.pl
@@ -0,0 +1,4 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +my $r = shift; +$r->content_type('text/plain'); +$r->print('ok');
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/env.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/env.pl new file mode 100755 index 0000000..d5990c5 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/env.pl
@@ -0,0 +1,7 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# test env vars + +print "Content-type: text/plain\n\n"; +print exists $ENV{QUERY_STRING} && $ENV{QUERY_STRING}; + +__END__
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/env_val.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/env_val.pl new file mode 100755 index 0000000..5632183 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/env_val.pl
@@ -0,0 +1,8 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# test env vars + +print "Content-type: text/plain\n\n"; +my $var = $ENV{QUERY_STRING}; +print exists $ENV{$var} && $ENV{$var}; + +__END__
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/exit.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/exit.pl new file mode 100755 index 0000000..90810ca --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/exit.pl
@@ -0,0 +1,18 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# XXX: exit should work by stopping the script, but not quitting the +# interpreter, though it's not trivial to make an automated test since +# what you really want to check whether the process didn't quit after +# exit was called. Things become more complicated with +# ithreads-enabled perls where one process may have many interpreters +# and you can't really track those at the moment. So this test needs +# more work. + +print "Content-type: text/plain\n\n"; + +print "before exit"; + +exit; + +print "after exit"; + +
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/flush.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/flush.pl new file mode 100755 index 0000000..b21f2cb --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/flush.pl
@@ -0,0 +1,18 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +local $| = 1; # unbuffered mode + +my $r = shift; + +print "Content-Type: text/html\n\n"; +print "yet another boring test string"; + +# This line passes a bucket brigade with a single bucket FLUSH +# it was causing problems in the mod_deflate filter which was trying to +# deflate empty output buffer, (the previous print has already flushed +# all the output) (the fix in mod_deflate.c was to check whether the +# buffer is full) +print ""; +
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/ithreads_io_n_tie.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/ithreads_io_n_tie.pl new file mode 100755 index 0000000..50d5f71 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/ithreads_io_n_tie.pl
@@ -0,0 +1,87 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# +# there is a problem when STDOUT is internally opened to an +# Apache2::PerlIO layer is cloned on a new thread start. PerlIO_clone +# in perl_clone() is called too early, before PL_defstash is +# cloned. As PerlIO_clone calls PerlIOApache_getarg, which calls +# gv_fetchpv via sv_setref_pv and boom the segfault happens. +# +# at the moment we should either not use an internally opened to +# :Apache2 streams, so the config must be: +# +# SetHandler modperl +# +# and then either use $r->print("foo") or tie *STDOUT, $r + print "foo" +# +# or close and re-open STDOUT to :Apache2 *after* the thread was spawned +# +# the above discussion equally applies to STDIN +# +# XXX: ->join calls leak under registry, this doesn't happen in the +# non-registry tests. + +use threads; + +my $r = shift; +$r->print("Content-type: text/plain\n\n"); + +{ + # now we can use $r->print API: + my $thr = threads->new( + sub { + my $id = shift; + $r->print("thread $id\n"); + return 1; + }, 1); + # $thr->join; # XXX: leaks scalar +} + +{ + # close and re-open STDOUT to :Apache2 *after* the thread was + # spawned + my $thr = threads->new( + sub { + my $id = shift; + close STDOUT; + open STDOUT, ">:Apache2", $r + or die "can't open STDOUT via :Apache2 layer : $!"; + print "thread $id\n"; + return 1; + }, 2); + # $thr->join; # XXX: leaks scalar +} + +{ + # tie STDOUT to $r *after* the ithread was started has + # happened, in which case we can use print + my $thr = threads->new( + sub { + my $id = shift; + tie *STDOUT, $r; + print "thread $id\n"; + return 1; + }, 3); + # $thr->join; # XXX: leaks scalar +} + +{ + # tie STDOUT to $r before the ithread was started has + # happened, in which case we can use print + tie *STDOUT, $r; + my $thr = threads->new( + sub { + my $id = shift; + print "thread $id\n"; + return 1; + }, 4); + # $thr->join; # XXX: leaks scalar +} + +sleep 2; # XXX: will go away ones join() calls are enabled + +print "parent\n"; + +untie *STDOUT; # don't affect other tests
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/local-conf.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/local-conf.pl new file mode 100644 index 0000000..e4e8dc9 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/local-conf.pl
@@ -0,0 +1,4 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +$test_require = 'it works'; + +1;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/missing_headers.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/missing_headers.pl new file mode 100755 index 0000000..5dad82d --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/missing_headers.pl
@@ -0,0 +1,9 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +BEGIN { + use Apache::TestUtil; + t_server_log_error_is_expected(); +} +print "No HTTP headers were sent\n\n"; + +print "Here is some more body coming\n even with double new line\n\n"; +print "Here is some more body coming";
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/not_executable.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/not_executable.pl new file mode 100644 index 0000000..d9ed3ba --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/not_executable.pl
@@ -0,0 +1,11 @@ +#!perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +# this test should return forbidden, since it should be not-executable + +print "Content-type: text/plain\n\n"; +print "ok"; + +__END__ + +this is some irrelevant data
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/nph-foo.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/nph-foo.pl new file mode 100755 index 0000000..a46836a --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/nph-foo.pl
@@ -0,0 +1,14 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +my $r = shift; + +print "HTTP/1.0 250 Pretty OK\r\n"; +print join("\n", + 'Content-type: text/text', + 'Pragma: no-cache', + 'Cache-control: must-revalidate, no-cache, no-store', + 'Expires: -1', + "\n"); + +print "non-parsed headers body";
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_decl.pm b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_decl.pm new file mode 100644 index 0000000..748b1af --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_decl.pm
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package perlrun_decl; + +use warnings; +use strict; + +use base qw(Exporter); +our @EXPORT = qw(decl_proto); + +# this BEGIN block is called only once, since this module doesn't get +# removed from %INC after it was loaded +BEGIN { + # use an external package which will persist across requests + $MyData::blocks{perlrun_decl}++; +} + +sub decl_proto ($;$) { shift } + +# this END block won't be executed until the server shutdown +END { + $MyData::blocks{perlrun_decl}--; +} + +1;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_extload.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_extload.pl new file mode 100755 index 0000000..72269de --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_extload.pl
@@ -0,0 +1,62 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use warnings; +use strict; + +use Apache::Test (); +use Apache::TestUtil; +use File::Spec::Functions qw(catfile catdir); + +use lib catdir Apache::Test::vars('serverroot'), 'cgi-bin'; +my $require = catfile Apache::Test::vars('serverroot'), + qw(cgi-bin perlrun_nondecl.pl); + +print "Content-type: text/plain\n\n"; + +### declared package module ### +{ + # require a module w/ package declaration (it doesn't get reloaded + # because it declares the package). But we still have a problem with + # subs declaring prototypes. When perlrun_decl->import is called, the + # original function's prototype doesn't match the aliases prototype. + # see decl_proto() + BEGIN { t_server_log_warn_is_expected() + if perlrun_decl->can("decl_proto"); + } + use perlrun_decl; + + die "perlrun_decl BEGIN block was run more than once" + if $MyData::blocks{perlrun_decl} > 1; + + print "d"; + print decl_proto(1); +} + +### non-declared package module ### +{ + # how many times were were called from the same interpreter + $MyData::blocks{cycle}{perlrun_nondecl}++; + $MyData::blocks{BEGIN}{perlrun_nondecl} ||= 0; + $MyData::blocks{END} {perlrun_nondecl} ||= 0; + + # require a lib w/o package declaration. Functions in that lib get + # automatically aliased to the functions in the current package. + require "$require"; + + die "perlrun_nondecl's BEGIN block wasn't run" + if $MyData::blocks{BEGIN}{perlrun_nondecl} != + $MyData::blocks{cycle}{perlrun_nondecl}; + + # the END block for this cycle didn't run yet, but we can test the + # previous cycle's one + die "perlrun_nondecl's END block wasn't run" + if $MyData::blocks{END}{perlrun_nondecl} + 1 != + $MyData::blocks{cycle}{perlrun_nondecl}; + + # they all get redefined warning inside perlrun_nondecl.pl, since that + # lib loads it into main::, vs. PerlRun undefs the current __PACKAGE__ + print "nd"; + print nondecl_no_proto(); + print nondecl_proto(2); + print nondecl_proto_empty("whatever"); + print nondecl_const(); +}
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_nondecl.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_nondecl.pl new file mode 100644 index 0000000..da36515 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/perlrun_nondecl.pl
@@ -0,0 +1,56 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# we use this file to test how the files w/o package declaration, +# required from perlrun, work + +use Apache::TestUtil; + +my $num; + +# this BEGIN block is called on every request, since this file gets +# removed from %INC after it was loaded +BEGIN { + # use an external package which will persist across requests + $MyData::blocks{BEGIN}{perlrun_nondecl}++; +} + +use subs qw(warn_exp); + +# all subs in this file get 'redefined' warning because they are +# reloaded in the main:: package, which is not under PerlRun's +# control. + +BEGIN { + t_server_log_warn_is_expected() + if defined *{"nondecl_no_proto"}{CODE}; +} +# normal sub, no prototype +sub nondecl_no_proto { 1 } + +BEGIN { + t_server_log_warn_is_expected() + if defined *{"nondecl_proto"}{CODE}; +} +# sub with a scalar proto +sub nondecl_proto ($) { $num = shift } + +BEGIN { + t_server_log_warn_is_expected() + if defined *{"nondecl_proto_empty"}{CODE}; +} +# sub with an empty proto, but not a constant +sub nondecl_proto_empty () { $num + 1 } + +# besides the the constant sub will generate two warnings for nondecl_const: +# - one for main:: +# - another for perlrun's virtual package +BEGIN { + t_server_log_warn_is_expected(2); +} +# a constant. +sub nondecl_const () { 4 } + +END { + $MyData::blocks{END}{perlrun_nondecl}++; +} + +1;
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/prefork.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/prefork.pl new file mode 100755 index 0000000..ae66b87 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/prefork.pl
@@ -0,0 +1,20 @@ +#!perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +# test that prefork runs from the directory the script lives in + +# All Modperl::*Prefork modules must chdir into the current dir, so we +# should be able to read ourselves via a relative path + +print "Content-type: text/plain\n\n"; + +my $script = "prefork.pl"; +if (open my $fh, $script) { + print "ok $script"; +} +else { + print "prefork didn't chdir into the scripts directory?"; + print " The error was: $!"; +} + +
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/r_inherited.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/r_inherited.pl new file mode 100755 index 0000000..a6eee27 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/r_inherited.pl
@@ -0,0 +1,13 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings; + +# this script shouldn't work + +# this is to test that $r is not in the scope from the function that +# has compiled this script in the registry module + +# my $r = shift; + +$r->content_type('text/plain'); +$r->print($r->args);
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/redirect-cookie.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/redirect-cookie.pl new file mode 100755 index 0000000..41fd912 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/redirect-cookie.pl
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# test env vars + +use Apache2::URI (); +use Apache2::Const -compile => qw(REDIRECT SERVER_ERROR); + +my $r = shift; +my $path = $r->args || ''; +$server = $r->construct_server; + +$r->err_headers_out->set('Set-Cookie' => "mod_perl=ubercool; path=/"); +$r->headers_out->set(Location => " http://$server$path"); +$r->status(Apache2::Const::REDIRECT); + +# exit status is completely ignored in Registry +# due to $r->status hacking +return Apache2::Const::SERVER_ERROR; + +__END__
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/redirect.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/redirect.pl new file mode 100755 index 0000000..7c92679 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/redirect.pl
@@ -0,0 +1,13 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# test env vars + +use Apache2::URI (); + +my $r = shift; +my $path = $r->args || ''; +$server = $r->construct_server; + +print "Location: http://$server$path\n\n"; +#warn "Location: http://$server$path\n\n"; + +__END__
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/require.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/require.pl new file mode 100755 index 0000000..43bd7eb --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/require.pl
@@ -0,0 +1,17 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# test the require + +use Apache::Test (); +use File::Spec::Functions qw(catfile); + +my $vars = Apache::Test::config()->{vars}; +my $require = catfile $vars->{serverroot}, 'cgi-bin', 'local-conf.pl'; + +print "Content-type: text/plain\n\n"; + +# XXX: meanwhile we don't chdir to the script's dir +delete $INC{$require}; +require $require; + +print defined $test_require && $test_require; +
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error.pl new file mode 100755 index 0000000..9cf74a1 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error.pl
@@ -0,0 +1,11 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +BEGIN { + use Apache::TestUtil; + t_server_log_error_is_expected(); +} + +# this script sends no body at all, and since the error happens +# the script will return 500 + +print "Content-type: text/plain\n\n"; +print no_such_func();
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_n_status_change.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_n_status_change.pl new file mode 100755 index 0000000..1687d2d --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_n_status_change.pl
@@ -0,0 +1,12 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +BEGIN { + use Apache::TestUtil; + t_server_log_error_is_expected(); +} + +use Apache2::Const -compile => qw(NOT_FOUND); + +my $r = shift; +$r->status(Apache2::Const::NOT_FOUND); +$r->print("Content-type: text/plain\n\n"); +$r->print(no_such_func());
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_plus_body.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_plus_body.pl new file mode 100755 index 0000000..c53f5dd --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/runtime_error_plus_body.pl
@@ -0,0 +1,11 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +BEGIN { + use Apache::TestUtil; + t_server_log_error_is_expected(); +} + +# this script sends some body before the error happens, +# so 200 OK is expected, followed by an error +print "Content-type: text/plain\n\n"; +print "some body"; +print no_such_func();
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/send_headers.html b/2_0_13/ModPerl-Registry/t/cgi-bin/send_headers.html new file mode 100755 index 0000000..1c35576 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/send_headers.html
@@ -0,0 +1,3 @@ +print "Content-type: text/plain\n\n"; +print "ok"; +
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/special_blocks.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/special_blocks.pl new file mode 100755 index 0000000..d1d66f9 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/special_blocks.pl
@@ -0,0 +1,35 @@ +#!perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +# test BEGIN/END blocks + +use Apache2::RequestRec (); + +use vars qw($query); +$query = '' unless defined $query; + +BEGIN { + $query = $ENV{QUERY_STRING}; +} + +print "Content-type: text/plain\n\n"; + +my $r = shift; +our $test = $r->args || ''; + +if ($test eq 'uncache') { + # mark the script as non-cached for the next execution + require ModPerl::RegistryCooker; + ModPerl::RegistryCooker::uncache_myself(); +} +elsif ($test eq 'begin') { + print "begin ok" if $query eq 'begin'; + # reset the global + $query = ''; +} + +END { + if (defined $test && $test eq 'end') { + print "end ok"; + } +}
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/status_change.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/status_change.pl new file mode 100755 index 0000000..4475d5a --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/status_change.pl
@@ -0,0 +1,6 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache2::Const -compile => qw(NOT_FOUND); + +my $r = shift; +$r->status(Apache2::Const::NOT_FOUND); +$r->print("Content-type: text/plain\n\n");
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/syntax_error.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/syntax_error.pl new file mode 100755 index 0000000..1716354 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/syntax_error.pl
@@ -0,0 +1,13 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +BEGIN { + use Apache::TestUtil; + t_server_log_error_is_expected(); +} + +print "Content-type: text/plain\n\n"; + +# the following syntax error is here on purpose! + +lkj;\; + +print "done";
diff --git a/2_0_13/ModPerl-Registry/t/cgi-bin/use_error.pl b/2_0_13/ModPerl-Registry/t/cgi-bin/use_error.pl new file mode 100755 index 0000000..00188c8 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi-bin/use_error.pl
@@ -0,0 +1,10 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +BEGIN { + use Apache::TestUtil; + t_server_log_error_is_expected(); +} + +use DoesNotExist (); + +print "Content-type: text/plain\n\n"; +print "this script is expected to fail";
diff --git a/2_0_13/ModPerl-Registry/t/cgi.t b/2_0_13/ModPerl-Registry/t/cgi.t new file mode 100644 index 0000000..b9133c5 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/cgi.t
@@ -0,0 +1,21 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET); + +plan tests => 2, need [qw(mod_alias.c HTML::HeadParser)], + need_min_module_version CGI => 3.08; + +my $url = "/registry/cgi.pl"; +my $res = GET $url; + +ok t_cmp($res->header('Content-type'), + qr{^text/html}, + "test 'Content-type header setting"); + +ok t_cmp(lc($res->content), + '<b>done</b>', + "test body");
diff --git a/2_0_13/ModPerl-Registry/t/closure.t b/2_0_13/ModPerl-Registry/t/closure.t new file mode 100644 index 0000000..dad160f --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/closure.t
@@ -0,0 +1,146 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +use TestCommon::SameInterp; + +use File::Spec::Functions; + +# this test tests how various registry packages cache and flush the +# scripts their run, and whether they check modification on the disk +# or not. We don't test the closure side effect, but we use it as a +# test aid. The tests makes sure that they run through the same +# interpreter all the time (in case that the server is running more +# than one interpreter) + +my @modules = qw(registry registry_bb perlrun); + +plan tests => 6, need [qw(mod_alias.c HTML::HeadParser)]; + +my $cfg = Apache::Test::config(); + +my $file = 'closure.pl'; +my $path = catfile $cfg->{vars}->{serverroot}, 'cgi-bin', $file; +my $orig_mtime = (stat($path))[8]; + +# for all sub-tests in this test, we make sure that we always get onto +# the same interpreter. if this doesn't happen we skip the sub-test or +# a group of them, where several sub-tests rely on each other. + +{ + # ModPerl::PerlRun + # always flush + # no cache + + my $url = "/same_interp/perlrun/$file"; + my $same_interp = Apache::TestRequest::same_interp_tie($url); + + # should be no closure effect, always returns 1 + my $first = same_interp_req_body($same_interp, \&GET, $url); + my $second = same_interp_req_body($same_interp, \&GET, $url); + same_interp_skip_not_found( + (scalar(grep defined, $first, $second) != 2), + $first && $second && ($second - $first), + 0, + "never the closure problem", + ); + + # modify the file + touch_mtime($path); + + # it doesn't matter, since the script is not cached anyway + my $third = same_interp_req_body($same_interp, \&GET, $url); + same_interp_skip_not_found( + (scalar(grep defined, $first, $second, $third) != 3), + $third, + 1, + "never the closure problem", + ); + + reset_mtime($path); +} + +{ + # ModPerl::Registry + # no flush + # cache, but reload on modification + my $url = "/same_interp/registry/$file"; + my $same_interp = Apache::TestRequest::same_interp_tie($url); + + # we don't know what other test has called this uri before, so we + # check the difference between two subsequent calls. In this case + # the difference should be 1. + my $first = same_interp_req_body($same_interp, \&GET, $url); + my $second = same_interp_req_body($same_interp, \&GET, $url); + same_interp_skip_not_found( + (scalar(grep defined, $first, $second) != 2), + $first && $second && ($second - $first), + 1, + "the closure problem should exist", + ); + + # modify the file + touch_mtime($path); + + # should not notice closure effect on the first request + my $third = same_interp_req_body($same_interp, \&GET, $url); + same_interp_skip_not_found( + (scalar(grep defined, $first, $second, $third) != 3), + $third, + 1, + "no closure on the first request", + ); + + reset_mtime($path); +} + +{ + # ModPerl::RegistryBB + # no flush + # cache once, don't check for mods + my $url = "/same_interp/registry_bb/$file"; + my $same_interp = Apache::TestRequest::same_interp_tie($url); + + # we don't know what other test has called this uri before, so we + # check the difference between two subsequent calls. In this case + # the difference should be 1. + my $first = same_interp_req_body($same_interp, \&GET, $url); + my $second = same_interp_req_body($same_interp, \&GET, $url); + same_interp_skip_not_found( + (scalar(grep defined, $first, $second) != 2), + $first && $second && ($second - $first), + 1, + "the closure problem should exist", + ); + + # modify the file + touch_mtime($path); + + # modification shouldn't be noticed + my $third = same_interp_req_body($same_interp, \&GET, $url); + same_interp_skip_not_found( + (scalar(grep defined, $first, $second, $third) != 3), + $first && $second && $third - $second, + 1, + "no reload on modification, the closure problem persists", + ); + + reset_mtime($path); +} + +sub touch_mtime { + my $file = shift; + # push the mtime into the future (at least 2 secs to work on win32) + # so ModPerl::Registry will re-compile the package + my $time = time + 5; # make it 5 to be sure + utime $time, $time, $file; +} + +sub reset_mtime { + my $file = shift; + # reset the timestamp to the original mod-time + utime $orig_mtime, $orig_mtime, $file; +}
diff --git a/2_0_13/ModPerl-Registry/t/conf/extra.conf.in b/2_0_13/ModPerl-Registry/t/conf/extra.conf.in new file mode 100644 index 0000000..1bdf835 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/conf/extra.conf.in
@@ -0,0 +1,235 @@ +#this file will be Include-d by @ServerRoot@/httpd.conf + +# Adjust PerlInterpMax and PerlInterpMaxSpare if the requirements change +# at the moment all tests require only 1 interprter +<IfDefine PERL_USEITHREADS> + PerlInterpStart 1 + PerlInterpMax 1 + PerlInterpMinSpare 1 + PerlInterpMaxSpare 1 +</IfDefine> + +# make sure that we test under Taint and warnings mode enabled +PerlSwitches -wT + +PerlSwitches -I@ServerRoot@/../lib \ + -I@ServerRoot@/../../Apache-Test/lib \ + -I@ServerRoot@/../../lib \ + -I@ServerRoot@/../../blib/lib \ + -I@ServerRoot@/../../blib/arch + +# run on startup +PerlRequire @ServerRoot@/conf/modperl_extra_startup.pl + +PerlSetVar ModPerl::RegistryCooker::DEBUG 2 + +PerlModule ModPerl::RegistryCooker +PerlModule ModPerl::Util + +############################# +### Normal registry setup ### +############################# +<IfModule mod_alias.c> + Alias /registry/ @ServerRoot@/cgi-bin/ + Alias /dirindex/ @ServerRoot@/cgi-bin/ + Alias /registry_bb/ @ServerRoot@/cgi-bin/ + Alias /registry_oo_conf/ @ServerRoot@/cgi-bin/ + Alias /registry_prefork/ @ServerRoot@/cgi-bin/ + Alias /perlrun/ @ServerRoot@/cgi-bin/ + Alias /perlrun_prefork/ @ServerRoot@/cgi-bin/ + Alias /nph/ @ServerRoot@/cgi-bin/ + Alias /registry_modperl_handler/ @ServerRoot@/cgi-bin/ + Alias /rewrite_env/ @ServerRoot@/cgi-bin/ + + ScriptAlias /cgi-bin/ @ServerRoot@/cgi-bin/ +</IfModule> + +PerlModule ModPerl::RegistryBB +<Location /registry_bb> + PerlOptions +GlobalRequest + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::RegistryBB + PerlOptions +ParseHeaders +</Location> + +PerlModule ModPerl::Registry +<Location /registry> + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::Registry + PerlOptions +ParseHeaders +</Location> + +<IfModule mod_dir.c> + <Location /dirindex> + AddHandler perl-script .pl + Options +ExecCGI + PerlResponseHandler ModPerl::Registry + PerlOptions +ParseHeaders + DirectoryIndex cgi.pl + </Location> +</IfModule> + +<Location /registry_modperl_handler> + SetHandler modperl + Options +ExecCGI + PerlResponseHandler ModPerl::Registry + PerlOptions +ParseHeaders +</Location> + +<Location /registry_oo_conf> + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::Registry->handler + PerlOptions +ParseHeaders +</Location> + +<Location /nph> + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::Registry +</Location> + +# don't preload ModPerl::RegistryPrefork as it won't load under +# threaded MPMs +<Location /registry_prefork> + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::RegistryPrefork + PerlOptions +ParseHeaders +</Location> + +# don't preload ModPerl::PerlRunPrefork as it won't load under +# threaded MPMs +<Location /perlrun_prefork> + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::PerlRunPrefork + PerlOptions +ParseHeaders +</Location> + +PerlModule ModPerl::PerlRun +<Location /perlrun> + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::PerlRun + PerlOptions +ParseHeaders +</Location> + +####################################### +### Same interpreter registry setup ### +####################################### +<IfModule mod_alias.c> + Alias /same_interp/registry/ @ServerRoot@/cgi-bin/ + Alias /same_interp/registry_bb/ @ServerRoot@/cgi-bin/ + Alias /same_interp/registry_oo_conf/ @ServerRoot@/cgi-bin/ + Alias /same_interp/perlrun/ @ServerRoot@/cgi-bin/ +</IfModule> + +PerlModule Apache::TestHandler + +<Location /same_interp/registry_bb> + PerlOptions +GlobalRequest + SetHandler perl-script + Options +ExecCGI + PerlFixupHandler Apache::TestHandler::same_interp_fixup + PerlResponseHandler ModPerl::RegistryBB + PerlOptions +ParseHeaders +</Location> + +<Location /same_interp/registry> + # PerlOptions +GlobalRequest + SetHandler perl-script + Options +ExecCGI + PerlFixupHandler Apache::TestHandler::same_interp_fixup + PerlResponseHandler ModPerl::Registry + PerlOptions +ParseHeaders +</Location> + +<Location /same_interp/registry_oo_conf> + PerlOptions +GlobalRequest + SetHandler perl-script + Options +ExecCGI + PerlFixupHandler Apache::TestHandler::same_interp_fixup + PerlResponseHandler ModPerl::Registry->handler + PerlOptions +ParseHeaders +</Location> + +<Location /same_interp/perlrun> + PerlOptions +GlobalRequest + SetHandler perl-script + Options +ExecCGI + PerlFixupHandler Apache::TestHandler::same_interp_fixup + PerlResponseHandler ModPerl::PerlRun + PerlOptions +ParseHeaders +</Location> + +### the 404 test ### +<IfModule mod_alias.c> + Alias /error_document/ @ServerRoot@/cgi-bin/ +</IfModule> + +<Location /error_document> + ErrorDocument 404 /error_document/404.pl + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::Registry +</Location> + +### deflate tests ### +<IfModule mod_alias.c> + Alias /registry_bb_deflate/ @ServerRoot@/cgi-bin/ +</IfModule> + +#PerlOutputFilterHandler ModPerl::TestFilterDebug::snoop_connection +PerlModule ModPerl::RegistryBB +<Location /registry_bb_deflate> + PerlOptions +GlobalRequest + SetHandler perl-script + Options +ExecCGI + PerlResponseHandler ModPerl::RegistryBB + PerlOptions +ParseHeaders + #PerlOutputFilterHandler ModPerl::TestFilterDebug::snoop_request + <IfModule mod_deflate.c> + SetOutputFilter DEFLATE + </IfModule> +</Location> + +# <sandbox-friendly> +# keep everything self-contained, to avoid problems with sandboxes +# which break when things try to run off /tmp +# +# XXX: consider folding the the following two settings into +# Apache-Test's autogenerated httpd.conf +<IfModule mod_cgid.c> + ScriptSock logs/cgisock +</IfModule> +# +# XXX: would be nice to have Apache-Test support a new 'tmp' token +# (similar to t_logs) which will map onto t/tmp by default and provide +# a new -tmp option to override this default +<IfModule mod_env.c> + SetEnv TMPDIR @t_logs@ +</IfModule> +# </sandbox-friendly> + + +<IfModule mod_rewrite.c> + + RewriteEngine On + <IfVersion < 2.4.0> + RewriteLogLevel 9 + RewriteLog @ServerRoot@/logs/rewrite_log + </IfVersion> + RewriteRule /rewritetest /rewrite_env/env_val.pl?REWRITE_TEST [E=REWRITE_TEST:GOTCHA,PT,NS,L] + + <Location /rewrite_env> + SetHandler perl-script + PerlResponseHandler ModPerl::Registry + Options +ExecCGI + PerlOptions +ParseHeaders + </Location> +</IfModule> + +
diff --git a/2_0_13/ModPerl-Registry/t/conf/modperl_extra_startup.pl b/2_0_13/ModPerl-Registry/t/conf/modperl_extra_startup.pl new file mode 100644 index 0000000..5511694 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/conf/modperl_extra_startup.pl
@@ -0,0 +1,53 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use ModPerl::RegistryLoader (); + +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Process (); + +use DirHandle (); + +my $proc = Apache2::ServerUtil->server->process; +my $pool = $proc->pool; + +# can't use catfile with server_root as it contains unix dir +# separators and in a few of our particular tests we compare against +# win32 separators. in general avoid using server_root_relative in your +# code, see the manpage for more details +my $base_dir = Apache2::ServerUtil::server_root_relative($pool, "cgi-bin"); + +# test the scripts pre-loading by explicitly specifying uri => filename +my $rl = ModPerl::RegistryLoader->new(package => "ModPerl::Registry"); +my $base_uri = "/cgi-bin"; +for my $file (qw(basic.pl env.pl)) { + my $file_path = "$base_dir/$file"; + my $uri = "$base_uri/$file"; + $rl->handler($uri, $file_path); +} + + +# test the scripts pre-loading by using trans sub +{ + sub trans { + my $uri = shift; + $uri =~ s|^/registry_bb/|cgi-bin/|; + return Apache2::ServerUtil::server_root_relative($pool, $uri); + } + + my $rl = ModPerl::RegistryLoader->new( + package => "ModPerl::RegistryBB", + trans => \&trans, + ); + + my @preload = qw(basic.pl env.pl require.pl special_blocks.pl + redirect.pl 206.pl content_type.pl); + + for my $file (@preload) { + $rl->handler("/registry_bb/$file"); + } +} + +1;
diff --git a/2_0_13/ModPerl-Registry/t/dirindex.t b/2_0_13/ModPerl-Registry/t/dirindex.t new file mode 100644 index 0000000..30520a7 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/dirindex.t
@@ -0,0 +1,23 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET); + +plan tests => 2, need [qw(mod_alias.c HTML::HeadParser mod_dir.c)], + need_min_module_version CGI => 3.08; + +{ + my $url = "/dirindex/"; + my $res = GET $url; + + ok t_cmp($res->header('Content-type'), + qr{^text/html}, + "DirectoryIndex + AddHandler - Content-type"); + + ok t_cmp(lc($res->content), + '<b>done</b>', + "DirectoryIndex + AddHandler - body"); +}
diff --git a/2_0_13/ModPerl-Registry/t/fatalstobrowser.t b/2_0_13/ModPerl-Registry/t/fatalstobrowser.t new file mode 100644 index 0000000..400d259 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/fatalstobrowser.t
@@ -0,0 +1,51 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil qw( + t_cmp t_write_perl_script + t_client_log_error_is_expected + ); +use Apache::TestRequest qw(GET); + +use File::Spec::Functions qw(catfile); + +plan tests => 4, need need_module(qw(mod_alias)), + need_cgi, + need_min_module_version CGI => 99.99, + skip_reason('fatalsToBrowser known not to work'); + +my $file = catfile(Apache::Test::vars('serverroot'), + qw(cgi-bin fatalstobrowser.pl)); + +t_write_perl_script($file, <DATA>); + +foreach my $base (qw(cgi-bin registry)) { + + my $url = "$base/fatalstobrowser.pl"; + my $res = GET $url; + + ok t_cmp($res->code, + 200, + "error intercepted"); + + t_client_log_error_is_expected(); + + ok t_cmp($res->content, + qr/uninitiated_scalar/, + "error message captured and returned"); +} + +__END__ +use strict; +use CGI::Carp qw (fatalsToBrowser); + +use CGI; + +my $cgi = new CGI; +print $cgi->header; + +print "$uninitiated_scalar"; + +print "Hello World";
diff --git a/2_0_13/ModPerl-Registry/t/flush.t b/2_0_13/ModPerl-Registry/t/flush.t new file mode 100644 index 0000000..d126ea8 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/flush.t
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET_BODY); + +plan tests => 1, need [qw(mod_alias.c deflate HTML::HeadParser)], + need_min_module_version("Compress::Zlib", "1.09"), + need_min_apache_version("2.0.48"); +# it requires httpd 2.0.48 because of the bug in mod_deflate: +# http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22259 + +require Compress::Zlib; + +my $url = "/registry_bb_deflate/flush.pl"; + +my $expected = "yet another boring test string"; +my $received = GET_BODY $url, 'Accept-encoding' => 'gzip'; +my $decompressed = Compress::Zlib::memGunzip($received); + +ok t_cmp( + $decompressed, + $expected, + "test flush body" + ); +
diff --git a/2_0_13/ModPerl-Registry/t/ithreads.t b/2_0_13/ModPerl-Registry/t/ithreads.t new file mode 100644 index 0000000..7d91ce9 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/ithreads.t
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use Config; + +use constant HAS_ITHREADS => ($] >= 5.008001 && $Config{useithreads}); + +plan tests => 1, need 'mod_alias.c', + {"perl 5.8.1 or higher w/ithreads enabled is required" => HAS_ITHREADS}; + +{ + # the order of prints on the server side is not important here, + # what's important is that we get all the printed strings + my @expected = sort map("thread $_", 1..4), "parent"; + my $url = "/registry_modperl_handler/ithreads_io_n_tie.pl"; + my $received = GET_BODY_ASSERT($url) || ''; + my @received = sort split /\n/, $received; + ok t_cmp \@received, \@expected; +}
diff --git a/2_0_13/ModPerl-Registry/t/nph.t b/2_0_13/ModPerl-Registry/t/nph.t new file mode 100644 index 0000000..f9b29e2 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/nph.t
@@ -0,0 +1,52 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 6, need 'mod_alias.c'; + +my $url = "/nph/nph-foo.pl"; + +my %expected = ( + code => '250', + body => "non-parsed headers body", + headers => { + 'content-type' => 'text/text', + 'pragma' => 'no-cache', + 'cache-control' => 'must-revalidate, no-cache, no-store', + 'expires' => '-1', + }, +); + +my $res = GET $url; + +my %received = ( + code => $res->code, + body => $res->content, + headers => $res->headers, # LWP lc's the headers +); + +for my $key (keys %expected) { + my $expected = $expected{$key}; + my $received = $received{$key}; + if ($key eq 'headers') { + for my $header (keys %$expected) { + ok t_cmp( + $received->{$header}, + $expected->{$header}, + "test header $header" + ); + } + } + else { + ok t_cmp( + $received, + $expected, + "test key: $key" + ); + } +} +
diff --git a/2_0_13/ModPerl-Registry/t/perlrun_extload.t b/2_0_13/ModPerl-Registry/t/perlrun_extload.t new file mode 100644 index 0000000..e99fd65 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/perlrun_extload.t
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET); +use TestCommon::SameInterp; + +plan tests => 2, need [qw(mod_alias.c HTML::HeadParser)]; + +my $url = "/same_interp/perlrun/perlrun_extload.pl"; +my $same_interp = Apache::TestRequest::same_interp_tie($url); + +for (1..2) { + # should not fail on the second request + my $res = same_interp_req_body($same_interp, \&GET, $url); + same_interp_skip_not_found( + !defined($res), + $res, + "d1nd1234", + "PerlRun requiring an external lib with subs", + ); +} +
diff --git a/2_0_13/ModPerl-Registry/t/prefork.t b/2_0_13/ModPerl-Registry/t/prefork.t new file mode 100644 index 0000000..00376a3 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/prefork.t
@@ -0,0 +1,48 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +use Apache::TestConfig (); + +use Apache2::Build (); + +my $mpm_is_threaded = Apache2::Build->build_config->mpm_is_threaded(); + +my %modules = ( + registry => 'ModPerl::Registry', + perlrun => 'ModPerl::PerlRun', + registry_prefork => 'ModPerl::RegistryPrefork', + perlrun_prefork => 'ModPerl::PerlRunPrefork', +); + +my @aliases = sort keys %modules; + +plan tests => 1*@aliases, need 'mod_alias.c', + { "can't run under threaded MPMs" => !$mpm_is_threaded }; + +my $script = "prefork.pl"; + +# very basic compilation/response test +for my $alias (qw(registry_prefork perlrun_prefork)) { + my $url = "/$alias/$script"; + + #t_debug "$url"; + ok t_cmp GET_BODY($url), "ok $script", "$modules{$alias} test"; +} + +# the order is important, we also want to check that prefork specific +# modules didn't affect the cwd of other modules + +# the normal handlers should not find the script in the cwd, as they +# don't chdir to its directory before running the script +for my $alias (qw(registry perlrun)) { + my $url = "/$alias/$script"; + + #t_debug "$url"; + ok t_cmp GET_BODY($url), + qr/prefork didn't chdir into the scripts directory/, + "$modules{$alias} test"; +}
diff --git a/2_0_13/ModPerl-Registry/t/redirect.t b/2_0_13/ModPerl-Registry/t/redirect.t new file mode 100644 index 0000000..b4e304e --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/redirect.t
@@ -0,0 +1,61 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET_BODY HEAD); + +use Apache::TestUtil qw(t_catfile_apache); + +plan tests => 4, need [qw(mod_alias.c HTML::HeadParser)], need_lwp; + +# need LWP to handle redirects +my $base_url = "/registry/redirect.pl"; + +{ + my $redirect_path = "/registry/basic.pl"; + my $url = "$base_url?$redirect_path"; + my $vars = Apache::Test::config()->{vars}; + my $script_file = t_catfile_apache $vars->{serverroot}, 'cgi-bin', 'basic.pl'; + + ok t_cmp( + GET_BODY($url), + "ok $script_file", + "test redirect: existing target", + ); +} + +{ + my $redirect_path = "/registry/does_not_exists.pl"; + my $url = "$base_url?$redirect_path"; + t_client_log_error_is_expected(); + ok t_cmp( + HEAD($url)->code, + 404, + "test redirect: non-existing target", + ); +} + +{ + local $Apache::TestRequest::RedirectOK = 0; + + my $base_url = "/registry/redirect-cookie.pl"; + my $redirect_path = "/registry/basic.pl"; + my $url = "$base_url?$redirect_path"; + + my $response = HEAD $url; + + ok t_cmp( + $response->code, + 302, + "test Registry style redirect: status", + ); + + ok t_cmp( + $response->header('Set-Cookie'), + "mod_perl=ubercool; path=/", + "test Registry style redirect: cookie", + ); +} +
diff --git a/2_0_13/ModPerl-Registry/t/regex.t b/2_0_13/ModPerl-Registry/t/regex.t new file mode 100644 index 0000000..4aba470 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/regex.t
@@ -0,0 +1,34 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil qw(t_cmp t_catfile_apache); +use Apache::TestRequest; +use Apache::TestConfig (); + +my %modules = ( + registry => 'ModPerl::Registry', + registry_bb => 'ModPerl::RegistryBB', + perlrun => 'ModPerl::PerlRun', +); + +my @aliases = sort keys %modules; + +plan tests => @aliases * 1, need 'mod_alias.c'; + +my $vars = Apache::Test::config()->{vars}; +my $script_file = t_catfile_apache $vars->{serverroot}, 'cgi-bin', 'basic.pl'; + +# extended regex quoting +# CVE-2007-1349 (which doesn't affect any of our shipped handlers) + +for my $alias (@aliases) { + my $url = "/$alias/basic.pl/("; + + ok t_cmp( + GET_BODY($url), + "ok $script_file", + "$modules{$alias} regex in path_info", + ); +}
diff --git a/2_0_13/ModPerl-Registry/t/rewrite_env.t b/2_0_13/ModPerl-Registry/t/rewrite_env.t new file mode 100644 index 0000000..b3e439d --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/rewrite_env.t
@@ -0,0 +1,18 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET); + +plan tests => 1, need [qw(mod_alias.c mod_rewrite.c)]; + +{ + my $url = "/rewritetest"; + my $res = GET $url; + + ok t_cmp($res->content(), + "GOTCHA", + 'found environment variable from mod_rewrite'); +}
diff --git a/2_0_13/ModPerl-Registry/t/special_blocks.t b/2_0_13/ModPerl-Registry/t/special_blocks.t new file mode 100644 index 0000000..2868064 --- /dev/null +++ b/2_0_13/ModPerl-Registry/t/special_blocks.t
@@ -0,0 +1,140 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# test BEGIN/END blocks's behavior + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +use TestCommon::SameInterp; + +my %modules = ( + registry => 'ModPerl::Registry', + registry_bb => 'ModPerl::RegistryBB', + perlrun => 'ModPerl::PerlRun', +); + +my @aliases = sort keys %modules; + +plan tests => @aliases * 4, need [qw(mod_alias.c HTML::HeadParser)]; + +{ + # PerlRun always run BEGIN/END since it's never cached + + # see also t/perlrun_extload.t which exercises BEGIN/END blocks + # from external modules loaded from PerlRun scripts + + my $alias = "perlrun"; + my $url = "/same_interp/$alias/special_blocks.pl"; + my $same_interp = Apache::TestRequest::same_interp_tie($url); + + # if one sub-test has failed to run on the same interpreter, skip + # the rest in the same group + my $skip = 0; + + my $res = same_interp_req_body($same_interp, \&GET, "$url?begin"); + $skip++ unless defined $res; + same_interp_skip_not_found( + $skip, + $res, + "begin ok", + "$modules{$alias} is running BEGIN blocks on the first request", + ); + + $res = $skip ? undef : same_interp_req_body($same_interp, \&GET, + "$url?begin"); + $skip++ unless defined $res; + same_interp_skip_not_found( + $skip, + $res, + "begin ok", + "$modules{$alias} is running BEGIN blocks on the second request", + ); + + $res = $skip ? undef : same_interp_req_body($same_interp, \&GET, + "$url?end"); + $skip++ unless defined $res; + same_interp_skip_not_found( + $skip, + $res, + "end ok", + "$modules{$alias} is running END blocks on the third request", + ); + + $res = $skip ? undef : same_interp_req_body($same_interp, \&GET, + "$url?end"); + $skip++ unless defined $res; + same_interp_skip_not_found( + $skip, + $res, + "end ok", + "$modules{$alias} is running END blocks on the fourth request", + ); +} + +# To properly test BEGIN/END blocks in registry implmentations +# that do caching, we need to manually reset the registry* cache +# for each given script, before starting each group of tests. + + +for my $alias (grep !/^perlrun$/, @aliases) { + my $url = "/same_interp/$alias/special_blocks.pl"; + my $same_interp = Apache::TestRequest::same_interp_tie($url); + + # if one sub-test has failed to run on the same interpreter, skip + # the rest in the same group + my $skip = 0; + + # clear the cache of the registry package for the script in $url + my $res = same_interp_req_body($same_interp, \&GET, "$url?uncache"); + $skip++ unless defined $res; + + $res = $skip ? undef : same_interp_req_body($same_interp, \&GET, + "$url?begin"); + $skip++ unless defined $res; + same_interp_skip_not_found( + $skip, + $res, + "begin ok", + "$modules{$alias} is running BEGIN blocks on the first request", + ); + + $res = $skip ? undef : same_interp_req_body($same_interp, \&GET, + "$url?begin"); + $skip++ unless defined $res; + t_debug($res); + same_interp_skip_not_found( + $skip, + $res, + "", + "$modules{$alias} is not running BEGIN blocks on the second request", + ); + + $same_interp = Apache::TestRequest::same_interp_tie($url); + $skip = 0; + + # clear the cache of the registry package for the script in $url + $res = same_interp_req_body($same_interp, \&GET, "$url?uncache"); + $skip++ unless defined $res; + + $res = $skip ? undef : same_interp_req_body($same_interp, \&GET, + "$url?end"); + $skip++ unless defined $res; + same_interp_skip_not_found( + $skip, + $res, + "end ok", + "$modules{$alias} is running END blocks on the first request", + ); + + $res = $skip ? undef : same_interp_req_body($same_interp, \&GET, + "$url?end"); + $skip++ unless defined $res; + same_interp_skip_not_found( + $skip, + $res, + "end ok", + "$modules{$alias} is running END blocks on the second request", + ); +}
diff --git a/2_0_13/NOTICE b/2_0_13/NOTICE new file mode 100644 index 0000000..3f59805 --- /dev/null +++ b/2_0_13/NOTICE
@@ -0,0 +1,2 @@ +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/).
diff --git a/2_0_13/README b/2_0_13/README new file mode 100644 index 0000000..a9d3739 --- /dev/null +++ b/2_0_13/README
@@ -0,0 +1,85 @@ +This is mod_perl version 2.0 + +*** Prerequisites *** + +Apache: + Dynamic mod_perl (DSO): Apache 2.0.47 - 2.4.57. + Static mod_perl: Apache 2.0.51 - 2.4.57. + + Newer Apache versions may work with this version of mod_perl. If + not, the svn version likely will, which can be obtained from: + http://perl.apache.org/download/source.html#Development_mod_perl_2_0_Source_Distribution + +Perl: + Any stable version of Perl currently in support by the Perl community, + as described in recent Perl distributions' "perlpolicy.pod" document. + + Newer Perl versions may work with this version of mod_perl. If not, + the svn version likely will (see above). + + Many older Perl versions also work with this version of mod_perl: + Perls back to version 5.8.2 (and possibly earlier in some build + configurations) are currently believed to work, but this is not + guaranteed to be the case, either now or in the future. + +*** Status *** + +mod_perl is currently considered stable. + +The following test failures are known (see CPAN RT #118919): + + t/filter/in_bbs_inject_header.t (Fails tests 22, 26 and 30) + +There is currently a known test failure on Windows when using Perls built +with the PERL_IMPLICIT_SYS build option enabled (which it is by default): + + t/modperl/env.t (Fails many tests) + +Various other tests are also known to fail in certain configurations on +Windows, including but not limited to: + + t/modperl/setupenv.t (Fails tests 8, 22, 29, 36, 50 and 57) + t/preconnection/note.t (Fails test 1) + +*** Documentation *** + +Documentation can be found in the docs/ directory. Currently they +don't get installed on 'make install'. Certain API documentation can +be found in docs/api/. The online version is at +http://perl.apache.org/docs/2.0/. + +*** Todo *** + +mod_perl-2.0 is not 100% feature complete with the 1.xx version. +See the files in the todo/ directory for what remains to be done. Some +of those features will be implemented after 2.0 is released. The goal +is to empty the file todo/release and document/test/verify the API +that's going to be supported by 2.0. More API will be supported post +2.0 release. + +*** Support *** + +For comments, questions, bug-reports, etc., join the mod_perl users +list by sending mail to modperl-subscribe@perl.apache.org. + +Bugs can also be reported at: +https://rt.cpan.org/Dist/Display.html?Name=mod_perl +which can be accessed from the "Issues" link in the left-hand menu on +the metacpan.org page, https://metacpan.org/pod/mod_perl2 . +(Note: You will need to log in to https://rt.cpan.org in order to get +the "Report a new bug" button on the bug tracker page.) + +When reporting bugs please follow the instructions at: +http://perl.apache.org/docs/2.0/user/help/help.html#Reporting_Problems + +For announcements join the mod_perl announce list by sending mail to +announce-subscribe@perl.apache.org. + +*** Developers *** + +Development discussion takes place on dev (at) perl.apache.org + +*** Authors *** + +mod_perl-2.0 was designed and written by Doug MacEachern, with +contributions from many others (see Changes files).
diff --git a/2_0_13/README-SVN b/2_0_13/README-SVN new file mode 100644 index 0000000..ff929f5 --- /dev/null +++ b/2_0_13/README-SVN
@@ -0,0 +1,59 @@ +this is a very simple document that outlines some of the important +details about the mod_perl svn repository. + + +LAYOUT + +the mod_perl project at the Apache Software Foundation lives here + + http://svn.apache.org/repos/asf/perl/ + +and uses the following structure + + modperl/trunk # equivalent to cvs HEAD - currently + # the mod_perl 2.0 development branch + + modperl/tags # every official mod_perl release + + modperl/docs/trunk # the mod_perl documentation project + +modperl/trunk includes the following svn:externals properties: + + % cd modperl + % svn propedit svn:externals . + [vi pops up] +Apache-Test https://svn.apache.org/repos/asf/perl/Apache-Test/trunk +Apache-Reload https://svn.apache.org/repos/asf/perl/Apache-Reload/trunk +Apache-SizeLimit https://svn.apache.org/repos/asf/perl/Apache-SizeLimit/trunk +docs https://svn.apache.org/repos/asf/perl/modperl/docs/trunk/src/docs/2.0 + +DEVELOPER ACCESS + +assuming that you have already been granted commit access to the repository, +you should follow the following steps to checkout mod_perl + +Change your password via: +https://svn.apache.org/change-password + + $ svn checkout https://svn.apache.org/repos/asf/perl/modperl/trunk/ mod_perl-2.0 + +if you want to test that your commit access is working, this file is +an acceptable place to take a test drive. + + +FURTHER READING + +for more details, see + + http://perl.apache.org/docs/2.0/user/install/install.html + +for information on getting httpd and mod_perl from svn, as well as + + http://svnbook.red-bean.com/ + +for svn information in general. + +svn for cvs users (including migration tools): + + http://svnbook.red-bean.com/en/1.0/apa.html +
diff --git a/2_0_13/RELEASE b/2_0_13/RELEASE new file mode 100644 index 0000000..41b7404 --- /dev/null +++ b/2_0_13/RELEASE
@@ -0,0 +1,211 @@ +Instructions for mod_perl 2.0 Release Manager + +0. make sure your public key is in the KEYS file in the mod_perl docs. + you should only need to do this if this is your first time playing + Release Manager + + $ cd mod_perl-docs + $ grep $USER src/dist/KEYS + + note that the KEYS file itself contains all the instructions you + need on how to add your key. if you need further help on gpg + (like how to create a key in the first place) you can look here + + https://people.apache.org/~geoff/gpghowto.html + + Copy the KEYS file into place: + % scp KEYS people.apache.org:/www/www.apache.org/dist/perl/KEYS + + If this is your first release, ask someone with APML karma on PAUSE + to verify you have the appropriate permissions. Likely someone on + the PMC can do this. + + a. login into https://pause.perl.org + b. menu click: Select Mailinglist/Action + c. choose APML and Change Permissions and click go + d. click 3.1 Make somebody else co-maintainer + e. choose the modules to give the perms to + type the username of the new co-maintainer + f. if you happen to know that packages were added this release, + make sure you give the correct permissions to them. + +1. 'make mydist' - to make sure nothing is missing from the manifest, + etc. Now test this generated package mod_perl-2.0.13.tar.gz (not + the current build) with as many + configurations as possible on as many platforms as possible, + unpacking the package each time afresh. + + a. edit ./Changes + - change -dev to -rc\d+ starting with -rc1 + - edit META.yml to the rc\d version above in the version key + + b. commit Changes + % svn ci -m "2.0.13 rc1" Changes + + c. nuke any preinstalled mod_perl libs and run 'make test' + + d. test that you can 'make install' and then run 'make test' again + + e. test whether we are still 100% OK on systems with no LWP: + % APACHE_TEST_PRETEND_NO_LWP=1 make test + + f. build and test as root. double check that you have started from a + fresh source, without having any stale dirs from the previous + build laying around. + +2. once confident that the package is good, commit the release candidate + to https://dist.apache.org/repos/dist/dev/perl and post 24 hour-ish + candidate alert to the modperl/dev list (may be longer to give most + people a chance to catch up). no need to tag this package + + Subject: [RELEASE CANDIDATE]: mod_perl-2.0.13 RC\d+ + +2a. if problems are detected during stage 2, repeat stages 1 and 2. + +3. when the package has been reported to be good, prepare a new + package to be released + + a. edit ./Changes: + - remove -rc\d+ + - add release date + - edit META.yml to remove the -rc\d+ from the version key + + b. check ./README and ./Makefile.PL + - make sure supported httpd versions (dso & static) are current + + c. rerun: + % perl Makefile.PL + make sure tag looks right + % make -n tag + + d. commit Changes README Makefile.PL + % svn ci -m "2.0.13 release" Changes README Makefile.PL + + e. tag + % make tag + + f. Update the svn:externals in the new tag to refer to the new docs tag that + was created by the previous step: + % svn co https://svn.apache.org/repos/asf/perl/modperl/tags/2_0_13 + % svn propedit svn:externals 2_0_13 + Update the docs line from: + ^/perl/modperl/docs/trunk/src/docs/2.0 + to: + ^/perl/modperl/docs/tags/2_0_13/src/docs/2.0 + The complete svn:externals should now look like: + % svn propget svn:externals 2_0_13 + Apache-Test ^/perl/Apache-Test/tags/<X> + Apache-Reload ^/perl/Apache-Reload/tags/<Y> + Apache-SizeLimit ^/perl/Apache-SizeLimit/tags/<Z> + docs ^/perl/modperl/docs/tags/2_0_13/src/docs/2.0 + where <X>, <Y> and <Z> are the tags of the releases of Apache-Test, + Apache-Reload and Apache-SizeLimit included in this release of mod_perl. + % svn ci -m "2.0.13 release" + + g. create the final package + % make dist + + h. test the final package again at least once + +4. Tarball signing + + (depending on whether you use GPG or PGP, pick the first or the + second set of the commands): + + a. sign your local copy of the tarball: + + % gpg --detach-sign --armor mod_perl-2.0.13.tar.gz + + % pgps -b --armor mod_perl-2.0.13.tar.gz + + b. create SHA256 and SHA512 checksums of the tarball: + % sha256sum mod_perl-2.0.13.tar.gz >mod_perl-2.0.13.tar.gz.sha256 + % sha512sum mod_perl-2.0.13.tar.gz >mod_perl-2.0.13.tar.gz.sha512 + +5. Release the package and update links + + a. commit the tarball, the signature file and the checksum files to + https://dist.apache.org/repos/dist/release/perl - ask the PMC + chair to give you the needed permissions if you do not have them. + + b. delete the previous release's files from the same location (they will + already have been archived at https://archive.apache.org/dist/perl/) + + c. update the example command-lines in README.html in the same location + + d. ask one of the other developers to double check the signature file + and tarball: download both files and verify the signature: + + https://www.apache.org/dist/perl/mod_perl-2.0.13.tar.gz.asc + https://www.apache.org/dist/perl/mod_perl-2.0.13.tar.gz + + % gpg --verify mod_perl-2.0.13.tar.gz.asc + + % pgpv mod_perl-2.0.13.tar.gz.asc + + e. respond to the automated email that will arrive requesting that release + data be filled in at https://reporter.apache.org/addrelease.html?perl + + f. update the version and release date in the docs: + % vi modperl-docs/src/download/index_top.html + % vi modperl-docs/doap_Perl.rdf + and commit. + % svn ci -m "2.0.13 release" \ + modperl-docs/src/download/index_top.html \ + modperl-docs/doap_Perl.rdf + + Now run modperl-docs/bin/site_build to generate a local copy of the + website, and commit that to https://svn.apache.org/repos/asf/perl/site + + (Alternatively, if running modperl-docs/bin/site_build is too difficult + on your local machine, you can just directly edit download/index.html + with the changes that were made to modperl-docs/download/index_top.html) + + The change to the website will appear at https://perl.apache.org/ sometime + later (but maybe not until the next day). + +6. Upload the package to CPAN + +7. Announce the package + + a. post to the following lists: + + o dev/perl.apache.org + o modperl/perl.apache.org + o announce/apache.org + + Note, to post to announce@, you must be sending from an apache.org address. + + Subject: [ANNOUNCE] mod_perl 2.0.13 + + include: + - link at perl.apache.org: + https://perl.apache.org/download/index.html + - SHA256 and SHA512 sigs + - the latest Changes + +8. Prepare for the next cycle + + a. increment version in lib/mod_perl2.pm + + b. increment version in META.yml + + c. edit ./Changes: + - start a new item with incremented version + '-dev' + + =item 2.0.14-dev + + d. add a release entry in STATUS + + e. update this file versions to make it easy to copy-n-paste things + on the next release: + % perl -pi.bak -e 's/(\d+)([._])(\d+)(\2)(\d+)/join($2, $1, $3, $5+1)/eg' RELEASE + + f. commit the changed files + % svn ci -m "start 2.0.13-dev cycle" Changes META.yml lib/mod_perl2.pm \ + STATUS RELEASE + +9. Old Versions + + Remind other developers to delete versions older then the prior release + from CPAN. Old releases can always be found on BACKPAN.
diff --git a/2_0_13/STATUS b/2_0_13/STATUS new file mode 100644 index 0000000..1083f10 --- /dev/null +++ b/2_0_13/STATUS
@@ -0,0 +1,44 @@ +mod_perl 2.0 STATUS: -*-text-*- + Last modified at [$Date$] + +Release: +-------- + 2.000.12 : Released Jan 30, 2022 + 2.000.11 : Released Oct 05, 2019 + 2.000.10 : Released Oct 27, 2016 + 2.000.09 : Released Jun 18, 2015 + 2.000.08 : Released Apr 17, 2013 + 2.000.07 : Released Jun 05, 2012 + 2.000.06 : Released Apr 24, 2012 + 2.000.05 : Released Feb 07, 2011 + 2.000.04 : Released Apr 16, 2008 + 2.000.03 : Released Nov 29, 2006 + 2.000.02 : Released Oct 20, 2005 + 2.000.01 : Released Jun 17, 2005 + 2.000.00 : Released May 20, 2005 + 1.999.23 : Released May 03, 2005 + 1.999.22 : Released Apr 14, 2005 + 1.999.21 : Released Jan 22, 2005 + 1.999.20 : Released Jan 05, 2005 + 1.99_19 : Released Dec 22, 2004 + 1.99_18 : Released Dec 12, 2004 + 1.99_17 : Released Oct 22, 2004 + 1.99_16 : Released Aug 22, 2004 + 1.99_15 : Released Aug 20, 2004 + 1.99_14 : Released May 21, 2004 + 1.99_13 : Released Mar 08, 2004 + 1.99_12 : Released Dec 22, 2003 + 1.99_11 : Released Nov 10, 2003 + 1.99_10 : Released Sep 30, 2003 + 1.99_09 : Released Apr 28, 2003 + 1.99_08 : Released Jan 10, 2003 + 1.99_07 : Released Sep 27, 2002 + 1.99_06 : Not released + 1.99_05 : Released Aug 20, 2002 + 1.99_04 : Released Jun 21, 2002 + 1.99_03 : Released Jun 16, 2002 + 1.99_02 : Released Jun 01, 2002 + 1.99_01 : Released Apr 06, 2002 + +Issues, bugs and features and their implementation status are spread +across several files under the todo/ directory
diff --git a/2_0_13/SVN-MOVE b/2_0_13/SVN-MOVE new file mode 100644 index 0000000..e98bfc1 --- /dev/null +++ b/2_0_13/SVN-MOVE
@@ -0,0 +1,30 @@ +This file tracks the things that need to be done to accomplish the +move of modperl projects to SVN: + +* missing commit template files (à là CVS) + PR: + Obtained from: + Submitted by: + Reviewed by: + ... + +* commit messages should trim the unrelated crap in the file path + e.g. currently we get: + + --- perl/modperl/docs/trunk/src/search/swish.conf (original) + +++ perl/modperl/docs/trunk/src/search/swish.conf Fri Nov 19 21:23:25 2004 +and it should be: + + --- src/search/swish.conf (original) + +++ src/search/swish.conf Fri Nov 19 21:23:25 2004 + +so it can be applied/edited easily. + +* improve the commit message subject line to print only important info + (currently may print 100 files listed in the subject), e.g.: + + Subject: svn commit: r105803 - in httpd/test/trunk/perl-framework: . Apache-Test Apache-Test/lib/Apache Apache-Test/t Apache-Test/t/conf c-modules c-modules/authany c-modules/client_add_filter c-modules/eat_post c-modules/echo_post c-modules/echo_post_chunk c-modules/input_body_filter c-modules/list_modules c-modules/nntp_like c-modules/random_chunk c-modules/test_apr_uri c-modules/test_pass_brigade c-modules/test_rwrite c-modules/test_ssl t t/conf t/conf/ssl t/htdocs/modules/access/htaccess t/htdocs/modules/cgi t/htdocs/modules/rewrite t/modules + + Proposed Subject format: + + $svn_id $first_subdir/$first_file ($trunk)
diff --git a/2_0_13/bin/mp2bug b/2_0_13/bin/mp2bug new file mode 100755 index 0000000..c3a312a --- /dev/null +++ b/2_0_13/bin/mp2bug
@@ -0,0 +1,36 @@ +#!perl +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +use strict; +use warnings FATAL => 'all'; + +use FindBin; + +use constant IS_MOD_PERL_BUILD => -e "$FindBin::Bin/../lib/mod_perl2.pm"; + +if (IS_MOD_PERL_BUILD) { + unshift @INC, "$FindBin::Bin/../lib"; +} +else { + eval { require mod_perl2 }; + if ($@) { + die "This script requires mod_perl 2.0\n", "$@"; + } +} + +require ModPerl::TestReport; +ModPerl::TestReport->new(@ARGV)->run;
diff --git a/2_0_13/build/config.pl b/2_0_13/build/config.pl new file mode 100644 index 0000000..7b9e09c --- /dev/null +++ b/2_0_13/build/config.pl
@@ -0,0 +1,10 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use FindBin qw($Bin); +use lib "$Bin/../lib"; + +use ModPerl::Config (); + +print ModPerl::Config::as_string();
diff --git a/2_0_13/build/make_etags b/2_0_13/build/make_etags new file mode 100644 index 0000000..703588a --- /dev/null +++ b/2_0_13/build/make_etags
@@ -0,0 +1,27 @@ +search=".. ../.." +for dir in $search; do + if test -d "`pwd`/$dir/modperl-2.0"; then + root="`pwd`/$dir" + echo "root=$root" + fi +done + +#e.g. symlink to $HOME/perl/perl-current +#XXX: perl has its own (more robust) TAGS generator: emacs/ptags +perl_src=$root/perl/ +#XXX: apache has its own: build/MakeEtags +apache_src=$root/httpd-2.0/ +modperl_src=$root/modperl-2.0/src/ +xs_src=$root/modperl-2.0/xs + +cd $root/modperl-2.0 +rm -f src/modules/perl/etag_files + +for dir in $apache_src $modperl_src $perl_src $xs_src; do + echo $dir + find $dir -follow -name '*.[ch]' >> src/modules/perl/etag_files +done + +(cd src/modules/perl && etags `cat etag_files`) + +rm -f src/modules/perl/etag_files
diff --git a/2_0_13/build/make_rpm_spec b/2_0_13/build/make_rpm_spec new file mode 100755 index 0000000..2ad2c4e --- /dev/null +++ b/2_0_13/build/make_rpm_spec
@@ -0,0 +1,146 @@ +#!perl +use strict; + +require "./lib/mod_perl2.pm"; + +my $dev_build = is_dev_build(); +my $release = $dev_build ? svn_release() : 1; +my $version = $mod_perl2::VERSION_TRIPLET; +my $path = $dev_build ? "mod_perl-$version-$dev_build" : "mod_perl-$version"; +my $tarname = "$path.tar.gz"; + +my $httpd_ver = min_httpd_ver(); + +open(my $spec, ">mod_perl.spec") || die "Can't open mod_perl.spec $!"; + +print $spec <<"EOF"; +%define _version $mod_perl2::VERSION_TRIPLET +%define _release $release +%define _source https://apache.org/dist/perl/$tarname +%define _dirname $path +%define _httpd_min_ver $httpd_ver +%define _perl_min_ver 5.6.1 +EOF + +print $spec <<'EOF'; +Name: mod_perl +Version: %{_version} +Release: %{_release} +Summary: An embedded Perl interpreter for the Apache Web server +Group: System Environment/Daemons +License: Apache License, Version 2.0 +Packager: mod_perl Development Team <dev@perl.apache.org> +URL: https://perl.apache.org/ +Source: %{_source} +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Requires: httpd >= %{_httpd_min_ver} +BuildRequires: perl >= %{_perl_min_ver} +BuildRequires: httpd-devel >= %{_httpd_min_ver} +BuildRequires: apr-devel, apr-util-devel + +%description +Mod_perl incorporates a Perl interpreter into the Apache web server, +so that the Apache web server can directly execute Perl code. +Mod_perl links the Perl runtime library into the Apache web server and +provides an object-oriented Perl interface for Apache's C language +API. The end result is a quicker CGI script turnaround process, since +no external Perl interpreter has to be started. + +Install mod_perl if you're installing the Apache web server and you'd +like for it to directly incorporate a Perl interpreter. + +%package devel +Summary: Files needed for building XS modules that use mod_perl +Group: Development/Libraries +Requires: mod_perl = %{version}-%{release}, httpd-devel + +%description devel +The mod_perl-devel package contains the files needed for building XS +modules that use mod_perl. + +%prep +%setup -q -n %{_dirname} + +%build +CFLAGS="$RPM_OPT_FLAGS" %{__perl} Makefile.PL </dev/null \ + PREFIX=$RPM_BUILD_ROOT/usr \ + INSTALLDIRS=vendor \ + MP_APXS=%{_sbindir}/apxs +make %{?_smp_mflags} OPTIMIZE="$RPM_OPT_FLAGS" + +%install +rm -rf $RPM_BUILD_ROOT +install -d -m 755 $RPM_BUILD_ROOT%{_libdir}/httpd/modules +make install \ + MODPERL_AP_LIBEXECDIR=$RPM_BUILD_ROOT%{_libdir}/httpd/modules \ + MODPERL_AP_INCLUDEDIR=$RPM_BUILD_ROOT%{_includedir}/httpd + +# Remove the temporary files. +find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';' +find $RPM_BUILD_ROOT -type f -name perllocal.pod -exec rm -f {} ';' +find $RPM_BUILD_ROOT -type f -name '*.bs' -a -size 0 -exec rm -f {} ';' +find $RPM_BUILD_ROOT -type d -depth -exec rmdir {} 2>/dev/null ';' + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc Changes LICENSE README* STATUS SVN-MOVE docs/ +%{_bindir}/* +%{_libdir}/httpd/modules/mod_perl.so +%{perl_vendorarch}/auto/* +%{perl_vendorarch}/Apache/ +%{perl_vendorarch}/Apache2/ +%{perl_vendorarch}/Bundle/ +%{perl_vendorarch}/APR/ +%{perl_vendorarch}/ModPerl/ +%{perl_vendorarch}/*.pm +%{_mandir}/man?/* + +%files devel +%defattr(-,root,root,-) +%{_includedir}/httpd/* + +%changelog +EOF + +sub min_httpd_ver { + my $min_httpd_ver; + open my $mk, 'Makefile.PL'; + while (<$mk>) { + if (/MIN_HTTPD_VERSION_DYNAMIC\s*=>\s*'(.*)'/) { + $min_httpd_ver = $1; + last; + } + } + close $mk; + $min_httpd_ver; +} + +sub svn_release { + open my $svn, "<.svn/entries"; + my $revision; + while (<$svn>) { + if (/revision="(\d+)"/) { + $revision = $1; + last; + } + } + close $svn; + $revision; +} + +sub is_dev_build { + my $dev; + open my $fh, 'Changes'; + while (<$fh>) { + if (/^=item.*-(dev|rc\d+)/) { + $dev = $1; + last; + } + last if /^=item/; + } + close $fh; + $dev; +}
diff --git a/2_0_13/build/source_scan.pl b/2_0_13/build/source_scan.pl new file mode 100644 index 0000000..3a6da0e --- /dev/null +++ b/2_0_13/build/source_scan.pl
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +#requires C::Scan 0.75+ + +use lib qw(lib Apache-Test/lib); + +use strict; +use Apache2::ParseSource (); +use ModPerl::ParseSource (); +use ModPerl::FunctionMap (); +use ModPerl::WrapXS (); #XXX: we should not need to require this here + +my $p = Apache2::ParseSource->new(prefixes => ModPerl::FunctionMap->prefixes, + @ARGV); + +$p->parse; + +$p->write_constants_pm; + +$p->write_functions_pm; + +$p->write_structs_pm; + +$p = ModPerl::ParseSource->new(@ARGV); + +$p->parse; + +$p->write_functions_pm;
diff --git a/2_0_13/build/win32_fetch_apxs b/2_0_13/build/win32_fetch_apxs new file mode 100755 index 0000000..ee6c964 --- /dev/null +++ b/2_0_13/build/win32_fetch_apxs
@@ -0,0 +1,101 @@ +#!C:/Perl/bin/perl +################################################################### +# apxs, apr-config, and apu-config are Apache utilities used # +# to both get certain configuration information and also to # +# assist in building Apache modules. These utilities have not # +# yet been officially ported to Win32. The following will fetch # +# and install a development version of these scripts which can # +# be used in both mod_perl 2 and Apache C modules. # +# # +# Please report problems in installing or using these utilties to # +# Randy Kobes <randy@theoryx5.uwinnipeg.ca> # +################################################################### +use strict; +use warnings; +use Getopt::Long; +use File::Spec::Functions; +use File::Path; +use ExtUtils::MakeMaker qw(prompt); +use Cwd; + +die "This is intended for Win32" unless ($^O =~ /Win32/i); + +my $prefix; +GetOptions( 'with-apache2=s' => \$prefix); +unless ($prefix and -d $prefix) { + die << 'END'; + +I could not determine a valid Apache2 directory. Please +run this script specifying the option + --with-apache2=/Path/to/Apache2 +where /Path/to/Apache2 is the location of your installed +Apache2 top-level directory. + +END +} + +exit 0 if (-e catfile($prefix, 'bin', 'apxs.bat')); + +print << 'END'; + +---------------------------------------------------------------------- +I could not find an apxs utility, which will be used in certain parts +of the build, if present. This utility (and the apr-config and +apu-config utilities) have not yet been ported to Apache2 on Win32, +but a development port is available. You can either + +- ignore installing apxs by answering "no" at the prompt below + (mod_perl will still build), +- install apxs by answering "yes" at the prompt below, +- quit now, run the "fetch_win32_apxs.pl" script in the build/ directory + to fetch and install the utilities, and then rebuild mod_perl, +- quit now, and from https://apache.org/dist/perl/win32-bin/ grab + apxs_win32.tar.gz; when unpacked, this contains a README explaining + how to install the utilities. Afterwards, rebuild mod_perl. +---------------------------------------------------------------------- + +END + +my $ans = prompt('Install apxs now?', 'yes'); +exit 0 unless $ans =~ /^y/i; + +my $prog; +for my $trial(qw(Apache.exe httpd.exe)) { + next unless -e File::Spec->catfile($prefix, 'bin', $trial); + $prog = $trial; + last; +} +die "Could not determine the Apache2 binary name" unless $prog; + +require LWP::Simple; +LWP::Simple->import(qw(is_success getstore)); + +my $file = 'apxs_win32.tar.gz'; +unless (-e $file) { + my $remote = 'https://apache.org/dist/perl/win32-bin/' . $file; + print "Fetching $remote ... "; + die "Download of $remote failed" + unless (is_success(getstore($remote, $file))); + print " done!\n"; +} + +require Archive::Tar; +my $cwd = getcwd; +my $dir = 'apxs'; +my $arc = Archive::Tar->new($file, 1); +$arc->extract($arc->list_files()); +die "Unpacking $file failed" unless (-d $dir); + +print "chdir $dir\n"; +chdir $dir or die "chdir to $dir failed: $!"; + +my @args = ($^X, 'Configure.pl', + "--with-apache2=$prefix", + "--with-apache-prog=$prog"); +print "@args\n"; +system(@args) == 0 or die "system @args failed: $?"; + +chdir $cwd; +#rmtree($dir, 1, 1) or warn "rmtree of $dir failed: $!"; +#print "unlink $file\n\n"; +#unlink $file or warn "unlink of $file failed: $!";
diff --git a/2_0_13/build/xs_generate.pl b/2_0_13/build/xs_generate.pl new file mode 100644 index 0000000..74761b5 --- /dev/null +++ b/2_0_13/build/xs_generate.pl
@@ -0,0 +1,11 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use lib qw(lib Apache-Test/lib); + +use Apache::TestConfig (); # needed to resolve circular use dependency + +use ModPerl::WrapXS (); + +my $xs = ModPerl::WrapXS->new; + +$xs->generate; +
diff --git a/2_0_13/lib/APR/XSLoader.pm b/2_0_13/lib/APR/XSLoader.pm new file mode 100644 index 0000000..fc390f2 --- /dev/null +++ b/2_0_13/lib/APR/XSLoader.pm
@@ -0,0 +1,38 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package APR::XSLoader; + +use strict; +use warnings FATAL => 'all'; + +use XSLoader (); + +BEGIN { + unless (defined &BOOTSTRAP) { + *BOOTSTRAP = sub () { 0 }; + } +} + +sub load { + return unless BOOTSTRAP; + # do not change the next line and do not insert anything below it in this + # function. XSLoader::load depends on it. + goto &XSLoader::load; +} + +1; +__END__
diff --git a/2_0_13/lib/Apache2/Build.pm b/2_0_13/lib/Apache2/Build.pm new file mode 100644 index 0000000..19692a8 --- /dev/null +++ b/2_0_13/lib/Apache2/Build.pm
@@ -0,0 +1,2400 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::Build; + +use 5.006; +use strict; +use warnings; + +use Config; +use Cwd (); +use File::Spec::Functions qw(catfile catdir canonpath rel2abs devnull + catpath splitpath); +use File::Basename; +use ExtUtils::Embed (); +use File::Copy (); + +BEGIN { # check for a sane ExtUtils::Embed + unless ($ENV{MP_USE_MY_EXTUTILS_EMBED}) { + my ($version, $path)=(ExtUtils::Embed->VERSION, + $INC{q{ExtUtils/Embed.pm}}); + my $msg=<<"EOF"; +I have found ExtUtils::Embed $version at + + $path + +This is probably not the right one for this perl version. Please make sure +there is only one version of this module installed and that it is the one +that comes with this perl version. + +If you insist on using the ExtUtils::Embed as is set the environment +variable MP_USE_MY_EXTUTILS_EMBED=1 and try again. + +EOF + if (eval {require Module::CoreList}) { + my $req=$Module::CoreList::version{$]}->{q/ExtUtils::Embed/}; + die "Please repair your Module::CoreList" unless $req; + unless ($version eq $req) { + $msg.=("Details: expecting ExtUtils::Embed $req ". + "(according to Module::CoreList)\n\n"); + die $msg; + } + } + else { + my $req=$Config{privlib}.'/ExtUtils/Embed.pm'; + unless ($path eq $req) { + $msg.="Details: expecting ExtUtils::Embed at $req\n\n"; + die $msg; + } + } + } +} + +use constant IS_MOD_PERL_BUILD => grep + { -e "$_/Makefile.PL" && -e "$_/lib/mod_perl2.pm" } qw(. ..); + +use constant AIX => $^O eq 'aix'; +use constant DARWIN => $^O eq 'darwin'; +use constant CYGWIN => $^O eq 'cygwin'; +use constant IRIX => $^O eq 'irix'; +use constant HPUX => $^O eq 'hpux'; +use constant OPENBSD => $^O eq 'openbsd'; +use constant WIN32 => $^O eq 'MSWin32'; + +use constant MSVC => WIN32() && ($Config{cc} eq 'cl'); +use constant DMAKE => WIN32() && ($Config{make} eq 'dmake'); + +use constant REQUIRE_ITHREADS => grep { $^O eq $_ } qw(MSWin32); +use constant PERL_HAS_ITHREADS => + $Config{useithreads} && ($Config{useithreads} eq 'define'); +use constant BUILD_APREXT => WIN32() || CYGWIN(); + +use ModPerl::Code (); +use ModPerl::BuildOptions (); +use Apache::TestTrace; +use Apache::TestConfig (); + +our $VERSION = '0.01'; +our $AUTOLOAD; + +sub AUTOLOAD { + my $self = shift; + my $name = uc ((split '::', $AUTOLOAD)[-1]); + unless ($name =~ /^MP_/) { + die "no such method: $AUTOLOAD"; + } + unless ($self->{$name}) { + return wantarray ? () : undef; + } + return wantarray ? (split /\s+/, $self->{$name}) : $self->{$name}; +} + +#--- apxs stuff --- + +our $APXS; + +my %apxs_query = ( + INCLUDEDIR => 'include', + LIBEXECDIR => 'modules', + CFLAGS => undef, + PREFIX => '', +); + +sub ap_prefix_invalid { + my $self = shift; + + my $prefix = $self->{MP_AP_PREFIX}; + + unless (-d $prefix) { + return "$prefix: No such file or directory"; + } + + my $include_dir = $self->apxs(-q => 'INCLUDEDIR'); + + unless (-d $include_dir) { + return "include/ directory not found in $prefix"; + } + + return ''; +} + +sub httpd_is_source_tree { + my $self = shift; + + return $self->{httpd_is_source_tree} + if exists $self->{httpd_is_source_tree}; + + my $prefix = $self->dir; + $self->{httpd_is_source_tree} = + defined $prefix && -d $prefix && -e "$prefix/CHANGES"; +} + +# try to find the apxs utility, set $self->{MP_APXS} to the path if found, +# otherwise to '' +sub find_apxs_util { + my $self = shift; + + if (not defined $self->{MP_APXS}) { + $self->{MP_APXS} = ''; # not found + } + + my @trys = ($Apache2::Build::APXS, + $self->{MP_APXS}, + $ENV{MP_APXS}); + + push @trys, catfile $self->{MP_AP_PREFIX}, 'bin', 'apxs' + if exists $self->{MP_AP_PREFIX}; + + if (WIN32) { + my $ext = '.bat'; + for (@trys) { + $_ .= $ext if ($_ and $_ !~ /$ext$/); + } + } + + unless (IS_MOD_PERL_BUILD) { + #if we are building mod_perl via apxs, apxs should already be known + #these extra tries are for things built outside of mod_perl + #e.g. libapreq + # XXX: this may pick a wrong apxs version! + push @trys, + Apache::TestConfig::which('apxs'), + '/usr/local/apache/bin/apxs'; + } + + my $apxs_try; + for (@trys) { + next unless ($apxs_try = $_); + chomp $apxs_try; + if (-x $apxs_try) { + $self->{MP_APXS} = $apxs_try; + last; + } + } +} + +# if MP_AP_DESTDIR was specified this sub will prepend this path to +# any Apache-specific installation path (that option is used only by +# package maintainers). +sub ap_destdir { + my $self = shift; + my $path = shift || ''; + return $path unless $self->{MP_AP_DESTDIR}; + + if (WIN32) { + my ($dest_vol, $dest_dir) = splitpath $self->{MP_AP_DESTDIR}, 1; + my $real_dir = (splitpath $path)[1]; + + $path = catpath $dest_vol, catdir($dest_dir, $real_dir), ''; + } + else { + $path = catdir $self->{MP_AP_DESTDIR}, $path; + } + + return canonpath $path; +} + +sub apxs { + my $self = shift; + + $self->find_apxs_util() unless defined $self->{MP_APXS}; + + my $is_query = (@_ == 2) && ($_[0] eq '-q'); + + $self = $self->build_config unless ref $self; + + my $query_key; + if ($is_query) { + $query_key = 'APXS_' . uc $_[1]; + if (exists $self->{$query_key}) { + return $self->{$query_key}; + } + } + + unless ($self->{MP_APXS}) { + my $prefix = $self->{MP_AP_PREFIX} || ""; + return '' unless -d $prefix and $is_query; + my $val = $apxs_query{$_[1]}; + return defined $val ? ($val ? "$prefix/$val" : $prefix) : ""; + } + + my $devnull = devnull(); + my $val = qx($self->{MP_APXS} @_ 2>$devnull); + chomp $val if defined $val; + + unless ($val) { + # do we have an error or is it just an empty value? + my $error = qx($self->{MP_APXS} @_ 2>&1); + chomp $error if defined $error; + if ($error) { + error "'$self->{MP_APXS} @_' failed:"; + error $error; + } + else { + $val = ''; + } + } + + $self->{$query_key} = $val; +} + +sub apxs_cflags { + my $who = caller_package(shift); + my $cflags = $who->apxs('-q' => 'CFLAGS'); + $cflags =~ s/\"/\\\"/g; + $cflags; +} + +sub apxs_extra_cflags { + my $who = caller_package(shift); + my $flags = $who->apxs('-q' => 'EXTRA_CFLAGS'); + $flags =~ s/\"/\\\"/g; + $flags; +} + +sub apxs_extra_cppflags { + my $who = caller_package(shift); + my $flags = $who->apxs('-q' => 'EXTRA_CPPFLAGS') ." ". + $who->apxs('-q' => 'NOTEST_CPPFLAGS'); + $flags =~ s/\"/\\\"/g; + $flags; +} + +sub caller_package { + my $arg = shift; + return ($arg and ref($arg) eq __PACKAGE__) ? $arg : __PACKAGE__; +} + +my %threaded_mpms = map { $_ => 1 } + qw(worker winnt beos mpmt_os2 netware leader perchild threadpool + dynamic); +sub mpm_is_threaded { + my $self = shift; + my $mpm_name = $self->mpm_name(); + return exists $threaded_mpms{$mpm_name} ? 1 : 0; +} + +sub mpm_name { + my $self = shift; + + return $self->{mpm_name} if $self->{mpm_name}; + + if ($self->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/) { + delete $threaded_mpms{dynamic} if $self->mp_nonthreaded_ok; + return $self->{mpm_name} = 'dynamic' if ($1*1000+$2)*1000+$3>=2003000; + } + + # XXX: hopefully apxs will work on win32 one day + return $self->{mpm_name} = 'winnt' if WIN32; + + my $mpm_name; + + # httpd >= 2.3 + if ($self->httpd_version_as_int =~ m/^2[3-9]\d+/) { + $mpm_name = 'dynamic'; + } + else { + $mpm_name = $self->apxs('-q' => 'MPM_NAME'); + } + + # building against the httpd source dir + unless (($mpm_name and $self->httpd_is_source_tree)) { + if ($self->dir) { + my $config_vars_file = catfile $self->dir, + "build", "config_vars.mk"; + if (open my $fh, $config_vars_file) { + while (<$fh>) { + if (/MPM_NAME = (\w+)/) { + $mpm_name = $1; + last; + } + } + close $fh; + } + } + } + + unless ($mpm_name) { + my $msg = 'Failed to obtain the MPM name.'; + $msg .= " Please specify MP_APXS=/full/path/to/apxs to solve " . + "this problem." unless exists $self->{MP_APXS}; + error $msg; + die "\n"; + } + + return $self->{mpm_name} = $mpm_name; +} + +sub should_build_apache { + my ($self) = @_; + return $self->{MP_USE_STATIC} ? 1 : 0; +} + +sub configure_apache { + my ($self) = @_; + + unless ($self->{MP_AP_CONFIGURE}) { + error "You specified MP_USE_STATIC but did not specify the " . + "arguments to httpd's ./configure with MP_AP_CONFIGURE"; + exit 1; + } + + unless ($self->{MP_AP_PREFIX}) { + error "You specified MP_USE_STATIC but did not speficy the " . + "location of httpd's source tree with MP_AP_PREFIX"; + exit 1; + } + + debug "Configuring httpd in $self->{MP_AP_PREFIX}"; + + my $httpd = File::Spec->catfile($self->{MP_AP_PREFIX}, 'httpd'); + $self->{'httpd'} ||= $httpd; + push @Apache::TestMM::Argv, ('httpd' => $self->{'httpd'}); + + my $mplibpath = ''; + my $ldopts = $self->ldopts; + + if (CYGWIN) { + # Cygwin's httpd port links its modules into httpd2core.dll, + # instead of httpd.exe. In this case, we have a problem, + # because libtool doesn't want to include static libs (.a) + # into a dynamic lib (.dll). Workaround this by setting + # mod_perl.a as a linker argument (including all other flags + # and libs). + my $mplib = "$self->{MP_LIBNAME}$Config{lib_ext}"; + + $ldopts = join ' ', + '--export-all-symbols', + '--enable-auto-image-base', + "$self->{cwd}/src/modules/perl/$mplib", + $ldopts; + + $ldopts =~ s/(\S+)/-Wl,$1/g; + + } else { + my $mplib = "$self->{MP_LIBNAME}$Config{lib_ext}"; + $mplibpath = catfile($self->{cwd}, qw(src modules perl), $mplib); + } + + local $ENV{BUILTIN_LIBS} = $mplibpath; + local $ENV{AP_LIBS} = $ldopts; + local $ENV{MODLIST} = 'perl'; + + # XXX: -Wall and/or -Werror at httpd configure time breaks things + local $ENV{CFLAGS} = join ' ', grep { ! /\-Wall|\-Werror/ } + split /\s+/, $ENV{CFLAGS} || ''; + + my $cd = qq(cd $self->{MP_AP_PREFIX}); + + # We need to clean the httpd tree before configuring it + if (-f File::Spec->catfile($self->{MP_AP_PREFIX}, 'Makefile')) { + my $cmd = qq(make clean); + debug "Running $cmd"; + system("$cd && $cmd") == 0 or die "httpd: $cmd failed"; + } + + my $cmd = qq(./configure $self->{MP_AP_CONFIGURE}); + debug "Running $cmd"; + system("$cd && $cmd") == 0 or die "httpd: $cmd failed"; + + # Got to build in srclib/* early to have generated files present. + my $srclib = File::Spec->catfile($self->{MP_AP_PREFIX}, 'srclib'); + $cd = qq(cd $srclib); + $cmd = qq(make); + debug "Building srclib in $srclib"; + system("$cd && $cmd") == 0 or die "srclib: $cmd failed"; +} + +#--- Perl Config stuff --- + +my %gtop_config = (); +sub find_gtop { + my $self = shift; + + return %gtop_config if %gtop_config; + + if (%gtop_config = find_gtop_config()) { + return %gtop_config; + } + + if ($self->find_dlfile('gtop')) { + $gtop_config{ldopts} = $self->gtop_ldopts_old(); + $gtop_config{ccopts} = ''; + return %gtop_config; + } + + return (); +} + +sub find_gtop_config { + my %c = (); + + my $ver_2_5_plus = 0; + if (system('pkg-config --exists libgtop-2.0') == 0) { + # 2.x + chomp($c{ccopts} = qx|pkg-config --cflags libgtop-2.0|); + chomp($c{ldopts} = qx|pkg-config --libs libgtop-2.0|); + + # 2.0.0 bugfix + chomp(my $libdir = qx|pkg-config --variable=libdir libgtop-2.0|); + $c{ldopts} =~ s|\$\(libdir\)|$libdir|; + + chomp($c{ver} = qx|pkg-config --modversion libgtop-2.0|); + ($c{ver_maj}, $c{ver_min}) = split /\./, $c{ver}; + $ver_2_5_plus++ if $c{ver_maj} == 2 && $c{ver_min} >= 5; + + if ($ver_2_5_plus) { + # some headers were removed in libgtop 2.5.0 so we need to + # be able to exclude them at compile time + $c{ccopts} .= ' -DGTOP_2_5_PLUS'; + } + + } + elsif (system('gnome-config --libs libgtop') == 0) { + chomp($c{ccopts} = qx|gnome-config --cflags libgtop|); + chomp($c{ldopts} = qx|gnome-config --libs libgtop|); + + # buggy ( < 1.0.9?) versions fixup + $c{ccopts} =~ s|^/|-I/|; + $c{ldopts} =~ s|^/|-L/|; + } + + # starting from 2.5.0 'pkg-config --cflags libgtop-2.0' already + # gives us all the cflags that are needed + if ($c{ccopts} && !$ver_2_5_plus) { + chomp(my $ginc = `glib-config --cflags`); + $c{ccopts} .= " $ginc"; + } + + if (%c) { + $c{ccopts} = " $c{ccopts}"; + $c{ldopts} = " $c{ldopts}"; + } + + return %c; +} + +my @Xlib = qw(/usr/X11/lib /usr/X11R6/lib); + +sub gtop_ldopts_old { + my $self = shift; + my $xlibs = ""; + + my ($path) = $self->find_dlfile('Xau', @Xlib); + if ($path) { + $xlibs = "-L$path -lXau"; + } + + if ($self->find_dlfile('intl')) { + $xlibs .= ' -lintl'; + } + + return " -lgtop -lgtop_sysdeps -lgtop_common $xlibs"; +} + +sub gtop_ldopts { + exists $gtop_config{ldopts} ? $gtop_config{ldopts} : ''; +} + +sub gtop_ccopts { + exists $gtop_config{ccopts} ? $gtop_config{ccopts} : ''; +} + +sub ldopts { + my ($self) = @_; + + my $config = tied %Config; + my $ldflags = $config->{ldflags}; + + if (WIN32) { + $config->{ldflags} = ''; #same as lddlflags + } + elsif (DARWIN) { + #not sure how this can happen, but it shouldn't + my @bogus_flags = ('flat_namespace', 'bundle', 'undefined suppress'); + for my $flag (@bogus_flags) { + $config->{ldflags} =~ s/-$flag\s*//; + } + } + + my $ldopts = ExtUtils::Embed::ldopts(); + chomp $ldopts; + + my $ld = $self->perl_config('ld'); + + if (HPUX && $ld eq 'ld') { + while ($ldopts =~ s/-Wl,(\S+)/$1/) { + my $cp = $1; + (my $repl = $cp) =~ s/,/ /g; + $ldopts =~ s/\Q$cp/$repl/; + } + } + + if ($self->{MP_USE_GTOP}) { + $ldopts .= $self->gtop_ldopts; + } + + $config->{ldflags} = $ldflags; #reset + + # on Irix mod_perl.so needs to see the libperl.so symbols, which + # requires the -exports option immediately before -lperl. + if (IRIX) { + ($ldopts =~ s/-lperl\b/-exports -lperl/) + or warn "Failed to fix Irix symbol exporting\n"; + } + + $ldopts; +} + +my $Wall = + "-Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"; + +# perl v5.6.1 and earlier produces lots of warnings, so we can't use +# -Werror with those versions. +$Wall .= " -Werror" if $] >= 5.006002; + +sub ap_ccopts { + my ($self) = @_; + my $ccopts = "-DMOD_PERL"; + + if ($self->{MP_USE_GTOP}) { + $ccopts .= " -DMP_USE_GTOP"; + $ccopts .= $self->gtop_ccopts; + } + + if ($self->{MP_MAINTAINER}) { + $self->{MP_DEBUG} = 1; + if ($self->perl_config('gccversion')) { + #same as --with-maintainter-mode + $ccopts .= " $Wall"; + } + + if (!OPENBSD && + $self->has_gcc_version('3.3.2') && + $ccopts !~ /declaration-after-statement/) { + debug "Adding -Wdeclaration-after-statement to ccopts"; + $ccopts .= " -Wdeclaration-after-statement"; + } + } + + if ($self->{MP_COMPAT_1X}) { + $ccopts .= " -DMP_COMPAT_1X"; + } + + if ($self->{MP_DEBUG}) { + $self->{MP_TRACE} = 1; + my $win32_flags = MSVC ? '-Od -MD -Zi' : ''; + my $debug_flags = WIN32 ? $win32_flags : '-g'; + $ccopts .= " $debug_flags" unless $Config{optimize} =~ /$debug_flags/; + $ccopts .= ' -DMP_DEBUG'; + } + + if ($self->{MP_CCOPTS}) { + $ccopts .= " $self->{MP_CCOPTS}"; + } + + if ($self->{MP_TRACE}) { + $ccopts .= " -DMP_TRACE"; + } + + if ($self->has_gcc_version('5.0.0') && $ccopts !~ /-fgnu89-inline/) { + $ccopts .= " -fgnu89-inline"; + } + + if ($self->has_clang && $ccopts !~ /-std=gnu89/) { + $ccopts .= " -std=gnu89"; + } + + # make sure apr.h can be safely included + # for example Perl's included -D_GNU_SOURCE implies + # -D_LARGEFILE64_SOURCE on linux, but this won't happen on + # Solaris, so we need apr flags living in apxs' EXTRA_CPPFLAGS + my $extra_cppflags = $self->apxs_extra_cppflags; + $ccopts .= " " . $extra_cppflags; + + # Make sure the evil AP_DEBUG is not defined when building mod_perl + $ccopts =~ s/ ?-DAP_DEBUG\b//; + + $ccopts; +} + +sub has_gcc_version { + my $self = shift; + my $requested_version = shift; + + my $has_version = $self->perl_config('gccversion'); + + return 0 unless $has_version; + + #Only interested in leading version digits + $has_version =~ s/^([0-9.]+).*/$1/; + + my @tuples = split /\./, $has_version, 3; + my @r_tuples = split /\./, $requested_version, 3; + + return cmp_tuples(\@tuples, \@r_tuples) == 1; +} + +sub has_clang { + my $self = shift; + + my $has_version = $self->perl_config('gccversion'); + + return 0 unless $has_version; + + return $has_version =~ m/Clang/; +} + +sub cmp_tuples { + my ($num_a, $num_b) = @_; + + while (@$num_a && @$num_b) { + my $cmp = shift @$num_a <=> shift @$num_b; + return $cmp if $cmp; + } + + return @$num_a <=> @$num_b; +} + +sub perl_ccopts { + my $self = shift; + + my $cflags = $self->strip_lfs(" $Config{ccflags} "); + + my $fixup = \&{"ccopts_$^O"}; + if (defined &$fixup) { + $fixup->(\$cflags); + } + + if (WIN32 and $self->{MP_DEBUG}) { + #only win32 has -DDEBUGGING in both optimize and ccflags + my $optim = $Config{optimize}; + + unless ($optim =~ /-DDEBUGGING/) { + $cflags =~ s/$optim//; + } + } + + if (CYGWIN) { + $cflags .= " -DCYGWIN "; + } + + $cflags; +} + +sub ccopts_hpux { + my $cflags = shift; + return if $Config{cc} eq 'gcc'; #XXX? + return if $$cflags =~ /(-Ae|\+e)/; + $$cflags .= " -Ae "; +} + +# XXX: there could be more, but this is just for cosmetics +my %cflags_dups = map { $_ => 1 } qw(-D_GNU_SOURCE -D_REENTRANT); +sub ccopts { + my ($self) = @_; + + my $cflags = $self->perl_ccopts . ExtUtils::Embed::perl_inc() . + $self->ap_ccopts; + + # remove duplicates of certain cflags coming from perl and ap/apr + my @cflags = (); + my %dups = (); + for (split /\s+/, $cflags) { + if ($cflags_dups{$_}) { + next if $dups{$_}; + $dups{$_}++; + } + push @cflags, $_; + } + $cflags = "@cflags"; + + $cflags; +} + +sub ldopts_prefix { + my $self = shift; + $self->perl_config('ld') eq 'ld' ? '' : "-Wl,"; +} + +sub perl_config_optimize { + my ($self, $val) = @_; + + $val ||= $Config{optimize}; + + if ($self->{MP_DEBUG}) { + return ' ' unless $Config{ccflags} =~ /-DDEBUGGING/; + } + + $val; +} + +sub perl_config_ld { + my ($self, $val) = @_; + + $val ||= $Config{ld}; + + basename $val; #bleedperl hpux value is /usr/bin/ld ! +} + +sub perl_config_lddlflags { + my ($self, $val) = @_; + + if ($self->{MP_DEBUG}) { + if (MSVC) { + unless ($val =~ s/-release/-debug/) { + $val .= ' -debug'; + } + } + } + + if (AIX) { + my $Wl = $self->ldopts_prefix; + + # it's useless to import symbols from libperl.so this way, + # because perl.exp is incomplete. a better way is to link + # against -lperl which has all the symbols + $val =~ s|${Wl}-bI:\$\(PERL_INC\)/perl\.exp||; + # also in the case of Makefile.modperl PERL_INC is defined + + # this works with at least ld(1) on powerpc-ibm-aix5.1.0.0: + # -berok ignores symbols resolution problems (they will be + # resolved at run-time + # -brtl prepares the object for run-time loading + # LDFLAGS already inserts -brtl + $val .= " ${Wl}-berok"; + # XXX: instead of -berok, could make sure that we have: + # -Lpath/to/CORE -lperl + # -bI:$path/apr.exp -bI:$path/aprutil.exp -bI:$path/httpd.exp + # -bI:$path/modperl_*.exp + # - don't import modperl_*.exp in Makefile.modperl which + # exports -bE:$path/modperl_*.exp + # - can't rely on -bI:$path/perl.exp, because it's incomplete, + # use -lperl instead + # - the issue with using apr/aprutil/httpd.exp is to pick the + # right path if httpd wasn't yet installed + } + + $val; +} + +sub perl_config { + my ($self, $key) = @_; + + my $val = $Config{$key} || ''; + + my $method = \&{"perl_config_$key"}; + if (defined &$method) { + return $method->($self, $val); + } + + return $val; +} + +sub find_in_inc { + my $name = shift; + for (@INC) { + my $file; + if (-e ($file = "$_/auto/Apache2/$name")) { + return $file; + } + } +} + +sub libpth { + my $self = shift; + $self->{libpth} ||= [split /\s+/, $Config{libpth}]; + return wantarray ? @{ $self->{libpth} } : $self->{libpth}; +} + +sub find_dlfile { + my ($self, $name) = (shift, shift); + + require DynaLoader; + require AutoLoader; #eek + + my $found = 0; + my $loc = ""; + my (@path) = ($self->libpth, @_); + + for (@path) { + if ($found = DynaLoader::dl_findfile($_, "-l$name")) { + $loc = $_; + last; + } + } + + return wantarray ? ($loc, $found) : $found; +} + +sub find_dlfile_maybe { + my ($self, $name) = @_; + + my $path = $self->libpth; + + my @maybe; + my $lib = 'lib' . $name; + + for (@$path) { + push @maybe, grep { ! -l $_ } <$_/$lib.*>; + } + + return \@maybe; +} + +sub lib_check { + my ($self, $name) = @_; + return unless $self->perl_config('libs') =~ /$name/; + + return if $self->find_dlfile($name); + + my $maybe = $self->find_dlfile_maybe($name); + my $suggest = @$maybe ? + "You could just symlink it to $maybe->[0]" : + 'You might need to install Perl from source'; + $self->phat_warn(<<EOF); +Your Perl is configured to link against lib$name, + but lib$name.so was not found. + $suggest +EOF +} + +#--- user interaction --- + +sub prompt { + my ($self, $q, $default) = @_; + return $default if $self->{MP_PROMPT_DEFAULT}; + require ExtUtils::MakeMaker; + ExtUtils::MakeMaker::prompt($q, $default); +} + +sub prompt_y { + my ($self, $q) = @_; + $self->prompt($q, 'y') =~ /^y/i; +} + +sub prompt_n { + my ($self, $q) = @_; + $self->prompt($q, 'n') =~ /^n/i; +} + +sub phat_warn { + my ($self, $msg, $abort) = @_; + my $level = $abort ? 'ERROR' : 'WARNING'; + warn <<EOF; +************* $level ************* + + $msg + +************* $level ************* +EOF + if ($abort) { + exit 1; + } + else { + sleep 5; + } +} + +#--- constructors --- + +my $bpm = 'Apache2/BuildConfig.pm'; + +sub build_config { + my $self = shift; + my $bpm_mtime = 0; + + $bpm_mtime = (stat _)[9] if $INC{$bpm} && -e $INC{$bpm}; + + if (-e "lib/$bpm" and (stat _)[9] > $bpm_mtime) { + #reload if Makefile.PL has regenerated + unshift @INC, 'lib'; + delete $INC{$bpm}; + eval { require Apache2::BuildConfig; }; + shift @INC; + } + else { + eval { require Apache2::BuildConfig; }; + } + + return bless {}, (ref($self) || $self) if $@; + return Apache2::BuildConfig->new; +} + +sub new { + my $class = shift; + + my $self = bless { + cwd => Cwd::fastcwd(), + MP_LIBNAME => 'mod_perl', + MP_APXS => undef, # so we know we haven't tried to set it yet + @_, + }, $class; + + $self->{MP_APR_LIB} = 'aprext'; + + ModPerl::BuildOptions->init($self) if delete $self->{init}; + + $self; +} + +sub DESTROY {} + +my %default_files = ( + 'build_config' => 'lib/Apache2/BuildConfig.pm', + 'ldopts' => 'src/modules/perl/ldopts', + 'makefile' => 'src/modules/perl/Makefile', +); + +sub clean_files { + my $self = shift; + [sort map { $self->default_file($_) } keys %default_files]; +} + +sub default_file { + my ($self, $name, $override) = @_; + my $key = join '_', 'file', $name; + $self->{$key} ||= ($override || $default_files{$name}); +} + +sub file_path { + my $self = shift; + + # work around when Apache2::BuildConfig has not been created yet + return unless $self && $self->{cwd}; + + my @files = map { m:^/: ? $_ : join('/', $self->{cwd}, $_) } @_; + return wantarray ? @files : $files[0]; +} + +sub freeze { + require Data::Dumper; + local $Data::Dumper::Terse = 1; + local $Data::Dumper::Sortkeys = 1; + my $data = Data::Dumper::Dumper(shift); + chomp $data; + $data; +} + +sub save_ldopts { + my ($self, $file) = @_; + + $file ||= $self->default_file('ldopts', $file); + my $ldopts = $self->ldopts; + + open my $fh, '>', $file or die "open $file: $!"; + print $fh "#!/bin/sh\n\necho $ldopts\n"; + close $fh; + chmod 0755, $file; +} + +sub noedit_warning_hash { + ModPerl::Code::noedit_warning_hash(__PACKAGE__); +} + +sub save { + my ($self, $file) = @_; + + delete $INC{$bpm}; + + $file ||= $self->default_file('build_config'); + $file = $self->file_path($file); + + my $obj = $self->freeze; + $obj =~ s/^\s{9}//mg; + $obj =~ s/^/ /; + + open my $fh, '>', $file or die "open $file: $!"; + + #work around autosplit braindeadness + my $package = 'package Apache2::BuildConfig'; + + print $fh noedit_warning_hash(); + + print $fh <<EOF; +$package; + +use Apache2::Build (); + +sub new { +$obj; +} + +1; +EOF + + close $fh or die "failed to write $file: $!"; +} + +sub rebuild { + my $self = __PACKAGE__->build_config; + my @opts = map { qq[$_='$self->{$_}'] } sort grep /^MP_/, keys %$self; + my $command = "perl Makefile.PL @opts"; + print "Running: $command\n"; + system $command; +} +# % perl -MApache2::Build -e rebuild +*main::rebuild = \&rebuild if $0 eq '-e'; + +#--- attribute access --- + +sub is_dynamic { shift->{MP_USE_DSO} } + +sub default_dir { + my $build = shift->build_config; + + return $build->dir || '../apache_x.x/src'; +} + +sub dir { + my ($self, $dir) = @_; + + if ($dir) { + for (qw(ap_includedir)) { + delete $self->{$_}; + } + if ($dir =~ m:^\.\.[/\\]:) { + $dir = "$self->{cwd}/$dir"; + } + $self->{dir} = $dir; + } + + return $self->{dir} if $self->{dir}; + + # be careful with the guesswork, or may pick up some wrong headers + if (IS_MOD_PERL_BUILD && $self->{MP_AP_PREFIX}) { + my $build = $self->build_config; + + if (my $bdir = $build->{'dir'}) { + for ($bdir, "../$bdir", "../../$bdir") { + if (-d $_) { + $dir = $_; + last; + } + } + } + } + + $dir ||= $self->{MP_AP_PREFIX}; + +# we no longer install Apache headers, so don't bother looking in @INC +# might end up finding 1.x headers anyhow +# unless ($dir and -d $dir) { +# for (@INC) { +# last if -d ($dir = "$_/auto/Apache2/include"); +# } +# } + return $self->{dir} = $dir ? canonpath(rel2abs $dir) : undef; +} + +#--- finding apache *.h files --- + +sub find { + my $self = shift; + my %seen = (); + my @dirs = (); + + for my $src_dir ($self->dir, + $self->default_dir, + '../httpd-2.0') + { + next unless $src_dir; + next unless (-d $src_dir || -l $src_dir); + next if $seen{$src_dir}++; + push @dirs, $src_dir; + #$modified{$src_dir} = (stat($src_dir))[9]; + } + + return @dirs; +} + +sub ap_includedir { + my ($self, $d) = @_; + + return $self->{ap_includedir} + if $self->{ap_includedir} and -d $self->{ap_includedir}; + + return unless $d ||= $self->apxs('-q' => 'INCLUDEDIR') || $self->dir; + + if (-e "$d/include/ap_release.h") { + return $self->{ap_includedir} = "$d/include"; + } + + $self->{ap_includedir} = $d; +} + +# This is necessary for static builds that needs to make a +# difference between where the apache headers are (to build +# against) and where they will be installed (to install our +# own headers alongside) +# +# ap_exp_includedir is where apache is going to install its +# headers to +sub ap_exp_includedir { + my ($self) = @_; + + return $self->{ap_exp_includedir} if $self->{ap_exp_includedir}; + + my $build_vars = File::Spec->catfile($self->{MP_AP_PREFIX}, + qw(build config_vars.mk)); + open my $vars, "<$build_vars" or die "Couldn't open $build_vars $!"; + my $ap_exp_includedir; + while (<$vars>) { + if (/exp_includedir\s*=\s*(.*)/) { + $ap_exp_includedir = $1; + last; + } + } + + $self->{ap_exp_includedir} = $ap_exp_includedir; +} + +sub install_headers_dir { + my ($self) = @_; + if ($self->should_build_apache) { + return $self->ap_exp_includedir(); + } + else { + return $self->ap_includedir(); + } +} + + +# where apr-config and apu-config reside +sub apr_bindir { + my ($self) = @_; + + $self->apr_config_path unless $self->{apr_bindir}; + $self->{apr_bindir}; +} + +sub apr_generation { + my ($self) = @_; + return $self->httpd_version_as_int =~ m/2[1-9]\d+/ ? 1 : 0; +} + +# returns an array of apr/apu linking flags (--link-ld --libs) if found +# an empty array otherwise +my @apru_link_flags = (); +sub apru_link_flags { + my ($self) = @_; + + return @apru_link_flags if @apru_link_flags; + + # first use apu_config_path and then apr_config_path in order to + # resolve the symbols right during linking + for ($self->apu_config_path, $self->apr_config_path) { + my $flags = '--link-ld --libs'; + $flags .= ' --ldflags' unless (WIN32); + if (my $link = $_ && -x $_ && qx{$_ $flags}) { + chomp $link; + + # Change '/path/to/libanything.la' to '-L/path/to -lanything' + if (CYGWIN) { + $link =~ s|(\S*)/lib([^.\s]+)\.\S+|-L$1 -l$2|g; + } + + if ($self->httpd_is_source_tree) { + my @libs; + while ($link =~ m/-L(\S+)/g) { + my $dir = File::Spec->catfile($1, '.libs'); + push @libs, $dir if -d $dir; + } + push @apru_link_flags, join ' ', map { "-L$_" } @libs; + } + push @apru_link_flags, $link; + } + } + + return @apru_link_flags; +} + +sub apr_config_path { + shift->apru_config_path("apr"); +} + +sub apu_config_path { + shift->apru_config_path("apu"); +} + +sub apru_config_path { + my ($self, $what) = @_; + + my $key = "${what}_config_path"; # apr_config_path + my $mp_key = "MP_" . uc($what) . "_CONFIG"; # MP_APR_CONFIG + my $bindir = uc($what) . "_BINDIR"; # APR_BINDIR + + return $self->{$key} if $self->{$key} and -x $self->{$key}; + + if (exists $self->{$mp_key} and -x $self->{$mp_key}) { + $self->{$key} = $self->{$mp_key}; + } + + my $config = $self->apr_generation ? "$what-1-config" : "$what-config"; + + if (!$self->{$key}) { + my @tries = (); + if ($self->httpd_is_source_tree) { + for my $base (grep defined $_, $self->dir) { + push @tries, grep -d $_, + map catdir($base, "srclib", $_), qw(apr apr-util); + } + + # Check for MP_AP_CONFIGURE="--with-apr[-util]=DIR|FILE" + my $what_long = ($what eq 'apu') ? 'apr-util' : 'apr'; + if ($self->{MP_AP_CONFIGURE} && + $self->{MP_AP_CONFIGURE} =~ /--with-${what_long}=(\S+)/) { + my $dir = $1; + $dir = dirname $dir if -f $dir; + push @tries, grep -d $_, $dir, catdir $dir, 'bin'; + } + } + else { + push @tries, grep length, + map $self->apxs(-q => $_), $bindir, "BINDIR"; + push @tries, catdir $self->{MP_AP_PREFIX}, "bin" + if exists $self->{MP_AP_PREFIX} and -d $self->{MP_AP_PREFIX}; + } + + @tries = map { catfile $_, $config } @tries; + if (WIN32) { + my $ext = '.bat'; + for (@tries) { + $_ .= $ext if ($_ and $_ !~ /$ext$/); + } + } + + for my $try (@tries) { + next unless -x $try; + $self->{$key} = $try; + } + } + + $self->{$key} ||= Apache::TestConfig::which($config); + + # apr_bindir makes sense only if httpd/apr is installed, if we are + # building against the source tree we can't link against + # apr/aprutil libs + unless ($self->httpd_is_source_tree) { + $self->{apr_bindir} = $self->{$key} + ? dirname $self->{$key} + : ''; + } + + $self->{$key}; +} + +sub apr_includedir { + my ($self) = @_; + + return $self->{apr_includedir} + if $self->{apr_includedir} and -d $self->{apr_includedir}; + + my $incdir; + my $apr_config_path = $self->apr_config_path; + + if ($apr_config_path) { + my $httpd_version = $self->httpd_version; + chomp($incdir = `$apr_config_path --includedir`); + } + + unless ($incdir and -d $incdir) { + # falling back to the default when apr header files are in the + # same location as the httpd header files + $incdir = $self->ap_includedir; + } + + my @tries = ($incdir); + if ($self->httpd_is_source_tree) { + my $path = catdir $self->dir, "srclib", "apr", "include"; + push @tries, $path if -d $path; + } + + + for (@tries) { + next unless $_ && -e catfile $_, "apr.h"; + $self->{apr_includedir} = $_; + last; + } + + unless ($self->{apr_includedir}) { + error "Can't find apr include/ directory,", + "use MP_APR_CONFIG=/path/to/apr-config"; + exit 1; + } + + $self->{apr_includedir}; +} + +#--- parsing apache *.h files --- + +sub mmn_eq { + my ($class, $dir) = @_; + + return 1 if WIN32; #just assume, till Apache2::Build works under win32 + + my $instsrc; + { + local @INC = grep { !/blib/ } @INC; + my $instdir; + for (@INC) { + last if -d ($instdir = "$_/auto/Apache2/include"); + } + $instsrc = $class->new(dir => $instdir); + } + my $targsrc = $class->new($dir ? (dir => $dir) : ()); + + my $inst_mmn = $instsrc->module_magic_number; + my $targ_mmn = $targsrc->module_magic_number; + + unless ($inst_mmn && $targ_mmn) { + return 0; + } + if ($inst_mmn == $targ_mmn) { + return 1; + } + print "Installed MMN $inst_mmn does not match target $targ_mmn\n"; + + return 0; +} + +sub module_magic_number { + my $self = shift; + + return $self->{mmn} if $self->{mmn}; + + my $d = $self->ap_includedir; + + return 0 unless $d; + + #return $mcache{$d} if $mcache{$d}; + my $fh; + for (qw(ap_mmn.h http_config.h)) { + last if open $fh, "$d/$_"; + } + return 0 unless $fh; + + my $n; + my $mmn_pat = join '|', qw(MODULE_MAGIC_NUMBER_MAJOR MODULE_MAGIC_NUMBER); + while(<$fh>) { + if(s/^\#define\s+($mmn_pat)\s+(\d+).*/$2/) { + chomp($n = $_); + last; + } + } + close $fh; + + $self->{mmn} = $n +} + +sub fold_dots { + my $v = shift; + $v =~ s/\.//g; + $v .= '0' if length $v < 3; + $v; +} + +sub httpd_version_as_int { + my ($self, $dir) = @_; + my $v = $self->httpd_version($dir); + fold_dots($v); +} + +sub httpd_version_cache { + my ($self, $dir, $v) = @_; + return '' unless $dir; + $self->{httpd_version}->{$dir} = $v if $v; + $self->{httpd_version}->{$dir}; +} + +sub httpd_version { + my ($self, $dir) = @_; + + return unless $dir = $self->ap_includedir($dir); + + if (my $v = $self->httpd_version_cache($dir)) { + return $v; + } + + my $header = "$dir/ap_release.h"; + open my $fh, $header or do { + error "Unable to open $header: $!"; + return undef; + }; + + my $version; + + while (<$fh>) { + #now taking bets on how many friggin times this will change + #over the course of apache 2.0. 1.3 changed it at least a half + #dozen times. hopefully it'll stay in the same file at least. + if (/^\#define\s+AP_SERVER_MAJORVERSION\s+\"(\d+)\"/) { + #XXX could be more careful here. whatever. see above. + my $major = $1; + my $minor = (split /\s+/, scalar(<$fh>))[-1]; + my $patch = (split /\s+/, scalar(<$fh>))[-1]; + $version = join '.', $major, $minor, $patch; + $version =~ s/\"//g; + last; + } + elsif (/^\#define\s+AP_SERVER_BASEREVISION\s+\"(.*)\"/) { + $version = $1; + last; + } + elsif(/^\#define\s+AP_SERVER_MAJORVERSION_NUMBER\s+(\d+)/) { + # new 2.1 config + my $major = $1; + my $minor = (split /\s+/, scalar(<$fh>))[-1]; + my $patch = (split /\s+/, scalar(<$fh>))[-1]; + + my ($define, $macro, $dev) = (split /\s+/, scalar(<$fh>)); + + if ($macro =~ /AP_SERVER_DEVBUILD_BOOLEAN/ && $dev eq '1') { + $dev = "-dev"; + } + else { + $dev = ""; + } + + $version = join '.', $major, $minor, "$patch$dev"; + $version =~ s/\"//g; + last; + } + } + + close $fh; + + debug "parsed version $version from ap_release.h"; + + $self->httpd_version_cache($dir, $version); +} + +my %wanted_apr_config = map { $_, 1} qw( + HAS_THREADS HAS_DSO HAS_MMAP HAS_RANDOM HAS_SENDFILE + HAS_LARGE_FILES HAS_INLINE HAS_FORK +); + +sub get_apr_config { + my $self = shift; + + return $self->{apr_config} if $self->{apr_config}; + + my $fh; + my $header = catfile $self->apr_includedir, "apr.h"; + if (WIN32) { + open $fh, $header or do { + error "Unable to open $header: $!"; + return undef; + }; + } + else { + my @command = ($self->perl_config('cpp'), '-E', '-dM', $header); + open $fh, '-|', @command or do { + error "Unable to preprocess $header with @command: $!"; + return undef; + }; + } + + my %cfg; + while (<$fh>) { + next unless s/^\#define\s+APR_((HAVE|HAS|USE)_\w+)/$1/; + chomp; + my ($name, $val) = split /\s+/, $_, 2; + next unless $wanted_apr_config{$name}; + $val =~ s/\s+$//; + next unless $val =~ /^\d+$/; + $cfg{$name} = $val; + } + + $self->{apr_config} = \%cfg; +} + +#--- generate Makefile --- + +sub canon_make_attr { + my ($self, $name) = (shift, shift); + + my $attr = join '_', 'MODPERL', uc $name; + $self->{$attr} = "@_"; + "$attr = $self->{$attr}\n\n"; +} + +sub xsubpp { + my $self = shift; + my $xsubpp = join ' ', '$(MODPERL_PERLPATH)', + '$(MODPERL_PRIVLIBEXP)/ExtUtils/xsubpp', + '-typemap', '$(MODPERL_PRIVLIBEXP)/ExtUtils/typemap'; + + my $typemap = $self->file_path('lib/typemap'); + if (-e $typemap) { + $xsubpp .= join ' ', + ' -typemap', $typemap; + } + + $xsubpp; +} + +sub make_xs { + my ($self, $fh) = @_; + + print $fh $self->canon_make_attr(xsubpp => $self->xsubpp); + + return [] unless $self->{XS}; + + my @files; + my @xs_targ; + + foreach my $name (sort keys %{ $self->{XS} }) { + my $xs = $self->{XS}->{$name}; + #Foo/Bar.xs => Foo_Bar.c + (my $c = $xs) =~ s:.*?WrapXS/::; + $c =~ s:/:_:g; + $c =~ s:\.xs$:.c:; + + push @files, $c; + + push @xs_targ, <<EOF; +$c: $xs +\t\$(MODPERL_XSUBPP) $xs > \$*.xsc && \$(MODPERL_MV) \$*.xsc \$@ + +EOF + } + + my %o = (xs_o_files => 'o', xs_o_pic_files => 'lo'); + + for my $ext (qw(xs_o_files xs_o_pic_files)) { + print $fh $self->canon_make_attr($ext, map { + (my $file = $_) =~ s/c$/$o{$ext}/; $file; + } @files); + } + + print $fh $self->canon_make_attr(xs_clean_files => @files); + + \@xs_targ; +} + +#when we use a bit of MakeMaker, make it use our values for these vars +my %perl_config_pm_alias = ( + ABSPERL => 'perlpath', + ABSPERLRUN => 'perlpath', + PERL => 'perlpath', + PERLRUN => 'perlpath', + PERL_LIB => 'privlibexp', + PERL_ARCHLIB => 'archlibexp', +); + +my $mm_replace = join '|', keys %perl_config_pm_alias; + +# get rid of dups +my %perl_config_pm_alias_values = reverse %perl_config_pm_alias; +my @perl_config_pm_alias_values = keys %perl_config_pm_alias_values; + +my @perl_config_pm = sort(@perl_config_pm_alias_values, qw(cc cpprun + rm ranlib lib_ext obj_ext cccdlflags lddlflags optimize)); + +sub mm_replace { + my $val = shift; + $$val =~ s/\(($mm_replace)\)/(MODPERL_\U$perl_config_pm_alias{$1})/g; +} + +#help prevent warnings +my @mm_init_vars = (BASEEXT => '', NAME => ''); + +sub make_tools { + my ($self, $fh) = @_; + + for (@perl_config_pm) { + print $fh $self->canon_make_attr($_, $self->perl_config($_)); + } + + require ExtUtils::MakeMaker; + my $mm = bless { @mm_init_vars }, 'MM'; + + # Fake initialize MakeMaker + foreach my $m (qw(init_main init_others init_tools)) { + $mm->$m() if $mm->can($m); + + # init_main() undefines the BASEEXT member which we initialized + # to a blank string to prevent warnings; reset it now + $mm->{BASEEXT} = '' if not defined $mm->{BASEEXT}; + } + + for (qw(rm_f mv ld ar cp test_f)) { + my $val = $mm->{"\U$_"}; + if ($val) { + mm_replace(\$val); + } + else { + $val = $Config{$_}; + } + print $fh $self->canon_make_attr($_ => $val); + } +} + +sub export_files_MSWin32 { + my $self = shift; + my $xs_dir = $self->file_path("xs"); + "-def:$xs_dir/modperl.def"; +} + +sub export_files_aix { + my $self = shift; + + my $Wl = $self->ldopts_prefix; + # there are several modperl_*.exp, not just $(BASEEXT).exp + # $(BASEEXT).exp resolves to modperl_global.exp + my $xs_dir = $self->file_path("xs"); + join " ", map "${Wl}-bE:$xs_dir/modperl_$_.exp", qw(inline ithreads); +} + +sub dynamic_link_header_default { + return <<'EOF'; +$(MODPERL_LIBNAME).$(MODPERL_DLEXT): $(MODPERL_PIC_OBJS) + $(MODPERL_RM_F) $@ + $(MODPERL_LD) $(MODPERL_LDDLFLAGS) \ + $(MODPERL_AP_LIBS) \ + $(MODPERL_PIC_OBJS) $(MODPERL_LDOPTS) \ +EOF +} + +sub dynamic_link_default { + my $self = shift; + + my $link = $self->dynamic_link_header_default . "\t" . '-o $@'; + + my $ranlib = "\t" . '$(MODPERL_RANLIB) $@' . "\n"; + + $link .= "\n" . $ranlib unless (DARWIN or OPENBSD); + + $link; +} + +sub dynamic_link_MSWin32 { + my $self = shift; + my $defs = $self->export_files_MSWin32; + my $symbols = $self->modperl_symbols_MSWin32; + return $self->dynamic_link_header_default . + "\t$defs" . + ($symbols ? ' \\' . "\n\t-pdb:$symbols" : '') . + ' -out:$@' . "\n\t" . + 'if exist $(MODPERL_MANIFEST_LOCATION)' . " \\\n\t" . + 'mt /nologo /manifest $(MODPERL_MANIFEST_LOCATION)' . " \\\n\t" . + '/outputresource:$@;2' . "\n\n"; +} + +sub dynamic_link_aix { + my $self = shift; + my $link = $self->dynamic_link_header_default . + "\t" . $self->export_files_aix . " \\\n" . + "\t" . '-o $@' . " \n" . + "\t" . '$(MODPERL_RANLIB) $@'; +} + +sub dynamic_link_cygwin { + my $self = shift; + return <<'EOF'; +$(MODPERL_LIBNAME).$(MODPERL_DLEXT): $(MODPERL_PIC_OBJS) + $(MODPERL_RM_F) $@ + $(MODPERL_CC) -shared -o $@ \ + -Wl,--out-implib=$(MODPERL_LIBNAME).dll.a \ + -Wl,--export-all-symbols -Wl,--enable-auto-import \ + -Wl,--enable-auto-image-base -Wl,--stack,8388608 \ + $(MODPERL_PIC_OBJS) \ + $(MODPERL_LDDLFLAGS) $(MODPERL_LDOPTS) \ + $(MODPERL_AP_LIBS) + $(MODPERL_RANLIB) $@ +EOF +} + +sub dynamic_link { + my $self = shift; + my $link = \&{"dynamic_link_$^O"}; + $link = \&dynamic_link_default unless defined &$link; + $link->($self); +} + +# Returns the link flags for the apache shared core library +my $apache_corelib_cygwin; +sub apache_corelib_cygwin { + return $apache_corelib_cygwin if $apache_corelib_cygwin; + + my $self = shift; + my $mp_src = "$self->{cwd}/src/modules/perl"; + my $core = 'httpd2core'; + + # There's a problem with user-installed perl on cygwin. + # MakeMaker doesn't know about the .dll.a libs and warns + # about missing -lhttpd2core. "Fix" it by copying + # the lib and adding .a suffix. + # For the static build create a soft link, because libhttpd2core.dll.a + # doesn't exist at this time. + if ($self->is_dynamic) { + my $libpath = $self->apxs(-q => 'exp_libdir'); + File::Copy::copy("$libpath/lib$core.dll.a", "$mp_src/lib$core.a"); + } else { + my $libpath = catdir($self->{MP_AP_PREFIX}, '.libs'); + mkdir $libpath unless -d $libpath; + qx{touch $libpath/lib$core.dll.a && \ + ln -fs $libpath/lib$core.dll.a $mp_src/lib$core.a}; + } + + $apache_corelib_cygwin = "-L$mp_src -l$core"; +} + +sub apache_libs_MSWin32 { + my $self = shift; + my $prefix = $self->apxs(-q => 'PREFIX') || $self->dir; + my $lib = catdir $prefix, 'lib'; + opendir(my $dir, $lib) or die qq{Cannot opendir $lib: $!}; + my @libs = map {catfile($lib, $_)} + grep /^lib(apr|aprutil|httpd)\b\S*?\.lib$/, readdir $dir; + closedir $dir; + "@libs"; +} + +sub apache_libs_cygwin { + my $self = shift; + join ' ', $self->apache_corelib_cygwin, $self->apru_link_flags; +} + +sub apache_libs { + my $self = shift; + my $libs = \&{"apache_libs_$^O"}; + return "" unless defined &$libs; + $libs->($self); +} + +sub modperl_libs_MSWin32 { + my $self = shift; + "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.lib"; +} + +sub modperl_libs_cygwin { + my $self = shift; + return '' unless $self->is_dynamic; + return "-L$self->{cwd}/src/modules/perl -l$self->{MP_LIBNAME}"; +} + +sub modperl_libs { + my $self = shift; + my $libs = \&{"modperl_libs_$^O"}; + return "" unless defined &$libs; + $libs->($self); +} + +sub modperl_libpath_MSWin32 { + my $self = shift; + # mod_perl.lib will be installed into MP_AP_PREFIX/lib + # for use by 3rd party xs modules + "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.lib"; +} + +sub modperl_libpath_cygwin { + my $self = shift; + "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.dll.a"; +} + +sub modperl_libpath { + my $self = shift; + my $libpath = \&{"modperl_libpath_$^O"}; + return "" unless defined &$libpath; + $libpath->($self); +} + +# returns the directory and name of the aprext lib built under blib/ +sub mp_apr_blib { + my $self = shift; + return unless (my $mp_apr_lib = $self->{MP_APR_LIB}); + my $lib_mp_apr_lib = 'lib' . $mp_apr_lib; + my @dirs = qw(blib arch auto); + my $apr_blib = catdir $self->{cwd}, @dirs, $lib_mp_apr_lib; + my $full_libname = $lib_mp_apr_lib . $Config{lib_ext}; + return ($apr_blib, $full_libname); +} + +sub mp_apr_lib_MSWin32 { + my $self = shift; + # The MP_APR_LIB will be installed into MP_AP_PREFIX/lib + # for use by 3rd party xs modules + my ($dir, $lib) = $self->mp_apr_blib(); + $lib =~ s[^lib(\w+)$Config{lib_ext}$][$1]; + $dir = Win32::GetShortPathName($dir); + return qq{ -L$dir -l$lib }; +} + +sub mp_apr_lib_cygwin { + my $self = shift; + my ($dir, $lib) = $self->mp_apr_blib(); + $lib =~ s[^lib(\w+)$Config{lib_ext}$][$1]; + my $libs = "-L$dir -l$lib"; + + # This is ugly, but is the only way to prevent the "undefined + # symbols" error + $libs .= join ' ', '', + '-L' . catdir($self->perl_config('archlibexp'), 'CORE'), '-lperl'; + + $libs; +} + +# linking used for the aprext lib used to build APR/APR::* +sub mp_apr_lib { + my $self = shift; + my $libs = \&{"mp_apr_lib_$^O"}; + return "" unless defined &$libs; + $libs->($self); +} + +sub modperl_symbols_MSWin32 { + my $self = shift; + return "" unless $self->{MP_DEBUG}; + "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.pdb"; +} + +sub modperl_symbols { + my $self = shift; + my $symbols = \&{"modperl_symbols_$^O"}; + return "" unless defined &$symbols; + $symbols->($self); +} + +sub write_src_makefile { + my $self = shift; + my $code = ModPerl::Code->new; + my $path = $code->path; + + my $install = <<'EOI'; +install: +EOI + if (!$self->should_build_apache) { + $install .= <<'EOI'; +# install mod_perl.so + @$(MKPATH) $(DESTDIR)$(MODPERL_AP_LIBEXECDIR) + $(MODPERL_TEST_F) $(MODPERL_LIB_DSO) && \ + $(MODPERL_CP) $(MODPERL_LIB_DSO) $(DESTDIR)$(MODPERL_AP_LIBEXECDIR) +EOI + } + + $install .= <<'EOI'; +# install mod_perl .h files + @$(MKPATH) $(DESTDIR)$(MODPERL_AP_INCLUDEDIR) + $(MODPERL_CP) $(MODPERL_H_FILES) $(DESTDIR)$(MODPERL_AP_INCLUDEDIR) +EOI + + my $mf = $self->default_file('makefile'); + + open my $fh, '>', $mf or die "open $mf: $!"; + + print $fh noedit_warning_hash(); + + print $fh $self->canon_make_attr('makefile', basename $mf); + + $self->make_tools($fh); + + print $fh $self->canon_make_attr('ap_libs', $self->apache_libs); + + print $fh $self->canon_make_attr('libname', $self->{MP_LIBNAME}); + print $fh $self->canon_make_attr('dlext', 'so'); #always use .so + + if (AIX) { + my $xs_dir = $self->file_path("xs"); + print $fh "BASEEXT = $xs_dir/modperl_global\n\n"; + } + + my %libs = ( + dso => "$self->{MP_LIBNAME}.$self->{MODPERL_DLEXT}", + static => "$self->{MP_LIBNAME}$self->{MODPERL_LIB_EXT}", + ); + + #XXX short-term compat for Apache::TestConfigPerl + $libs{shared} = $libs{dso}; + + foreach my $type (sort keys %libs) { + my $lib = $libs{$type}; + print $fh $self->canon_make_attr("lib_$type", $libs{$type}); + } + + if (my $symbols = $self->modperl_symbols) { + print $fh $self->canon_make_attr('lib_symbols', $symbols); + $install .= <<'EOI'; +# install mod_perl symbol file + @$(MKPATH) $(MODPERL_AP_LIBEXECDIR) + $(MODPERL_TEST_F) $(MODPERL_LIB_SYMBOLS) && \ + $(MODPERL_CP) $(MODPERL_LIB_SYMBOLS) $(MODPERL_AP_LIBEXECDIR) +EOI + } + + if ($self->is_dynamic && (my $libs = $self->modperl_libpath)) { + print $fh $self->canon_make_attr('lib_location', $libs); + + # Visual Studio 8 on Win32 uses manifest files + if (WIN32) { + (my $manifest = $libs) =~ s/\.lib$/.so.manifest/; + print $fh $self->canon_make_attr('manifest_location', $manifest); + } + + print $fh $self->canon_make_attr('ap_libdir', + $self->ap_destdir(catdir $self->{MP_AP_PREFIX}, 'lib') + ); + + $install .= <<'EOI'; +# install mod_perl.lib + @$(MKPATH) $(MODPERL_AP_LIBDIR) + $(MODPERL_TEST_F) $(MODPERL_LIB_LOCATION) && \ + $(MODPERL_CP) $(MODPERL_LIB_LOCATION) $(MODPERL_AP_LIBDIR) +EOI + } + + my $libperl = join '/', + $self->perl_config('archlibexp'), 'CORE', $self->perl_config('libperl'); + + #this is only used for deps, if libperl has changed, relink mod_perl.so + #not all perl dists put libperl where it should be, so just leave this + #out if it isn't in the proper place + if (-e $libperl) { + print $fh $self->canon_make_attr('libperl', $libperl); + } + + for my $method (qw(ccopts ldopts inc)) { + print $fh $self->canon_make_attr($method, $self->$method()); + } + + for my $method (qw(c_files o_files o_pic_files h_files)) { + print $fh $self->canon_make_attr($method, @{ $code->$method() }); + } + + my @libs; + for my $type (sort map { uc } keys %libs) { + next unless $self->{"MP_USE_$type"}; + # on win32 mod_perl.lib must come after mod_perl.so + $type eq 'STATIC' + ? push @libs, $self->{"MODPERL_LIB_$type"} + : unshift @libs, $self->{"MODPERL_LIB_$type"}; + } + + print $fh $self->canon_make_attr('lib', "@libs"); + + print $fh $self->canon_make_attr('AP_INCLUDEDIR', + $self->ap_destdir($self->install_headers_dir)); + + print $fh $self->canon_make_attr('AP_LIBEXECDIR', + $self->ap_destdir($self->apxs(-q => 'LIBEXECDIR'))); + + my $xs_targ = $self->make_xs($fh); + + print $fh <<'EOF'; +MODPERL_CCFLAGS = $(MODPERL_INC) $(MODPERL_CCOPTS) $(MODPERL_OPTIMIZE) + +MODPERL_CCFLAGS_SHLIB = $(MODPERL_CCFLAGS) $(MODPERL_CCCDLFLAGS) + +MODPERL_OBJS = $(MODPERL_O_FILES) $(MODPERL_XS_O_FILES) + +MODPERL_PIC_OBJS = $(MODPERL_O_PIC_FILES) $(MODPERL_XS_O_PIC_FILES) + +MKPATH = $(MODPERL_PERLPATH) "-MExtUtils::Command" -e mkpath + +all: lib + +lib: $(MODPERL_LIB) + +EOF + + print $fh $install; + + print $fh <<'EOF' if DMAKE; + +.USESHELL : +EOF + + print $fh <<'EOF'; + +.SUFFIXES: .xs .c $(MODPERL_OBJ_EXT) .lo .i .s + +.c.lo: + $(MODPERL_CC) $(MODPERL_CCFLAGS_SHLIB) \ + -c $< && $(MODPERL_MV) $*$(MODPERL_OBJ_EXT) $*.lo + +.c$(MODPERL_OBJ_EXT): + $(MODPERL_CC) $(MODPERL_CCFLAGS) -c $< + +.c.i: + $(MODPERL_CPPRUN) $(MODPERL_CCFLAGS) -c $< > $*.i + +.c.s: + $(MODPERL_CC) -O -S $(MODPERL_CCFLAGS) -c $< + +.xs.c: + $(MODPERL_XSUBPP) $*.xs >$@ + +.xs$(MODPERL_OBJ_EXT): + $(MODPERL_XSUBPP) $*.xs >$*.c + $(MODPERL_CC) $(MODPERL_CCFLAGS) -c $*.c + +.xs.lo: + $(MODPERL_XSUBPP) $*.xs >$*.c + $(MODPERL_CC) $(MODPERL_CCFLAGS_SHLIB) \ + -c $*.c && $(MODPERL_MV) $*$(MODPERL_OBJ_EXT) $*.lo + +clean: + $(MODPERL_RM_F) *.a *.so *.xsc \ + $(MODPERL_LIBNAME).exp $(MODPERL_LIBNAME).lib \ + *$(MODPERL_OBJ_EXT) *.lo *.i *.s *.pdb *.manifest \ + $(MODPERL_CLEAN_FILES) \ + $(MODPERL_XS_CLEAN_FILES) + +$(MODPERL_OBJS): $(MODPERL_H_FILES) $(MODPERL_MAKEFILE) +$(MODPERL_PIC_OBJS): $(MODPERL_H_FILES) $(MODPERL_MAKEFILE) +$(MODPERL_LIB): $(MODPERL_LIBPERL) + +$(MODPERL_LIBNAME)$(MODPERL_LIB_EXT): $(MODPERL_OBJS) + $(MODPERL_RM_F) $@ + $(MODPERL_AR) crv $@ $(MODPERL_OBJS) + $(MODPERL_RANLIB) $@ + +EOF + + print $fh $self->dynamic_link; + + print $fh @$xs_targ; + + print $fh "\n"; # Makefile must end with \n to avoid warnings + + close $fh; +} + +#--- generate MakeMaker parameter values --- + +sub otherldflags_default { + my $self = shift; + # e.g. aix's V:ldflags feeds -brtl and other flags + $self->perl_config('ldflags'); +} + +sub otherldflags { + my $self = shift; + my $flags = \&{"otherldflags_$^O"}; + return $self->otherldflags_default unless defined &$flags; + $flags->($self); +} + +sub otherldflags_MSWin32 { + my $self = shift; + my $flags = $self->otherldflags_default; + $flags .= ' -pdb:$(INST_ARCHAUTODIR)\$(BASEEXT).pdb' if $self->{MP_DEBUG}; + $flags; +} + +sub typemaps { + my $self = shift; + my @typemaps = (); + + # XXX: could move here the code from ModPerl::BuildMM + return [] if IS_MOD_PERL_BUILD; + + # for post install use + for (@INC) { + # make sure not to pick mod_perl 1.0 typemap + my $file = "$_/auto/Apache2/typemap"; + push @typemaps, $file if -e $file; + } + + return \@typemaps; +} + +sub includes { + my $self = shift; + + my @inc = (); + + unless (IS_MOD_PERL_BUILD) { + # XXX: what if apxs is not available? win32? + my $ap_inc = $self->apxs('-q' => 'INCLUDEDIR'); + if ($ap_inc && -d $ap_inc) { + push @inc, $ap_inc; + return \@inc; + } + + # this is fatal + my $reason = $ap_inc + ? "path $ap_inc doesn't exist" + : "apxs -q INCLUDEDIR didn't return a value"; + die "Can't find the mod_perl include dir (reason: $reason)"; + } + + my $os = WIN32 ? 'win32' : 'unix'; + push @inc, $self->file_path("src/modules/perl", "xs"); + + push @inc, $self->mp_include_dir; + + unless ($self->httpd_is_source_tree) { + push @inc, $self->apr_includedir; + + my $apuc = $self->apu_config_path; + if ($apuc && -x $apuc) { + chomp(my $apuincs = qx($apuc --includes)); + # win32: /Ipath, elsewhere -Ipath + $apuincs =~ s{^\s*(-|/)I}{}; + push @inc, $apuincs; + } + + my $ainc = $self->apxs('-q' => 'INCLUDEDIR'); + if (-d $ainc) { + push @inc, $ainc; + return \@inc; + } + } + + if ($self->{MP_AP_PREFIX}) { + my $src = $self->dir; + for ("$src/modules/perl", "$src/include", + "$src/srclib/apr/include", + "$src/srclib/apr-util/include", + "$src/os/$os") + { + push @inc, $_ if -d $_; + } + } + + return \@inc; +} + +sub inc { + local $_; + my @includes = map { "-I$_" } @{ shift->includes }; + "@includes"; +} + +### Picking the right LFS support flags for mod_perl, by Joe Orton ### +# +# on Unix systems where by default off_t is a "long", a 32-bit integer, +# there are two different ways to get "large file" support, i.e. the +# ability to manipulate files bigger than 2Gb: +# +# 1) you compile using -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64. This +# makes sys/types.h expose off_t as a "long long", a 64-bit integer, and +# changes the size of a few other types too. The C library headers +# automatically arrange to expose a correct implementation of functions +# like lseek() which take off_t parameters. +# +# 2) you compile using -D_LARGEFILE64_SOURCE, and use what is called the +# "transitional" interface. This means that the system headers expose a +# new type, "off64_t", which is a long long, but the size of off_t is not +# changed. A bunch of new functions like lseek64() are exposed by the C +# library headers, which take off64_t parameters in place of off_t. +# +# Perl built with -Duselargefiles uses approach (1). +# +# APR HEAD uses (2) by default. APR 0.9 does not by default use either +# approach, but random users can take a httpd-2.0.49 tarball, and do: +# +# export CPPFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" +# ./configure +# +# to build a copy of apr/httpd which uses approach (1), though this +# isn't really a supported configuration. +# +# The problem that mod_perl has to work around is when you take a +# package built with approach (1), i.e. Perl, and any package which was +# *not* built with (1), i.e. APR, and want to interface between +# them. [1] +# +# So what you want to know is whether APR was built using approach (1) +# or not. APR_HAS_LARGE_FILES in HEAD just tells you whether APR was +# built using approach (2) or not, which isn't useful in solving this +# problem. +# +# [1]: In some cases, it may be OK to interface between packages which +# use (1) and packages which use (2). APR HEAD is currently not such a +# case, since the size of apr_ino_t is still changing when +# _FILE_OFFSET_BITS is defined. +# +# If you want to see how this matters, get some httpd function to do at +# the very beginning of main(): +# +# printf("sizeof(request_rec) = %lu, sizeof(apr_finfo_t) = %ul", +# sizeof(request_rec), sizeof(apr_finfo_t)); +# +# and then put the same printf in mod_perl somewhere, and see the +# differences. This is why it is a really terribly silly idea to ever +# use approach (1) in anything other than an entirely self-contained +# application. +# +# there is no conflict if both libraries either have or don't have +# large files support enabled +sub has_large_files_conflict { + my $self = shift; + + my $apxs_flags = join $self->apxs_extra_cflags, $self->apxs_extra_cppflags; + my $apr_lfs64 = $apxs_flags =~ /-D_FILE_OFFSET_BITS=64/; + my $perl_lfs64 = $Config{ccflags} =~ /-D_FILE_OFFSET_BITS=64/; + + # XXX: we don't really deal with the case where APR was built with + # -D_FILE_OFFSET_BITS=64 but perl wasn't, since currently we strip + # only perl's ccflags, not apr's flags. the reason we don't deal + # with it is that we didn't have such a case yet, but may need to + # deal with it later + + return 0; + # $perl_lfs64 ^ $apr_lfs64; +} + +# if perl is built with uselargefiles, but apr not, the build won't +# work together as it uses two binary incompatible libraries, so +# reduce the functionality to the greatest common denominator (C code +# will have to make sure to prevent any operations that may rely on +# effects created by uselargefiles, e.g. Off_t=8 instead of Off_t=4) +sub strip_lfs { + my ($self, $cflags) = @_; + return $cflags unless $self->has_large_files_conflict(); + + my $lf = $Config{ccflags_uselargefiles} + || '-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'; + $cflags =~ s/$lf//; + $cflags; +} + +sub define { + my $self = shift; + + return ""; +} + +1; + +__END__ + +=head1 NAME + +Apache2::Build - Methods for locating and parsing bits of Apache source code + +=head1 SYNOPSIS + + use Apache2::Build (); + my $build = Apache2::Build->new; + + # rebuild mod_perl with build opts from the previous build + % cd modperl-2.0 + % perl -MApache2::Build -e rebuild + +=head1 DESCRIPTION + +This module provides methods for locating and parsing bits of Apache +source code. + +Since mod_perl remembers what build options were used to build it, you +can use this knowledge to rebuild it using the same options. Simply +chdir to the mod_perl source directory and run: + + % cd modperl-2.0 + % perl -MApache2::Build -e rebuild + +If you want to rebuild not yet installed, but already built mod_perl, +run from its root directory: + + % perl -Ilib -MApache2::Build -e rebuild + +=head1 METHODS + +=over 4 + +=item new + +Create an object blessed into the B<Apache2::Build> class. + + my $build = Apache2::Build->new; + +=item dir + +Top level directory where source files are located. + + my $dir = $build->dir; + -d $dir or die "can't stat $dir $!\n"; + +=item find + +Searches for apache source directories, return a list of those found. + +Example: + + for my $dir ($build->find) { + my $yn = prompt "Configure with $dir ?", "y"; + ... + } + +=item inc + +Print include paths for MakeMaker's B<INC> argument to +C<WriteMakefile>. + +Example: + + use ExtUtils::MakeMaker; + + use Apache2::Build (); + + WriteMakefile( + 'NAME' => 'Apache2::Module', + 'VERSION' => '0.01', + 'INC' => Apache2::Build->new->inc, + ); + + +=item module_magic_number + +Return the B<MODULE_MAGIC_NUMBER> defined in the apache source. + +Example: + + my $mmn = $build->module_magic_number; + +=item httpd_version + +Return the server version. + +Example: + + my $v = $build->httpd_version; + +=item otherldflags + +Return other ld flags for MakeMaker's B<dynamic_lib> argument to +C<WriteMakefile>. This might be needed on systems like AIX that need +special flags to the linker to be able to reference mod_perl or httpd +symbols. + +Example: + + use ExtUtils::MakeMaker; + + use Apache2::Build (); + + WriteMakefile( + 'NAME' => 'Apache2::Module', + 'VERSION' => '0.01', + 'INC' => Apache2::Build->new->inc, + 'dynamic_lib' => { + 'OTHERLDFLAGS' => Apache2::Build->new->otherldflags, + }, + ); + +=back + + +=head1 AUTHOR + +Doug MacEachern + +=cut
diff --git a/2_0_13/lib/Apache2/ParseSource.pm b/2_0_13/lib/Apache2/ParseSource.pm new file mode 100644 index 0000000..7dada94 --- /dev/null +++ b/2_0_13/lib/Apache2/ParseSource.pm
@@ -0,0 +1,646 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::ParseSource; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Build (); +use Config; +use File::Basename; +use File::Spec::Functions qw(catdir); + +our $VERSION = '0.02'; + +sub new { + my $class = shift; + + my $self = bless { + config => Apache2::Build->build_config, + @_, + }, $class; + + my $prefixes = join '|', @{ $self->{prefixes} || [qw(ap_ apr_)] }; + $self->{prefix_re} = qr{^($prefixes)}; + + $Apache2::Build::APXS ||= $self->{apxs}; + + $self; +} + +sub config { + shift->{config}; +} + +sub parse { + my $self = shift; + + $self->{scan_filename} = $self->generate_cscan_file; + + $self->{c} = $self->scan; +} + +sub DESTROY { + my $self = shift; + unlink $self->{scan_filename} +} + +{ + package Apache2::ParseSource::Scan; + + our @ISA = qw(ModPerl::CScan); + + sub get { + local $SIG{__DIE__} = \&Carp::confess; + shift->SUPER::get(@_); + } +} + +my @c_scan_defines = ( + 'CORE_PRIVATE', #so we get all of apache + 'MP_SOURCE_SCAN', #so we can avoid some c-scan barfing + '_NETINET_TCP_H', #c-scan chokes on netinet/tcp.h + '_BYTESWAP_H', #c-scan chokes on byteswap.h + '_BITS_BYTESWAP_H', #c-scan chokes on byteswap.h + 'Expat_INCLUDED', #c-scan chokes on expath.h + # 'APR_OPTIONAL_H', #c-scan chokes on apr_optional.h + 'apr_table_do_callback_fn_t=void', #c-scan chokes on function pointers +); + + +# some types c-scan failing to resolve +push @c_scan_defines, map { "$_=void" } + qw(PPADDR_t PerlExitListEntry modperl_tipool_vtbl_t); + +sub scan { + require ModPerl::CScan; + ModPerl::CScan->VERSION(0.75); + require Carp; + + my $self = shift; + + my $c = ModPerl::CScan->new(filename => $self->{scan_filename}); + + my $includes = $self->includes; + + # where to find perl headers, but we don't want to parse them otherwise + my $perl_core_path = catdir $Config{installarchlib}, "CORE"; + push @$includes, $perl_core_path; + + $c->set(includeDirs => $includes); + + my @defines = @c_scan_defines; + + unless ($Config{useithreads} and $Config{useithreads} eq 'define') { + #fake -DITHREADS so function tables are the same for + #vanilla and ithread perls, that is, + #make sure THX and friends are always expanded + push @defines, 'MP_SOURCE_SCAN_NEED_ITHREADS'; + } + + $c->set(Defines => join ' ', map "-D$_", @defines); + + bless $c, 'Apache2::ParseSource::Scan'; +} + +sub include_dirs { + my $self = shift; + my $inc = $self->config->apxs('-q' => 'INCLUDEDIR'); + my @dirs = ($inc, $self->config->mp_include_dir); + my $aprinc = $self->config->apxs('-q' => 'APR_INCLUDEDIR'); + + unless ($aprinc eq $inc) { + # Add APR include directory if different to httpd includedir + push @dirs, $aprinc; + } + + @dirs; +} + +sub includes { shift->config->includes } + +sub find_includes { + my $self = shift; + + return $self->{includes} if $self->{includes}; + + require File::Find; + + my @includes = (); + # don't pick preinstalled mod_perl headers if any, but pick the rest + { + my @dirs = $self->include_dirs; + die "could not find include directory (build the project first)" + unless -d $dirs[0]; + + my $unwanted = join '|', qw(ap_listen internal version + apr_optional mod_include mod_cgi + mod_proxy mod_ssl ssl_ apr_anylock + apr_rmm ap_config mod_log_config + mod_perl modperl_ apreq mod_cache + mod_serf mod_dav); + $unwanted = qr|^$unwanted|; + my $wanted = ''; + + push @includes, find_includes_wanted($wanted, $unwanted, @dirs); + } + + # now add the live mod_perl headers (to make sure that we always + # work against the latest source) + { + my @dirs = map { catdir $self->config->{cwd}, $_ } + catdir(qw(src modules perl)), 'xs'; + + my $unwanted = ''; + my $wanted = join '|', qw(mod_perl modperl_); + $wanted = qr|^$wanted|; + + push @includes, find_includes_wanted($wanted, $unwanted, @dirs); + } + + # now reorg the header files list, so the fragile scan won't choke + my @apr = (); + my @mp = (); + my @rest = (); + for (@includes) { + if (/mod_perl.h$/) { + # mod_perl.h needs to be included before other mod_perl + # headers + unshift @mp, $_; + } + elsif (/modperl_\w+.h$/) { + push @mp, $_; + } + elsif (/apr_\w+\.h$/ ) { + # apr headers need to be included first + push @apr, $_; + } + else { + push @rest, $_; + } + } + @includes = (@apr, @rest, @mp); + + return $self->{includes} = \@includes; +} + +sub find_includes_wanted { + my ($wanted, $unwanted, @dirs) = @_; + my @includes = (); + for my $dir (@dirs) { + File::Find::finddepth({ + wanted => sub { + return unless /\.h$/; + + if ($wanted) { + return unless /$wanted/; + } + else { + return if /$unwanted/; + } + + my $dir = $File::Find::dir; + push @includes, "$dir/$_"; + }, + (Apache2::Build::WIN32 ? '' : follow => 1), + }, $dir); + } + return @includes; +} + +sub generate_cscan_file { + my $self = shift; + + my $includes = $self->find_includes; + + my $filename = '.apache_includes'; + open my $fh, '>', $filename or die "can't open $filename: $!"; + + for my $path (@$includes) { + my $filename = basename $path; + print $fh qq(\#include "$path"\n); + } + + close $fh; + + return $filename; +} + +my %defines_wanted = ( + 'Apache2::Const' => { + common => [qw{OK DECLINED DONE}], + config => [qw{DECLINE_CMD}], + context => [qw(NOT_IN_ GLOBAL_ONLY)], + http => [qw{HTTP_}], + log => [qw(APLOG_)], + methods => [qw{M_ METHODS}], + mpmq => [qw{AP_MPMQ_}], + options => [qw{OPT_}], + override => [qw{OR_ EXEC_ON_READ ACCESS_CONF RSRC_CONF}], + proxy => [qw{PROXYREQ_}], + platform => [qw{CRLF CR LF}], + remotehost => [qw{REMOTE_}], + satisfy => [qw{SATISFY_}], + types => [qw{DIR_MAGIC_TYPE}], + auth => [qw{AUTHN_ AUTHZ AP_AUTH_ AUTH_ AUTHZ_}], + }, + 'APR::Const' => { + common => [qw{APR_SUCCESS}], + error => [qw{APR_E}], + filepath => [qw{APR_FILEPATH_}], + filetype => [qw{APR_FILETYPE_}], + fopen => [qw{APR_FOPEN_}], + fprot => [qw{APR_FPROT_}], + finfo => [qw{APR_FINFO_}], + flock => [qw{APR_FLOCK_}], + hook => [qw{APR_HOOK_}], + limit => [qw{APR_LIMIT}], + poll => [qw{APR_POLL}], + socket => [qw{APR_SO_}], + status => [qw{APR_TIMEUP}], + table => [qw{APR_OVERLAP_TABLES_}], + uri => [qw{APR_URI_}], + }, + ModPerl => { + common => [qw{MODPERL_RC_}], + } +); + +my %defines_wanted_re; +while (my ($class, $groups) = each %defines_wanted) { + while (my ($group, $wanted) = each %$groups) { + my $pat = join '|', @$wanted; + $defines_wanted_re{$class}->{$group} = $pat; #qr{^($pat)}; + } +} + +my %enums_wanted = ( + 'Apache2::Const' => { map { $_, 1 } qw(cmd_how input_mode filter_type conn_keepalive authn_status authz_status) }, + 'APR::Const' => { map { $_, 1 } qw(apr_shutdown_how apr_read_type apr_lockmech) }, +); + +my $defines_unwanted = join '|', qw{ +HTTP_VERSION APR_EOL_STR APLOG_MARK APLOG_NOERRNO APR_SO_TIMEOUT +APR_HOOK_PROBES_ENABLED APR_HOOK_INT_DCL_UD +APLOG_MAX_LOGLEVEL +APR_BEGIN_DECLS APR_END_DECLS +}; + +sub get_constants { + my ($self) = @_; + + my $includes = $self->find_includes; + my (%constants, %seen); + + for my $file (@$includes) { + open my $fh, $file or die "open $file: $!"; + while (<$fh>) { + if (s/^\#define\s+(\w+)\s+.*/$1/) { + chomp; + next if /_H$/; + next if $seen{$_}++; + $self->handle_constant(\%constants); + } + elsif (m/enum[^\{]+\{/) { + $self->handle_enum($fh, \%constants); + } + } + close $fh; + } + + #maintain a few handy shortcuts from 1.xx + #aliases are defined in ModPerl::Code + push @{ $constants{'Apache2::Const'}->{common} }, + qw(NOT_FOUND FORBIDDEN AUTH_REQUIRED SERVER_ERROR REDIRECT); + + return \%constants; +} + +sub handle_constant { + my ($self, $constants) = @_; + my $keys = keys %defines_wanted_re; + + return if /^($defines_unwanted)/o; + + while (my ($class, $groups) = each %defines_wanted_re) { + my $keys = keys %$groups; + + while (my ($group, $re) = each %$groups) { + next unless /^($re)/; + push @{ $constants->{$class}->{$group} }, $_; + return; + } + } +} + +sub handle_enum { + my ($self, $fh, $constants) = @_; + + my ($name, $e) = $self->parse_enum($fh); + return unless $name; + + $name =~ s/^ap_//; + $name =~ s/_(e|t)$//; + + my $class; + for (keys %enums_wanted) { + next unless $enums_wanted{$_}->{$name}; + $class = $_; + } + + return unless $class; + $name =~ s/^apr_//; + + push @{ $constants->{$class}->{$name} }, @$e if $e; +} + +#this should win an award for worlds lamest parser +sub parse_enum { + my ($self, $fh) = @_; + my $code = $_; + my @e; + + unless ($code =~ /;\s*$/) { + local $_; + while (<$fh>) { + $code .= $_; + last if /;\s*$/; + } + } + + my $name; + if ($code =~ s/^\s*enum\s+(\w*)\s*//) { + $name = $1; + } + elsif ($code =~ s/^\s*typedef\s+enum\s+//) { + $code =~ s/\s*(\w+)\s*;\s*$//; + $name = $1; + } + + $code =~ s:/\*.*?\*/::sg; + $code =~ s/\s*=\s*\w+//g; + $code =~ s/^[^\{]*\{//s; + $code =~ s/\}[^;]*;?//s; + $code =~ s/^\s*\n//gm; + + while ($code =~ /\b(\w+)\b,?/g) { + push @e, $1; + } + + return ($name, \@e); +} + +sub wanted_functions { shift->{prefix_re} } +sub wanted_structures { shift->{prefix_re} } + +sub get_functions { + my $self = shift; + + my $key = 'parsed_fdecls'; + return $self->{$key} if $self->{$key}; + + my $c = $self->{c}; + + my $fdecls = $c->get($key); + my $inlines = $c->get('parsed_inlines'); + push @{$fdecls}, @{$inlines}; + + my %seen; + my $wanted = $self->wanted_functions; + + my @functions; + + for my $entry (@$fdecls) { + my ($rtype, $name, $args) = @$entry; + next unless $name =~ $wanted; + next if $seen{$name}++; + my @attr; + + for (qw(static __inline__)) { + if ($rtype =~ s/^($_)\s+//) { + push @attr, $1; + } + } + + #XXX: working around ModPerl::CScan confusion here + #macro defines ap_run_error_log causes + #cpp filename:linenumber to be included as part of the type + for (@$args) { + next unless $_->[0]; + $_->[0] =~ s/^\#.*?\"\s+//; + $_->[0] =~ s/^register //; + } + + my $func = { + name => $name, + return_type => $rtype, + args => [map { + { type => $_->[0], name => $_->[1] } + } @$args], + }; + + $func->{attr} = \@attr if @attr; + + push @functions, $func; + } + + # sort the functions by the 'name' attribute to ensure a + # consistent output on different systems. + $self->{$key} = [sort { $a->{name} cmp $b->{name} } @functions]; +} + +sub get_structs { + my $self = shift; + + my $key = 'typedef_structs'; + return $self->{$key} if $self->{$key}; + + my $c = $self->{c}; + + my $typedef_structs = $c->get($key); + + my %seen; + my $wanted = $self->wanted_structures; + my $other = join '|', qw(_rec module + piped_log uri_t htaccess_result + cmd_parms cmd_func cmd_how); + + my @structures; + my $sx = qr(^struct\s+); + + while (my ($type, $elts) = each %$typedef_structs) { + next unless $type =~ $wanted or $type =~ /($other)$/o; + + $type =~ s/$sx//; + + next if $seen{$type}++; + + my $struct = { + type => $type, + elts => [map { + my $type = $_->[0]; + $type =~ s/$sx//; + $type .= $_->[1] if $_->[1]; + $type =~ s/:\d+$//; #unsigned:1 + { type => $type, name => $_->[2] } + } @$elts], + }; + + push @structures, $struct; + } + + # sort the structs by the 'type' attribute to ensure a consistent + # output on different systems. + $self->{$key} = [sort { $a->{type} cmp $b->{type} } @structures]; +} + +sub write_functions_pm { + my $self = shift; + my $file = shift || 'FunctionTable.pm'; + my $name = shift || 'Apache2::FunctionTable'; + + $self->write_pm($file, $name, $self->get_functions); +} + +sub write_structs_pm { + my $self = shift; + my $file = shift || 'StructureTable.pm'; + my $name = shift || 'Apache2::StructureTable'; + + $self->write_pm($file, $name, $self->get_structs); +} + +sub write_constants_pm { + my $self = shift; + my $file = shift || 'ConstantsTable.pm'; + my $name = shift || 'Apache2::ConstantsTable'; + + $self->write_pm($file, $name, $self->get_constants); +} + +sub write_pm { + my ($self, $file, $name, $data) = @_; + + require Data::Dumper; + local $Data::Dumper::Indent = 1; + + my ($subdir) = (split '::', $name)[0]; + + my $tdir = ''; + my $build = Apache2::Build->new(init => 1); + my $httpd_version = $build->httpd_version; + if ($httpd_version lt '2.4.0') { + $tdir='xs/tables/current'; + } + else { + $tdir='xs/tables/current24'; + } + + if (-d "$tdir/$subdir") { + $file = "$tdir/$subdir/$file"; + } + + # sort the hashes (including nested ones) for a consistent dump + canonsort(\$data); + + my $dump = Data::Dumper->new([$data], + [$name])->Dump; + + my $package = ref($self) || $self; + my $version = $self->VERSION; + my $date = scalar localtime; + + my $new_content = << "EOF"; +package $name; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by $package/$version +# ! $date +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$dump + +1; +EOF + + my $old_content = ''; + if (-e $file) { + open my $pm, '<', $file or die "open $file: $!"; + local $/ = undef; # slurp the file + $old_content = <$pm>; + close $pm; + } + + my $overwrite = 1; + if ($old_content) { + # strip the date line, which will never be the same before + # comparing + my $table_header = qr{^\#\s!.*}; + (my $old = $old_content) =~ s/$table_header//mg; + (my $new = $new_content) =~ s/$table_header//mg; + $overwrite = 0 if $old eq $new; + } + + if ($overwrite) { + open my $pm, '>', $file or die "open $file: $!"; + print $pm $new_content; + close $pm; + } + +} + +# canonsort(\$data); +# sort nested hashes in the data structure. +# the data structure itself gets modified + +sub canonsort { + my $ref = shift; + my $type = ref $$ref; + + return unless $type; + + require Tie::IxHash; + + my $data = $$ref; + + if ($type eq 'ARRAY') { + for (@$data) { + canonsort(\$_); + } + } + elsif ($type eq 'HASH') { + for (keys %$data) { + canonsort(\$data->{$_}); + } + + tie my %ixhash, 'Tie::IxHash'; + + # reverse sort so we get the order of: + # return_type, name, args { type, name } for functions + # type, elts { type, name } for structures + + for (sort { $b cmp $a } keys %$data) { + $ixhash{$_} = $data->{$_}; + } + + $$ref = \%ixhash; + } +} + +1; +__END__
diff --git a/2_0_13/lib/Apache2/PerlSections.pm b/2_0_13/lib/Apache2/PerlSections.pm new file mode 100644 index 0000000..69cd6b8 --- /dev/null +++ b/2_0_13/lib/Apache2/PerlSections.pm
@@ -0,0 +1,233 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::PerlSections; + +use strict; +use warnings FATAL => 'all'; + +our $VERSION = '2.00'; + +use Apache2::CmdParms (); +use Apache2::Directive (); +use APR::Table (); +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Const -compile => qw(OK); + +use constant SPECIAL_NAME => 'PerlConfig'; +use constant SPECIAL_PACKAGE => 'Apache2::ReadConfig'; + +sub new { + my ($package, @args) = @_; + return bless { @args }, ref($package) || $package; +} + +sub parms { return shift->{'parms'} } +sub directives { return shift->{'directives'} ||= [] } +sub package { return shift->{'args'}->{'package'} } + +my @saved; +sub save { return $Apache2::PerlSections::Save } +sub server { return $Apache2::PerlSections::Server } +sub saved { return @saved } + +sub handler : method { + my ($self, $parms, $args) = @_; + + unless (ref $self) { + $self = $self->new('parms' => $parms, 'args' => $args); + } + + if ($self->save) { + push @saved, $self->package; + } + + my $special = $self->SPECIAL_NAME; + + for my $entry ($self->symdump()) { + if ($entry->[0] !~ /$special/) { + $self->dump_any(@$entry); + } + } + + { + no strict 'refs'; + foreach my $package ($self->package) { + my @config = map { split /\n/ } + grep { defined } + (@{"${package}::$special"}, + ${"${package}::$special"}); + $self->dump_special(@config); + } + } + + $self->post_config(); + + Apache2::Const::OK; +} + +my %directives_seen_hack; + +sub symdump { + my ($self) = @_; + + unless ($self->{symbols}) { + no strict; + + $self->{symbols} = []; + + #XXX: Here would be a good place to warn about NOT using + # Apache2::ReadConfig:: directly in <Perl> sections + foreach my $pack ($self->package, $self->SPECIAL_PACKAGE) { + #XXX: Shamelessly borrowed from Devel::Symdump; + while (my ($key, $val) = each(%{ *{"$pack\::"} })) { + #We don't want to pick up stashes... + next if ($key =~ /::$/); + local (*ENTRY) = $val; + if (defined $val && defined *ENTRY{SCALAR} && defined $ENTRY) { + push @{$self->{symbols}}, [$key, $ENTRY]; + } + if (defined $val && defined *ENTRY{ARRAY}) { + unless (exists $directives_seen_hack{"$key$val"}) { + $directives_seen_hack{"$key$val"} = 1; + push @{$self->{symbols}}, [$key, \@ENTRY]; + } + } + if (defined $val && defined *ENTRY{HASH} && $key !~ /::/) { + push @{$self->{symbols}}, [$key, \%ENTRY]; + } + } + } + } + + return @{$self->{symbols}}; +} + +sub dump_special { + my ($self, @data) = @_; + $self->add_config(@data); +} + +sub dump_any { + my ($self, $name, $entry) = @_; + my $type = ref $entry; + + if ($type eq 'ARRAY') { + $self->dump_array($name, $entry); + } + elsif ($type eq 'HASH') { + $self->dump_hash($name, $entry); + } + else { + $self->dump_entry($name, $entry); + } +} + +sub dump_hash { + my ($self, $name, $hash) = @_; + + for my $entry (keys %{ $hash || {} }) { + my $item = $hash->{$entry}; + my $type = ref($item); + + if ($type eq 'HASH') { + $self->dump_section($name, $entry, $item); + } + elsif ($type eq 'ARRAY') { + for my $e (@$item) { + $self->dump_section($name, $entry, $e); + } + } + } +} + +sub dump_section { + my ($self, $name, $loc, $hash) = @_; + + $self->add_config("<$name $loc>\n"); + + for my $entry (keys %{ $hash || {} }) { + $self->dump_entry($entry, $hash->{$entry}); + } + + $self->add_config("</$name>\n"); +} + +sub dump_array { + my ($self, $name, $entries) = @_; + + for my $entry (@$entries) { + $self->dump_entry($name, $entry); + } +} + +sub dump_entry { + my ($self, $name, $entry) = @_; + my $type = ref $entry; + + if ($type eq 'SCALAR') { + $self->add_config("$name $$entry\n"); + } + elsif ($type eq 'ARRAY') { + if (grep {ref} @$entry) { + $self->dump_entry($name, $_) for @$entry; + } + else { + $self->add_config("$name @$entry\n"); + } + } + elsif ($type eq 'HASH') { + $self->dump_hash($name, $entry); + } + elsif ($type) { + #XXX: Could do $type->can('httpd_config') here on objects ??? + die "Unknown type '$type' for directive $name"; + } + elsif (defined $entry) { + $self->add_config("$name $entry\n"); + } +} + +sub add_config { + my ($self, @config) = @_; + foreach my $config (@config) { + return unless defined $config; + chomp($config); + push @{ $self->directives }, $config; + } +} + +sub post_config { + my ($self) = @_; + my $errmsg = $self->parms->add_config($self->directives); + die $errmsg if $errmsg; +} + +sub dump { + my $class = shift; + require Apache2::PerlSections::Dump; + return Apache2::PerlSections::Dump->dump(@_); +} + +sub store { + my $class = shift; + require Apache2::PerlSections::Dump; + return Apache2::PerlSections::Dump->store(@_); +} + +1; +__END__
diff --git a/2_0_13/lib/Apache2/PerlSections/Dump.pm b/2_0_13/lib/Apache2/PerlSections/Dump.pm new file mode 100644 index 0000000..4366410 --- /dev/null +++ b/2_0_13/lib/Apache2/PerlSections/Dump.pm
@@ -0,0 +1,101 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::PerlSections::Dump; + +use strict; +use warnings FATAL => 'all'; + +our $VERSION = '0.01'; + +use Apache2::PerlSections; +our @ISA = qw(Apache2::PerlSections); + +use Data::Dumper; + +# Process all saved packages +sub package { return shift->saved } + +# We don't want to save anything +sub save { return } + +# We don't want to post any config to apache, we are dumping +sub post_config { return } + +sub dump { + my $self = shift; + unless (ref $self) { + $self = $self->new; + } + $self->handler(); + return join "\n", @{$self->directives}, '1;', '__END__', ''; +} + +sub store { + my ($class, $filename) = @_; + require IO::File; + + my $fh = IO::File->new(">$filename") or die "can't open $filename $!\n"; + + $fh->print($class->dump); + + $fh->close; +} + +sub dump_array { + my ($self, $name, $entry) = @_; + $self->add_config(Data::Dumper->Dump([$entry], ["*$name"])); +} + +sub dump_hash { + my ($self, $name, $entry) = @_; + for my $elem (sort keys %{$entry}) { + $self->add_config(Data::Dumper->Dump([$entry->{$elem}], + ["\$$name"."{'$elem'}"])); + } + +} + +sub dump_entry { + my ($self, $name, $entry) = @_; + + return if not defined $entry; + my $type = ref($entry); + + if ($type eq 'SCALAR') { + $self->add_config(Data::Dumper->Dump([$$entry],[$name])); + } + if ($type eq 'ARRAY') { + $self->dump_array($name,$entry); + } + else { + $self->add_config(Data::Dumper->Dump([$entry],[$name])); + } +} + +sub dump_special { + my ($self, @data) = @_; + + my @dump = grep { defined } @data; + return unless @dump; + + $self->add_config(Data::Dumper->Dump([\@dump],['*'.$self->SPECIAL_NAME])); +} + + + +1; +__END__
diff --git a/2_0_13/lib/Apache2/Resource.pm b/2_0_13/lib/Apache2/Resource.pm new file mode 100644 index 0000000..ccf70d9 --- /dev/null +++ b/2_0_13/lib/Apache2/Resource.pm
@@ -0,0 +1,150 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package Apache2::Resource; + +use strict; +use warnings FATAL => 'all'; + +use mod_perl2; + +use Apache2::Module (); + +use BSD::Resource qw(setrlimit getrlimit get_rlimits); + +use Apache2::Const -compile => qw(OK); + +$Apache2::Resource::VERSION = '1.72'; + +our $Debug; + +$Debug ||= 0; + +sub MB ($) { + my $num = shift; + return ($num < (1024 * 1024)) ? $num*1024*1024 : $num; +} + +sub BM ($) { + my $num = shift; + return ($num > (1024 * 1024)) ? '(' . ($num>>20) . 'Mb)' : ''; +} + +sub DEFAULT_RLIMIT_DATA () { 64 } # data (memory) size in MB +sub DEFAULT_RLIMIT_AS () { 64 } # address space (memory) size in MB +sub DEFAULT_RLIMIT_CPU () { 60*6 } # cpu time in seconds +sub DEFAULT_RLIMIT_CORE () { 0 } # core file size (MB) +sub DEFAULT_RLIMIT_RSS () { 16 } # resident set size (MB) +sub DEFAULT_RLIMIT_FSIZE () { 10 } # file size (MB) +sub DEFAULT_RLIMIT_STACK () { 20 } # stack size (MB) + +my %is_mb = map {$_, 1} qw{DATA RSS STACK FSIZE CORE MEMLOCK AS}; + +sub debug { print STDERR @_ if $Debug } + +sub install_rlimit ($$$) { + my ($res, $soft, $hard) = @_; + + my $name = $res; + + my $cv = \&{"BSD::Resource::RLIMIT_${res}"}; + eval { $res = $cv->() }; + return if $@; + + unless ($soft) { + my $defval = \&{"DEFAULT_RLIMIT_${name}"}; + if (defined &$defval) { + $soft = $defval->(); + } else { + warn "can't find default for `$defval'\n"; + } + } + + $hard ||= $soft; + + debug "Apache2::Resource: PID $$ attempting to set `$name'=$soft:$hard ..."; + + ($soft, $hard) = (MB $soft, MB $hard) if $is_mb{$name}; + + return setrlimit $res, $soft, $hard; +} + +sub handler { + while (my ($k, $v) = each %ENV) { + next unless $k =~ /^PERL_RLIMIT_(\w+)$/; + $k = $1; + next if $k eq "DEFAULTS"; + my ($soft, $hard) = split ":", $v, 2; + $hard ||= $soft; + + my $set = install_rlimit $k, $soft, $hard; + debug "not " unless $set; + debug "ok\n"; + debug $@ if $@; + } + + Apache2::Const::OK; +} + +sub default_handler { + while (my ($k, $v) = each %Apache2::Resource::) { + next unless $k =~ s/^DEFAULT_/PERL_/; + $ENV{$k} = ""; + } + handler(); +} + +sub status_rlimit { + my $lim = get_rlimits(); + my @retval = ("<table border=1><tr>", + (map "<th>$_</th>", qw(Resource Soft Hard)), + "</tr>"); + + for my $res (keys %$lim) { + my ($soft, $hard) = getrlimit($lim->{$res}); + (my $limit = $res) =~ s/^RLIMIT_//; + ($soft, $hard) = ("$soft " . BM($soft), "$hard ". BM($hard)) + if $is_mb{$limit}; + push @retval, + "<tr>", (map { "<td>$_</td>" } $res, $soft, $hard), "</tr>\n"; + } + + push @retval, "</table><P>"; + push @retval, "<small>Apache2::Resource $Apache2::Resource::VERSION</small>"; + + return \@retval; +} + +if ($ENV{MOD_PERL}) { + if ($ENV{PERL_RLIMIT_DEFAULTS}) { + require Apache2::ServerUtil; + Apache2::ServerUtil->server->push_handlers( + PerlChildInitHandler => \&default_handler); + } + + Apache2::Status->menu_item(rlimit => "Resource Limits", + \&status_rlimit) + if Apache2::Module::loaded("Apache2::Status"); +} + +# perl Apache2/Resource.pm +++$Debug, default_handler unless caller(); + +1; + +__END__ +
diff --git a/2_0_13/lib/Apache2/SourceTables.pm b/2_0_13/lib/Apache2/SourceTables.pm new file mode 100644 index 0000000..b82ba13 --- /dev/null +++ b/2_0_13/lib/Apache2/SourceTables.pm
@@ -0,0 +1,32 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::SourceTables; + +use Apache2::StructureTable (); +use Apache2::FunctionTable (); + +#build hash versions of the tables +%Apache2::StructureTable = + map { $_->{type}, $_->{elts} } @$Apache2::StructureTable; + +%Apache2::FunctionTable = + map { $_->{name}, {elts => $_->{elts}, + return_type => $_->{return_type} } } + @$Apache2::FunctionTable; + +1; +__END__
diff --git a/2_0_13/lib/Apache2/Status.pm b/2_0_13/lib/Apache2/Status.pm new file mode 100644 index 0000000..ee4bb8c --- /dev/null +++ b/2_0_13/lib/Apache2/Status.pm
@@ -0,0 +1,911 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::Status; + +use strict; +use warnings FATAL => 'all'; + +use mod_perl2; + +use Apache2::RequestIO (); +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use Apache2::ServerUtil (); + +use File::Spec (); + +use Apache2::Const -compile => qw(OK); + +$Apache2::Status::VERSION = '4.01'; # mod_perl 2.0 + +use constant IS_WIN32 => ($^O eq "MSWin32"); + +my %status = ( + script => "PerlRequire'd Files", + inc => "Loaded Modules", + rgysubs => "Compiled Registry Scripts", + symdump => "Symbol Table Dump", + inh_tree => "Inheritance Tree", + isa_tree => "ISA Tree", + env => "Environment", + sig => "Signal Handlers", + myconfig => "Perl Configuration", +); +delete $status{'sig'} if IS_WIN32; + +if ($Apache2::PerlSections::Save) { + $status{"section_config"} = "Perl Section Configuration"; +} + +my %requires = ( + deparse => ["StatusDeparse", "B::Deparse", 0.59, ], + fathom => ["StatusFathom", "B::Fathom", 0.05, ], + symdump => ["", "Devel::Symdump", 2.00, ], + dumper => ["StatusDumper", "Data::Dumper", 0, ], + b => ["", "B", 0, ], + graph => ["StatusGraph", "B::Graph", 0.03, ], + lexinfo => ["StatusLexInfo", "B::LexInfo", 0, ], + xref => ["StatusXref", "B::Xref", 1.01, ], + terse => ["StatusTerse", "B::Terse", 0, ], + tersesize => ["StatusTerseSize", "B::TerseSize", 0.09, ], + packagesize => ["StatusPackageSize", "B::TerseSize", 0.09, ], + peek => ["StatusPeek", "Apache::Peek", 1.03, ], +); + +sub has { + my ($r, $what) = @_; + + return 0 unless exists $requires{$what}; + + my ($opt, $module, $version) = @{ $requires{$what} }; + + (my $file = $module) =~ s|::|/|; + $file .= ".pm"; + + # if !$opt we skip the testing for the option + return 0 if $opt && !status_config($r, $opt); + return 0 unless eval { require $file }; + my $mod_ver = $module->VERSION; + $mod_ver =~ s/_.*//; # handle dev versions like 2.121_02 + return 0 unless $mod_ver && $mod_ver >= $version; + + return 1; +} + +use constant CPAN_SEARCH => 'http://search.cpan.org/search?mode=module;query'; + +sub install_hint { + my ($module) = @_; + return qq{<p>Please install the } . + qq{<a href="@{[CPAN_SEARCH]}=$module">$module</a> module.</p>}; +} + +sub status_config { + my ($r, $key) = @_; + return (lc($r->dir_config($key) || '') eq "on") || + (lc($r->dir_config('StatusOptionsAll') || '') eq "on"); +} + +sub menu_item { + my ($self, $key, $val, $sub) = @_; + $status{$key} = $val; + no strict; + no warnings 'redefine'; + *{"status_${key}"} = $sub if $sub and ref $sub eq 'CODE'; +} + +sub handler { + my ($r) = @_; + my $qs = $r->args || ""; + my $sub = "status_$qs"; + no strict 'refs'; + + if ($qs =~ s/^(noh_\w+).*/$1/) { + &{$qs}($r); + return Apache2::Const::OK; + } + + header($r); + if (defined &$sub) { + $r->print(@{ &{$sub}($r) }); + } + elsif ($qs and %{$qs."::"}) { + $r->print(symdump($r, $qs)); + } + else { + my $uri = $r->location; + $r->print('<p>'); + $r->print( + map { qq[<a href="$uri?$_">$status{$_}</a><br />\n] } sort { lc $a cmp lc $b } keys %status + ); + $r->print('</p>'); + } + $r->print("</body></html>"); + + Apache2::Const::OK; +} + +sub header { + my $r = shift; + my $start = scalar localtime $^T; + my $srv = Apache2::ServerUtil::get_server_banner(); + $r->content_type("text/html"); + my $v = $^V ? sprintf "v%vd", $^V : $]; + $r->print(<<"EOF"); +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>Apache2::Status $Apache2::Status::VERSION</title> + <style type="text/css"> + body { + color: #000; + background-color: #fff; + } + p.hdr { + background-color: #ddd; + border: 2px outset; + padding: 3px; + width: 99%; + } + </style> + </head> + <body> + <p class="hdr"> + Embedded Perl version <b>$v</b> for <b>$srv</b> process <b>$$</b>,<br /> + running since $start + </p> +EOF + +} + +sub symdump { + my ($r, $package) = @_; + + return install_hint("Devel::Symdump") unless has($r, "symdump"); + + # lc generates a (FATAL) warning if $r->dir_config is undef + my $meth = lc($r->dir_config("StatusRdump") || '') eq "on" + ? "rnew" : "new"; + my $sob = Devel::Symdump->$meth($package); + return $sob->Apache2::Status::as_HTML($package, $r); +} + +sub status_symdump { + my ($r) = @_; + [symdump($r, 'main')]; +} + +sub status_section_config { + my ($r) = @_; + require Apache2::PerlSections; + ["<pre>", Apache2::PerlSections->dump, "</pre>"]; +} + +sub status_inc { + my ($r) = @_; + + my $uri = $r->location; + my @retval = ( + '<table border="1">', + "<tr>", + (map "<td><b>$_</b></td>", qw(Package Version Modified File)), + "</tr>\n" + ); + + foreach my $file (sort keys %INC) { + local $^W = 0; + next if $file =~ m:^/:; + next unless $file =~ m:\.pm:; + next unless $INC{$file}; #e.g. fake Apache2/TieHandle.pm + + no strict 'refs'; + (my $module = $file) =~ s,/,::,g; + $module =~ s,\.pm$,,; + next if $module eq 'mod_perl'; + my $v = ${"$module\:\:VERSION"} || '0.00'; + my $mtime = -e $INC{$file} ? scalar localtime((stat $INC{$file})[9]) : + 'N/A'; + + push @retval, ( + "<tr>", + (map "<td>$_</td>", + qq(<a href="$uri?$module">$module</a>), + $v, $mtime, $INC{$file}), + "</tr>\n" + ); + } + push @retval, "</table>\n"; + push @retval, "<p><b>\@INC</b> = <br />", join "<br />\n", @INC, ""; + \@retval; +} + +sub status_script { + my ($r) = @_; + + my @retval = ( + '<table border="1">', + "<tr><td><b>PerlRequire</b></td><td><b>Location</b></td></tr>\n", + ); + + foreach my $file (sort keys %INC) { + next if $file =~ m:\.(pm|al|ix)$:; + push @retval, + qq(<tr><td>$file</td><td>$INC{$file}</td></tr>\n); + } + push @retval, "</table>"; + \@retval; +} + +my $RegistryCache; + +sub registry_cache { + my ($self, $cache) = @_; + + # XXX: generalize + + $RegistryCache = $cache if $cache; + $RegistryCache || $Apache2::Registry; +} + +sub get_packages_per_handler { + my ($root, $stash) = @_; + + my %handlers = (); + my @packages = get_packages($stash); + for (@packages) { + /^\*${root}::([\w:]+)::(\w+)::$/ && push @{ $handlers{$1} }, $2; + } + + return %handlers; +} + +sub get_packages { + my ($stash) = @_; + + no strict 'refs'; + my @packages = (); + for (keys %$stash) { + return $stash unless $stash->{$_} =~ /::$/; + push @packages, get_packages($stash->{$_}); + } + return @packages; +} + +sub status_rgysubs { + my ($r) = @_; + + local $_; + my $uri = $r->location; + my $cache = __PACKAGE__->registry_cache; + + my @retval = "<h2>Compiled registry scripts grouped by their handler</h2>"; + + push @retval, + "<p><b>Click on package name to see its symbol table</b></p>\n"; + + my $root = "ModPerl::ROOT"; + no strict 'refs'; + my %handlers = get_packages_per_handler($root, *{$root . "::"}); + for my $handler (sort keys %handlers) { + push @retval, "<h4>$handler:</h4>\n<p>\n"; + for (sort @{ $handlers{$handler} }) { + my $full = join '::', $root, $handler, $_; + push @retval, qq(<a href="$uri?$full">$_</a>\n), "<br />"; + } + push @retval, "</p>\n"; + } + + \@retval; +} + +sub status_env { + my ($r) = shift; + + my @retval = ("<p>\n"); + + if ($r->handler eq 'modperl') { + # the handler can be executed under the "modperl" handler + push @retval, + qq{<b>Under the "modperl" handler, the environment is</b>:}; + # XXX: I guess we could call $r->subprocess_env; and show how + # would it look like under the 'perl-script' environment, but + # under the 'modperl' handler %ENV doesn't get reset, + # therefore on the first reload it'll see the bloated %ENV in + # first place. + } else { + # the handler can be executed under the "perl-script" handler + push @retval, + qq{<b>Under the "perl-script" handler, the environment is</b>:}; + } + push @retval, "\n</p>\n"; + push @retval, "<pre>", + (map "$_ = " . escape_html($ENV{$_}||'') . "\n", + sort keys %ENV), "</pre>"; + + \@retval; +} + +sub status_sig { + ["<pre>", + (map { + my $val = $SIG{$_} || ""; + if ($val and ref $val eq "CODE") { + # XXX: 2.0 doesn't have Apache2::Symbol + if (my $cv = Apache2::Symbol->can('sv_name')) { + $val = "\\&". $cv->($val); + } + } + "$_ = $val\n" } + sort keys %SIG), + "</pre>"]; +} + +sub status_myconfig { + ["<pre>", myconfig(), "</pre>"]; +} + +sub status_inh_tree { + return has(shift, "symdump") + ? ["<pre>", Devel::Symdump->inh_tree, "</pre>"] + : install_hint("Devel::Symdump"); +} + +sub status_isa_tree { + return has(shift, "symdump") + ? ["<pre>", Devel::Symdump->isa_tree, "</pre>"] + : install_hint("Devel::Symdump"); +} + +sub status_data_dump { + my ($r) = @_; + + return install_hint('Data::Dumper') unless has($r, "dumper"); + + my ($name, $type) = (split "/", $r->uri)[-2,-1]; + + no strict 'refs'; + my @retval = "<p>\nData Dump of $name $type\n</p>\n<pre>\n"; + my $str = Data::Dumper->Dump([*$name{$type}], ['*'.$name]); + $str = escape_html($str); + $str =~ s/= \\/= /; #whack backwack + push @retval, $str, "\n"; + push @retval, peek_link($r, $name, $type); + push @retval, b_graph_link($r, $name); + push @retval, "</pre>"; + \@retval; +} + +sub cv_file { + my $obj = shift; + $obj->can('FILEGV') ? $obj->FILEGV->SV->PV : $obj->FILE; +} + +sub status_cv_dump { + my ($r) = @_; + return [] unless has($r, "b"); + + no strict 'refs'; + my ($name, $type) = (split "/", $r->uri)[-2,-1]; + # could be another child, which doesn't have this symbol table? + return unless *$name{CODE}; + + my @retval = "<p>Subroutine info for <b>$name</b></p>\n<pre>\n"; + my $obj = B::svref_2object(*$name{CODE}); + my $file = cv_file($obj); + my $stash = $obj->GV->STASH->NAME; + my $script = $r->location; + + push @retval, "File: ", + (-e $file ? qq(<a href="file:$file">$file</a>) : $file), "\n"; + + my $cv = $obj->GV->CV; + my $proto = $cv->PV if $cv->can('PV'); + + push @retval, qq(Package: <a href="$script?$stash">$stash</a>\n); + push @retval, "Line: ", $obj->GV->LINE, "\n"; + push @retval, "Prototype: ", $proto || "none", "\n"; + push @retval, "XSUB: ", $obj->XSUB ? "yes" : "no", "\n"; + push @retval, peek_link($r, $name, $type); + push @retval, b_graph_link($r, $name); + push @retval, xref_link($r, $name); + push @retval, b_lexinfo_link($r, $name); + push @retval, b_terse_link($r, $name); + push @retval, b_terse_size_link($r, $name); + push @retval, b_deparse_link($r, $name); + push @retval, b_fathom_link($r, $name); + push @retval, "</pre>"; + \@retval; +} + +sub b_lexinfo_link { + my ($r, $name) = @_; + + return unless has($r, "lexinfo"); + + my $script = $r->location; + return qq(\n<a href="$script/$name?noh_b_lexinfo">Lexical Info</a>\n); +} + +sub noh_b_lexinfo { + my $r = shift; + + $r->content_type("text/plain"); + return unless has($r, "lexinfo"); + + no strict 'refs'; + my ($name) = (split "/", $r->uri)[-1]; + $r->print("Lexical Info for $name\n\n"); + my $lexi = B::LexInfo->new; + my $info = $lexi->cvlexinfo($name); + $r->print(${ $lexi->dumper($info) }); +} + +my %b_terse_exp = ('slow' => 'syntax', 'exec' => 'execution', basic => 'syntax'); + +sub b_terse_link { + my ($r, $name) = @_; + + return unless has($r, "terse"); + + my $script = $r->location; + my @retval; + for (qw(exec basic)) { + my $exp = "$b_terse_exp{$_} order"; + push @retval, + qq(\n<a href="$script/$_/$name?noh_b_terse">Syntax Tree Dump ($exp)</a>\n); + } + join '', @retval; +} + +sub noh_b_terse { + my $r = shift; + + $r->content_type("text/plain"); + return unless has($r, "terse"); + + no strict 'refs'; + my ($arg, $name) = (split "/", $r->uri)[-2,-1]; + $r->print("Syntax Tree Dump ($b_terse_exp{$arg}) for $name\n\n"); + + # XXX: blead perl dumps things to STDERR, though the same version + # works fine with 1.27 + # B::Concise couldn't parse XS code before perl patch 24681 (perl 5.9.3) + # B::Terse is deprecated and just a wrapper around B::Concise now adays + eval { B::Concise::compile("-terse", "-$arg", $name)->() }; + if ($@) { + $r->print("B::Concise has failed: $@"); + } +} + +sub b_terse_size_link { + my ($r, $name) = @_; + + return unless has($r, "tersesize"); + + my $script = $r->location; + my @retval; + for (qw(exec slow)) { + my $exp = "$b_terse_exp{$_} order"; + push @retval, + qq(\n<a href="$script/$_/$name?noh_b_terse_size">Syntax Tree Size ($exp)</a>\n); + } + join '', @retval; +} + +sub noh_b_terse_size { + my $r = shift; + + $r->content_type("text/html"); + return unless has($r, "tersesize"); + + $r->print('<pre>'); + my ($arg, $name) = (split "/", $r->uri)[-2,-1]; + my $uri = $r->location; + my $link = qq{<a href="$uri/$name/CODE?cv_dump">$name</a>}; + $r->print("Syntax Tree Size ($b_terse_exp{$arg} order) for $link\n\n"); + B::TerseSize::compile($arg, $name)->(); +} + +sub b_package_size_link { + my ($r, $name) = @_; + + return unless has($r, "packagesize"); + + my $script = $r->location; + qq(<a href="$script/$name?noh_b_package_size">Memory Usage</a>\n); +} + +sub noh_b_package_size { + my ($r) = @_; + + $r->content_type("text/html"); + return unless has($r, "packagesize"); + + $r->print('<pre>'); + + no strict 'refs'; + my ($package) = (split "/", $r->uri)[-1]; + my $script = $r->location; + $r->print("Memory Usage for package $package\n\n"); + my ($subs, $opcount, $opsize) = B::TerseSize::package_size($package); + my $Kb = sprintf "%.2f", $opsize / 1024; + my $Mb = sprintf "%.2f", $Kb / 1000; + $r->print("Totals: $opsize bytes, $Kb Kb, $Mb Mb | $opcount OPs\n\n"); + + my $nlen = 0; + my @keys = map { + $nlen = length > $nlen ? length : $nlen; + $_; + } (sort { $subs->{$b}->{size} <=> $subs->{$a}->{size} } keys %$subs); + + my $clen = $subs->{$keys[0]}->{count} ? + length $subs->{$keys[0]}->{count} : 0; + my $slen = length $subs->{$keys[0]}->{size}; + + for my $name (@keys) { + my $stats = $subs->{$name}; + if ($name =~ /^my /) { + $r->printf("%-${nlen}s %${slen}d bytes\n", $name, $stats->{size}); + } + elsif ($name =~ /^\*(\w+)\{(\w+)\}/) { + my $link = qq(<a href="$script/$package\::$1/$2?data_dump">); + $r->printf("$link%-${nlen}s</a> %${slen}d bytes\n", + $name, $stats->{size}); + } + else { + my $link = + qq(<a href="$script/slow/$package\::$name?noh_b_terse_size">); + $r->printf("$link%-${nlen}s</a> %${slen}d bytes | %${clen}d OPs\n", + $name, $stats->{size}, $stats->{count}); + } + } +} + +sub b_deparse_link { + my ($r, $name) = @_; + + return unless has($r, "deparse"); + + my $script = $r->location; + return qq(\n<a href="$script/$name?noh_b_deparse">Deparse</a>\n); +} + +sub noh_b_deparse { + my $r = shift; + + $r->content_type("text/plain"); + return unless has($r, "deparse"); + + my $name = (split "/", $r->uri)[-1]; + $r->print("Deparse of $name\n\n"); + my $deparse = B::Deparse->new(split /\s+/, + $r->dir_config('StatusDeparseOptions')||""); + my $body = $deparse->coderef2text(\&{$name}); + $r->print("sub $name $body"); +} + +sub b_fathom_link { + my ($r, $name) = @_; + + return unless has($r, "fathom"); + + my $script = $r->location; + return qq(\n<a href="$script/$name?noh_b_fathom">Fathom Score</a>\n); +} + +sub noh_b_fathom { + my $r = shift; + + $r->content_type("text/plain"); + return unless has($r, "fathom"); + + my $name = (split "/", $r->uri)[-1]; + $r->print("Fathom Score of $name\n\n"); + my $fathom = B::Fathom->new(split /\s+/, + $r->dir_config('StatusFathomOptions')||""); + $r->print($fathom->fathom(\&{$name})); +} + +sub peek_link { + my ($r, $name, $type) = @_; + + return unless has($r, "peek"); + + my $script = $r->location; + return qq(\n<a href="$script/$name/$type?noh_peek">Peek Dump</a>\n); +} + +sub noh_peek { + my $r = shift; + + $r->content_type("text/plain"); + return unless has($r, "peek"); + + no strict 'refs'; + my ($name, $type) = (split "/", $r->uri)[-2,-1]; + $type =~ s/^FUNCTION$/CODE/; + $r->print("Peek Dump of $name $type\n\n"); + Apache::Peek::Dump(*{$name}{$type}); +} + +sub xref_link { + my ($r, $name) = @_; + + return unless has($r, "xref"); + + my $script = $r->location; + return qq(\n<a href="$script/$name?noh_xref">Cross Reference Report</a>\n); +} + +sub noh_xref { + my $r = shift; + + $r->content_type("text/plain"); + return unless has($r, "xref"); + + (my $thing = $r->path_info) =~ s:^/::; + $r->print("Xref of $thing\n"); + B::Xref::compile($thing)->(); +} + +$Apache2::Status::BGraphCache ||= 0; +if ($Apache2::Status::BGraphCache) { + Apache2->server->push_handlers(PerlChildExitHandler => sub { + unlink keys %Apache2::Status::BGraphCache; + }); +} + +sub b_graph_link { + my ($r, $name) = @_; + + return unless has($r, "graph"); + + my $script = $r->location; + return qq(\n<a href="$script/$name?noh_b_graph">OP Tree Graph</a>\n); +} + +sub noh_b_graph { + my $r = shift; + + return unless has($r, "graph"); + + untie *STDOUT; + + my $dir = File::Spec->catfile(Apache2::ServerUtil::server_root(), + ($r->dir_config("GraphDir") || "logs/b_graphs")); + + mkdir $dir, 0755 unless -d $dir; + + (my $thing = $r->path_info) =~ s:^/::; + $thing =~ s{::}{-}g; # :: is not allowed in the filename on some OS + my $type = "dot"; + my $file = "$dir/$thing.$$.gif"; + + unless (-e $file) { + my $rv = tie *STDOUT, "B::Graph", $r, $file; + unless ($rv) { + $r->content_type("text/plain"); + $r->print("dot not found\n"); + } + else { + B::Graph::compile("-$type", $thing)->(); + (tied *STDOUT)->{graph}->close; + } + } + + if (-s $file) { + $r->content_type("image/gif"); + $r->sendfile($file); + } + else { + $r->content_type("text/plain"); + $r->print("Graph of $thing failed!\n"); + } + if ($Apache2::Status::BGraphCache) { + $Apache2::Status::BGraphCache{$file}++; + } + else { + unlink $file; + } + + 0; +} + +sub B::Graph::TIEHANDLE { + my ($class, $r, $file) = @_; + + if ($file =~ /^([^<>|;]+)$/) { + $file = $1; + } + else { + die "TAINTED data in THING=> ($file)"; + } + + $ENV{PATH} = join ":", qw{/usr/bin /usr/local/bin}; + my $dot = $r->dir_config("Dot") || "dot"; + + require IO::File; + my $pipe = IO::File->new("|$dot -Tgif -o $file"); + $pipe && $pipe->autoflush(1); + + if ($pipe) { + return bless { + graph => $pipe, + r => $r, + }, $class; + } + else { + return; + } +} + +sub B::Graph::PRINT { + my $self = shift; + + $self->{graph}->print(@_); +} + +my %can_dump = map {$_,1} qw(scalars arrays hashes); + +sub as_HTML { + my ($self, $package, $r) = @_; + + my @m = qw(<table>); + my $uri = $r->location; + my $is_main = $package eq "main"; + + my $do_dump = has($r, "dumper"); + + my @methods = sort keys %{$self->{'AUTOLOAD'}}; + + if ($is_main) { + @methods = grep { $_ ne "packages" } @methods; + unshift @methods, "packages"; + } + + for my $type (@methods) { + (my $dtype = uc $type) =~ s/E?S$//; + push @m, "<tr><td valign=\"top\"><b>$type</b></td>"; + my @line = (); + + for (sort $self->_partdump(uc $type)) { + s/([\000-\037\177])/ '^' . pack('c', ord($1) ^ 64)/eg; + + if ($type eq "scalars") { + no strict 'refs'; + next unless defined eval { $$_ }; + } + + if ($type eq "packages") { + push @line, qq(<a href="$uri?$_">$_</a>); + } + elsif ($type eq "functions") { + if (has($r, "b")) { + push @line, qq(<a href="$uri/$_/$dtype?cv_dump">$_</a>); + } + else { + push @line, $_; + } + } + elsif ($do_dump and $can_dump{$type}) { + next if /_</; + push @line, qq(<a href="$uri/$_/$dtype?data_dump">$_</a>); + } + else { + push @line, $_; + } + } + push @m, "<td>" . join(", ", @line) . "</td></tr>\n"; + } + push @m, "</table>"; + + return join "\n", @m, "<hr>", b_package_size_link($r, $package); +} + +sub escape_html { + my $str = shift; + + $str =~ s/&/&/g; + $str =~ s/</</g; + $str =~ s/>/>/g; + + return $str; +} + +sub myconfig { + require Config; + # Config::myconfig(); fails under threads with (5.8.0 < perl < 5.8.3) + # "Modification of a read-only value attempted" + # provide a workaround + if ($Config::Config{useithreads} and $] > 5.008 and $] < 5.008003) { + return $Config::summary_expanded if $Config::summary_expanded; + ($Config::summary_expanded = $Config::summary) =~ + s{\$(\w+)} + { my $c = $Config::Config{$1}; defined($c) ? $c : 'undef' }ge; + return $Config::summary_expanded; + } + else { + return Config::myconfig(); + } +} + +# mp2 modules have to deal with situations where a binary incompatible +# mp1 version of the same module is installed in the same +# tree. therefore when checking for a certain version, one wants to +# check the version of the module 'require()' will find without +# loading that module. this function partially adopted from +# ExtUtils::MM_Unix does just that. it returns the version number of +# the first module that it finds, forcing numerical context, making +# the return value suitable for immediate numerical comparison +# operation. (i.e. 2.03-dev will be returned as 2.03, 0 will be +# returned when the parsing has failed or a module wasn't found). +sub parse_version { + my $name = shift; + die "no module name passed" unless $name; + my $file = File::Spec->catfile(split /::/, $name) . '.pm'; + for my $dir (@INC) { + next if ref $dir; # skip code refs + + my $pmfile = File::Spec->catfile($dir, $file); + next unless -r $pmfile; + + open my $fh, $pmfile or die "can't open $pmfile: $!"; + + my $inpod = 0; + my $version; + while (<$fh>) { + $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod; + next if $inpod || /^\s*#/; + + chomp; + next unless /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/; + { local($1, $2); ($_ = $_) = /(.*)/; } # untaint + my $eval = qq{ + package Apache2::Status::_version; + no strict; + + local $1$2; + \$$2=undef; do { + $_ + }; \$$2 + }; + no warnings; + $version = eval $eval; + warn "Could not eval '$eval' in $pmfile: $@" if $@; + last; + } + + close $fh; + + # avoid situations like "2.03-dev" and return a numerical + # version + if (defined $version) { + no warnings; + $version += 0; # force number + return $version; + } + } + + return 0; # didn't find the file or the version number +} + +1; + +__END__ +
diff --git a/2_0_13/lib/Apache2/XSLoader.pm b/2_0_13/lib/Apache2/XSLoader.pm new file mode 100644 index 0000000..0c848a1 --- /dev/null +++ b/2_0_13/lib/Apache2/XSLoader.pm
@@ -0,0 +1,37 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::XSLoader; + +use strict; +use warnings FATAL => 'all'; + +use XSLoader (); + +BEGIN { + unless (defined &BOOTSTRAP) { + *BOOTSTRAP = sub () { 0 }; + } +} + +sub load { + return unless BOOTSTRAP; + # do not change the next line and do not insert anything below it in this + # function. XSLoader::load depends on it. + goto &XSLoader::load; +} + +1;
diff --git a/2_0_13/lib/Apache2/compat.pm b/2_0_13/lib/Apache2/compat.pm new file mode 100644 index 0000000..2a1a8d7 --- /dev/null +++ b/2_0_13/lib/Apache2/compat.pm
@@ -0,0 +1,873 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::compat; + +use strict; +use warnings FATAL => 'all'; +no warnings 'redefine'; + +#1.xx compat layer +#some of this will stay as-is +#some will be implemented proper later on + +#there's enough here to get simple registry scripts working +#add to startup.pl: +#use Apache2::compat (); +#use lib ...; #or something to find 1.xx Apache2::Registry + +#Alias /perl /path/to/perl/scripts +#<Location /perl> +# Options +ExecCGI +# SetHandler modperl +# PerlResponseHandler Apache2::Registry +#</Location> + +use Apache2::Connection (); +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Access (); +use Apache2::Module (); +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use Apache2::Response (); +use Apache2::SubRequest (); +use Apache2::Filter (); +use Apache2::Util (); +use Apache2::Log (); +use Apache2::URI (); +use APR::Date (); +use APR::Table (); +use APR::Pool (); +use APR::URI (); +use APR::Util (); +use APR::Brigade (); +use APR::Bucket (); +use mod_perl2 (); + +use Symbol (); +use File::Spec (); + +use APR::Const -compile => qw(FINFO_NORM FINFO_PROT); + +use constant WIN32 => ($^O eq "MSWin32"); + +BEGIN { + $INC{'Apache.pm'} = __FILE__; + + $INC{'Apache/Constants.pm'} = __FILE__; + + $INC{'Apache/File.pm'} = __FILE__; + + $INC{'Apache/Table.pm'} = __FILE__; +} + +($Apache::Server::Starting, $Apache::Server::ReStarting) = + Apache2::ServerUtil::restart_count() == 1 ? (1, 0) : (0, 1); + +# api => "overriding code" +# the overriding code, needs to "return" the original CODE reference +# when eval'ed , so that it can be restored later +my %overridable_mp2_api = ( + 'Apache2::RequestRec::filename' => <<'EOI', +{ + require Apache2::RequestRec; + require APR::Finfo; + my $orig_sub = *Apache2::RequestRec::filename{CODE}; + *Apache2::RequestRec::filename = sub { + my ($r, $newfile) = @_; + my $old_filename; + if (defined $newfile) { + $old_filename = $r->$orig_sub($newfile); + die "'$newfile' doesn't exist" unless -e $newfile; + my $wanted = APR::Const::FINFO_NORM; + if (WIN32) { + $wanted &= ~APR::Const::FINFO_PROT; + } + $r->finfo(APR::Finfo::stat($newfile, $wanted, $r->pool)); + } + else { + $old_filename = $r->$orig_sub(); + } + return $old_filename; + }; + $orig_sub; +} + +EOI + 'Apache2::RequestRec::notes' => <<'EOI', +{ + require Apache2::RequestRec; + my $orig_sub = *Apache2::RequestRec::notes{CODE}; + *Apache2::RequestRec::notes = sub { + my $r = shift; + return wantarray() + ? ($r->table_get_set(scalar($r->$orig_sub), @_)) + : scalar($r->table_get_set(scalar($r->$orig_sub), @_)); + }; + $orig_sub; +} +EOI + + 'Apache2::RequestRec::finfo' => <<'EOI', +{ + require APR::Finfo; + my $orig_sub = *APR::Finfo::finfo{CODE}; + sub Apache2::RequestRec::finfo { + my $r = shift; + stat $r->filename; + \*_; + } + $orig_sub; +} +EOI + + 'Apache2::Connection::local_addr' => <<'EOI', +{ + require Apache2::Connection; + require Socket; + require APR::SockAddr; + my $orig_sub = *Apache2::Connection::local_addr{CODE}; + *Apache2::Connection::local_addr = sub { + my $c = shift; + Socket::pack_sockaddr_in($c->$orig_sub->port, + Socket::inet_aton($c->$orig_sub->ip_get)); + }; + $orig_sub; +} +EOI + + 'Apache2::Connection::remote_addr' => <<'EOI', +{ + require Apache2::Connection; + require APR::SockAddr; + require Socket; + my $orig_sub; + if (defined *Apache2::Connection::client_addr{CODE}) { # httpd-2.4 + $orig_sub = *Apache2::Connection::client_addr{CODE}; + } else { # httpd-2.2 + $orig_sub = *Apache2::Connection::remote_addr{CODE}; + } + *Apache2::Connection::remote_addr = sub { + my $c = shift; + if (@_) { + my $addr_in = shift; + my ($port, $addr) = Socket::unpack_sockaddr_in($addr_in); + $c->$orig_sub->ip_set($addr); + $c->$orig_sub->port_set($port); + } + else { + Socket::pack_sockaddr_in($c->$orig_sub->port, + Socket::inet_aton($c->$orig_sub->ip_get)); + } + }; + $orig_sub; +} +EOI + + 'Apache2::Module::top_module' => <<'EOI', +{ + require Apache2::Module; + my $orig_sub = *Apache2::Module::top_module{CODE}; + *Apache2::Module::top_module = sub { + shift; + $orig_sub->(@_); + }; + $orig_sub; +} +EOI + + 'Apache2::Module::get_config' => <<'EOI', +{ + require Apache2::Module; + my $orig_sub = *Apache2::Module::get_config{CODE}; + *Apache2::Module::get_config = sub { + shift; + $orig_sub->(@_); + }; + $orig_sub; +} +EOI + + 'APR::URI::unparse' => <<'EOI', +{ + require APR::URI; + my $orig_sub = *APR::URI::unparse{CODE}; + *APR::URI::unparse = sub { + my ($uri, $flags) = @_; + + if (defined $uri->hostname && !defined $uri->scheme) { + # we do this only for back compat, the new APR::URI is + # protocol-agnostic and doesn't fallback to 'http' when the + # scheme is not provided + $uri->scheme('http'); + } + + $orig_sub->(@_); + }; + $orig_sub; +} +EOI + + 'Apache2::Util::ht_time' => <<'EOI', +{ + require Apache2::Util; + my $orig_sub = *Apache2::Util::ht_time{CODE}; + *Apache2::Util::ht_time = sub { + my $r = Apache2::compat::request('Apache2::Util::ht_time'); + return $orig_sub->($r->pool, @_); + }; + $orig_sub; +} + +EOI + +); + +my %overridden_mp2_api = (); + +# this function enables back-compatible APIs which can't coexist with +# mod_perl 2.0 APIs with the same name and therefore it should be +# avoided if possible. +# +# it expects a list of fully qualified functions, like +# "Apache2::RequestRec::finfo" +sub override_mp2_api { + my (@subs) = @_; + + for my $sub (@subs) { + unless (exists $overridable_mp2_api{$sub}) { + die __PACKAGE__ . ": $sub is not overridable"; + } + if (exists $overridden_mp2_api{$sub}) { + warn __PACKAGE__ . ": $sub has been already overridden"; + next; + } + $overridden_mp2_api{$sub} = eval $overridable_mp2_api{$sub}; + if ($@) { + die "error overriding $sub : $@"; + } + unless (exists $overridden_mp2_api{$sub} && + ref($overridden_mp2_api{$sub}) eq 'CODE') { + die "overriding $sub didn't return a CODE ref"; + } + } +} + +# restore_mp2_api does the opposite of override_mp2_api(), it removes +# the overriden API and restores the original mod_perl 2.0 API +sub restore_mp2_api { + my (@subs) = @_; + + for my $sub (@subs) { + unless (exists $overridable_mp2_api{$sub}) { + die __PACKAGE__ . ": $sub is not overridable"; + } + unless (exists $overridden_mp2_api{$sub}) { + warn __PACKAGE__ . ": can't restore $sub, " . + "as it has not been overridden"; + next; + } + # XXX: 5.8.2+ can't delete and assign at once - gives: + # Attempt to free unreferenced scalar + # after perl_clone. the 2 step works ok. to reproduce: + # t/TEST -maxclients 1 perl/ithreads2.t compat/request.t + my $original_sub = $overridden_mp2_api{$sub}; + delete $overridden_mp2_api{$sub}; + no warnings 'redefine'; + no strict 'refs'; + *$sub = $original_sub; + } +} + +sub request { + my $what = shift; + + my $r = Apache2::RequestUtil->request; + + unless ($r) { + die "cannot use $what ", + "without 'SetHandler perl-script' ", + "or 'PerlOptions +GlobalRequest'"; + } + + $r; +} + +{ + my $orig_sub = *Apache2::Module::top_module{CODE}; + *Apache2::Module::top_module = sub { + $orig_sub->(); + }; +} + +{ + my $orig_sub = *Apache2::Module::get_config{CODE}; + *Apache2::Module::get_config = sub { + shift if $_[0] eq 'Apache2::Module'; + $orig_sub->(@_); + }; +} + +package Apache::Server; +# XXX: is that good enough? see modperl/src/modules/perl/mod_perl.c:367 +our $CWD = Apache2::ServerUtil::server_root(); + +our $AddPerlVersion = 1; + +sub warn { + shift if @_ and $_[0] eq 'Apache::Server'; + Apache2::ServerRec::warn(@_); +} + +package Apache; + +sub request { + return Apache2::compat::request(@_); +} + +sub unescape_url_info { + my ($class, $string) = @_; + Apache2::URI::unescape_url($string); + $string =~ tr/+/ /; + $string; +} + +#sorry, have to use $r->Apache2::args at the moment +#for list context splitting + +sub args { + my $r = shift; + my $args = $r->args; + return $args unless wantarray; + return $r->parse_args($args); +} + +sub server_root_relative { + my $class = shift; + if (@_ && defined($_[0]) && File::Spec->file_name_is_absolute($_[0])) { + return File::Spec->catfile(@_); + } + else { + File::Spec->catfile(Apache2::ServerUtil::server_root(), @_); + } +} + +sub exit { + require ModPerl::Util; + + my $status = 0; + my $nargs = @_; + + if ($nargs == 2) { + $status = $_[1]; + } + elsif ($nargs == 1 and $_[0] =~ /^\d+$/) { + $status = $_[0]; + } + + ModPerl::Util::exit($status); +} + +#XXX: warn +sub import { +} + +sub untaint { + shift; + require ModPerl::Util; + ModPerl::Util::untaint(@_); +} + +sub module { + require Apache2::Module; + die 'Usage: Apache2->module($name)' if @_ != 2; + return Apache2::Module::loaded($_[1]); +} + +sub gensym { + return Symbol::gensym(); +} + +sub define { + shift if @_ == 2; + Apache2::ServerUtil::exists_config_define(@_); +} + +sub log_error { + Apache2::ServerUtil->server->log_error(@_); +} + +sub warn { + shift if @_ and $_[0] eq 'Apache'; + Apache2::ServerRec::warn(@_); +} + +sub httpd_conf { + shift; + my $obj; + eval { $obj = Apache2::RequestUtil->request }; + $obj = Apache2::ServerUtil->server if $@; + my $err = $obj->add_config([split /\n/, join '', @_]); + die $err if $err; +} + +# mp2 always can stack handlers +sub can_stack_handlers { 1; } + +sub push_handlers { + shift; + Apache2::ServerUtil->server->push_handlers(@_); +} + +sub set_handlers { + shift; + Apache2::ServerUtil->server->set_handlers(@_); +} + +sub get_handlers { + shift; + Apache2::ServerUtil->server->get_handlers(@_); +} + +package Apache::Constants; + +use Apache2::Const (); + +sub import { + my $class = shift; + my $package = scalar caller; + + my @args = @_; + + # treat :response as :common - it's not perfect + # but simple and close enough for the majority + my %args = map { s/^:response$/:common/; $_ => 1 } @args; + + Apache2::Const->compile($package => keys %args); +} + +#no need to support in 2.0 +sub export {} + +sub SERVER_VERSION { Apache2::ServerUtil::get_server_version() } + +package Apache2::RequestRec; + +use Apache2::Const -compile => qw(REMOTE_NAME); + +#no longer exist in 2.0 +sub soft_timeout {} +sub hard_timeout {} +sub kill_timeout {} +sub reset_timeout {} + +# this function is from mp1's Apache2::SubProcess 3rd party module +# which is now a part of mp2 API. this function doesn't exist in 2.0. +sub cleanup_for_exec {} + +sub current_callback { + require ModPerl::Util; + return ModPerl::Util::current_callback(); +} + +sub send_http_header { + my ($r, $type) = @_; + + # since send_http_header() in mp1 was telling mod_perl not to + # parse headers and in mp2 one must call $r->content_type($type) to + # perform the same, we make sure that this happens + $type = $r->content_type || 'text/html' unless defined $type; + + $r->content_type($type); +} + +#we support Apache2::RequestUtil->request; this is needed to support $r->request +#XXX: seems sorta backwards +*request = \&Apache2::request; + +sub table_get_set { + my ($r, $table) = (shift, shift); + my ($key, $value) = @_; + + if (1 == @_) { + return wantarray() + ? ($table->get($key)) + : scalar($table->get($key)); + } + elsif (2 == @_) { + if (defined $value) { + return wantarray() + ? ($table->set($key, $value)) + : scalar($table->set($key, $value)); + } + else { + return wantarray() + ? ($table->unset($key)) + : scalar($table->unset($key)); + } + } + elsif (0 == @_) { + return $table; + } + else { + my $name = (caller(1))[3]; + $r->warn("Usage: \$r->$name([key [,val]])"); + } +} + +sub header_out { + my $r = shift; + return wantarray() + ? ($r->table_get_set(scalar($r->headers_out), @_)) + : scalar($r->table_get_set(scalar($r->headers_out), @_)); +} + +sub header_in { + my $r = shift; + return wantarray() + ? ($r->table_get_set(scalar($r->headers_in), @_)) + : scalar($r->table_get_set(scalar($r->headers_in), @_)); +} + +sub err_header_out { + my $r = shift; + return wantarray() + ? ($r->table_get_set(scalar($r->err_headers_out), @_)) + : scalar($r->table_get_set(scalar($r->err_headers_out), @_)); +} + + +sub register_cleanup { + shift->pool->cleanup_register(@_); +} + +*post_connection = \®ister_cleanup; + +sub get_remote_host { + my ($r, $type) = @_; + $type = Apache2::Const::REMOTE_NAME unless defined $type; + $r->connection->get_remote_host($type, $r->per_dir_config); +} + +sub parse_args { + my ($r, $string) = @_; + return () unless defined $string and $string; + + return map { + tr/+/ /; + s/%([0-9a-fA-F]{2})/pack("C",hex($1))/ge; + $_; + } split /[=&;]/, $string, -1; +} + +use Apache2::Const -compile => qw(MODE_READBYTES); +use APR::Const -compile => qw(SUCCESS BLOCK_READ); + +use constant IOBUFSIZE => 8192; + +sub content { + my $r = shift; + + my $bb = APR::Brigade->new($r->pool, + $r->connection->bucket_alloc); + + my $data = ''; + my $seen_eos = 0; + do { + $r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES, + APR::Const::BLOCK_READ, IOBUFSIZE); + while (!$bb->is_empty) { + my $b = $bb->first; + + if ($b->is_eos) { + $seen_eos++; + last; + } + + if ($b->read(my $buf)) { + $data .= $buf; + } + + $b->delete; + } + } while (!$seen_eos); + + $bb->destroy; + + return $data unless wantarray; + return $r->parse_args($data); +} + +sub server_root_relative { + my $r = shift; + File::Spec->catfile(Apache2::ServerUtil::server_root(), @_); +} + +sub clear_rgy_endav { + my ($r, $script_name) = @_; + require ModPerl::Global; + my $package = 'Apache2::ROOT' . $script_name; + ModPerl::Global::special_list_clear(END => $package); +} + +sub stash_rgy_endav { + #see run_rgy_endav +} + +#if somebody really wants to have END subroutine support +#with the 1.x Apache2::Registry they will need to configure: +# PerlHandler Apache2::Registry Apache2::compat::run_rgy_endav +sub Apache2::compat::run_rgy_endav { + my $r = shift; + + require ModPerl::Global; + require Apache2::PerlRun; #1.x's + my $package = Apache2::PerlRun->new($r)->namespace; + + ModPerl::Global::special_list_call(END => $package); +} + +sub seqno { + 1; +} + +sub chdir_file { + #XXX resolve '.' in @INC to basename $r->filename +} + +#XXX: would like to have a proper implementation +#that reads line-by-line as defined by $/ +#the best way will probably be to use perlio in 5.8.0 +#anything else would be more effort than it is worth +sub READLINE { + my $r = shift; + my $line; + $r->read($line, $r->headers_in->get('Content-length')); + $line ? $line : undef; +} + +#XXX: howto convert PerlIO to apr_file_t +#so we can use the real ap_send_fd function +#2.0 ap_send_fd() also has an additional offset parameter + +sub send_fd_length { + my ($r, $fh, $length) = @_; + + my $buff; + my $total_bytes_sent = 0; + my $len; + + return 0 if $length == 0; + + if (($length > 0) && ($total_bytes_sent + IOBUFSIZE) > $length) { + $len = $length - $total_bytes_sent; + } + else { + $len = IOBUFSIZE; + } + + binmode $fh; + + while (CORE::read($fh, $buff, $len)) { + $total_bytes_sent += $r->puts($buff); + } + + $total_bytes_sent; +} + +sub send_fd { + my ($r, $fh) = @_; + $r->send_fd_length($fh, -1); +} + +sub is_main { !shift->main } + +# really old back-compat methods, they shouldn't be used in mp1 +*cgi_var = *cgi_env = \&Apache2::RequestRec::subprocess_env; + +package Apache::File; + +use Fcntl (); +use Symbol (); +use Carp (); + +sub new { + my ($class) = shift; + my $fh = Symbol::gensym; + my $self = bless $fh, ref($class)||$class; + if (@_) { + return $self->open(@_) ? $self : undef; + } + else { + return $self; + } +} + +sub open { + my ($self) = shift; + + Carp::croak("no Apache2::File object passed") + unless $self && ref($self); + + # cannot forward @_ to open() because of its prototype + if (@_ > 1) { + my ($mode, $file) = @_; + CORE::open $self, $mode, $file; + } + else { + my $file = shift; + CORE::open $self, $file; + } +} + +sub close { + my ($self) = shift; + CORE::close $self; +} + +my $TMPNAM = 'aaaaaa'; +my $TMPDIR = $ENV{'TMPDIR'} || $ENV{'TEMP'} || '/tmp'; +($TMPDIR) = $TMPDIR =~ /^([^<>|;*]+)$/; #untaint +my $Mode = Fcntl::O_RDWR()|Fcntl::O_EXCL()|Fcntl::O_CREAT(); +my $Perms = 0600; + +sub tmpfile { + my $class = shift; + my $limit = 100; + my $r = Apache2::compat::request('Apache::File->tmpfile'); + + while ($limit--) { + my $tmpfile = "$TMPDIR/${$}" . $TMPNAM++; + my $fh = $class->new; + + sysopen $fh, $tmpfile, $Mode, $Perms + or die "failed to open $tmpfile: $!"; + $r->pool->cleanup_register(sub { unlink $tmpfile }); + + if ($fh) { + return wantarray ? ($tmpfile, $fh) : $fh; + } + } +} + +# the following functions now live in Apache2::RequestIO +# * discard_request_body + +# the following functions now live in Apache2::Response +# * meets_conditions +# * set_content_length +# * set_etag +# * set_last_modified +# * update_mtime + +# the following functions now live in Apache2::RequestRec +# * mtime + +package Apache::Util; + +sub size_string { + my ($size) = @_; + + if (!$size) { + $size = " 0k"; + } + elsif ($size == -1) { + $size = " -"; + } + elsif ($size < 1024) { + $size = " 1k"; + } + elsif ($size < 1048576) { + $size = sprintf "%4dk", ($size + 512) / 1024; + } + elsif ($size < 103809024) { + $size = sprintf "%4.1fM", $size / 1048576.0; + } + else { + $size = sprintf "%4dM", ($size + 524288) / 1048576; + } + + return $size; +} + +*unescape_uri = \&Apache2::URI::unescape_url; + +*escape_path = \&Apache2::Util::escape_path; + +sub escape_uri { + my $path = shift; + my $r = Apache2::compat::request('Apache2::Util::escape_uri'); + Apache2::Util::escape_path($path, $r->pool); +} + +#tmp compat until ap_escape_html is reworked to not require a pool +my %html_escapes = ( + '<' => 'lt', + '>' => 'gt', + '&' => 'amp', + '"' => 'quot', +); + +%html_escapes = map { $_, "&$html_escapes{$_};" } keys %html_escapes; + +my $html_escape = join '|', keys %html_escapes; + +sub escape_html { + my $html = shift; + $html =~ s/($html_escape)/$html_escapes{$1}/go; + $html; +} + +*parsedate = \&APR::Date::parse_http; + +*validate_password = \&APR::Util::password_validate; + +sub Apache2::URI::parse { + my ($class, $r, $uri) = @_; + + $uri ||= $r->construct_url; + + APR::URI->parse($r->pool, $uri); +} + +package Apache::Table; + +sub new { + my ($class, $r, $nelts) = @_; + $nelts ||= 10; + APR::Table::make($r->pool, $nelts); +} + +package Apache::SIG; + +use Apache2::Const -compile => 'DECLINED'; + +sub handler { + # don't set the SIGPIPE + return Apache2::Const::DECLINED; +} + +package Apache2::Connection; + +# auth_type and user records don't exist in 2.0 conn_rec struct +# 'PerlOptions +GlobalRequest' is required +sub auth_type { shift; Apache2::RequestUtil->request->ap_auth_type(@_) } +sub user { shift; Apache2::RequestUtil->request->user(@_) } + +1; +__END__
diff --git a/2_0_13/lib/Apache2/porting.pm b/2_0_13/lib/Apache2/porting.pm new file mode 100644 index 0000000..2432604 --- /dev/null +++ b/2_0_13/lib/Apache2/porting.pm
@@ -0,0 +1,105 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::porting; + +use strict; +use warnings FATAL => 'all'; + +use Carp 'croak'; + +use ModPerl::MethodLookup (); +use Apache2::ServerUtil; + +use Apache2::Const -compile => 'OK'; + +our $AUTOLOAD; + +### methods ### +# handle: +# - removed and replaced methods +# - hinting the package names in which methods reside + +my %avail_methods = map { $_ => 1 } + (ModPerl::MethodLookup::avail_methods(), + ModPerl::MethodLookup::avail_methods_compat()); + +# XXX: unfortunately it doesn't seem to be possible to install +# *UNIVERSAL::AUTOLOAD at the server startup, httpd segfaults, +# child_init seems to be the first stage where it works. +Apache2::ServerUtil->server->push_handlers( + PerlChildInitHandler => \&porting_autoload); + +sub porting_autoload { + *UNIVERSAL::AUTOLOAD = sub { + # This is a porting module, no compatibility layers are allowed in + # this zone + croak("Apache2::porting can't be used with Apache2::compat") + if exists $ENV{"Apache2/compat.pm"}; + + (my $method = $AUTOLOAD) =~ s/.*:://; + + # we skip DESTROY methods + return if $method eq 'DESTROY'; + + # we don't handle methods that we don't know about + croak "Undefined subroutine $AUTOLOAD called" + unless defined $method && exists $avail_methods{$method}; + + my ($hint, @modules) = + ModPerl::MethodLookup::lookup_method($method, @_); + $hint ||= "Can't find method $AUTOLOAD"; + croak $hint; + }; + + return Apache2::Const::OK; +} + +### packages ### +# handle: +# - removed and replaced packages + +my %packages = ( + 'Apache::Constants' => [qw(Apache2::Const)], + 'Apache::Table' => [qw(APR::Table)], + 'Apache::File' => [qw(Apache2::Response Apache2::RequestRec)], + 'Apache' => [qw(ModPerl::Util Apache2::Module)], +); + +BEGIN { + sub my_require { + my $package = $_[0]; + $package =~ s|/|::|g; + $package =~ s|.pm$||; + + # this picks the original require (which could be overriden + # elsewhere, so we don't lose that) because we haven't + # overriden it yet + return require $_[0] unless $packages{$package}; + + my $msg = "mod_perl 2.0 API doesn't include package '$package'."; + my @replacements = @{ $packages{$package}||[] }; + if (@replacements) { + $msg .= " The package '$package' has moved to " . + join " ", map qq/'$_'/, @replacements; + } + croak $msg; + }; + + *CORE::GLOBAL::require = sub (*) { my_require($_[0])}; +} + +1;
diff --git a/2_0_13/lib/Bundle/Apache2.pm b/2_0_13/lib/Bundle/Apache2.pm new file mode 100644 index 0000000..7b9ec42 --- /dev/null +++ b/2_0_13/lib/Bundle/Apache2.pm
@@ -0,0 +1,70 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Bundle::Apache2; + +$VERSION = '1.00'; + +1; + +__END__ + +=head1 NAME + +Bundle::Apache2 - Install Apache mod_perl2 and related modules + + + +=head1 SYNOPSIS + +C<perl -MCPAN -e 'install Bundle::Apache2'> + + + +=head1 CONTENTS + +Bundle::ApacheTest - Needs for testing + +CGI 3.11 - Used in testing (it's in core, but some vendors exclude it) + +Chatbot::Eliza - Used in testing + +Compress::Zlib - Used in testing + +Devel::Symdump - Symbol table browsing with Apache::Status + +HTML::HeadParser - Used in testing + +IPC::Run3 - Used in testing + +LWP - Used in testing + + + + +=head1 DESCRIPTION + +This bundle contains modules used by Apache mod_perl2. + +Asking CPAN.pm to install a bundle means to install the bundle itself +along with all the modules contained in the CONTENTS section +above. Modules that are up to date are not installed, of course. + + + +=head1 AUTHOR + +mod_perl 2 development team
diff --git a/2_0_13/lib/ModPerl/BuildMM.pm b/2_0_13/lib/ModPerl/BuildMM.pm new file mode 100644 index 0000000..849f35e --- /dev/null +++ b/2_0_13/lib/ModPerl/BuildMM.pm
@@ -0,0 +1,377 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::BuildMM; + +use strict; +use warnings; + +use ExtUtils::MakeMaker (); +use Cwd (); +use File::Spec::Functions qw(catdir catfile splitdir); +use File::Basename; +use File::Find; + +use Apache2::Build (); +use ModPerl::MM; +use constant WIN32 => Apache2::Build::WIN32; +use constant CYGWIN => Apache2::Build::CYGWIN; + +our %PM; #add files to installation + +# MM methods that this package overrides +no strict 'refs'; +my $stash = \%{__PACKAGE__ . '::MY::'}; +my @methods = grep *{$stash->{$_}}{CODE}, keys %$stash; +ModPerl::MM::override_eu_mm_mv_all_methods(@methods); +use strict 'refs'; + +my $apache_test_dir = catdir Cwd::getcwd(), "Apache-Test", "lib"; + +#to override MakeMaker MOD_INSTALL macro +sub mod_install { + q{$(PERL) -I$(INST_LIB) -I$(PERL_LIB) \\}."\n" . + qq{-I$apache_test_dir -MModPerl::BuildMM \\}."\n" . + q{-e "ExtUtils::Install::install({@ARGV},'$(VERBINST)',0,'$(UNINST)');"}."\n"; +} + +my $build; + +sub build_config { + my $key = shift; + $build ||= Apache2::Build->build_config; + return $build unless $key; + $build->{$key}; +} + +#the parent WriteMakefile moves MY:: methods into a different class +#so alias them each time WriteMakefile is called in a subdir + +sub my_import { + no strict 'refs'; + my $stash = \%{__PACKAGE__ . '::MY::'}; + for my $sym (keys %$stash) { + next unless *{$stash->{$sym}}{CODE}; + my $name = "MY::$sym"; + undef &$name if defined &$name; + *$name = *{$stash->{$sym}}{CODE}; + } +} + +sub WriteMakefile { + my %args = @_; + + $build ||= build_config(); + ModPerl::MM::my_import(__PACKAGE__); + + my $inc = $args{INC} || ''; + $inc = $args{INC} if $args{INC}; + $inc .= " " . $build->inc; + if (my $glue_inc = $build->{MP_XS_GLUE_DIR}) { + for (split /\s+/, $glue_inc) { + $inc .= " -I$_"; + } + } + + my $libs; + my @libs = (); + push @libs, $args{LIBS} if $args{LIBS}; + if (Apache2::Build::BUILD_APREXT) { + # in order to decouple APR/APR::* from mod_perl.so, + # link these modules against the static MP_APR_LIB lib, + # rather than the mod_perl lib (which would demand mod_perl.so + # be available). For other modules, use mod_perl.lib as + # usual. This is done for APR in xs/APR/APR/Makefile.PL. + my $name = $args{NAME}; + if ($name =~ /^APR::\w+$/) { + # For cygwin compatibility, the order of the libs should be + # <mod_perl libs> <apache libs> + @libs = ($build->mp_apr_lib, $build->apache_libs); + } + else { + @libs = ($build->modperl_libs, $build->apache_libs); + } + } + else { + @libs = ($build->modperl_libs, $build->apache_libs); + } + $libs = join ' ', @libs; + + my $ccflags; + $ccflags = $args{CCFLAGS} if $args{CCFLAGS}; + $ccflags = " " . $build->perl_ccopts . $build->ap_ccopts; + + my $optimize; + $optimize = $args{OPTIMIZE} if $args{OPTIMIZE}; + $optimize = " " . $build->perl_config('optimize'); + + my $lddlflags; + $lddlflags = $args{LDDLFLAGS} if $args{LDDLFLAGS}; + $lddlflags = " " . $build->perl_config('lddlflags'); + + my %dynamic_lib; + %dynamic_lib = %{ $args{dynamic_lib}||{} } if $args{dynamic_lib}; + $dynamic_lib{OTHERLDFLAGS} = $build->otherldflags; + + my @opts = ( + INC => $inc, + CCFLAGS => $ccflags, + OPTIMIZE => $optimize, + LDDLFLAGS => $lddlflags, + LIBS => $libs, + dynamic_lib => \%dynamic_lib, + ); + + my @typemaps; + push @typemaps, $args{TYPEMAPS} if $args{TYPEMAPS}; + my $pwd = Cwd::fastcwd(); + for ('xs', $pwd, "$pwd/..") { + my $typemap = $build->file_path("$_/typemap"); + if (-e $typemap) { + push @typemaps, $typemap; + } + } + push @opts, TYPEMAPS => \@typemaps if @typemaps; + + my $clean_files = (exists $args{clean} && exists $args{clean}{FILES}) ? + $args{clean}{FILES} : ''; + $clean_files .= " glue_pods"; # cleanup the dependency target + $args{clean}{FILES} = $clean_files; + + ExtUtils::MakeMaker::WriteMakefile(@opts, %args); +} + +my %always_dynamic = map { $_, 1 } + qw(ModPerl::Const Apache2::Const APR::Const APR APR::PerlIO); + +sub ModPerl::BuildMM::MY::constants { + my $self = shift; + $build ||= build_config(); + + #"discover" xs modules. since there is no list hardwired + #any module can be unpacked in the mod_perl-2.xx directory + #and built static + + #this stunt also make it possible to leave .xs files where + #they are, unlike 1.xx where *.xs live in src/modules/perl + #and are copied to subdir/ if DYNAMIC=1 + + if ($build->{MP_STATIC_EXTS}) { + #skip .xs -> .so if we are linking static + my $name = $self->{NAME}; + unless ($always_dynamic{$name}) { + if (my ($xs) = keys %{ $self->{XS} }) { + $self->{HAS_LINK_CODE} = 0; + print "$name will be linked static\n"; + #propagate static xs module to src/modules/perl/Makefile + $build->{XS}->{$name} = + join '/', Cwd::fastcwd(), $xs; + $build->save; + } + } + } + + $self->MM::constants; +} + +sub ModPerl::BuildMM::MY::top_targets { + my $self = shift; + my $string = $self->MM::top_targets; + + return $string; +} + +sub ModPerl::BuildMM::MY::postamble { + my $self = shift; + + my $doc_root = catdir Cwd::getcwd(), "docs", "api"; + + my @targets = (); + + # reasons for glueing pods to the respective .pm files: + # - manpages will get installed over the mp1 manpages and vice + # versa. glueing pods avoids creation of manpages, but may be we + # could just tell make to skip manpages creation? + # if pods are installed directly they need to be also redirected, + # some into Apache2/ others (e.g. Apache2) not + + # add the code to glue the existing pods to the .pm files in blib. + # create a dependency on pm_to_blib subdirs linkext targets to + # allow 'make -j' + require ExtUtils::MakeMaker; + my $mm_ver = $ExtUtils::MakeMaker::VERSION; + $mm_ver =~ s/_.*//; # handle dev versions like 6.30_01 + my $pm_to_blib = ($mm_ver >= 6.22 && $mm_ver <= 6.25) + ? "pm_to_blib.ts" + : "pm_to_blib"; + my @target = ("glue_pods: $pm_to_blib subdirs linkext"); + + if (-d $doc_root) { + my $build = build_config(); + + # those living in modperl-2.0/lib are already nicely mapped + my %pms = %{ $self->{PM} }; + + my $cwd = Cwd::getcwd(); + my $blib_dir = catdir qw(blib lib); + + # those autogenerated under WrapXS/ + # those living under xs/ + # those living under ModPerl-Registry/lib/ + my @src = ('WrapXS', 'xs', catdir(qw(ModPerl-Registry lib))); + + for my $base (@src) { + chdir $base; + my @files = (); + find({ no_chdir => 1, + wanted => sub { push @files, $_ if /.pm$/ }, + }, "."); + chdir $cwd; + + for (@files) { + my $pm = catfile $base, $_; + my $blib; + if ($base =~ /^(xs|WrapXS)/) { + my @segm = splitdir $_; + splice @segm, -2, 1; # xs/APR/Const/Const.pm + splice @segm, -2, 1 if /APR.pm/; # odd case + $blib = catfile $blib_dir, @segm; + } + else { + $blib = catfile $blib_dir, $_; + } + $pms{$pm} = $blib; + } + } + + foreach my $pm (sort keys %pms) { + my $blib = $pms{$pm}; + $pm =~ s|/\./|/|g; # clean the path + $blib =~ s|/\./|/|g; # clean the path + my @segm = splitdir $blib; + for my $i (1..2) { + # try APR.pm and APR/Bucket.pm + my $pod = catdir(@segm[-$i .. -1]); + $pod =~ s/\.pm/\.pod/; + my $podpath = catfile $doc_root, $pod; + next unless -r $podpath; + + push @target, + '$(FULLPERL) -I$(INST_LIB) ' . + "-I$apache_test_dir -MModPerl::BuildMM " . + "-e ModPerl::BuildMM::glue_pod $pm $podpath $blib"; + + # Win32 doesn't normally install man pages + # and Cygwin doesn't allow '::' in file names + next if WIN32 || CYGWIN; + + # manify while we're at it + my (undef, $man, undef) = $blib =~ m!(blib/lib/)(.*)(\.pm)!; + $man =~ s!/!::!g; + + push @target, + '$(NOECHO) $(POD2MAN_EXE) --section=3 ' . + "$podpath \$(INST_MAN3DIR)/$man.\$(MAN3EXT)" + } + } + + push @target, $self->{NOECHO} . '$(TOUCH) $@'; + } + else { + # we don't have the docs sub-cvs repository extracted, skip + # the docs gluing + push @target, $self->{NOECHO} . '$(NOOP)'; + } + push @targets, join "\n\t", @target; + +# # next target: cleanup the dependency file +# @target = ('glue_pods_clean:'); +# push @target, '$(RM_F) glue_pods'; +# push @targets, join "\n\t", @target; + + return join "\n\n", @targets, ''; +} + +sub glue_pod { + + die "expecting 3 arguments: pm, pod, dst" unless @ARGV == 3; + my ($pm, $pod, $dst) = @ARGV; + + # it's possible that the .pm file is not existing + # (e.g. ThreadMutex.pm is not created on unless + # $apr_config->{HAS_THREADS}) + return unless -e $pm && -e $dst; + + # have we already glued the doc? + exit 0 unless -s $pm == -s $dst; + + # ExtUtils::Install::pm_to_blib removes the 'w' perms, so we can't + # just append the doc there + my $orig_mode = (stat $dst)[2]; + my $rw_mode = 0666; + + chmod $rw_mode, $dst or die "Can't chmod $rw_mode $dst: $!"; + open my $pod_fh, "<$pod" or die "Can't open $pod: $!"; + open my $dst_fh, ">>$dst" or die "Can't open $dst: $!"; + print $dst_fh "\n"; # must add one line separation + print $dst_fh (<$pod_fh>); + close $pod_fh; + close $dst_fh; + # restore the perms + chmod $orig_mode, $dst or die "Can't chmod $orig_mode $dst: $!"; +} + +sub ModPerl::BuildMM::MY::post_initialize { + my $self = shift; + $build ||= build_config(); + my $pm = $self->{PM}; + + while (my ($k, $v) = each %PM) { + if (-e $k) { + $pm->{$k} = $v; + } + } + + # prefix typemap with Apache2/ so when installed in the + # perl-lib-tree it won't be picked by non-mod_perl modules + if (exists $pm->{'lib/typemap'} ) { + $pm->{'lib/typemap'} = '$(INST_ARCHLIB)/auto/Apache2/typemap'; + } + + ''; +} + +my $apr_config; + +sub ModPerl::BuildMM::MY::libscan { + my ($self, $path) = @_; + + $apr_config ||= $build->get_apr_config(); + + if ($path =~ m/(Thread|Global)(Mutex|RWLock)/) { + return unless $apr_config->{HAS_THREADS}; + } + + return '' if $path =~ /DummyVersions.pm/; + + return '' if $path =~ m/\.pl$/; + return '' if $path =~ m/~$/; + return '' if $path =~ /\B\.svn\b/; + + $path; +} + +1;
diff --git a/2_0_13/lib/ModPerl/BuildOptions.pm b/2_0_13/lib/ModPerl/BuildOptions.pm new file mode 100644 index 0000000..b54bd8e --- /dev/null +++ b/2_0_13/lib/ModPerl/BuildOptions.pm
@@ -0,0 +1,271 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::BuildOptions; + +use strict; +use warnings; + +use Apache2::Build (); +use Apache::TestTrace; +use Config (); +my $param_qr = qr([\s=]+); + +use constant VERBOSE => 1; +use constant UNKNOWN_FATAL => 2; + +use File::Spec; + +sub init { + my ($class, $build) = @_; + + #@ARGV should override what's in .makepl_args.mod_perl2 + #but @ARGV might also override the default MP_OPTS_FILE + #so snag that first + parse($build, [grep { /^MP_OPTIONS_FILE/ } @ARGV]); + parse_file($build); + parse_argv($build); + + # if AP_PREFIX is used apxs and apr-config from the apache build + # tree won't work, so it can't co-exist with APXS and APR_CONFIG + # options + if ($build->{MP_AP_PREFIX} and $build->{MP_APXS}) { + error "You need to pass either MP_AP_PREFIX or MP_APXS, but not both"; + die "\n"; + } + if ($build->{MP_AP_PREFIX} and $build->{MP_APR_CONFIG}) { + error "You need to pass either MP_AP_PREFIX or MP_APR_CONFIG, " . + "but not both"; + die "\n"; + } + + if ($build->{MP_DEBUG} and $build->{MP_USE_GTOP} and !$build->find_gtop) { + error "Can't find libgtop, resetting MP_USE_GTOP=0"; + $build->{MP_USE_GTOP} = 0; + } + + unless ($build->{MP_USE_DSO} or $build->{MP_USE_STATIC}) { + # default to DSO + $build->{MP_USE_DSO} = 1; + } + + $build->{MP_GENERATE_XS} = 1 unless exists $build->{MP_GENERATE_XS}; + + # define MP_COMPAT_1X unless explicitly told to disable it + $build->{MP_COMPAT_1X} = 1 + unless exists $build->{MP_COMPAT_1X} && !$build->{MP_COMPAT_1X}; + + # try to find apxs + if (!$build->{MP_AP_PREFIX} && !$build->{MP_APXS}) { + $build->find_apxs_util(); + + # make a last ditch effort to find apxs in $ENV{PATH} + if (!$build->{MP_APXS}) { + my @paths = split(/$Config::Config{path_sep}/, $ENV{PATH}); + my $potential_apxs; + while (!$potential_apxs) { + last if scalar(@paths) == 0; # don't loop endlessly + $potential_apxs = File::Spec->catfile(shift @paths, 'apxs'); + $potential_apxs .= '.bat' if Apache2::Build::WIN32(); + if (-e $potential_apxs && -x $potential_apxs) { + $build->{MP_APXS} = $potential_apxs; + } else { + undef $potential_apxs; + } + } + } + } +} + +sub parse { + my ($build, $lines, $opts) = @_; + + $opts = VERBOSE|UNKNOWN_FATAL unless defined $opts; + my $table = table(); + my @unknown; + my $continue = ""; + + my @data = (); + for (@$lines) { + chomp; + s/^\s+//; s/\s+$//; + next if /^\#/ || /^$/; + last if /^__END__/; + + # more than one entry on the same line (but make sure to leave + # -DMP_* alone) + push @data, split /(?=\WMP_)/, $_; + } + + for (@data) { + #XXX: this "parser" should be more robust + + s/^\s+//; s/\s+$//; + + $_ = "$continue $_" if $continue; + + #example: +"MP_CCOPTS=-Werror" if $] >= 5.007 + if (s/^\+//) { + $_ = eval $_; + } + + if (/^MP_/) { + my ($key, $val) = split $param_qr, $_, 2; + $val ||= "" unless defined $val && $val eq '0'; + $continue = $val =~ s/\\$// ? $key : ""; + + if (!$table->{$key} and $opts & UNKNOWN_FATAL) { + my $usage = usage(); + die "Unknown Option: $key\nUsage:\n$usage\n"; + } + + if ($key eq 'MP_APXS') { + $val = File::Spec->canonpath(File::Spec->rel2abs($val)); + } + + if ($key eq 'MP_AP_PREFIX') { + $val = File::Spec->canonpath(File::Spec->rel2abs($val)); + + if (Apache2::Build::WIN32()) { + # MP_AP_PREFIX may not contain spaces + require Win32; + $val = Win32::GetShortPathName($val); + } + + if (!$val || !-d $val) { + error "MP_AP_PREFIX must point to a valid directory."; + die "\n"; + } + } + + if ($table->{$key}->{append}){ + $build->{$key} = join " ", grep $_, $build->{$key}, $val; + } + else { + $build->{$key} = $val; + } + + print " $key = $val\n" if $opts & VERBOSE; + } + else { + push @unknown, $_; + } + } + + return \@unknown; +} + +sub parse_file { + my $build = shift; + + my $fh; + my @dirs = qw(./ ../ ./. ../.); + push @dirs, "$ENV{HOME}/." if exists $ENV{HOME}; + my @files = map { $_ . 'makepl_args.mod_perl2' } @dirs; + unshift @files, $build->{MP_OPTIONS_FILE} if $build->{MP_OPTIONS_FILE}; + + for my $file (@files) { + if (open $fh, $file) { + $build->{MP_OPTIONS_FILE} = $file; + last; + } + $fh = undef; + } + + return unless $fh; + + print "Reading Makefile.PL args from $build->{MP_OPTIONS_FILE}\n"; + my $unknowns = parse($build, [<$fh>]); + push @ARGV, @$unknowns if $unknowns; + + close $fh; +} + +sub parse_argv { + my $build = shift; + return unless @ARGV; + + my @args = @ARGV; + @ARGV = (); + + print "Reading Makefile.PL args from \@ARGV\n"; + my $unknowns = parse($build, \@args); + push @ARGV, @$unknowns if $unknowns; +} + +sub usage { + my $table = table(); + my @opts = map { "$_ - $table->{$_}->{val}" } sort keys %$table; + join "\n", @opts; +} + +sub parse_table { + my ($fh) = @_; + my %table; + local $_; + + while (<$fh>) { + chomp; + s/^\s+//; s/\s+$//; + next if /^\#/ || /^$/; + last if /^__END__/; + my ($key, $append, $val) = split /\s+/, $_, 3; + $table{'MP_' . $key} = { append => $append, val => $val }; + } + + return \%table; +} + +my $Table; + +sub table { + $Table ||= parse_table(\*DATA); +} + +1; + +# __DATA__ format: +# key append description +# where: +# key: is the option name +# append: is whether we want to replace a default option (0) +# or append the arg to the option (1) +# desc: description for this option + +__DATA__ +USE_GTOP 0 Link with libgtop and enable libgtop reporting +DEBUG 0 Turning on debugging (-g -lperld) and tracing +MAINTAINER 0 Maintainer mode: DEBUG=1 -DAP_DEBUG -Wall ... +CCOPTS 1 Add to compiler flags +TRACE 0 Turn on tracing +USE_DSO 0 Build mod_perl as a dso +USE_STATIC 0 Build mod_perl static +PROMPT_DEFAULT 0 Accept default value for all would-be prompts +OPTIONS_FILE 0 Read options from given file +STATIC_EXTS 0 Build Apache2::*.xs as static extensions +APXS 0 Path to apxs +AP_DESTDIR 0 Destination for Apache specific mod_perl bits +AP_PREFIX 0 Apache installation or source tree prefix +AP_CONFIGURE 0 Apache ./configure arguments +APR_CONFIG 0 Path to apr-config +APU_CONFIG 0 Path to apu-config +XS_GLUE_DIR 1 Directories containing extension glue +INCLUDE_DIR 1 Add directories to search for header files +GENERATE_XS 0 Generate XS code based on httpd version +LIBNAME 0 Name of the modperl dso library (default is mod_perl) +COMPAT_1X 0 Compile-time mod_perl 1.0 backcompat (default is on) +APR_LIB 0 Lib used to build APR::* on Win32 (default is aprext) +NO_THREADS 0 Build mod_perl without thread support with httpd >= 2.4
diff --git a/2_0_13/lib/ModPerl/CScan.pm b/2_0_13/lib/ModPerl/CScan.pm new file mode 100644 index 0000000..4985ef0 --- /dev/null +++ b/2_0_13/lib/ModPerl/CScan.pm
@@ -0,0 +1,1010 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package ModPerl::CScan; + +require Exporter; +use Config '%Config'; +use File::Basename; + +# NOTE to distributors: this module is needed only for mp2 developers, +# it's not a requirement for mod_perl users +use Data::Flow qw(0.05); + +use strict; # Earlier it catches ISA and EXPORT. + +@ModPerl::CScan::ISA = qw(Exporter Data::Flow); + +# Items to export into callers namespace by default. Note: do not export +# names by default without a very good reason. Use EXPORT_OK instead. +# Do not simply export all your public functions/methods/constants. + +@ModPerl::CScan::EXPORT = qw( + ); +@ModPerl::CScan::EXPORT_OK = qw( + ); +# this flag tells cpp to only output macros +$ModPerl::CScan::MACROS_ONLY = '-dM'; + +$ModPerl::CScan::VERSION = '0.75'; + +my (%keywords,%style_keywords); +for (qw(asm auto break case char continue default do double else enum + extern float for fortran goto if int long register return short + sizeof static struct switch typedef union unsigned signed while void volatile)) { + $keywords{$_}++; +} +for (qw(bool class const delete friend inline new operator overload private + protected public virtual)) { + $style_keywords{'C++'}{$_}++; +} +for (qw(__func__ _Complex _Imaginary _Bool inline restrict)) { + $style_keywords{'C9X'}{$_}++; +} +for (qw(inline const asm noreturn section + constructor destructor unused weak)) { + $style_keywords{'GNU'}{$_}++; + $style_keywords{'GNU'}{"__$ {_}__"}++; +} + $style_keywords{'GNU'}{__attribute__}++; + $style_keywords{'GNU'}{__extension__}++; + $style_keywords{'GNU'}{__consts}++; + $style_keywords{'GNU'}{__const}++; + $style_keywords{'GNU'}{__restrict}++; + +my $recipes + = { Defines => { default => '' }, + cppstdin => { default => $Config{cppstdin} }, + cppflags => { default => $Config{cppflags} }, + cppminus => { default => $Config{cppminus} }, + c_styles => { default => [qw(C++ GNU C9X)] }, + add_cppflags => { default => '' }, + keywords => { prerequisites => ['c_styles'], + output => sub { + my %kw = %keywords; + my %add; + for ( @{ shift->{c_styles} } ) { + %add = %{ $style_keywords{$_} }; + %kw = (%kw, %add); + } + \%kw; + }, }, + 'undef' => { default => undef }, + filename_filter => { default => undef }, + full_text => { class_filter => [ 'text', 'C::Preprocessed', + qw(undef filename Defines includeDirs Cpp)] }, + text => { class_filter => [ 'text', 'C::Preprocessed', + qw(filename_filter filename Defines includeDirs Cpp)] }, + text_only_from => { class_filter => [ 'text_only_from', 'C::Preprocessed', + qw(filename_filter filename Defines includeDirs Cpp)] }, + includes => { filter => [ \&includes, + qw(filename Defines includeDirs Cpp) ], }, + includeDirs => { prerequisites => ['filedir'], + output => sub { + my $data = shift; + [ $data->{filedir}, '/usr/local/include', '.']; + } }, + Cpp => { prerequisites => [qw(cppminus add_cppflags cppflags cppstdin)], + output => sub { + my $data = shift; + return { cppstdin => $data->{cppstdin}, + cppflags => "$data->{cppflags} $data->{add_cppflags}", + cppminus => $data->{cppminus} }; + } }, + filedir => { output => sub { dirname ( shift->{filename} || '.' ) } }, + sanitized => { filter => [ \&sanitize, 'text'], }, + toplevel => { filter => [ \&top_level, 'sanitized'], }, + full_sanitized => { filter => [ \&sanitize, 'full_text'], }, + full_toplevel => { filter => [ \&top_level, 'full_sanitized'], }, + no_type_decl => { filter => [ \&remove_type_decl, 'toplevel'], }, + typedef_chunks => { filter => [ \&typedef_chunks, 'full_toplevel'], }, + struct_chunks => { filter => [ \&struct_chunks, 'full_toplevel'], }, + typedefs_whited => { filter => [ \&typedefs_whited, + 'full_sanitized', 'typedef_chunks', + 'keywords_rex'], }, + typedef_texts => { filter => [ \&typedef_texts, + 'full_text', 'typedef_chunks'], }, + struct_texts => { filter => [ \&typedef_texts, + 'full_text', 'struct_chunks'], }, + typedef_hash => { filter => [ \&typedef_hash, + 'typedef_texts', 'typedefs_whited'], }, + typedef_structs => { filter => [ \&typedef_structs, + 'typedef_hash', 'struct_texts'], }, + typedefs_maybe => { filter => [ sub {[keys %{+shift}]}, + 'typedef_hash'], }, + defines_maybe => { filter => [ \&defines_maybe, 'filename'], }, + defines_no_args => { prerequisites => ['defines_maybe'], + output => sub { shift->{defines_maybe}->[0] }, }, + defines_args => { prerequisites => ['defines_maybe'], + output => sub { shift->{defines_maybe}->[1] }, }, + + defines_full => { filter => [ \&defines_full, + qw(filename Defines includeDirs Cpp) ], }, + defines_no_args_full => { prerequisites => ['defines_full'], + output => sub { shift->{defines_full}->[0] }, }, + defines_args_full => { prerequisites => ['defines_full'], + output => sub { shift->{defines_full}->[1] }, }, + + decl_inlines => { filter => [ \&functions_in, 'no_type_decl'], }, + inline_chunks => { filter => [ sub { shift->[0] }, 'decl_inlines'], }, + inlines => { filter => [ \&from_chunks, 'inline_chunks', 'text'], }, + decl_chunks => { filter => [ sub { shift->[1] }, 'decl_inlines'], }, + decls => { filter => [ \&from_chunks, 'decl_chunks', 'text'], }, + fdecl_chunks => { filter => [ sub { shift->[4] }, 'decl_inlines'], }, + fdecls => { filter => [ \&from_chunks, 'fdecl_chunks', 'text'], }, + mdecl_chunks => { filter => [ sub { shift->[2] }, 'decl_inlines'], }, + mdecls => { filter => [ \&from_chunks, 'mdecl_chunks', 'text'], }, + vdecl_chunks => { filter => [ sub { shift->[3] }, 'decl_inlines'], }, + vdecls => { filter => [ \&from_chunks, 'vdecl_chunks', 'text'], }, + vdecl_hash => { filter => [ \&vdecl_hash, 'vdecls', 'mdecls' ], }, + parsed_fdecls => { filter => [ \&do_declarations, 'fdecls', + 'typedef_hash', 'keywords'], }, + parsed_inlines => { filter => [ \&do_declarations, 'inlines', + 'typedef_hash', 'keywords'], }, + keywords_rex => { filter => [ sub { my @k = keys %{ shift() }; + local $" = '|'; + my $r = "(?:@k)"; + eval 'qr/$r/' or $r # Older Perls + }, 'keywords'], }, + }; + +sub from_chunks { + my $chunks = shift; + my $txt = shift; + my @out; + my $i = 0; + while ($i < @$chunks) { + push @out, substr $txt, $chunks->[$i], $chunks->[ $i + 1 ] - $chunks->[$i]; + $i += 2; + } + \@out; +} + +#sub process { request($recipes, @_) } +# Preloaded methods go here. + +sub includes { + my %seen; + my $stream = new C::Preprocessed (@_) + or die "Cannot open pipe from cppstdin: $!\n"; + + while (<$stream>) { + next unless m(^\s*\#\s* # Leading hash + (line\s*)? # 1: Optional line + ([0-9]+)\s* # 2: Line number + (.*) # 3: The rest + )x; + my $include = $3; + $include = $1 if $include =~ /"(.*)"/; # Filename may be in quotes + $include =~ s,\\\\,/,g if $^O eq 'os2'; + $seen{$include}++ if $include ne ""; + } + [keys %seen]; +} + +sub defines_maybe { + my $file = shift; + my ($mline,$line,%macros,%macrosargs,$sym,$args); + open(C, $file) or die "Cannot open file $file: $!\n"; + while (not eof(C) and $line = <C>) { + next unless + ( $line =~ s[ + ^ \s* \# \s* # Start of directive + define \s+ + (\w+) # 1: symbol + (?: + \( (.*?) \s* \) # 2: Minimal match for arguments + # in parenths (without trailing + # spaces) + )? # optional, no grouping + \s* # rest is the definition + ([\s\S]*) # 3: the rest + ][]x ); + ($sym, $args, $mline) = ($1, $2, $3); + $mline .= <C> while not eof(C) and $mline =~ s/\\\n/\n/; + chomp $mline; + #print "sym: `$sym', args: `$args', mline: `$mline'\n"; + if (defined $args) { + $macrosargs{$sym} = [ [split /\s*,\s*/, $args], $mline]; + } else { + $macros{$sym} = $mline; + } + } + close(C) or die "Cannot close file $file: $!\n"; + [\%macros, \%macrosargs]; +} + +sub defines_full { + my $Cpp = $_[3]; + my ($mline,$line,%macros,%macrosargs,$sym,$args); + + # save the old cppflags and add the flag for only ouputting macro definitions + my $old_cppstdin = $Cpp->{'cppstdin'}; + $Cpp->{'cppstdin'} = $old_cppstdin . " " . $ModPerl::CScan::MACROS_ONLY; + + my $stream = new C::Preprocessed (@_) + or die "Cannot open pipe from cppstdin: $!\n"; + + while (defined ($line = <$stream>)) { + next unless + ( $line =~ s[ + ^ \s* \# \s* # Start of directive + define \s+ + (\w+) # 1: symbol + (?: + \( (.*?) \s* \) # 2: Minimal match for arguments + # in parenths (without trailing + # spaces) + )? # optional, no grouping + \s* # rest is the definition + ([\s\S]*) # 3: the rest + ][]x ); + ($sym, $args, $mline) = ($1, $2, $3); + $mline .= <$stream> while ($mline =~ s/\\\n/\n/); + chomp $mline; +#print STDERR "sym: `$sym', args: `$args', mline: `$mline'\n"; + if (defined $args) { + $macrosargs{$sym} = [ [split /\s*,\s*/, $args], $mline]; + } else { + $macros{$sym} = $mline; + } + } + # restore the original cppflags + $Cpp->{'cppstdin'} = $old_cppstdin; + [\%macros, \%macrosargs]; +} + +sub typedef_chunks { # Input is toplevel, output: starts and ends + my $txt = shift; + pos $txt = 0; + my ($b, $e, @out); + while ($txt =~ /\btypedef\b/g) { + push @out, pos $txt; + $txt =~ /(?=;)|\Z/g; + push @out, pos $txt; + } + \@out; +} + +sub struct_chunks { + my $txt = shift; + pos $txt = 0; + my ($b, $e, @out); + while ($txt =~ /\b(?=struct\s*(\w*\s*)?\{)/g) { + push @out, pos $txt; + $txt =~ /(?=;)|\Z/g; + push @out, pos $txt; + } + \@out; +} + +sub typedefs_whited { # Input is sanitized text, and list of beg/end. + my @lst = @{$_[1]}; + my @out; + my ($b, $e); + while ($b = shift @lst) { + $e = shift @lst; + push @out, whited_decl($_[2], substr $_[0], $b, $e - $b); + } + \@out; +} + +sub structs_whited { + my @lst = @{$_[1]}; + my @out; + my ($b, $e, $in); + while ($b = shift @lst) { + $e = shift @lst; + $in = substr $_[0], $b, $e - $b; + $in =~ s/^(struct\s*(\w*\s*)?)(.*)$/$1 . " " x length($3)/es; + push @out, $in; + } + \@out; +} + +sub typedef_texts { + my ($txt, $chunks) = (shift, shift); + my ($b, $e, $in, @out); + my @in = @$chunks; + while (($b, $e) = splice @in, 0, 2) { + $in = substr($txt, $b, $e - $b); + # remove any remaining directives + $in =~ s/^ ( \s* \# .* ( \\ $ \n .* )* ) / ' ' x length($1)/xgem; + push @out, $in; + } + \@out; +} + +sub typedef_hash { + my ($typedefs, $whited) = (shift,shift); + my %out; + + loop: + for my $o (0..$#$typedefs) { + my $wh = $whited->[$o]; + my $td = $typedefs->[$o]; +#my $verb = $td =~ /apr_child_errfn_t/ ? 1 : 0; +#warn "$wh || $td\n" if $verb; + if ($wh =~ /,/ or not $wh =~ /\w/) { # Hard case, guessimates ... + # Determine whether the new thingies are inside parens + $wh =~ /,/g; + my $p = pos $wh; + my ($s, $e); + if (matchingbrace($wh)) { # Inside. Easy part: just split on /,/... + $e = pos($wh) - 1; + $s = $e; + my $d = 0; + # Skip back + while (--$s >= 0) { + my $c = substr $wh, $s, 1; + if ($c =~ /[\(\{\[]/) { + $d--; + } elsif ($c =~ /[\)\]\}]/) { + $d++; + } + last if $d < 0; + } + if ($s < 0) { # Should not happen + warn("panic: could not match braces in\n\t$td\nwhited as\n\t$wh\n"); + next loop; + } + $s++; + } else { # We are at toplevel + # We need to skip back all the modifiers attached to the first thingy + # Guesstimates: everything after the first '*' (inclusive) + pos $wh = 0; + $wh = /(?=\w)/g; + my $ws = pos $wh; + my $pre = substr $wh, 0, $ws; + $s = $ws; + $s = pos $pre if $pre =~ /(?=\*)/g; + $e = length $wh; + } + # Now: need to split $td based on commas in $wh! + # And need to split each chunk of $td based on word in the chunk of $wh! + my $td_decls = substr($td, $s, $e - $s); + my ($pre, $post) = (substr($td, 0, $s), substr($td, $e)); + my $wh_decls = substr($wh, $s, $e - $s); + my @wh_decls = split /,/, $wh_decls; + my $td_s = 0; + my (@td_decl, @td_pre, @td_post, @td_word); + for my $wh_d (@wh_decls) { + my $td_d = substr $td, $td_s, length $wh_d; + push @td_decl, $td_d; + $wh_d =~ /(\w+)/g; + push @td_word, $1; + push @td_post, substr $td_d, pos($wh_d); + push @td_pre, substr $td_d, pos($wh_d) - length $1, length $1; + $td_s += 1 + length $wh_d; # Skip over ',' + } + for my $i (0..$#wh_decls) { + my $p = "$td_post[$i]$post"; + $p = '' unless $p =~ /\S/; + $out{$td_word[$i]} = ["$pre$td_pre[$i]", $p]; + } + } elsif ($td =~ /\(\s* \*? \s* ([^)]+) \s* \) \s* \(.*\)/gxs){ # XXX: function pointer typedef + $out{$1} = ['XXX: pre_foo', 'XXX: post_bar']; # XXX: not sure what to stuff here + #warn "[$1] [$td]" if $verb; + } else { # Only one thing defined... + $wh =~ /(\w+)/g; + my $e = pos $wh; + my $s = $e - length $1; + my $type = $1; + my $pre = substr $td, 0, $s; + my $post = substr $td, $e, length($td) - $e; + $post = '' unless $post =~ /\S/; + $out{$type} = [$pre, $post]; + } + + #die if $verb; + + } + \%out; +} + +sub typedef_structs { + my ($typehash, $structs) = @_; + my %structs; + for (0 .. $#$structs) { + my $in = $structs->[$_]; + my $key; + next unless $in =~ /^struct\s*(\w+)/; + next unless $in =~ s{^(struct\s*)(\w+)}{ + $key = "struct $2"; + $1 . " " x length($2) + }e; + my $name = parse_struct($in, \%structs); + $structs{$key} = defined($name) ? $structs{$name} : undef; + } + while (my ($key, $text) = each %$typehash) { + my $name = parse_struct($text->[0], \%structs); + $structs{$key} = defined($name) ? $structs{$name} : undef; + } + \%structs; +} + +sub parse_struct { + my ($in, $structs) = @_; + my ($b, $e, $chunk, $vars, $struct, $structname); + return "$1 $2" if $in =~ / + ^ \s* (struct | union) \s+ (\w+) \s* $ + /x; + ($structname, $in) = $in =~ / + ^ \s* ( (?: struct | union ) (?: \s+ \w+ )? ) \s* { \s* (.*?) \s* } \s* $ + /gisx or return; + $structname .= " _ANON" unless $structname =~ /\s/; + $structname .= " 0" if exists $structs->{$structname}; + $structname =~ s/(\d+$)/$1 + 1/e while exists $structs->{$structname}; + $structname =~ s/\s+/ /g; + $b = 0; + while ($in =~ /(\{|;|$)/g) { + matchingbrace($in), next if $1 eq '{'; + $e = pos($in); + next if $b == $e; + $chunk = substr($in, $b, $e - $b); + $b = $e; + if ($chunk =~ /\G\s*(struct|union|enum).*\}/gs) { + my $term = pos $chunk; + my $name = parse_struct(substr($chunk, 0, $term), $structs); + $vars = parse_vars(join ' ', $name, substr $chunk, $term); + } else { + $vars = parse_vars($chunk); + } + push @$struct, @{$vars||[]}; + } + $structs->{$structname} = $struct; + $structname; +} + +sub parse_vars { + my $in = shift; + my ($vars, $type, $word, $id, $post, $func); + + while ($in =~ /\G\s*([\[;,(]|\*+|:\s*\d+|\S+?\b|$)\s*/gc) { + $word = $1; + if ($word eq ';' || $word eq '') { + next unless defined $id; + $type = 'int' unless defined $type; # or is this an error? + push @$vars, [ $type, $post, $id ]; + ($type, $post, $id, $func) = (undef, undef, undef); + } elsif ($word eq ',') { + warn "panic: expecting name before comma in '$in'\n" unless defined $id; + $type = 'int' unless defined $type; # or is this an error? + push @$vars, [ $type, $post, $id ]; + $type =~ s/[ *]*$//; + $id = undef; + } elsif ($word eq '[') { + warn "panic: expecting name before '[' in '$in'\n" unless defined $id; + $type = 'int' unless defined $type; # or is this an error? + my $b = pos $in; + matchingbrace($in); + $post .= $word . substr $in, $b, pos($in) - $b; + } elsif ($word eq '(') { + # simple hack for function pointers + $type = join ' ', grep defined, $type, $id if defined $id; + $type = 'int' unless defined $type; + if ($in =~ /\G\s*(\*[\s\*]*?)\s*(\w+)[\[\]\d\s]*(\)\s*\()/gc) { + $type .= "($1"; + $id = $2; + $post = $3; + my $b = pos $in; + matchingbrace($in); + $post .= substr $in, $b, pos($in) - $b; + } else { + warn "panic: can't parse function pointer declaration in '$in'\n"; + return; + } + } elsif ($word =~ /^:/) { + # bitfield + $type = 'int' unless defined $type; + $post .= $word; + } else { + if (defined $post) { + if ($func) { + $post .= $word; + } else { + warn "panic: not expecting '$word' after array bounds in '$in'\n"; + } + } else { + $type = join ' ', grep defined, $type, $id if defined $id; + $id = $word; + } + } + } +unless ($vars) { + warn sprintf "failed on <%s> with type=<%s>, id=<%s>, post=<%s> at pos=%d\n", + $in, $type, $id, $post, pos($in); +} + $vars; +} + +sub vdecl_hash { + my ($vdecls, $mdecls) = @_; + my %vdecl_hash; + for (@$vdecls, @$mdecls) { + next if /[()]/; # ignore functions, and function pointers + my $copy = $_; + next unless $copy =~ s/^\s*extern\s*//; + my $vars = parse_vars($copy); + $vdecl_hash{$_->[2]} = [ @$_[0, 1] ] for @$vars; + } + \%vdecl_hash; +} + +# The output is the list of list of inline chunks and list of +# declaration chunks. + +sub functions_in { # The arg is text without type declarations. + my $in = shift; # remove_type_decl(top_level(sanitize($txt))); + # What remains now consists of variable and function declarations, + # and inline functions. + $in =~ /(?=\S)/g; + my ($b, $e, $b1, $e1, @inlines, @decls, @mdecls, @fdecls, @vdecls); + $b = pos $in; + my $chunk; + while (defined($b) && $b != length $in) { + $in =~ /;/g or pos $in = $b, $in =~ /.*\S|\Z/g ; # Or last non-space + $e = pos $in; + $chunk = substr $in, $b, $e - $b; + # Now subdivide the chunk. + # + # What we got is one chunk, probably finished by `;'. Whoever, it + # may start with several inline functions. + # + # Note that inline functions contain ( ) { } in the stripped version. + $b1 = 0; + while ($chunk =~ /\(\s*\)\s*\{\s*\}/g) { + $e1 = pos $chunk; + push @inlines, $b + $b1, $b + $e1; + $chunk =~ /(?=\S)/g; + $b1 = pos $chunk; + $b1 = length $chunk, last unless defined $b1; + } + if ($e - $b - $b1 > 0) { + my ($isvar, $isfunc) = (1, 1); + substr ($chunk, 0, $b1) = ''; + if ($chunk =~ /,/) { # Contains multiple declarations. + push @mdecls, $b + $b1, $e; + } else { # Non-multiple. + # Since leading \s* is not optimized, this is quadratic! + $chunk =~ s{ + ( ( const | __const + | __attribute__ \s* \( \s* \) + ) \s* )* ( ; \s* )? \Z # Strip from the end + }()x; + $chunk =~ s/\s*\Z//; + if ($chunk =~ /\)\Z/) { # Function declaration ends on ")"! + if ($chunk !~ m{ + \( .* \( # Multiple parenths + }x + and $chunk =~ / \w \s* \( /x) { # Most probably pointer to a function? + $isvar = 0; + } + } elsif ($chunk =~ / + ^ \s* (enum|struct|union|class) \s+ \w+ \s* $ + /x) { + $isvar = $isfunc = 0; + } + if ($isvar) { # Heuristically variable + push @vdecls, $b + $b1, $e; + } elsif ($isfunc) { + push @fdecls, $b + $b1, $e; + } + } + push @decls, $b + $b1, $e if $isvar || $isfunc; + } + $in =~ /\G\s*/g ; + $b = pos $in; + } + [\@inlines, \@decls, \@mdecls, \@vdecls, \@fdecls]; +} + +# XXXX This is heuristical in many respects... +# Recipe: remove all struct-ish chunks. Remove all array specifiers. +# Remove GCC attribute specifiers. +# What remains may contain function's arguments, old types, and newly +# defined types. +# Remove function arguments using heuristics methods. +# Now out of several words in a row the last one is a newly defined type. + +sub whited_decl { # Input is sanitized. + my $keywords_rex = shift; + my $in = shift; # Text of a declaration + + #typedef ret_type*(*func) -> typedef ret_type* (*func) + $in =~ s/\*\(\*/* \(*/; + + my $rest = $in; + my $out = $in; # Whited out $in + + # Remove all the structs + while ($out =~ /(\b(struct|union|class|enum)(\s+\w+)?\s*\{)/g) { + my $pos_start = pos($out) - length $1; + + matchingbrace($out); + my $pos_end = pos $out; + substr($out, $pos_start, $pos_end - $pos_start) = + ' ' x ($pos_end - $pos_start); + pos $out = $pos_end; + } + + # Deal with glibc's wierd ass __attribute__ tag. Just dump it. + # Maaaybe this should check to see if you're using GCC, but I don't + # think so since glibc is nice enough to do that for you. [MGS] + while ( $out =~ m/(\b(__attribute__|attribute)\s*\((?=\s*\())/g ) { + my $att_pos_start = pos($out) - length($1); + + # Need to figure out where ((..)) ends. + matchingbrace($out); + my $att_pos_end = pos $out; + + # Remove the __attribute__ tag. + substr($out, $att_pos_start, $att_pos_end - $att_pos_start) = + ' ' x ($att_pos_end - $att_pos_start); + pos $out = $att_pos_end; + } + + # Remove arguments of functions (heuristics only). + # These things (start) arglist of a declared function: + # paren word comma + # paren word space non-paren + # paren keyword paren + # start a list of arguments. (May be "cdecl *myfunc"?) XXXXX ????? + while ( $out =~ /(\(\s*(\w+(,|\s*[^\)\s])|$keywords_rex\s*\)))/g ) { + my $pos_start = pos($out) - length($1); + pos $out = $pos_start + 1; + matchingbrace($out); + substr ($out, $pos_start + 1, pos($out) - 2 - $pos_start) + = ' ' x (pos($out) - 2 - $pos_start); + } + # Remove array specifiers + $out =~ s/(\[[\w\s\+]*\])/ ' ' x length $1 /ge; + my $tout = $out; + # Several words in a row cannot be new typedefs, but the last one. + $out =~ s/((\w+\**\s+)+(?=[^\s,;\[\{\)]))/ ' ' x length $1 /ge; + unless ($out =~ /\w/) { + # Probably a function-type declaration: typedef int f(int); + # Redo scan leaving the last word of the first group of words: + if ($tout =~ /(\w+\s+)*(\w+)\s*\(/g) { + $out = ' ' x (pos($tout) - length $2) + . $2 . ' ' x (length($tout) - pos($tout)); + } + else { + # try a different approach to get the last type + my $len = length $tout; + # cut all non-words at the end of the definition + my $end = $tout =~ s/(\W*)$// ? length $1 : 0; + # remove everything but the last word + my $mid = $tout =~ s/.*?(\w*)$/$1/ ? length $1 : 0; + # restore the length + $out = $tout . ' ' x ($len - $mid); + } + # warn "function typedef\n\t'$in'\nwhited-out as\n\t'$out'\n"; + } + warn "panic: length mismatch\n\t'$in'\nwhited-out as\n\t'$out'\n" + if length($in) != length $out; + # Sanity check + warn "panic: multiple types without intervening comma in\n\t'$in'\nwhited-out as\n\t'$out'\n" + if $out =~ /\w[^\w,]+\w/; + warn "panic: no types found in\n\t'$in'\nwhited-out as\n\t'$out'\n" + unless $out =~ /\w/; + $out +} + +sub matchingbrace { + # pos($_[0]) is after the opening brace now + my $n = 0; + while ($_[0] =~ /([\{\[\(])|([\]\)\}])/g) { + $1 ? $n++ : $n-- ; + return 1 if $n < 0; + } + # pos($_[0]) is after the closing brace now + return; # false +} + +sub remove_Comments_no_Strings { # We expect that no strings are around + my $in = shift; + $in =~ s,/(/.*|\*[\s\S]*?\*/),,g ; # C and C++ + die "Unfinished comment" if $in =~ m,/\*, ; + $in; +} + +sub sanitize { # We expect that no strings are around + my $in = shift; + # C and C++, strings and characters + $in =~ s{ / ( + / .* # C++ style + | + \* [\s\S]*? \*/ # C style + ) # (1) + | '((?:[^\\\']|\\.)+)' # (2) Character constants + | "((?:[^\\\"]|\\.)*)" # (3) Strings + | ( ^ \s* \# .* # (4) Preprocessor + ( \\ $ \n .* )* ) # and continuation lines + } { + # We want to preserve the length, so that one may go back + defined $1 ? ' ' x (1 + length $1) : + defined $4 ? ' ' x length $4 : + defined $2 ? "'" . ' ' x length($2) . "'" : + defined $3 ? '"' . ' ' x length($3) . '"' : '???' + }xgem ; + die "Unfinished comment" if $in =~ m{ /\* }x; + $in; +} + +sub top_level { # We expect argument is sanitized + # Note that this may remove the variable in declaration: int (*func)(); + my $in = shift; + my $start; + my $out = $in; + while ($in =~ /[\[\{\(]/g ) { + $start = pos $in; + matchingbrace($in); + substr($out, $start, pos($in) - 1 - $start) + = ' ' x (pos($in) - 1 - $start); + } + $out; +} + +sub remove_type_decl { # We suppose that the arg is top-level only. + my $in = shift; + $in =~ s/(\b__extension__)(\s+typedef\b)/(' ' x length $1) . $2/gse; + $in =~ s/(\btypedef\b.*?;)/' ' x length $1/gse; + # The following form may appear only in the declaration of the type itself: + $in =~ + s/(\b(enum|struct|union|class)\b[\s\w]*\{\s*\}\s*;)/' ' x length $1/gse; + $in; +} + +sub new { + my $class = shift; + my $out = SUPER::new $class $recipes; + $out->set(@_); + $out; +} + +sub do_declarations { + my @d = map do_declaration($_, $_[1], $_[2]), @{ $_[0] }; + \@d; +} + +# Forth argument: if defined, there maybe no identifier. Generate one +# basing on this argument. + +sub do_declaration { + my ($decl, $typedefs, $keywords, $argnum) = @_; + $decl =~ s/;?\s*$//; + + my ($type, $typepre, $typepost, $ident, $args, $w, $pos, $repeater); + $decl =~ s/[\r\n]\s*/ /g; +#warn "DECLAR [$decl][$argnum]\n"; + $decl =~ s/^\s*__extension__\b\s*//; + $decl =~ s/^\s*extern\b\s*//; + $decl =~ s/^\s*__inline\b\s*//; + $pos = 0; + while ($decl =~ /(\w+)/g and ($typedefs->{$1} or $keywords->{$1})) { + $w = $1; + if ($w =~ /^(struct|class|enum|union)$/) { + $decl =~ /\G\s+\w+/g or die "`$w' is not followed by word in `$decl'"; + } + $pos = pos $decl; + } +#warn "pos: $pos\n"; + pos $decl = $pos; + $decl =~ /\G[\s*]*\*/g or pos $decl = $pos; + $type = substr $decl, 0, pos $decl; + $decl =~ /\G\s*/g or pos $decl = length $type; # ???? + $pos = pos $decl; +#warn "pos: $pos\n"; + if (defined $argnum) { + if ($decl =~ /\G(\w+)((\s*\[[^][]*\])*)/g) { # The best we can do with [2] + $ident = $1; + $repeater = $2; + $pos = pos $decl; + } else { + pos $decl = $pos = length $decl; + $type = $decl; + $ident = "arg$argnum"; + } + } else { + die "Cannot process declaration `$decl' without an identifier" + unless $decl =~ /\G(\w+)/g; + $ident = $1; + $pos = pos $decl; + } +#warn "pos: $pos\n"; + $decl =~ /\G\s*/g or pos $decl = $pos; + $pos = pos $decl; +#my $st = length $decl; +#warn substr($decl, 0, $pos), "\n"; +#warn "pos: $pos $st\n"; +#warn "DECLAR [$decl][$argnum]\n"; + if (pos $decl != length $decl) { + pos $decl = $pos; + die "Expecting parenth after identifier in `$decl'\nafter `", + substr($decl, 0, $pos), "'" + unless $decl =~ /\G\(/g; + my $argstring = substr($decl, pos($decl) - length $decl); + matchingbrace($argstring) or die "Cannot find matching parenth in `$decl'"; + $argstring = substr($argstring, 0, pos($argstring) - 1); + $argstring =~ s/ ^ ( \s* void )? \s* $ //x; + $args = []; + my @args; + if ($argstring ne '') { + my $top = top_level $argstring; + my $p = 0; + my $arg; + while ($top =~ /,/g) { + $arg = substr($argstring, $p, pos($top) - 1 - $p); + $arg =~ s/^\s+|\s+$//gs; + push @args, $arg; + $p = pos $top; + } + $arg = substr $argstring, $p; + $arg =~ s/^\s+|\s+$//gs; + push @args, $arg; + } + my $i = 0; + for (@args) { + push @$args, do_declaration1($_, $typedefs, $keywords, $i++); + } + } + [$type, $ident, $args, $decl, $repeater]; +} + +sub do_declaration1 { + my ($decl, $typedefs, $keywords, $argnum) = @_; + $decl =~ s/;?\s*$//; +#warn "DECLARO [$decl][$argnum]\n"; + my ($type, $typepre, $typepost, $ident, $args, $w, $pos, $repeater); + $pos = 0; + while ($decl =~ /(\w+)/g and ($typedefs->{$1} or $keywords->{$1})) { + $w = $1; + if ($w =~ /^(struct|class|enum|union)$/) { + $decl =~ /\G\s+\w+/g or die "`$w' is not followed by word in `$decl'"; + } + $pos = pos $decl; + } +#warn "POS: $pos\n"; + pos $decl = $pos; + $decl =~ /\G[\s*]*\*/g or pos $decl = $pos; + $type = substr $decl, 0, pos $decl; + $decl =~ /\G\s*/g or pos $decl = length $type; # ???? + $pos = pos $decl; + if (defined $argnum) { + if ($decl =~ /\G(\w+)((\s*\[[^][]*\])*)/g) { # The best we can do with [2] + $ident = $1; + $repeater = $2; + $pos = pos $decl; + } else { + pos $decl = $pos = length $decl; + $type = $decl; + $ident = "arg$argnum"; + } + } else { + die "Cannot process declaration `$decl' without an identifier" + unless $decl =~ /\G(\w+)/g; + $ident = $1; + $pos = pos $decl; + } + $decl =~ /\G\s*/g or pos $decl = $pos; + $pos = pos $decl; +#warn "DECLAR1 [$decl][$argnum]\n"; +#my $st = length $decl; +#warn substr($decl, 0, $pos), "\n"; +#warn "pos: $pos $st\n"; + if (pos $decl != length $decl) { + pos $decl = $pos; + die "Expecting parenth after identifier in `$decl'\nafter `", + substr($decl, 0, $pos), "'" + unless $decl =~ /\G\(/g; + my $argstring = substr($decl, pos($decl) - length $decl); + matchingbrace($argstring) or die "Cannot find matching parenth in `$decl'"; + $argstring = substr($argstring, 0, pos($argstring) - 1); + $argstring =~ s/ ^ ( \s* void )? \s* $ //x; + $args = []; + my @args; + if ($argstring ne '') { + my $top = top_level $argstring; + my $p = 0; + my $arg; + while ($top =~ /,/g) { + $arg = substr($argstring, $p, pos($top) - 1 - $p); + $arg =~ s/^\s+|\s+$//gs; + push @args, $arg; + $p = pos $top; + } + $arg = substr $argstring, $p; + $arg =~ s/^\s+|\s+$//gs; + push @args, $arg; + } + my $i = 0; + for (@args) { + push @$args, do_declaration1($_, $typedefs, $keywords, $i++); + } + } + [$type, $ident, $args, $decl, $repeater]; +} + +############################################################ + +package C::Preprocessed; +use Symbol; +use File::Basename; +use Config; +use constant WIN32 => $^O eq 'MSWin32'; + +sub new { + die "usage: C::Preprocessed->new(filename[, defines[, includes[, cpp]]])" + if @_ < 2 or @_ > 5; + my ($class, $filename, $Defines, $Includes, $Cpp) + = (shift, shift, shift, shift, shift); + $Cpp ||= \%Config::Config; + my $filedir = dirname $filename || '.'; + $Includes ||= [$filedir, '/usr/local/include', '.']; + my $addincludes = ""; + $addincludes = "-I" . join(" -I", @$Includes) + if defined $Includes and @$Includes; + my ($sym) = gensym; + my $cmd = WIN32 ? + "$Cpp->{cppstdin} $Defines $addincludes $Cpp->{cppflags} $filename |" : + "echo '\#include \"$filename\"' | $Cpp->{cppstdin} $Defines $addincludes $Cpp->{cppflags} $Cpp->{cppminus} | grep -v '^#' |"; + #my $cmd = "echo '\#include <$filename>' | $Cpp->{cppstdin} $Defines $addincludes $Cpp->{cppflags} $Cpp->{cppminus} |"; + + (open($sym, $cmd) or die "Cannot open pipe from `$cmd': $!") + and bless $sym => $class; +} + +sub text { + my $class = shift; + my $filter = shift; + if (defined $filter) { + return text_only_from($class, $filter, @_); + } + my $stream = $class->new(@_); + my $oh = select $stream; + local $/; + select $oh; + <$stream>; +} + +sub text_only_from { + my $class = shift; + my $from = shift || die "Expecting argument in `text_only_from'"; + my $stream = $class->new(@_); + my $on = $from eq $_[0]; + my $eqregexp = $on ? '\"\"|' : ''; + my @out; + while (<$stream>) { + #print; + + $on = /$eqregexp[\"\/]\Q$from\"/ if /^\#/; + push @out, $_ if $on; + } + join '', @out; +} + +sub DESTROY { + close($_[0]) + or die "Cannot close pipe from `$Config::Config{cppstdin}': err $?, $!\n"; +} + +# Autoload methods go after __END__, and are processed by the autosplit program. +# Return to the principal package. +package ModPerl::CScan; + +1; +__END__ + +=head1 NAME + +ModPerl::CScan - scan C language files for easily recognized constructs. + +=head1 SYNOPSIS + +=head1 DESCRIPTION + +See the C<C::Scan> manpage. This package is just a fork to fix certain +things that didn't work in the original C<C::Scan>, which is not +maintained any longer. These fixes required to make it work with the +Apache 2 source code. + +=cut
diff --git a/2_0_13/lib/ModPerl/Code.pm b/2_0_13/lib/ModPerl/Code.pm new file mode 100644 index 0000000..fa6dfe7 --- /dev/null +++ b/2_0_13/lib/ModPerl/Code.pm
@@ -0,0 +1,1180 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::Code; + +use strict; +use warnings FATAL => 'all'; + +use Config; +use File::Spec::Functions qw(catfile catdir); + +use mod_perl2 (); +use Apache2::Build (); + +use Apache::TestConfig (); +use Apache::TestTrace; + +our $VERSION = '0.01'; +our @ISA = qw(Apache2::Build); + +my %handlers = ( + Process => [qw(ChildInit ChildExit)], #Restart PreConfig + Files => [qw(OpenLogs PostConfig)], + PerSrv => [qw(PostReadRequest Trans MapToStorage)], + PerDir => [qw(HeaderParser + Access Authen Authz + Type Fixup Response Log Cleanup + InputFilter OutputFilter)], + Connection => [qw(ProcessConnection)], + PreConnection => [qw(PreConnection)], +); + +my %hooks = map { $_, canon_lc($_) } + map { @{ $handlers{$_} } } keys %handlers; + +my %not_ap_hook = map { $_, 1 } qw(child_exit response cleanup + output_filter input_filter); + +my %not_request_hook = map { $_, 1 } qw(child_init process_connection + pre_connection open_logs post_config); + +my %hook_proto = ( + Process => { + ret => 'void', + args => [{type => 'apr_pool_t', name => 'p'}, + {type => 'server_rec', name => 's'}, + {type => 'dummy', name => 'MP_HOOK_VOID'}], + }, + Files => { + ret => 'int', + args => [{type => 'apr_pool_t', name => 'pconf'}, + {type => 'apr_pool_t', name => 'plog'}, + {type => 'apr_pool_t', name => 'ptemp'}, + {type => 'server_rec', name => 's'}, + {type => 'dummy', name => 'MP_HOOK_RUN_ALL'}], + }, + PerSrv => { + ret => 'int', + args => [{type => 'request_rec', name => 'r'}, + {type => 'dummy', name => 'MP_HOOK_RUN_ALL'}], + }, + Connection => { + ret => 'int', + args => [{type => 'conn_rec', name => 'c'}, + {type => 'dummy', name => 'MP_HOOK_RUN_FIRST'}], + }, + PreConnection => { + ret => 'int', + args => [{type => 'conn_rec', name => 'c'}, + {type => 'void', name => 'csd'}, + {type => 'dummy', name => 'MP_HOOK_RUN_ALL'}], + }, +); + +my %cmd_push = ( + InputFilter => 'modperl_cmd_push_filter_handlers', + OutputFilter => 'modperl_cmd_push_filter_handlers', +); +my $cmd_push_default = 'modperl_cmd_push_handlers'; +sub cmd_push { + $cmd_push{+shift} || $cmd_push_default; +} + +$hook_proto{PerDir} = $hook_proto{PerSrv}; + +my $scfg_get = 'MP_dSCFG(parms->server)'; + +my $dcfg_get = "$scfg_get;\n" . + ' modperl_config_dir_t *dcfg = (modperl_config_dir_t *)dummy'; + +my %directive_proto = ( + PerSrv => { + args => [{type => 'cmd_parms', name => 'parms'}, + {type => 'void', name => 'dummy'}, + {type => 'const char', name => 'arg'}], + cfg => {get => $scfg_get, name => 'scfg'}, + scope => 'RSRC_CONF', + }, + PerDir => { + args => [{type => 'cmd_parms', name => 'parms'}, + {type => 'void', name => 'dummy'}, + {type => 'const char', name => 'arg'}], + cfg => {get => $dcfg_get, name => 'dcfg'}, + scope => 'OR_ALL', + }, +); + +for my $class (qw(Process Connection PreConnection Files)) { + $directive_proto{$class}->{cfg}->{name} = 'scfg'; + $directive_proto{$class}->{cfg}->{get} = $scfg_get; + + for (qw(args scope)) { + $directive_proto{$class}->{$_} = $directive_proto{PerSrv}->{$_}; + } +} + +while (my ($k,$v) = each %directive_proto) { + $directive_proto{$k}->{ret} = 'const char *'; + my $handlers = join '_', 'handlers', canon_lc($k); + $directive_proto{$k}->{handlers} = + join '->', $directive_proto{$k}->{cfg}->{name}, $handlers; +} + +#XXX: allow disabling of PerDir hooks on a PerDir basis +my @hook_flags = sort(map { canon_uc($_) } keys %hooks); +my @ithread_opts = qw(CLONE PARENT); +my %flags = ( + Srv => ['NONE', @ithread_opts, qw(ENABLE AUTOLOAD MERGE_HANDLERS), + @hook_flags, 'UNSET','INHERIT_SWITCHES'], + Dir => [qw(NONE PARSE_HEADERS SETUP_ENV MERGE_HANDLERS GLOBAL_REQUEST UNSET)], + Req => [qw(NONE SET_GLOBAL_REQUEST PARSE_HEADERS SETUP_ENV + CLEANUP_REGISTERED PERL_SET_ENV_DIR PERL_SET_ENV_SRV)], + Interp => [qw(NONE IN_USE CLONED BASE)], + Handler => [qw(NONE PARSED METHOD OBJECT ANON AUTOLOAD DYNAMIC FAKE)], +); + +$flags{DirSeen} = $flags{Dir}; + +my %flags_options = map { $_,1 } qw(Srv Dir); + +my %flags_field = ( + DirSeen => 'flags->opts_seen', + (map { $_, 'flags->opts' } keys %flags_options), +); + +sub new { + my $class = shift; + bless { + handlers => \%handlers, + hook_proto => \%hook_proto, + directive_proto => \%directive_proto, + flags => \%flags, + path => 'src/modules/perl', + }, $class; +} + +sub path { shift->{path} } + +sub handler_desc { + my ($self, $h_add, $c_add) = @_; + local $" = ",\n"; + foreach my $class (sort keys %{ $self->{handler_index_desc} }) { + my $h = $self->{handler_index_desc}->{$class}; + my $func = canon_func('handler', 'desc', $class); + my $array = join '_', 'MP', $func; + my $proto = "const char *$func(int idx)"; + + $$h_add .= "$proto;\n"; + + $$c_add .= <<EOF; +static const char * $array [] = { +@{ [ map { $_ ? qq( "$_") : ' NULL' } @$h, '' ] } +}; + +$proto +{ + return $array [idx]; +} + +EOF + } +} + +sub generate_handler_index { + my ($self, $h_fh) = @_; + + my $type = 1; + + foreach my $class (sort keys %{ $self->{handlers} }) { + my $handlers = $self->{handlers}->{$class}; + my $i = 0; + my $n = @$handlers; + my $handler_type = canon_define('HANDLER_TYPE', $class); + + print $h_fh "\n#define ", + canon_define('HANDLER_NUM', $class), " $n\n\n"; + + print $h_fh "#define $handler_type $type\n\n"; + + $type++; + + for my $name (@$handlers) { + my $define = canon_define($name, 'handler'); + $self->{handler_index}->{$class}->[$i] = $define; + $self->{handler_index_type}->{$class}->[$i] = $handler_type; + $self->{handler_index_desc}->{$class}->[$i] = "Perl${name}Handler"; + print $h_fh "#define $define $i\n"; + $i++; + } + } +} + +sub generate_handler_hooks { + my ($self, $h_fh, $c_fh) = @_; + + my @register_hooks; + + foreach my $class (sort keys %{ $self->{hook_proto} }) { + my $prototype = $self->{hook_proto}->{$class}; + my $callback = canon_func('callback', $class); + my $return = $prototype->{ret} eq 'void' ? '' : 'return'; + my $i = -1; + + for my $handler (@{ $self->{handlers}{$class} }) { + my $name = canon_func($handler, 'handler'); + $i++; + + if (my $hook = $hooks{$handler}) { + next if $not_ap_hook{$hook}; + + my $order = $not_request_hook{$hook} ? 'APR_HOOK_FIRST' + : 'APR_HOOK_REALLY_FIRST'; + + push @register_hooks, + " ap_hook_$hook($name, NULL, NULL, $order);"; + } + + my ($protostr, $pass) = canon_proto($prototype, $name); + my $ix = $self->{handler_index}->{$class}->[$i]; + + if ($callback =~ m/modperl_callback_per_(dir|srv)/) { + if ($ix =~ m/AUTH|TYPE|TRANS|MAP/) { + $pass =~ s/MP_HOOK_RUN_ALL/MP_HOOK_RUN_FIRST/; + } + } + + print $h_fh "\n$protostr;\n"; + + print $c_fh <<EOF; +$protostr +{ + $return $callback($ix, $pass); +} + +EOF + } + } + + local $" = "\n"; + my $hooks_proto = 'void modperl_register_handler_hooks(void)'; + my $h_add = "$hooks_proto;\n"; + my $c_add = "$hooks_proto {\n@register_hooks\n}\n"; + + $self->handler_desc(\$h_add, \$c_add); + + return ($h_add, $c_add); +} + +sub generate_handler_find { + my ($self, $h_fh, $c_fh) = @_; + + my $proto = 'int modperl_handler_lookup(const char *name, int *type)'; + my (%ix, %switch); + + print $h_fh "$proto;\n"; + + print $c_fh <<EOF; +$proto +{ + if (*name == 'P' && strnEQ(name, "Perl", 4)) { + name += 4; + } + + switch (*name) { +EOF + + foreach my $class (sort keys %{ $self->{handlers} }) { + my $handlers = $self->{handlers}->{$class}; + my $i = 0; + + for my $name (@$handlers) { + $name =~ /^([A-Z])/; + push @{ $switch{$1} }, $name; + $ix{$name}->{name} = $self->{handler_index}->{$class}->[$i]; + $ix{$name}->{type} = $self->{handler_index_type}->{$class}->[$i++]; + } + } + + for my $key (sort keys %switch) { + my $names = $switch{$key}; + print $c_fh " case '$key':\n"; + + #support $r->push_handlers(PerlHandler => ...) + if ($key eq 'H') { + print $c_fh <<EOF; + if (strEQ(name, "Handler")) { + *type = $ix{'Response'}->{type}; + return $ix{'Response'}->{name}; + } +EOF + } + + for my $name (@$names) { + my $n = length($name); + print $c_fh <<EOF; + if (strnEQ(name, "$name", $n)) { + *type = $ix{$name}->{type}; + return $ix{$name}->{name}; + } +EOF + } + } + + print $c_fh " };\n return -1;\n}\n"; + + return ("", ""); +} + +sub generate_handler_directives { + my ($self, $h_fh, $c_fh) = @_; + + my @cmd_entries; + + foreach my $class (sort keys %{ $self->{handlers} }) { + my $handlers = $self->{handlers}->{$class}; + my $prototype = $self->{directive_proto}->{$class}; + my $i = 0; + + for my $h (@$handlers) { + my $h_name = join $h, qw(Perl Handler); + my $name = canon_func('cmd', $h, 'handlers'); + my $cmd_name = canon_define('cmd', $h, 'entry'); + my $protostr = canon_proto($prototype, $name); + my $flag = 'MpSrv' . canon_uc($h); + my $ix = $self->{handler_index}->{$class}->[$i++]; + my $av = "$prototype->{handlers} [$ix]"; + my $cmd_push = cmd_push($h); + + print $h_fh "$protostr;\n"; + + push @cmd_entries, $cmd_name; + + print $h_fh <<EOF; + +#define $cmd_name \\ +AP_INIT_ITERATE("$h_name", $name, NULL, \\ + $prototype->{scope}, "Subroutine name") + +EOF + print $c_fh <<EOF; + +$protostr +{ + $prototype->{cfg}->{get}; + if (!MpSrvENABLE(scfg)) { + return apr_pstrcat(parms->pool, + "Perl is disabled for server ", + parms->server->server_hostname, NULL); + } + if (!$flag(scfg)) { + return apr_pstrcat(parms->pool, + "$h_name is disabled for server ", + parms->server->server_hostname, NULL); + } + MP_TRACE_d(MP_FUNC, "push \@%s, %s", parms->cmd->name, arg); + return $cmd_push(&($av), arg, parms->pool); +} +EOF + } + } + + my $h_add = '#define MP_CMD_ENTRIES \\' . "\n" . join ', \\'."\n", @cmd_entries; + + return ($h_add, ""); +} + +sub generate_flags { + my ($self, $h_fh, $c_fh) = @_; + + my $n = 1; + + (my $dlsrc = uc $Config{dlsrc}) =~ s/\.xs$//i; + + print $h_fh "\n#define MP_SYS_$dlsrc 1\n"; + + foreach my $class (sort keys %{ $self->{flags} }) { + my $opts = $self->{flags}->{$class}; + my @lookup = (); + my %lookup = (); + my $lookup_proto = ""; + my %dumper; + if ($flags_options{$class}) { + $lookup_proto = join canon_func('flags', 'lookup', $class), + 'U32 ', '(const char *str)'; + push @lookup, "$lookup_proto {"; + } + + my $flags = join $class, qw(Mp FLAGS); + my $field = $flags_field{$class} || 'flags'; + + print $h_fh "\n#define $flags(p) (p)->$field\n"; + + $class = "Mp$class"; + print $h_fh "\n#define ${class}Type $n\n"; + $n++; + + my $i = 0; + my $max_len = 0; + for my $f (@$opts) { + my $x = sprintf "0x%08x", $i; + my $flag = "${class}_f_$f"; + my $cmd = $class . $f; + my $name = canon_name($f); + $lookup{$name} = $flag; + $max_len = length $name if $max_len < length $name; + print $h_fh <<EOF; + +/* $f */ +#define $flag $x +#define $cmd(p) ($flags(p) & $flag) +#define ${cmd}_On(p) ($flags(p) |= $flag) +#define ${cmd}_Off(p) ($flags(p) &= ~$flag) + +EOF + $dumper{$name} = + qq{modperl_trace(NULL, " $name %s", \\ + ($flags(p) & $x) ? "On " : "Off");}; + + $i += $i || 1; + } + if (@lookup) { + my $indent1 = " " x 4; + my $indent2 = " " x 8; + my %switch = (); + for (sort keys %lookup) { + if (/^(\w)/) { + my $gap = " " x ($max_len - length $_); + push @{ $switch{$1} }, + qq{if (strEQ(str, "$_"))$gap return $lookup{$_};}; + } + } + + push @lookup, '', $indent1 . "switch (*str) {"; + for (sort keys %switch) { + push @lookup, $indent1 . " case '$_':"; + push @lookup, map { $indent2 . $_ } @{ $switch{$_} }; + } + push @lookup, map { $indent1 . $_ } ("}\n", "return -1;\n}\n\n"); + + print $c_fh join "\n", @lookup; + print $h_fh "$lookup_proto;\n"; + } + + delete $dumper{None}; #NONE + print $h_fh join ' \\'."\n", + "#define ${class}_dump_flags(p, str)", + qq{modperl_trace(NULL, "$class flags dump (%s):", str);}, + map $dumper{$_}, sort keys %dumper; + } + + print $h_fh "\n#define MpSrvHOOKS_ALL_On(p) MpSrvFLAGS(p) |= (", + (join '|', map { 'MpSrv_f_' . $_ } @hook_flags), ")\n"; + + print $h_fh "\n#define MpSrvOPT_ITHREAD_ONLY(o) \\\n", + (join ' || ', map("(o == MpSrv_f_$_)", @ithread_opts)), "\n"; + + (); +} + +my %trace = ( + 'a' => 'Apache API interaction', + 'c' => 'configuration for directive handlers', + 'd' => 'directive processing', + 'e' => 'environment variables', + 'f' => 'filters', + 'g' => 'globals management', + 'h' => 'handlers', + 'i' => 'interpreter pool management', + 'm' => 'memory allocations', + 'o' => 'I/O', + 'r' => 'Perl runtime interaction', + 's' => 'Perl sections', + 't' => 'benchmark-ish timings', +); + +sub generate_trace { + my ($self, $h_fh) = @_; + + my $v = $self->{build}->{VERSION}; + my $api_v = $self->{build}->{API_VERSION}; + + print $h_fh qq(#define MP_VERSION_STRING "mod_perl/$v"\n); + + # this needs to be a string, not an int, because of the + # macro definition. patches welcome. + print $h_fh qq(#define MP_API_VERSION "$api_v"\n); + + my $i = 1; + my @trace = sort keys %trace; + my $opts = join '', @trace; + my $tl = "MP_debug_level"; + + print $h_fh <<EOF; +#define MP_TRACE_OPTS "$opts" + +#ifdef MP_TRACE +#define MP_TRACE_any if ($tl) modperl_trace +#define MP_TRACE_any_do(exp) if ($tl) { \\ +exp; \\ +} +#else +#define MP_TRACE_any if (0) modperl_trace +#define MP_TRACE_any_do(exp) +#endif + +EOF + + my @dumper; + for my $type (sort @trace) { + my $define = "#define MP_TRACE_$type"; + my $define_do = join '_', $define, 'do'; + + print $h_fh <<EOF; +#ifdef MP_TRACE +$define if ($tl & $i) modperl_trace +$define_do(exp) if ($tl & $i) { \\ +exp; \\ +} +#else +$define if (0) modperl_trace +$define_do(exp) +#endif +EOF + push @dumper, + qq{modperl_trace(NULL, " $type %s ($trace{$type})", ($tl & $i) ? "On " : "Off");}; + $i += $i; + } + + print $h_fh join ' \\'."\n", + '#define MP_TRACE_dump_flags()', + qq{modperl_trace(NULL, "mod_perl trace flags dump:");}, + @dumper; + + (); +} + +sub generate_largefiles { + my ($self, $h_fh) = @_; + + my $flags = $self->perl_config('ccflags_uselargefiles'); + + return unless $flags; + + for my $flag (split /\s+/, $flags) { + next if $flag =~ /^-/; # skip -foo flags + my ($name, $val) = split '=', $flag; + $val ||= ''; + $name =~ s/^-D//; + print $h_fh "#define $name $val\n"; + } +} + +sub ins_underscore { + $_[0] =~ s/([a-z])([A-Z])/$1_$2/g; + $_[0] =~ s/::/_/g; +} + +sub canon_uc { + my $s = shift; + ins_underscore($s); + uc $s; +} + +sub canon_lc { + my $s = shift; + ins_underscore($s); + lc $s; +} + +sub canon_func { + join '_', 'modperl', map { canon_lc($_) } @_; +} + +sub canon_name { + local $_ = shift; + s/([A-Z]+)/ucfirst(lc($1))/ge; + s/_//g; + $_; +} + +sub canon_define { + join '_', 'MP', map { canon_uc($_) } @_; +} + +sub canon_args { + my $args = shift->{args}; + my @pass = map { $_->{name} } @$args; + my @in; + foreach my $href (@$args) { + push @in, "$href->{type} *$href->{name}" + unless $href->{type} eq 'dummy'; + } + return wantarray ? (\@in, \@pass) : \@in; +} + +sub canon_proto { + my ($prototype, $name) = @_; + my ($in,$pass) = canon_args($prototype); + + local $" = ', '; + + my $p = "$prototype->{ret} $name(@$in)"; + $p =~ s/\* /*/; + return wantarray ? ($p, "@$pass") : $p; +} + +my %sources = ( + generate_handler_index => {h => 'modperl_hooks.h'}, + generate_handler_hooks => {h => 'modperl_hooks.h', + c => 'modperl_hooks.c'}, + generate_handler_directives => {h => 'modperl_directives.h', + c => 'modperl_directives.c'}, + generate_handler_find => {h => 'modperl_hooks.h', + c => 'modperl_hooks.c'}, + generate_flags => {h => 'modperl_flags.h', + c => 'modperl_flags.c'}, + generate_trace => {h => 'modperl_trace.h'}, + generate_largefiles => {h => 'modperl_largefiles.h'}, + generate_constants => {h => 'modperl_constants.h', + c => 'modperl_constants.c'}, + generate_exports => {c => 'modperl_exports.c'}, +); + +my @c_src_names = qw(interp tipool log config cmd options callback handler + gtop util io io_apache filter bucket mgv pcw global env + cgi perl perl_global perl_pp sys module svptr_table + const constants apache_compat error debug + common_util common_log); +my @h_src_names = qw(perl_unembed); +my @g_c_names = map { "modperl_$_" } qw(hooks directives flags xsinit exports); +my @c_names = ('mod_perl', (map "modperl_$_", @c_src_names)); +sub c_files { [map { "$_.c" } @c_names, @g_c_names] } +sub o_files { [map { "$_.o" } @c_names, @g_c_names] } +sub o_pic_files { [map { "$_.lo" } @c_names, @g_c_names] } + +my @g_h_names = map { "modperl_$_" } qw(hooks directives flags trace + largefiles); +my @h_names = (@c_names, map { "modperl_$_" } @h_src_names, + qw(types time apache_includes perl_includes apr_includes + apr_compat common_includes common_types)); +sub h_files { [map { "$_.h" } @h_names, @g_h_names] } + +sub clean_files { + my @c_names = @g_c_names; + my @h_names = @g_h_names; + + for (\@c_names, \@h_names) { + push @$_, 'modperl_constants'; + } + + [(map { "$_.c" } @c_names), (map { "$_.h" } @h_names)]; +} + +sub classname { + my $self = shift || __PACKAGE__; + ref($self) || $self; +} + +sub noedit_warning_c { + my $class = classname(shift); + + my $v = join '/', $class, $class->VERSION; + my $trace = Apache::TestConfig::calls_trace(); + $trace =~ s/^/ * /mg; + return <<EOF; + +/* + * *********** WARNING ************** + * This file generated by $v + * Any changes made here will be lost + * *********************************** +$trace */ + +EOF +} + +#this is named hash after the `#' character +#rather than named perl, since #comments are used +#non-Perl files, e.g. Makefile, typemap, etc. +sub noedit_warning_hash { + my $class = classname(shift); + + (my $warning = noedit_warning_c($class)) =~ s/^/\# /mg; + return $warning; +} + +sub init_file { + my ($self, $name) = @_; + + return unless $name; + return if $self->{init_files}->{$name}++; + + my (@preamble); + if ($name =~ /\.h$/) { + (my $d = uc $name) =~ s/\./_/; + push @preamble, "#ifndef $d\n#define $d\n"; + push @{ $self->{postamble}->{$name} }, "\n#endif /* $d */\n"; + } + elsif ($name =~ /\.c/) { + push @preamble, qq{\#include "mod_perl.h"\n\n}; + } + + my $file = "$self->{path}/$name"; + debug "generating...$file"; + unlink $file; + open my $fh, '>>', $file or die "open $file: $!"; + print $fh @preamble, noedit_warning_c(); + + $self->{fh}->{$name} = $fh; +} + +sub fh { + my ($self, $name) = @_; + return unless $name; + $self->{fh}->{$name}; +} + +sub postamble { + my $self = shift; + for my $name (sort keys %{ $self->{fh} }) { + next unless my $av = $self->{postamble}->{$name}; + print { $self->fh($name) } @$av; + } +} + +sub generate { + my ($self, $build) = @_; + + $self->{build} = $build; + + for my $s (values %sources) { + for (qw(h c)) { + $self->init_file($s->{$_}); + } + } + + for my $method (reverse sort keys %sources) { + my ($h_fh, $c_fh) = map { + $self->fh($sources{$method}->{$_}); + } qw(h c); + my ($h_add, $c_add) = $self->$method($h_fh, $c_fh); + if ($h_add) { + print $h_fh $h_add; + } + if ($c_add) { + print $c_fh $c_add; + } + debug "$method...done"; + } + + $self->postamble; + + my $xsinit = "$self->{path}/modperl_xsinit.c"; + debug "generating...$xsinit"; + + # There's a possibility that $Config{static_ext} may contain spaces + # and ExtUtils::Embed::xsinit won't handle the situation right. In + # this case we'll get buggy "boot_" statements in modperl_xsinit.c. + # Fix this by cleaning the @Extensions array. + + # Loads @Extensions if not loaded + ExtUtils::Embed::static_ext(); + + @ExtUtils::Embed::Extensions = grep{$_} @ExtUtils::Embed::Extensions; + + #create bootstrap method for static xs modules + my $static_xs = [sort keys %{ $build->{XS} }]; + ExtUtils::Embed::xsinit($xsinit, 1, $static_xs); + + #$self->generate_constants_pod(); +} + +my $constant_prefixes = join '|', qw{APR? MODPERL_RC}; + +sub generate_constants { + my ($self, $h_fh, $c_fh) = @_; + + require Apache2::ConstantsTable; + + print $c_fh qq{\#include "modperl_const.h"\n}; + print $h_fh "#define MP_ENOCONST -3\n\n"; + + generate_constants_lookup($h_fh, $c_fh); + generate_constants_group_lookup($h_fh, $c_fh); +} + +my %shortcuts = ( + NOT_FOUND => 'HTTP_NOT_FOUND', + FORBIDDEN => 'HTTP_FORBIDDEN', + AUTH_REQUIRED => 'HTTP_UNAUTHORIZED', + SERVER_ERROR => 'HTTP_INTERNAL_SERVER_ERROR', + REDIRECT => 'HTTP_MOVED_TEMPORARILY', +); + +#backwards compat with older httpd/apr +#XXX: remove once we require newer httpd/apr +my %ifdef = map { $_, 1 } + qw(APLOG_TOCLIENT APR_LIMIT_NOFILE), # added in ??? + qw(AP_MPMQ_STARTING AP_MPMQ_RUNNING AP_MPMQ_STOPPING + AP_MPMQ_MPM_STATE), # added in 2.0.49 + qw(APR_FPROT_USETID APR_FPROT_GSETID + APR_FPROT_WSTICKY APR_FOPEN_LARGEFILE), # added in 2.0.50? + qw(OPT_INCNOEXEC OPT_INC_WITH_EXEC); # added/removed in 2.4 + +sub constants_ifdef { + my $name = shift; + + if ($ifdef{$name}) { + return ("#ifdef $name\n", "#endif /* $name */\n"); + } + + ("", ""); +} + +sub constants_lookup_code { + my ($h_fh, $c_fh, $constants, $class) = @_; + + my (%switch, %alias); + + %alias = %shortcuts; + + my $postfix = canon_lc(lc $class); + my $package = $class . '::'; + my $package_len = length $package; + my ($first_let) = $class =~ /^(\w)/; + + my $func = canon_func(qw(constants lookup), $postfix); + my $proto = "SV \*$func(pTHX_ const char *name)"; + + print $h_fh "$proto;\n"; + + print $c_fh <<EOF; + +$proto +{ + if (*name == '$first_let' && strnEQ(name, "$package", $package_len)) { + name += $package_len; + } + + switch (*name) { +EOF + + for (@$constants) { + if (s/^($constant_prefixes)(_)?//o) { + $alias{$_} = join $2 || "", $1, $_; + } + else { + $alias{$_} ||= $_; + } + next unless /^([A-Z])/; + push @{ $switch{$1} }, $_; + } + + for my $key (sort keys %switch) { + my $names = $switch{$key}; + print $c_fh " case '$key':\n"; + + for my $name (@$names) { + my @ifdef = constants_ifdef($alias{$name}); + print $c_fh <<EOF; +$ifdef[0] + if (strEQ(name, "$name")) { +EOF + + if ($name eq 'DECLINE_CMD' || + $name eq 'DIR_MAGIC_TYPE' || + $name eq 'CRLF' || + $name eq 'AUTHN_PROVIDER_GROUP' || + $name eq 'AUTHZ_PROVIDER_GROUP' || + $name eq 'AUTHN_PROVIDER_VERSION' || + $name eq 'AUTHZ_PROVIDER_VERSION' || + $name eq 'AUTHN_DEFAULT_PROVIDER' || + $name eq 'AUTHN_PROVIDER_NAME_NOTE' || + $name eq 'AUTHZ_PROVIDER_NAME_NOTE' || + $name eq 'AUTHN_PREFIX' || + $name eq 'AUTHZ_PREFIX' || + $name eq 'CRLF_ASCII') { + print $c_fh <<EOF; + return newSVpv($alias{$name}, 0); +EOF + } + else { + print $c_fh <<EOF; + return newSViv($alias{$name}); +EOF + } + + print $c_fh <<EOF; + } +$ifdef[1] +EOF + } + print $c_fh " break;\n"; + } + + print $c_fh <<EOF + }; + Perl_croak(aTHX_ "unknown $class\:: constant %s", name); + return newSViv(MP_ENOCONST); +} +EOF +} + +sub generate_constants_lookup { + my ($h_fh, $c_fh) = @_; + + foreach my $class (sort keys %$Apache2::ConstantsTable) { + my $groups = $Apache2::ConstantsTable->{$class}; + my $constants = [sort map { @$_ } values %$groups]; + + constants_lookup_code($h_fh, $c_fh, $constants, $class); + } +} + +sub generate_constants_group_lookup { + my ($h_fh, $c_fh) = @_; + + foreach my $class (sort keys %$Apache2::ConstantsTable) { + my $groups = $Apache2::ConstantsTable->{$class}; + constants_group_lookup_code($h_fh, $c_fh, $class, $groups); + } +} + +sub constants_group_lookup_code { + my ($h_fh, $c_fh, $class, $groups) = @_; + my @tags; + my @code; + + $class = canon_lc(lc $class); + foreach my $group (sort keys %$groups) { + my $constants = $groups->{$group}; + push @tags, $group; + my $name = join '_', 'MP_constants', $class, $group; + print $c_fh "\nstatic const char *$name [] = { \n", + (map { + my @ifdef = constants_ifdef($_); + s/^($constant_prefixes)_?//o; + qq($ifdef[0] "$_",\n$ifdef[1]) + } @$constants), " NULL,\n};\n"; + } + + my %switch; + for (@tags) { + next unless /^([A-Z])/i; + push @{ $switch{$1} }, $_; + } + + my $func = canon_func(qw(constants group lookup), $class); + + my $proto = "const char **$func(const char *name)"; + + print $h_fh "$proto;\n"; + print $c_fh "\n$proto\n{\n", " switch (*name) {\n"; + + for my $key (sort keys %switch) { + my $val = $switch{$key}; + print $c_fh "\tcase '$key':\n"; + for my $group (@$val) { + my $name = join '_', 'MP_constants', $class, $group; + print $c_fh qq|\tif(strEQ("$group", name))\n\t return $name;\n|; + } + print $c_fh " break;\n"; + } + + print $c_fh <<EOF; + }; + Perl_croak_nocontext("unknown $class\:: group `%s'", name); + return NULL; +} +EOF +} + +my %seen_const = (); +# generates APR::Const and Apache2::Const manpages in ./tmp/ +sub generate_constants_pod { + my ($self) = @_; + + my %data = (); + generate_constants_group_lookup_doc(\%data); + generate_constants_lookup_doc(\%data); + + # XXX: may be dump %data into ModPerl::MethodLookup and provide an + # easy api to map const groups to constants and vice versa + + require File::Path; + my $file = "Const.pod"; + for my $class (sort keys %data) { + my $path = catdir "tmp", $class; + File::Path::mkpath($path, 0, 0755); + my $filepath = catfile $path, $file; + open my $fh, ">$filepath" or die "Can't open $filepath: $!\n"; + + print $fh <<"EOF"; +=head1 NAME + +$class\::Const - Perl Interface for $class Constants + +=head1 SYNOPSIS + +=head1 CONSTANTS + +EOF + + my $groups = $data{$class}; + for my $group (sort keys %$groups) { + print $fh <<"EOF"; + + + +=head2 C<:$group> + + use $class\::Const -compile qw(:$group); + +The C<:$group> group is for XXX constants. + +EOF + + for my $const (sort @{ $groups->{$group} }) { + print $fh "=head3 C<$class\::$const>\n\n\n"; + } + } + + print $fh "=cut\n"; + } +} + +sub generate_constants_lookup_doc { + my ($data) = @_; + + foreach my $class (sort keys %$Apache2::ConstantsTable) { + my $groups = $Apache2::ConstantsTable->{$class}; + my $constants = [sort map { @$_ } values %$groups]; + + constants_lookup_code_doc($constants, $class, $data); + } +} + +sub generate_constants_group_lookup_doc { + my ($data) = @_; + + foreach my $class (sort keys %$Apache2::ConstantsTable) { + my $groups = $Apache2::ConstantsTable->{$class}; + constants_group_lookup_code_doc($class, $groups, $data); + } +} + +sub constants_group_lookup_code_doc { + my ($class, $groups, $data) = @_; + my @tags; + my @code; + + while (my ($group, $constants) = each %$groups) { + $data->{$class}{$group} = [ + map { + my @ifdef = constants_ifdef($_); + s/^($constant_prefixes)_?//o; + $seen_const{$class}{$_}++; + $_; + } @$constants + ]; + } +} + +sub constants_lookup_code_doc { + my ($constants, $class, $data) = @_; + + my (%switch, %alias); + + %alias = %shortcuts; + + my $postfix = lc $class; + my $package = $class . '::'; + my $package_len = length $package; + + my $func = canon_func(qw(constants lookup), $postfix); + + for (@$constants) { + if (s/^($constant_prefixes)(_)?//o) { + $alias{$_} = join $2 || "", $1, $_; + } + else { + $alias{$_} ||= $_; + } + next unless /^([A-Z])/; + push @{ $switch{$1} }, $_; + } + + for my $key (sort keys %switch) { + my $names = $switch{$key}; + for my $name (@$names) { + my @ifdef = constants_ifdef($alias{$name}); + push @{ $data->{$class}{other} }, $name + unless $seen_const{$class}{$name} + } + } +} + +sub generate_exports { + my ($self, $c_fh) = @_; + require ModPerl::WrapXS; + ModPerl::WrapXS->generate_exports($c_fh); +} + +# src/modules/perl/*.c files needed to build APR/APR::* outside +# of mod_perl.so +sub src_apr_ext { + return map { "modperl_$_" } (qw(error bucket), + map { "common_$_" } qw(util log)); +} + +1; +__END__ + +=head1 NAME + +ModPerl::Code - Generate mod_perl glue code + +=head1 SYNOPSIS + + use ModPerl::Code (); + my $code = ModPerl::Code->new; + $code->generate; + +=head1 DESCRIPTION + +This module provides functionality for generating mod_perl glue code. +Reason this code is generated rather than written by hand include: + +=over 4 + +=item consistency + +=item thin and clean glue code + +=item enable/disable features (without #ifdefs) + +=item adapt to changes in Apache + +=item experiment with different approaches to gluing + +=back + +=head1 AUTHOR + +Doug MacEachern + +=cut
diff --git a/2_0_13/lib/ModPerl/Config.pm b/2_0_13/lib/ModPerl/Config.pm new file mode 100644 index 0000000..89b0f51 --- /dev/null +++ b/2_0_13/lib/ModPerl/Config.pm
@@ -0,0 +1,98 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::Config; + +use strict; + +use Apache2::Build (); +use Apache::TestConfig (); +use File::Spec (); + +use constant WIN32 => Apache2::Build::WIN32; + +sub as_string { + my $build = Apache2::Build->build_config; + + my $cfg = ''; + + $cfg .= "*** mod_perl version $mod_perl::VERSION\n\n";; + + my $file = File::Spec->rel2abs($INC{'Apache2/BuildConfig.pm'}); + $cfg .= "*** using $file\n\n"; + + # the widest key length + my $max_len = 0; + for (map {length} grep /^MP_/, keys %$build) { + $max_len = $_ if $_ > $max_len; + } + + # mod_perl opts + $cfg .= "*** Makefile.PL options:\n"; + $cfg .= join '', + map {sprintf " %-${max_len}s => %s\n", $_, $build->{$_}} + grep /^MP_/, sort keys %$build; + + my $command = ''; + + # httpd opts + my $test_config = Apache::TestConfig->new({thaw=>1}); + + if (my $httpd = $test_config->{vars}->{httpd}) { + $command = "$httpd -V"; + $cfg .= "\n\n*** $command\n"; + $cfg .= qx{$command}; + + $cfg .= Apache::TestConfig::ldd_as_string($httpd); + } + else { + $cfg .= "\n\n*** The httpd binary was not found\n"; + } + + # apr + $cfg .= "\n\n*** (apr|apu)-config linking info\n\n"; + my @apru_link_flags = $build->apru_link_flags; + if (@apru_link_flags) { + my $libs = join "\n", @apru_link_flags; + $cfg .= "$libs\n\n"; + } + else { + $cfg .= "(apr|apu)-config scripts were not found\n\n"; + } + + # perl opts + my $perl = $build->{MODPERL_PERLPATH}; + $command = "$perl -V"; + $cfg .= "\n\n*** $command\n"; + $cfg .= qx{$command}; + + return $cfg; + +} + +1; +__END__ + +=pod + +=head1 NAME + +ModPerl::Config - Functions to retrieve mod_perl specific env information. + +=head1 DESCRIPTION + +=cut +
diff --git a/2_0_13/lib/ModPerl/FunctionMap.pm b/2_0_13/lib/ModPerl/FunctionMap.pm new file mode 100644 index 0000000..e611132 --- /dev/null +++ b/2_0_13/lib/ModPerl/FunctionMap.pm
@@ -0,0 +1,216 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::FunctionMap; + +use strict; +use warnings FATAL => 'all'; +use ModPerl::MapUtil qw(); +use ModPerl::ParseSource (); + +our @ISA = qw(ModPerl::MapBase); + +sub new { + my $class = shift; + bless {}, $class; +} + +#for adding to function.map +sub generate { + my $self = shift; + + my $missing = $self->check; + return unless $missing; + + print " $_\n" for @$missing; +} + +sub disabled { shift->{disabled} } + +#look for functions that do not exist in *.map +sub check { + my $self = shift; + my $map = $self->get; + + my @missing; + my $mp_func = ModPerl::ParseSource->wanted_functions; + + for my $name (map $_->{name}, @{ $self->function_table() }) { + next if exists $map->{$name}; + push @missing, $name unless $name =~ /^($mp_func)/o; + } + + return @missing ? \@missing : undef; +} + +#look for functions in *.map that do not exist +my $special_name = qr{(^DEFINE_|DESTROY$)}; + +sub check_exists { + my $self = shift; + + my %functions = map { $_->{name}, 1 } @{ $self->function_table() }; + my @missing = (); + + for my $name (keys %{ $self->{map} }) { + next if $functions{$name}; + push @missing, $name unless $name =~ $special_name; + } + + return @missing ? \@missing : undef; +} + +my $keywords = join '|', qw(MODULE PACKAGE PREFIX BOOT); + +sub guess_prefix { + my $entry = shift; + + my ($name, $class) = ($entry->{name}, $entry->{class}); + my $prefix = ""; + $name =~ s/^DEFINE_//; + $name =~ s/^mpxs_//i; + + (my $modprefix = ($entry->{class} || $entry->{module}) . '_') =~ s/::/__/g; + (my $guess = lc $modprefix) =~ s/_+/_/g; + + $guess =~ s/(apache2)_/($1|ap)_{1,2}/; + + if ($name =~ s/^($guess|$modprefix).*/$1/i) { + $prefix = $1; + } + else { + if ($name =~ /^(apr?_)/) { + $prefix = $1; + } + } + + #print "GUESS prefix=$guess, name=$entry->{name} -> $prefix\n"; + + return $prefix; +} + +sub parse { + my ($self, $fh, $map) = @_; + my %cur; + my $disabled = 0; + + while ($fh->readline) { + if (/($keywords)=/o) { + $disabled = s/^\W//; #module is disabled + my %words = $self->parse_keywords($_); + + if ($words{MODULE}) { + %cur = (); + } + + if ($words{PACKAGE}) { + delete $cur{CLASS}; + } + + for (keys %words) { + $cur{$_} = $words{$_}; + } + + next; + } + + my ($name, $dispatch, $argspec, $alias) = split /\s*\|\s*/; + my $return_type; + + if ($name =~ s/^([^:]+)://) { + $return_type = $1; + $return_type =~ s/\s+$//; # allow: char * :.... + } + + if ($name =~ s/^(\W)// or not $cur{MODULE} or $disabled) { + #notimplemented or cooked by hand + die qq[function '$name' appears more than once in xs/maps files] + if $map->{$name}; + + $map->{$name} = undef; + push @{ $self->{disabled}->{ $1 || '!' } }, $name; + next; + } + + if (my $package = $cur{PACKAGE}) { + unless ($package eq 'guess') { + $cur{CLASS} = $package; + } + if ($cur{ISA}) { + $self->{isa}->{ $cur{MODULE} }->{$package} = delete $cur{ISA}; + } + if ($cur{BOOT}) { + $self->{boot}->{ $cur{MODULE} } = delete $cur{BOOT}; + } + } + else { + $cur{CLASS} = $cur{MODULE}; + } + + #XXX: make_prefix() stuff should be here, not ModPerl::WrapXS + if ($name =~ /^DEFINE_/ and $cur{CLASS}) { + $name =~ s{^(DEFINE_)(.*)} + {$1 . ModPerl::WrapXS::make_prefix($2, $cur{CLASS})}e; + } + + die qq[function '$name' appears more than once in xs/maps files] + if $map->{$name}; + + my $entry = $map->{$name} = { + name => $alias || $name, + dispatch => $dispatch, + argspec => $argspec ? [split /\s*,\s*/, $argspec] : "", + return_type => $return_type, + alias => $alias, + }; + + for (keys %cur) { + $entry->{lc $_} = $cur{$_}; + } + + #avoid 'use of uninitialized value' warnings + $entry->{$_} ||= "" for keys %{ $entry }; + if ($entry->{dispatch} =~ /_$/) { + $entry->{dispatch} .= $name; + } + } +} + +sub get { + my $self = shift; + + $self->{map} ||= $self->parse_map_files; +} + +sub prefixes { + my $self = shift; + $self = ModPerl::FunctionMap->new unless ref $self; + + my $map = $self->get; + my %prefix; + + while (my ($name, $ent) = each %$map) { + next unless $ent->{prefix}; + $prefix{ $ent->{prefix} }++; + } + + $prefix{$_} = 1 for qw(ap_ apr_); #make sure we get these + + [keys %prefix] +} + +1; +__END__
diff --git a/2_0_13/lib/ModPerl/MM.pm b/2_0_13/lib/ModPerl/MM.pm new file mode 100644 index 0000000..597a743 --- /dev/null +++ b/2_0_13/lib/ModPerl/MM.pm
@@ -0,0 +1,175 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::MM; + +use strict; +use warnings; + +use ExtUtils::MakeMaker (); +use ExtUtils::Install (); + +use Cwd (); +use Carp; + +our %PM; #add files to installation + +# MM methods that this package overrides +no strict 'refs'; +my $stash = \%{__PACKAGE__ . '::MY::'}; +my @methods = grep *{$stash->{$_}}{CODE}, keys %$stash; +my $eu_mm_mv_all_methods_overriden = 0; + +use strict 'refs'; + +sub override_eu_mm_mv_all_methods { + my @methods = @_; + + my $orig_sub = \&ExtUtils::MakeMaker::mv_all_methods; + no warnings 'redefine'; + *ExtUtils::MakeMaker::mv_all_methods = sub { + # do the normal move + $orig_sub->(@_); + # for all the overloaded methods mv_all_method installs a stab + # eval "package MY; sub $method { shift->SUPER::$method(\@_); }"; + # therefore we undefine our methods so on the recursive invocation of + # Makefile.PL they will be undef, unless defined in Makefile.PL + # and my_import will override these methods properly + for my $sym (@methods) { + my $name = "MY::$sym"; + undef &$name if defined &$name; + } + }; +} + +sub add_dep { + my ($string, $targ, $add) = @_; + $$string =~ s/($targ\s+::)/$1 $add/; +} + +sub add_dep_before { + my ($string, $targ, $before_targ, $add) = @_; + $$string =~ s/($targ\s+::.*?) ($before_targ)/$1 $add $2/; +} + +sub add_dep_after { + my ($string, $targ, $after_targ, $add) = @_; + $$string =~ s/($targ\s+::.*?$after_targ)/$1 $add/; +} + +my $build; + +sub build_config { + my $key = shift; + require Apache2::Build; + $build ||= Apache2::Build->build_config; + return $build unless $key; + $build->{$key}; +} + +#the parent WriteMakefile moves MY:: methods into a different class +#so alias them each time WriteMakefile is called in a subdir + +sub my_import { + my $package = shift; + no strict 'refs'; + my $stash = \%{$package . '::MY::'}; + for my $sym (keys %$stash) { + next unless *{$stash->{$sym}}{CODE}; + my $name = "MY::$sym"; + # the method is defined in Makefile.PL + next if defined &$name; + # do the override behind the scenes + *$name = *{$stash->{$sym}}{CODE}; + } +} + +my @default_opts = qw(CCFLAGS LIBS INC OPTIMIZE LDDLFLAGS TYPEMAPS); +my @default_dlib_opts = qw(OTHERLDFLAGS); +my @default_macro_opts = (); +my %opts = ( + CCFLAGS => sub { $build->{MODPERL_CCOPTS} }, + LIBS => sub { join ' ', $build->apache_libs, $build->modperl_libs }, + INC => sub { $build->inc; }, + OPTIMIZE => sub { $build->perl_config('optimize'); }, + LDDLFLAGS => sub { $build->perl_config('lddlflags'); }, + TYPEMAPS => sub { $build->typemaps; }, + OTHERLDFLAGS => sub { $build->otherldflags; }, +); + +sub get_def_opt { + my $opt = shift; + return $opts{$opt}->() if exists $opts{$opt}; + # handle cases when Makefile.PL wants an option we don't have a + # default for. XXX: some options expect [] rather than scalar. + Carp::carp("!!! no default argument defined for argument: $opt"); + return ''; +} + +sub WriteMakefile { + my %args = @_; + + # override ExtUtils::MakeMaker::mv_all_methods + # can't do that on loading since ModPerl::MM is also use()'d + # by ModPerl::BuildMM which itself overrides it + unless ($eu_mm_mv_all_methods_overriden) { + override_eu_mm_mv_all_methods(@methods); + $eu_mm_mv_all_methods_overriden++; + } + + $build ||= build_config(); + my_import(__PACKAGE__); + + # set top-level WriteMakefile's values if weren't set already + for my $o (@default_opts) { + $args{$o} = get_def_opt($o) unless exists $args{$o}; # already defined + } + + # set dynamic_lib-level WriteMakefile's values if weren't set already + $args{dynamic_lib} ||= {}; + my $dlib = $args{dynamic_lib}; + for my $o (@default_dlib_opts) { + $dlib->{$o} = get_def_opt($o) unless exists $dlib->{$o}; + } + + # set macro-level WriteMakefile's values if weren't set already + $args{macro} ||= {}; + my $macro = $args{macro}; + for my $o (@default_macro_opts) { + $macro->{$o} = get_def_opt($o) unless exists $macro->{$o}; + } + + ExtUtils::MakeMaker::WriteMakefile(%args); +} + +#### MM overrides #### + +sub ModPerl::MM::MY::post_initialize { + my $self = shift; + + $build ||= build_config(); + my $pm = $self->{PM}; + + while (my ($k, $v) = each %PM) { + if (-e $k) { + $pm->{$k} = $v; + } + } + + ''; +} + +1;
diff --git a/2_0_13/lib/ModPerl/Manifest.pm b/2_0_13/lib/ModPerl/Manifest.pm new file mode 100644 index 0000000..82cbdec --- /dev/null +++ b/2_0_13/lib/ModPerl/Manifest.pm
@@ -0,0 +1,128 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::Manifest; + +use strict; +use warnings FATAL => 'all'; + +use File::Basename; +use File::Find; +use Cwd (); +use Exporter (); + +our @EXPORT_OK = qw(mkmanifest); + +*import = \&Exporter::import; + +#generate a MANIFEST based on CVS/Entries +#anything to be skipped goes after __DATA__ (MANIFEST.SKIP format) +#anything else to be added should go here: +my @add_files = qw{ + MANIFEST + mod_perl.spec + Apache-Test/META.yml +}; + +sub get_svn_files { + my @files; + + my $cwd = Cwd::cwd(); + my @lines = `svn status -v` ; + foreach my $line (@lines) { + chomp $line; + if ($line =~ /(?:\d+)\s+(?:\d+)\s+(?:\w+)\s+(.*)\s*/) { + my $file = $1; + if (-e $file && ! -d $file) { + $file =~ s{\\}{/}g; + push @files, $file; + } + } + } + + # files to add which aren't under svn + push @files, qw(lib/ModPerl/DummyVersions.pm lib/ModPerl/MethodLookup.pm); + + return @files; +} + +sub mkmanifest { + my @files = (@add_files, get_svn_files()); + + my $matches = maniskip(); + open my $fh, '>', 'MANIFEST' or die "open MANIFEST: $!"; + + for my $file (sort @files) { + if ($matches->($file)) { + warn "skipping $file\n"; + next; + } + + print "$file\n"; + print $fh "$file\n"; + } + + close $fh; +} + +#copied from ExtUtils::Manifest +#uses DATA instead of MANIFEST.SKIP +sub maniskip { + my $matches = sub {0}; + my @skip; + + while (<DATA>){ + chomp; + next if /^#/; + next if /^\s*$/; + push @skip, $_; + } + + my $sub = "\$matches = " + . "sub { my (\$arg)=\@_; return 1 if " + . join (" || ", (map {s!/!\\/!g; "\$arg =~ m/$_/o"} @skip), 0) + . " }"; + + eval $sub; + + $matches; +} + +1; +__DATA__ +patches/ +#very few will have Chatbot::Eliza installed +eliza +# random failures +t/perl/ithreads.t +t/perl/ithreads2.t +t/response/TestPerl/ithreads.pm +t/response/TestPerl/ithreads_args.pm +t/response/TestPerl/ithreads_eval.pm +# broken/out-dated +t/perl/ithreads3.t +t/response/TestPerl/ithreads3.pm +# incomplete +t/apr-ext/perlio +# PAUSE breaks if a dist has more than one META.yml. the top-level +# META.yml already excludes Apache-Test from indexing +Apache-Test/META.yml +# exclude Apache-Test/MANIFEST since it confuses the mp2 build (e.g it +# wants Apache-Test/META.yml which we don't supply, see above) +Apache-Test/MANIFEST + +# this is an internal to developers sub-project +Apache-Test/Apache-TestItSelf
diff --git a/2_0_13/lib/ModPerl/MapUtil.pm b/2_0_13/lib/ModPerl/MapUtil.pm new file mode 100644 index 0000000..aa4f3d1 --- /dev/null +++ b/2_0_13/lib/ModPerl/MapUtil.pm
@@ -0,0 +1,259 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::MapUtil; + +use strict; +use warnings; +use Exporter (); +use Apache2::Build (); + +our @EXPORT_OK = qw(list_first disabled_reason + function_table structure_table + xs_glue_dirs); + +our @ISA = qw(Exporter); + +# the mapping happens in lib/ModPerl/StructureMap.pm: sub parse +# '<' => 'auto-generated but gives only a read-only access' +# '&' => 'RDWR accessor to a char* field, supporting undef arg' +# '$' => 'RONLY accessor, with WRITE accessor before child_init' +# '%' => like $, but makes sure that for the write accessor the +# original perl scalar can change or go away w/o affecting +# the object +my %disabled_map = ( + '!' => 'disabled or not yet implemented', + '~' => 'implemented but not auto-generated', + '-' => 'likely never be available to Perl', + '>' => '"private" to apache', + '?' => 'unclassified', +); + +my $function_table = []; + +sub function_table { + return $function_table if @$function_table; + my $build = Apache2::Build->new(); + my $httpd_version = $build->httpd_version; + if ($httpd_version lt '2.4.0' || ! -d "xs/tables/current24") { + push @INC, "xs/tables/current"; + } + else { + push @INC, "xs/tables/current24"; + } + require Apache2::FunctionTable; + require ModPerl::FunctionTable; + require APR::FunctionTable; + @$function_table = (@$Apache2::FunctionTable, @$ModPerl::FunctionTable, + @$APR::FunctionTable); + $function_table; +} + +my $structure_table = []; + +sub structure_table { + return $structure_table if @$structure_table; + require Apache2::StructureTable; + @$structure_table = (@$Apache2::StructureTable); + $structure_table; +} + +sub disabled_reason { + $disabled_map{+shift} || 'unknown'; +} + +sub xs_glue_dirs { + Apache2::Build->build_config->mp_xs_glue_dir; +} + +sub list_first (&@) { + my $code = shift; + + for (@_) { + return $_ if $code->(); + } + + undef; +} + +package ModPerl::MapBase; + +*function_table = \&ModPerl::MapUtil::function_table; +*structure_table = \&ModPerl::MapUtil::structure_table; + +my @condition; + +sub readline { + my $fh = shift; + + while (<$fh>) { + chomp; + s/^\s+//; s/\s+$//; + + # this implements + # #_if_ cmd + # ... + # #_else_ + # #_end_ + if (/^\s*#\s*_(if|unless|els(?:e|if)|end)_(?:\s(.+))?/) { + my ($cmd, $param) = ($1, $2); + if (defined $param) { + while ($param=~s!\\$!!) { + my $l=<$fh>; + die "$ModPerl::MapUtil::MapFile($.): unexpected EOF\n" + unless defined $l; + chomp $l; + $param.=$l; + } + } + if ($cmd eq 'if') { + unshift @condition, + 0+!!eval "#line $. $ModPerl::MapUtil::MapFile\n".$param; + die $@ if $@; + } + elsif ($cmd eq 'elsif') { + die "parse error ($ModPerl::MapUtil::MapFile line $.)". + " #_elsif_ without #_if_" + unless @condition; + if ($condition[0] == 0) { + $condition[0]+= + !!eval "#line $. $ModPerl::MapUtil::MapFile\n".$param; + die $@ if $@; + } else { + $condition[0]++; + } + } + elsif ($cmd eq 'else') { + die "parse error ($ModPerl::MapUtil::MapFile line $.)". + " #_elsif_ without #_if_" + unless @condition; + $condition[0]+=1; + } + elsif ($cmd eq 'unless') { + unshift @condition, + 0+!eval "#line $. $ModPerl::MapUtil::MapFile\n".$param; + die $@ if $@; + } + elsif ($cmd eq 'end') { + shift @condition; + } + } + next if @condition and $condition[0] != 1; + + if (/^\s*#\s*_(eval)_(?:\s(.+))?/) { + my ($cmd, $param) = ($1, $2); + if (defined $param) { + while ($param=~s!\\$!!) { + my $l=<$fh>; + die "$ModPerl::MapUtil::MapFile($.): unexpected EOF\n" + unless defined $l; + chomp $l; + $param.=$l; + } + } + if ($cmd eq 'eval') { + eval "#line $. $ModPerl::MapUtil::MapFile\n".$param; + die $@ if $@; + } + next; + } + + s/\s*\#.*//; + + next unless $_; + + if (s:\\$::) { + my $cur = $_; + $_ = $cur . $fh->readline; + return $_; + } + + return $_; + } +} + +our $MapDir; + +my $map_classes = join '|', qw(type structure function); + +sub map_files { + my $self = shift; + my $package = ref($self) || $self; + + my ($wanted) = $package =~ /($map_classes)/io; + + my (@dirs) = (($MapDir || './xs'), ModPerl::MapUtil::xs_glue_dirs()); + + my @files; + + for my $dir (map { -d "$_/maps" ? "$_/maps" : $_ } @dirs) { + opendir my $dh, $dir or warn "opendir $dir: $!"; + + for (readdir $dh) { + next unless /\.map$/; + + my $file = "$dir/$_"; + + if ($wanted) { + next unless $file =~ /$wanted/i; + } + + #print "$package => $file\n"; + push @files, $file; + } + + closedir $dh; + } + + return @files; +} + +sub parse_keywords { + my ($self, $line) = @_; + my %words; + + for my $pair (split /\s+/, $line) { + my ($key, $val) = split /=/, $pair; + + unless ($key and $val) { + die "parse error ($ModPerl::MapUtil::MapFile line $.)"; + } + + $words{$key} = $val; + } + + %words; +} + +sub parse_map_files { + my ($self) = @_; + + my $map = {}; + + for my $file (map_files($self)) { + open my $fh, $file or die "open $file: $!"; + local $ModPerl::MapUtil::MapFile = $file; + bless $fh, __PACKAGE__; + @condition=(); # see readline() above + $self->parse($fh, $map); + close $fh; + } + + return $map; +} + +1; +__END__
diff --git a/2_0_13/lib/ModPerl/ParseSource.pm b/2_0_13/lib/ModPerl/ParseSource.pm new file mode 100644 index 0000000..4b8ccb7 --- /dev/null +++ b/2_0_13/lib/ModPerl/ParseSource.pm
@@ -0,0 +1,65 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::ParseSource; + +use strict; +use Config (); +use Apache2::ParseSource (); + +our @ISA = qw(Apache2::ParseSource); +our $VERSION = '0.01'; + +sub includes { + my $self = shift; + my $dirs = $self->SUPER::includes; + return [ + '.', qw(xs src/modules/perl), + @$dirs, + "$Config::Config{archlibexp}/CORE", + ]; +} + +sub include_dirs { '.' } + +sub find_includes { + my $self = shift; + my $includes = $self->SUPER::find_includes; + #filter/sort + my @wanted = grep { /mod_perl\.h/ } @$includes; + push @wanted, grep { m:xs/modperl_xs_: } @$includes; + push @wanted, grep { m:xs/[AM]: } @$includes; + \@wanted; +} + +my $prefixes = join '|', qw(modperl mpxs mp_xs); +my $prefix_re = qr{^($prefixes)_}; +sub wanted_functions { $prefix_re } + +sub write_functions_pm { + my $self = shift; + my $file = shift || 'FunctionTable.pm'; + my $name = shift || 'ModPerl::FunctionTable'; + $self->SUPER::write_functions_pm($file, $name); +} + +for my $method (qw(get_constants get_structs write_structs_pm get_structs)) { + no strict 'refs'; + *$method = sub { die __PACKAGE__ . "->$method not implemented" }; +} + +1; +__END__
diff --git a/2_0_13/lib/ModPerl/StructureMap.pm b/2_0_13/lib/ModPerl/StructureMap.pm new file mode 100644 index 0000000..2d4c47b --- /dev/null +++ b/2_0_13/lib/ModPerl/StructureMap.pm
@@ -0,0 +1,164 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::StructureMap; + +use strict; +use warnings FATAL => 'all'; +use ModPerl::MapUtil qw(structure_table); + +our @ISA = qw(ModPerl::MapBase); + +sub new { + my $class = shift; + bless {}, $class; +} + +sub generate { + my $self = shift; + my $map = $self->get; + + for my $entry (@{ structure_table() }) { + my $type = $entry->{type}; + my $elts = $entry->{elts}; + + next unless @$elts; + next if $type =~ $self->{IGNORE_RE}; + next unless grep { + not exists $map->{$type}->{ $_->{name} } + } @$elts; + + print "<$type>\n"; + for my $e (@$elts) { + print " $e->{name}\n"; + } + print "</$type>\n\n"; + } +} + +sub disabled { shift->{disabled} } + +sub check { + my $self = shift; + my $map = $self->get; + + my @missing; + + for my $entry (@{ structure_table() }) { + my $type = $entry->{type}; + + for my $name (map $_->{name}, @{ $entry->{elts} }) { + next if exists $map->{$type}->{$name}; + next if $type =~ $self->{IGNORE_RE}; + push @missing, "$type.$name"; + } + } + + return @missing ? \@missing : undef; +} + +sub check_exists { + my $self = shift; + + my %structures; + for my $entry (@{ structure_table() }) { + $structures{ $entry->{type} } = { map { + $_->{name}, 1 + } @{ $entry->{elts} } }; + } + + my @missing; + + while (my ($type, $elts) = each %{ $self->{map} }) { + for my $name (keys %$elts) { + next if exists $structures{$type}->{$name}; + push @missing, "$type.$name"; + } + } + + return @missing ? \@missing : undef; +} + +sub parse { + my ($self, $fh, $map) = @_; + + my ($disabled, $class); + my %cur; + + while ($fh->readline) { + if (m:^(\W?)</?([^>]+)>:) { + my $args; + $disabled = $1; + ($class, $args) = split /\s+/, $2, 2; + + %cur = (); + if ($args and $args =~ /E=/) { + %cur = $self->parse_keywords($args); + } + + $self->{MODULES}->{$class} = $cur{MODULE} if $cur{MODULE}; + + next; + } + elsif (s/^(\w+):\s*//) { + push @{ $self->{$1} }, split /\s+/; + next; + } + + if (s/^(\W)\s*// or $disabled) { + # < denotes a read-only accessor + if ($1) { + if ($1 eq '<') { + $map->{$class}->{$_} = 'ro'; + } + elsif ($1 eq '&') { + $map->{$class}->{$_} = 'rw_char_undef'; + } + elsif ($1 eq '$') { + $map->{$class}->{$_} = 'r+w_startup'; + } + elsif ($1 eq '%') { + $map->{$class}->{$_} = 'r+w_startup_dup'; + } + } + else { + $map->{$class}->{$_} = undef; + push @{ $self->{disabled}->{ $1 || '!' } }, "$class.$_"; + } + + } + else { + $map->{$class}->{$_} = 'rw'; + } + } + + if (my $ignore = $self->{IGNORE}) { + $ignore = join '|', @$ignore; + $self->{IGNORE_RE} = qr{^($ignore)}; + } + else { + $self->{IGNORE_RE} = qr{^$}; + } +} + +sub get { + my $self = shift; + + $self->{map} ||= $self->parse_map_files; +} + +1; +__END__
diff --git a/2_0_13/lib/ModPerl/TestReport.pm b/2_0_13/lib/ModPerl/TestReport.pm new file mode 100644 index 0000000..f2b9825 --- /dev/null +++ b/2_0_13/lib/ModPerl/TestReport.pm
@@ -0,0 +1,104 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::TestReport; + +use strict; +use warnings FATAL => 'all'; + +use base qw(Apache::TestReportPerl); + +use ExtUtils::MakeMaker (); + +my @interesting_packages = qw( + CGI + ExtUtils::MakeMaker + Apache2::Request + mod_perl2 + LWP + Apache2 + mod_perl +); + +# we want to see only already installed packages, so skip over +# modules that are about to be installed +my @skip_dirs = qw( + blib/lib + blib/arch + lib +); +my $skip_dir_str = join '|', map { s|/|[/\\\\]|g; $_ } @skip_dirs; +my $skip_dir_pat = qr|[/\\]($skip_dir_str)[/\\]*$|; + +sub packages { + + my @inc = grep !/$skip_dir_pat/, @INC; + + my %packages = (); + my $max_len = 0; + for my $package (sort @interesting_packages ) { + $max_len = length $package if length $package > $max_len; + my $filename = package2filename($package); + my @ver = (); + for my $dir (@inc) { + my $path = "$dir/$filename"; + if (-e $path) { + my $ver = MM->parse_version($path); + # two versions could be installed (one under Apache2/) + push @{ $packages{$package} }, $ver if $ver; + } + } + } + + my @lines = "*** Packages of interest status:\n"; + + for my $package (sort @interesting_packages) { + my $vers = exists $packages{$package} + ? join ", ", sort @{ $packages{$package} } + : "-"; + push @lines, sprintf "%-${max_len}s: %s", $package, $vers; + } + + return join "\n", @lines, ''; +} + +sub config { + my $self = shift; + + my @report = (); + + # core config + push @report, ModPerl::Config::as_string(); + + # installed packages + push @report, $self->packages; + + # this report is generated by user/group + + return join "\n", @report; +} + +sub package2filename { + my $package = shift; + $package =~ s|::|/|g; + $package .= ".pm"; + return $package; +} + +sub report_to { 'modperl@perl.apache.org' } + + +1;
diff --git a/2_0_13/lib/ModPerl/TestRun.pm b/2_0_13/lib/ModPerl/TestRun.pm new file mode 100644 index 0000000..eb37692 --- /dev/null +++ b/2_0_13/lib/ModPerl/TestRun.pm
@@ -0,0 +1,74 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::TestRun; + +use strict; +use warnings FATAL => 'all'; + +use base qw(Apache::TestRunPerl); + +use Apache2::Build; + +# some mp2 tests require more than one server instance to be available +# without which the server may hang, waiting for the single server +# become available +use constant MIN_CLIENTS => 2; + +sub new_test_config { + my $self = shift; + + # default timeout in secs (threaded mpms are extremely slow to + # startup, due to a slow perl_clone operation) + $self->{conf_opts}->{startup_timeout} ||= + $ENV{APACHE_TEST_STARTUP_TIMEOUT} || + Apache2::Build->build_config->mpm_is_threaded() ? 300 : 120; + + $self->{conf_opts}->{minclients} ||= MIN_CLIENTS; + + ModPerl::TestConfig->new($self->{conf_opts}); +} + +sub bug_report { + my $self = shift; + + print <<EOI; ++--------------------------------------------------------+ +| Please file a bug report: http://perl.apache.org/bugs/ | ++--------------------------------------------------------+ +EOI +} + +package ModPerl::TestConfig; + +use base qw(Apache::TestConfig); + +sub new { + my $class = shift; + my $self = $class->SUPER::new(@_); + my $config = Apache2::Build->build_config; + $self->{conf_opts}->{httpd} ||= $config->{httpd}; + return $self; +} + +# - don't inherit LoadModule perl_module from the apache httpd.conf +# - loaded fastcgi crashes some mp2 tests +my @skip = ('mod_perl.c', qr/mod_fastcgi.*?\.c$/); + +Apache::TestConfig::autoconfig_skip_module_add(@skip); + +1; +
diff --git a/2_0_13/lib/ModPerl/TypeMap.pm b/2_0_13/lib/ModPerl/TypeMap.pm new file mode 100644 index 0000000..5548cca --- /dev/null +++ b/2_0_13/lib/ModPerl/TypeMap.pm
@@ -0,0 +1,534 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::TypeMap; + +use strict; +use warnings FATAL => 'all'; + +use ModPerl::FunctionMap (); +use ModPerl::StructureMap (); +use ModPerl::MapUtil qw(list_first); + +our @ISA = qw(ModPerl::MapBase); + +sub new { + my $class = shift; + + my $self = bless { + INCLUDE => [], + struct => [], + typedef => [], + }, $class; + + $self->{function_map} = ModPerl::FunctionMap->new, + $self->{structure_map} = ModPerl::StructureMap->new, + + $self->get; + $self; +} + +my %special = map { $_, 1 } qw(UNDEFINED NOTIMPL CALLBACK); + +sub special { + my ($self, $class) = @_; + return $special{$class}; +} + +sub function_map { shift->{function_map}->get } +sub structure_map { shift->{structure_map}->get } + +sub parse { + my ($self, $fh, $map) = @_; + + while ($fh->readline) { + if (/E=/) { + my %args = $self->parse_keywords($_); + while (my ($key,$val) = each %args) { + push @{ $self->{$key} }, $val; + } + next; + } + + my @aliases; + my ($type, $class) = (split /\s*\|\s*/, $_)[0,1]; + $class ||= 'UNDEFINED'; + + if ($type =~ s/^(struct|typedef)\s+(.*)/$2/) { + my $typemap = $1; + push @aliases, $type; + + if ($typemap eq 'struct') { + push @aliases, "const $type", "$type *", "const $type *", + "struct $type *", "const struct $type *", + "$type **"; + } + + my $cname = $class; + if ($cname =~ s/::/__/g) { + push @{ $self->{$typemap} }, [$type, $cname]; + } + } + elsif ($type =~ /_t$/) { + push @aliases, $type, "$type *", "const $type *"; + } + else { + push @aliases, $type; + } + + for (@aliases) { + $map->{$_} = $class; + } + } +} + +sub get { + my $self = shift; + + $self->{map} ||= $self->parse_map_files; +} + +my $ignore = join '|', qw{ +ap_LINK ap_HOOK _ UINT union._ +union.block_hdr cleanup process_chain +iovec struct.rlimit Sigfunc in_addr_t +}; + +sub should_ignore { + my ($self, $type) = @_; + return 1 if $type =~ /^($ignore)/o; +} + +sub is_callback { + my ($self, $type) = @_; + return 1 if $type =~ /\(/ and $type =~ /\)/; #XXX: callback +} + +sub exists { + my ($self, $type) = @_; + + return 1 if $self->is_callback($type) || $self->should_ignore($type); + + $type =~ s/\[\d+\]$//; #char foo[64] + + return exists $self->get->{$type}; +} + +sub map_type { + my ($self, $type) = @_; + my $class = $self->get->{$type}; + + return unless $class and ! $self->special($class); +# return if $type =~ /\*\*$/; #XXX + if ($class =~ /::/) { + return $class; + } + else { + return $type; + } +} + +sub null_type { + my ($self, $type) = @_; + my $class = $self->get->{$type}; + + if ($class =~ /^[INU]V/) { + return '0'; + } + else { + return 'NULL'; + } +} + +sub can_map { + my $self = shift; + my $map = shift; + + return 1 if $map->{argspec}; + + for (@_) { + return (0, $_) unless $self->map_type($_); + } + + return 1; +} + +sub map_arg { + my ($self, $arg) = @_; + + my $map_type = $self->map_type($arg->{type}); + die "unknown typemap: '$arg->{type}'" unless defined $map_type; + + return { + name => $arg->{name}, + default => $arg->{default}, + type => $map_type, + rtype => $arg->{type}, + } +} + +sub map_args { + my ($self, $func) = @_; + + my $entry = $self->function_map->{ $func->{name} }; + my $argspec = $entry->{argspec}; + my $args = []; + + if ($argspec) { + $entry->{orig_args} = [ map $_->{name}, @{ $func->{args} } ]; + + for my $arg (@$argspec) { + my $default; + ($arg, $default) = split /=/, $arg, 2; + my ($type, $name) = split ':', $arg, 2; + + if ($type and $name) { + push @$args, { + name => $name, + type => $type, + default => $default, + }; + } + else { + my $e = list_first { $_->{name} eq $arg } @{ $func->{args} }; + if ($e) { + push @$args, { %$e, default => $default }; + } + elsif ($arg eq '...') { + push @$args, { name => '...', type => 'SV *' }; + } + else { + warn "bad argspec: $func->{name} ($arg)\n"; + } + } + } + } + else { + $args = $func->{args}; + } + + return [ map $self->map_arg($_), @$args ] +} + +#this is needed for modperl-only functions +#unlike apache/apr functions which are remapped to a mpxs_ function +sub thx_fixup { + my ($self, $func) = @_; + + my $first = $func->{args}->[0]; + + return unless $first; + + if ($first->{type} =~ /PerlInterpreter/) { + shift @{ $func->{args} }; + $func->{thx} = 1; + } +} + +sub map_function { + my ($self, $func) = @_; + + my $map = $self->function_map->{ $func->{name} }; + return unless $map; + + $self->thx_fixup($func); + + my ($status, $failed_type) = + $self->can_map($map, $func->{return_type}, + map $_->{type}, @{ $func->{args} }); + + unless ($status) { + warn "unknown typemap: '$failed_type' (skipping $func->{name})\n"; + return; + } + + my $type = $map->{return_type} || $func->{return_type} || 'void'; + my $map_type = $self->map_type($type); + die "unknown typemap: '$type'" unless defined $map_type; + + my $mf = { + name => $func->{name}, + return_type => $map_type, + args => $self->map_args($func), + perl_name => $map->{name}, + thx => $func->{thx}, + }; + + for (qw(dispatch argspec orig_args prefix)) { + $mf->{$_} = $map->{$_}; + } + + unless ($mf->{class}) { + $mf->{class} = $map->{class} || $self->first_class($mf); + #print "GUESS class=$mf->{class} for $mf->{name}\n"; + } + + $mf->{prefix} ||= ModPerl::FunctionMap::guess_prefix($mf); + + $mf->{module} = $map->{module} || $mf->{class}; + + $mf; +} + +sub map_structure { + my ($self, $struct) = @_; + + my ($class, @elts); + my $stype = $struct->{type}; + + return unless $class = $self->map_type($stype); + + for my $e (@{ $struct->{elts} }) { + my ($name, $type) = ($e->{name}, $e->{type}); + my $rtype; + + # ro/rw/r+w_startup/undef(disabled) + my $access_mode = $self->structure_map->{$stype}->{$name}; + next unless $access_mode; + next unless $rtype = $self->map_type($type); + + push @elts, { + name => $name, + type => $rtype, + default => $self->null_type($type), + pool => $self->class_pool($class), + class => $self->{map}->{$type} || "", + access_mode => $access_mode, + }; + } + + return { + module => $self->{structure_map}->{MODULES}->{$stype} || $class, + class => $class, + type => $stype, + elts => \@elts, + }; +} + +sub destructor { + my ($self, $prefix) = @_; + $self->function_map->{$prefix . 'DESTROY'}; +} + +sub first_class { + my ($self, $func) = @_; + + for my $e (@{ $func->{args} }) { + next unless $e->{type} =~ /::/; + #there are alot of util functions that take an APR::Pool + #that do not belong in the APR::Pool class + next if $e->{type} eq 'APR::Pool' and $func->{name} !~ /^apr_pool/; + return $e->{type}; + } + + return $func->{name} =~ /^apr_/ ? 'APR' : 'Apache2'; +} + +sub check { + my $self = shift; + + my (@types, @missing, %seen); + + require Apache2::StructureTable; + for my $entry (@$Apache2::StructureTable) { + push @types, map $_->{type}, @{ $entry->{elts} }; + } + + for my $entry (@$Apache2::FunctionTable) { + push @types, grep { not $seen{$_}++ } + ($entry->{return_type}, + map $_->{type}, @{ $entry->{args} }) + } + + #printf "%d types\n", scalar @types; + + for my $type (@types) { + push @missing, $type unless $self->exists($type); + } + + return @missing ? \@missing : undef; +} + +#look for Apache/APR structures that do not exist in structure.map +my %ignore_check = map { $_,1 } qw{ +module_struct cmd_how kill_conditions +regex_t regmatch_t pthread_mutex_t +unsigned void va_list ... iovec char int long const +gid_t uid_t time_t pid_t size_t +sockaddr hostent +SV +}; + +sub check_exists { + my $self = shift; + + my %structures = map { $_->{type}, 1 } @{ $self->structure_table() }; + my @missing = (); + my %seen; + + for my $name (keys %{ $self->{map} }) { + 1 while $name =~ s/^\w+\s+(\w+)/$1/; + $name =~ s/\s+\**.*$//; + next if $seen{$name}++ or $structures{$name} or $ignore_check{$name}; + push @missing, $name; + } + + return @missing ? \@missing : undef; +} + +#XXX: generate this +my %class_pools = map { + (my $f = "mpxs_${_}_pool") =~ s/:/_/g; + $_, $f; +} qw{ + Apache2::RequestRec Apache2::Connection Apache2::URI APR::URI +}; + +sub class_pool : lvalue { + my ($self, $class) = @_; + $class_pools{$class}; +} + +#anything needed that mod_perl.h does not already include +#XXX: .maps should INCLUDE= these +my @includes = qw{ +apr_uuid.h +apr_sha1.h +apr_md5.h +apr_base64.h +apr_getopt.h +apr_hash.h +apr_lib.h +apr_general.h +apr_signal.h +apr_thread_rwlock.h +util_script.h +}; + +sub h_wrap { + my ($self, $file, $code) = @_; + + $file = 'modperl_xs_' . $file; + + my $h_def = uc "${file}_h"; + my $preamble = "\#ifndef $h_def\n\#define $h_def\n\n"; + my $postamble = "\n\#endif /* $h_def */\n"; + + return ("$file.h", $preamble . $code . $postamble); +} + +sub typedefs_code { + my $self = shift; + my $map = $self->get; + my %seen; + + my $file = 'modperl_xs_typedefs'; + my $h_def = uc "${file}_h"; + my $code = ""; + + for (@includes, @{ $self->{INCLUDE} }) { + $code .= qq{\#include "$_"\n} + } + + for my $t (sort {$a->[1] cmp $b->[1]} @{ $self->{struct} }) { + next if $seen{ $t->[1] }++; + $code .= "typedef $t->[0] * $t->[1];\n"; + } + + for my $t (sort {$a->[1] cmp $b->[1]} @{ $self->{typedef} }) { + next if $seen{ $t->[1] }++; + $code .= "typedef $t->[0] $t->[1];\n"; + } + + $self->h_wrap('typedefs', $code); +} + +my %convert_alias = ( + Apache2__RequestRec => 'r', + Apache2__Server => 'server', + Apache2__Connection => 'connection', + APR__Table => 'table', + APR__UUID => 'uuid', + apr_status_t => 'status', +); + +sub sv_convert_code { + my $self = shift; + my $map = $self->get; + my %seen; + my $code = ""; + + for my $ctype (sort keys %$map) { + my $ptype = $map->{$ctype}; + + next if $self->special($ptype); + next if $ctype =~ /\s/; + my $class = $ptype; + + if ($ptype =~ s/:/_/g) { + next if $seen{$ptype}++; + + my $alias; + my $expect = "expecting an $class derived object"; + my $croak = "argument is not a blessed reference"; + + #Perl -> C + my $define = "mp_xs_sv2_$ptype"; + + $code .= <<EOF; +#define $define(sv) \\ +((SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG)) \\ +|| (Perl_croak(aTHX_ "$croak ($expect)"),0) ? \\ +INT2PTR($ctype *, SvIV((SV*)SvRV(sv))) : ($ctype *)NULL) + +EOF + + if ($alias = $convert_alias{$ptype}) { + $code .= "#define mp_xs_sv2_$alias $define\n\n"; + } + + #C -> Perl + $define = "mp_xs_${ptype}_2obj"; + + $code .= <<EOF; +#define $define(ptr) \\ +sv_setref_pv(sv_newmortal(), "$class", (void*)ptr) + +EOF + + if ($alias) { + $code .= "#define mp_xs_${alias}_2obj $define\n\n"; + } + } + else { + if ($ptype =~ /^(\wV)$/) { + my $class = $1; + my $define = "mp_xs_sv2_$ctype"; + + $code .= "#define $define(sv) ($ctype)Sv$class(sv)\n\n"; + + if (my $alias = $convert_alias{$ctype}) { + $code .= "#define mp_xs_sv2_$alias $define\n\n"; + } + } + } + } + + $self->h_wrap('sv_convert', $code); +} + +1; +__END__
diff --git a/2_0_13/lib/ModPerl/WrapXS.pm b/2_0_13/lib/ModPerl/WrapXS.pm new file mode 100644 index 0000000..9f5cb08 --- /dev/null +++ b/2_0_13/lib/ModPerl/WrapXS.pm
@@ -0,0 +1,1401 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::WrapXS; + +use strict; +use warnings FATAL => 'all'; + +use constant GvUNIQUE => 0; #$] >= 5.008; +use Apache::TestTrace; +use Apache2::Build (); +use ModPerl::Code (); +use ModPerl::TypeMap (); +use ModPerl::MapUtil qw(function_table xs_glue_dirs); +use File::Path qw(rmtree mkpath); +use Cwd qw(fastcwd); +use Data::Dumper; +use File::Spec::Functions qw(catfile catdir); + +our $VERSION = '0.01'; + +my (@xs_includes) = ('mod_perl.h', + map "modperl_xs_$_.h", qw(sv_convert util typedefs)); + +my @global_structs = qw(perl_module); + +my $build = Apache2::Build->build_config; +push @global_structs, 'MP_debug_level' unless Apache2::Build::WIN32; + +sub new { + my $class = shift; + + my $self = bless { + typemap => ModPerl::TypeMap->new, + includes => \@xs_includes, + glue_dirs => [xs_glue_dirs()], + }, $class; + + $self->typemap->get; + $self; +} + +sub typemap { shift->{typemap} } + +sub includes { shift->{includes} } + +sub function_list { + my $self = shift; + my (@list) = @{ function_table() }; + + while (my ($name, $val) = each %{ $self->typemap->function_map }) { + #entries that do not exist in C::Scan generated tables + next unless $name =~ /^DEFINE_/; + push @list, $val; + } + + return \@list; +} + +sub get_functions { + my $self = shift; + my $typemap = $self->typemap; + + for my $entry (sort { $a->{name} cmp $b->{name} } @{ $self->function_list() }) { + my $func = $typemap->map_function($entry); + #print "FAILED to map $entry->{name}\n" unless $func; + next unless $func; + + my ($name, $module, $class, $args) = + @{ $func } { qw(perl_name module class args) }; + + $self->{XS}->{ $module } ||= []; + + #eg ap_fputs() + if ($name =~ s/^DEFINE_//) { + $func->{name} =~ s/^DEFINE_//; + + if (needs_prefix($func->{name})) { + #e.g. DEFINE_add_output_filter + $func->{name} = make_prefix($func->{name}, $class); + } + } + + my $xs_parms = join ', ', + map { defined $_->{default} ? + "$_->{name}=$_->{default}" : $_->{name} } @$args; + + (my $parms = $xs_parms) =~ s/=[^,]+//g; #strip defaults + + my $proto = join "\n", + (map " $_->{type} $_->{name}", @$args), ""; + + my ($dispatch, $orig_args) = + @{ $func } {qw(dispatch orig_args)}; + + if ($dispatch =~ /^MPXS_/) { + $name =~ s/^mpxs_//; + $name =~ s/^$func->{prefix}//; + push @{ $self->{newXS}->{ $module } }, + ["$class\::$name", $dispatch]; + next; + } + + my $passthru = @$args && $args->[0]->{name} eq '...'; + if ($passthru) { + $parms = '...'; + $proto = ''; + } + + my $return_type = + $name =~ /^DESTROY$/ ? 'void' : $func->{return_type}; + + my $attrs = $self->attrs($name); + + my $code = <<EOF; +$return_type +$name($xs_parms) +$proto +$attrs +EOF + + if ($dispatch || $orig_args || $func->{thx}) { + my $thx = $func->{thx} ? 'aTHX_ ' : ""; + + if ($dispatch) { + $thx = 'aTHX_ ' if $dispatch =~ /^mpxs_/i; + } + else { + if ($orig_args and @$orig_args == @$args) { + #args were reordered + $parms = join ', ', @$orig_args; + } + + $dispatch = $func->{name}; + } + + if ($passthru) { + $thx ||= 'aTHX_ '; + $parms = 'items, MARK+1, SP'; + } + + $thx =~ s/_ $// unless $parms; + + my $retval = $return_type eq 'void' ? + ["", ""] : ["RETVAL = ", "OUTPUT:\n RETVAL\n"]; + + my $avoid_warning = ""; + if (@$args and not $passthru) { + $avoid_warning = " /* avoiding -Wall warnings */\n"; + $avoid_warning .= join "\n", + (map " $_->{name} = $_->{name};", @$args), ""; + } + $code .= <<EOF; + CODE: +$avoid_warning + $retval->[0]$dispatch($thx$parms); + + $retval->[1] +EOF + } + + $func->{code} = $code; + push @{ $self->{XS}->{ $module } }, $func; + } +} + +sub get_value { + my $e = shift; + my $val = 'val'; + + if ($e->{class} eq 'PV') { + if (my $pool = $e->{pool}) { + $pool .= '(obj)'; + $val = "(SvOK(ST(1)) ? + apr_pstrndup($pool, val, val_len) : NULL)" + } + } + + return $val; +} + +sub get_structures { + my $self = shift; + my $typemap = $self->typemap; + + require Apache2::StructureTable; + for my $entry (@$Apache2::StructureTable) { + my $struct = $typemap->map_structure($entry); + next unless $struct; + + my $class = $struct->{class}; + + for my $e (@{ $struct->{elts} }) { + my ($name, $default, $type, $access_mode) = + @{$e}{qw(name default type access_mode)}; + + (my $cast = $type) =~ s/:/_/g; + my $val = get_value($e); + + my $type_in = $type; + my $preinit = "/*nada*/"; + if ($e->{class} eq 'PV' and $val ne 'val') { + $type_in =~ s/char/char_len/; + $preinit = "STRLEN val_len;"; + } + + my $attrs = $self->attrs($name); + + my $code; + if ($access_mode eq 'ro') { + $code = <<EOF; +$type +$name(obj) + $class obj + +$attrs + + CODE: + RETVAL = ($cast) obj->$name; + + OUTPUT: + RETVAL + +EOF + } + elsif ($access_mode eq 'rw' or $access_mode eq 'r+w_startup') { + + my $check_runtime = $access_mode eq 'rw' + ? '' + : qq[MP_CROAK_IF_THREADS_STARTED("setting $name");]; + + $code = <<EOF; +$type +$name(obj, val=$default) + $class obj + $type_in val + + PREINIT: + $preinit +$attrs + + CODE: + RETVAL = ($cast) obj->$name; + + if (items > 1) { + $check_runtime + obj->$name = ($cast) $val; + } + + OUTPUT: + RETVAL + +EOF + } + elsif ($access_mode eq 'r+w_startup_dup') { + + my $convert = $cast !~ /\bchar\b/ + ? "mp_xs_sv2_$cast" + : "SvPV_nolen"; + + $code = <<EOF; +$type +$name(obj, val=(SV *)NULL) + $class obj + SV *val + + PREINIT: + $preinit +$attrs + + CODE: + RETVAL = ($cast) obj->$name; + + if (items > 1) { + SV *dup = get_sv("_modperl_private::server_rec_$name", TRUE); + MP_CROAK_IF_THREADS_STARTED("setting $name"); + sv_setsv(dup, val); + obj->$name = ($cast)$convert(dup); + } + + OUTPUT: + RETVAL + +EOF + } + elsif ($access_mode eq 'rw_char_undef') { + my $pool = $e->{pool} + or die "rw_char_undef accessors need pool"; + $pool .= '(obj)'; +# XXX: not sure where val=$default is coming from, but for now use +# hardcoded (SV *)NULL + $code = <<EOF; +$type +$name(obj, val_sv=(SV *)NULL) + $class obj + SV *val_sv + + PREINIT: +$attrs + + CODE: + RETVAL = ($cast) obj->$name; + + if (val_sv) { + if (SvOK(val_sv)) { + STRLEN val_len; + char *val = (char *)SvPV(val_sv, val_len); + obj->$name = apr_pstrndup($pool, val, val_len); + } + else { + obj->$name = NULL; + } + } + + OUTPUT: + RETVAL + +EOF + } + + push @{ $self->{XS}->{ $struct->{module} } }, { + code => $code, + class => $class, + name => $name, + }; + } + } +} + +sub prepare { + my $self = shift; + $self->{DIR} = 'WrapXS'; + $self->{XS_DIR} = catdir fastcwd(), 'xs'; + + my $verbose = Apache::TestTrace::trace_level() eq 'debug' ? 1 : 0; + + if (-e $self->{DIR}) { + rmtree([$self->{DIR}], $verbose, 1); + } + + mkpath [$self->{DIR}], $verbose, 0755; +} + +sub class_dirname { + my ($self, $class) = @_; + my ($base, $sub) = split '::', $class; + return "$self->{DIR}/$base" unless $sub; #Apache2 | APR + return $sub if $sub eq $self->{DIR}; #WrapXS + return "$base/$sub"; +} + +sub class_dir { + my ($self, $class) = @_; + + my $dirname = $self->class_dirname($class); + my $dir = ($dirname =~ m:/: and $dirname !~ m:^$self->{DIR}:) ? + catdir($self->{DIR}, $dirname) : $dirname; + + unless (-d $dir) { + mkpath [$dir], 0, 0755; + debug "mkdir.....$dir"; + } + + $dir; +} + +sub class_file { + my ($self, $class, $file) = @_; + catfile $self->class_dir($class), $file; +} + +sub cname { + my ($self, $class) = @_; + $class =~ s/:/_/g; + $class; +} + +sub open_class_file { + my ($self, $class, $file) = @_; + + if ($file =~ /^\./) { + my $sub = (split '::', $class)[-1]; + $file = $sub . $file; + } + + my $name = $self->class_file($class, $file); + + open my $fh, '>', $name or die "open $name: $!"; + debug "writing...$name"; + + return $fh; +} + +sub module_version { + local $_ = shift; + require mod_perl2; + # XXX: for now APR gets its libapr-0.9 version + return /^APR/ ? "0.009000" : "$mod_perl2::VERSION"; +} + +sub write_makefilepl { + my ($self, $class) = @_; + + my $fh = $self->open_class_file($class, 'Makefile.PL'); + + my $includes = $self->includes; + my $xs = (split '::', $class)[-1] . '.c'; + my $deps = {$xs => ""}; + + if (my $mod_h = $self->mod_h($class, 1)) { + $deps->{$xs} .= " $mod_h"; + } + + local $Data::Dumper::Terse = 1; + $deps = Dumper $deps; + + my $noedit_warning = $self->ModPerl::Code::noedit_warning_hash(); + require mod_perl2; + my $version = module_version($class); + + print $fh <<EOF; +$noedit_warning + +use lib qw(../../../lib); #for Apache2::BuildConfig +use ModPerl::BuildMM (); + +ModPerl::BuildMM::WriteMakefile( + 'NAME' => '$class', + 'VERSION' => '$version', + 'depend' => $deps, +); +EOF + + close $fh; +} + +sub mod_h { + my ($self, $module, $complete) = @_; + + my $dirname = $self->class_dirname($module); + my $cname = $self->cname($module); + my $mod_h = "$dirname/$cname.h"; + + for ($self->{XS_DIR}, @{ $self->{glue_dirs} }) { + my $file = "$_/$mod_h"; + $mod_h = $file if $complete; + return $mod_h if -e $file; + } + + undef; +} + +sub mod_pm { + my ($self, $module, $complete) = @_; + + my $dirname = $self->class_dirname($module); + my ($base, $sub) = split '::', $module; + my $mod_pm = "$dirname/${sub}_pm"; + + for ($self->{XS_DIR}, @{ $self->{glue_dirs} }) { + my $file = "$_/$mod_pm"; + $mod_pm = $file if $complete; + return $mod_pm if -e $file; + } + + undef; +} + +sub class_c_prefix { + my $class = shift; + $class =~ s/:/_/g; + $class; +} + +sub class_mpxs_prefix { + my $class = shift; + my $class_prefix = class_c_prefix($class); + "mpxs_${class_prefix}_"; +} + +sub needs_prefix { + my $name = shift; + $name !~ /^(ap|apr|mpxs)_/i; +} + +sub make_prefix { + my ($name, $class) = @_; + my $class_prefix = class_mpxs_prefix($class); + return $name if $name =~ /^$class_prefix/; + $class_prefix . $name; +} + +sub isa_str { + my ($self, $module) = @_; + my $str = ""; + + if (my $isa = $self->typemap->{function_map}->{isa}->{$module}) { + foreach my $sub (sort keys %$isa) { + my $base = $isa->{$sub}; +#XXX cannot set isa in the BOOT: section because XSLoader local-ises +#ISA during bootstrap +# $str .= qq{ av_push(get_av("$sub\::ISA", TRUE), +# newSVpv("$base",0));} + $str .= qq{\@$sub\::ISA = '$base';\n} + } + } + + $str; +} + +sub boot { + my ($self, $module) = @_; + my $str = ""; + + if (my $boot = $self->typemap->{function_map}->{boot}->{$module}) { + $str = ' mpxs_' . $self->cname($module) . "_BOOT(aTHX);\n"; + } + + $str; +} + +my $notshared = join '|', qw(TIEHANDLE); #not sure why yet + +sub attrs { + my ($self, $name) = @_; + my $str = ""; + return $str if $name =~ /$notshared$/o; + $str = " ATTRS: unique\n" if GvUNIQUE; + $str; +} + +sub write_xs { + my ($self, $module, $functions) = @_; + + my $fh = $self->open_class_file($module, '.xs'); + print $fh $self->ModPerl::Code::noedit_warning_c(), "\n"; + print $fh "\n#define MP_IN_XS\n\n"; + + my @includes = @{ $self->includes }; + + if (my $mod_h = $self->mod_h($module)) { + push @includes, $mod_h; + } + + for (@includes) { + print $fh qq{\#include "$_"\n\n}; + } + + my $last_prefix = ""; + + for my $func (@$functions) { + my $class = $func->{class}; + my $prefix = $func->{prefix}; + $last_prefix = $prefix if $prefix; + + if ($func->{name} =~ /^mpxs_/) { + #e.g. mpxs_Apache2__RequestRec_ + my $class_prefix = class_c_prefix($class); + if ($func->{name} =~ /$class_prefix/) { + $prefix = class_mpxs_prefix($class); + } + } + + $prefix = $prefix ? " PREFIX = $prefix" : ""; + print $fh "MODULE = $module PACKAGE = $class $prefix\n\n"; + + print $fh $func->{code}; + } + + if (my $destructor = $self->typemap->destructor($last_prefix)) { + my $arg = $destructor->{argspec}[0]; + + print $fh <<EOF; +void +$destructor->{name}($arg) + $destructor->{class} $arg + +EOF + } + + print $fh "MODULE = $module\n"; + print $fh "PROTOTYPES: disabled\n\n"; + print $fh "BOOT:\n"; + print $fh $self->boot($module); + print $fh " items = items; /* -Wall */\n\n"; + + if (my $newxs = $self->{newXS}->{$module}) { + for my $xs (sort { $a->[0] cmp $b->[0] } @$newxs) { + print $fh qq{ cv = newXS("$xs->[0]", $xs->[1], __FILE__);\n}; + print $fh qq{ GvUNIQUE_on(CvGV(cv));\n} if GvUNIQUE; + } + } + + if ($module eq 'APR::Pool' && Apache2::Build::PERL_HAS_ITHREADS) { + print $fh " modperl_opt_interp_unselect = APR_RETRIEVE_OPTIONAL_FN(modperl_interp_unselect);\n\n"; + print $fh " modperl_opt_thx_interp_get = APR_RETRIEVE_OPTIONAL_FN(modperl_thx_interp_get);\n\n"; + } + + close $fh; +} + +sub write_pm { + my ($self, $module) = @_; + + my $isa = $self->isa_str($module); + + my $code = ""; + if (my $mod_pm = $self->mod_pm($module, 1)) { + open my $fh, '<', $mod_pm; + local $/; + $code = <$fh>; + close $fh; + } + + my $base = (split '::', $module)[0]; + unless (-e "lib/$base/XSLoader.pm") { + $base = 'Apache2'; + } + my $loader = join '::', $base, 'XSLoader'; + + my $fh = $self->open_class_file($module, '.pm'); + my $noedit_warning = $self->ModPerl::Code::noedit_warning_hash(); + my $use_apr = ($module =~ /^APR::\w+$/) ? 'use APR ();' : ''; + my $version = module_version($module); + + print $fh <<EOF; +$noedit_warning + +package $module; + +use strict; +use warnings FATAL => 'all'; + +$isa +$use_apr +use $loader (); +our \$VERSION = '$version'; +$loader\::load __PACKAGE__; + +$code + +1; +__END__ +EOF +} + +my %typemap = ( + 'Apache2::RequestRec' => 'T_APACHEOBJ', + 'apr_time_t' => 'T_APR_TIME', + 'APR::Table' => 'T_HASHOBJ', + 'APR::Pool' => 'T_POOLOBJ', + 'apr_size_t *' => 'T_UVPTR', +); + +sub write_typemap { + my $self = shift; + my $typemap = $self->typemap; + my $map = $typemap->get; + my %seen; + + my $fh = $self->open_class_file('ModPerl::WrapXS', 'typemap'); + print $fh $self->ModPerl::Code::noedit_warning_hash(), "\n"; + + my %entries = (); + my $max_key_len = 0; + while (my ($type, $class) = each %$map) { + $class ||= $type; + next if $seen{$type}++ || $typemap->special($class); + + if ($class =~ /::/) { + $entries{$class} = $typemap{$class} || 'T_PTROBJ'; + $max_key_len = length $class if length $class > $max_key_len; + } + else { + $entries{$type} = $typemap{$type} || "T_$class"; + $max_key_len = length $type if length $type > $max_key_len; + } + } + + for (sort keys %entries) { + printf $fh "%-${max_key_len}s %s\n", $_, $entries{$_}; + } + + close $fh; +} + +sub write_typemap_h_file { + my ($self, $method) = @_; + + $method = $method . '_code'; + my ($h, $code) = $self->typemap->$method(); + my $file = catfile $self->{XS_DIR}, $h; + + open my $fh, '>', $file or die "open $file: $!"; + print $fh $self->ModPerl::Code::noedit_warning_c(), "\n"; + print $fh $code; + close $fh; +} + +sub write_lookup_method_file { + my $self = shift; + + my %map = (); + foreach my $module (sort keys %{ $self->{XS} }) { + my $functions = $self->{XS}->{$module}; + my $last_prefix = ""; + for my $func (@$functions) { + my $class = $func->{class}; + my $prefix = $func->{prefix}; + $last_prefix = $prefix if $prefix; + + my $name = $func->{perl_name} || $func->{name}; + $name =~ s/^DEFINE_//; + + if ($name =~ /^mpxs_/) { + #e.g. mpxs_Apache2__RequestRec_ + my $class_prefix = class_c_prefix($class); + if ($name =~ /$class_prefix/) { + $prefix = class_mpxs_prefix($class); + } + } + elsif ($name =~ /^ap_sub_req/) { + $prefix = 'ap_sub_req_'; + } + + $name =~ s/^$prefix// if $prefix; + + push @{ $map{$name} }, [$module, $class]; + } + + # pure XS wrappers don't have the information about the + # arguments they receive, since they manipulate the arguments + # stack directly. therefore for these methods we can't tell + # what are the objects they are invoked on + for my $xs (@{ $self->{newXS}->{$module} || []}) { + push @{ $map{$1} }, [$module, undef] if $xs->[0] =~ /.+::(.+)/; + } + } + + local $Data::Dumper::Terse = 1; + local $Data::Dumper::Sortkeys = 1; + $Data::Dumper::Terse = $Data::Dumper::Terse; # warn + $Data::Dumper::Sortkeys = $Data::Dumper::Sortkeys; # warn + my $methods = Dumper(\%map); + $methods =~ s/\n$//; + + my $package = "ModPerl::MethodLookup"; + my $file = catfile "lib", "ModPerl", "MethodLookup.pm"; + debug "creating $file"; + open my $fh, ">$file" or die "Can't open $file: $!"; + + my $noedit_warning = $self->ModPerl::Code::noedit_warning_hash(); + + print $fh <<EOF; +$noedit_warning +package $package; + +use strict; +use warnings; + +my \$methods = $methods; + +EOF + + print $fh <<'EOF'; + +use base qw(Exporter); +use mod_perl2; + +our @EXPORT = qw(print_method print_module print_object); +our $VERSION = $mod_perl2::VERSION; +use constant MODULE => 0; +use constant OBJECT => 1; + +my $modules; +my $objects; + +sub _get_modules { + for my $method (sort keys %$methods) { + for my $item ( @{ $methods->{$method} }) { + push @{ $modules->{$item->[MODULE]} }, [$method, $item->[OBJECT]]; + } + } +} + +sub _get_objects { + for my $method (sort keys %$methods) { + for my $item ( @{ $methods->{$method} }) { + next unless defined $item->[OBJECT]; + push @{ $objects->{$item->[OBJECT]} }, [$method, $item->[MODULE]]; + } + } +} + +# if there is only one replacement method in 2.0 API we can +# automatically lookup it, up however if there are more than one +# (e.g. new()), we need to use a fully qualified value here +# of course the same if the package is not a mod_perl one. +# +# the first field represents the replacement method or undef if none +# exists, the second field is for extra comments (e.g. when there is +# no replacement method) +my $methods_compat = { + # Apache2:: + gensym => ['Symbol::gensym', + 'or use "open my $fh, $file"'], + module => ['Apache2::Module::loaded', + ''], + define => ['exists_config_define', + ''], + httpd_conf => ['add_config', + ''], + SERVER_VERSION => ['get_server_version', + ''], + can_stack_handlers=> [undef, + 'there is no more need for that method in mp2'], + + # Apache2::RequestRec + soft_timeout => [undef, + 'there is no more need for that method in mp2'], + hard_timeout => [undef, + 'there is no more need for that method in mp2'], + kill_timeout => [undef, + 'there is no more need for that method in mp2'], + reset_timeout => [undef, + 'there is no more need for that method in mp2'], + cleanup_for_exec => [undef, + 'there is no more need for that method in mp2'], + send_http_header => ['content_type', + ''], + header_in => ['headers_in', + 'this method works in mod_perl 1.0 too'], + header_out => ['headers_out', + 'this method works in mod_perl 1.0 too'], + err_header_out => ['err_headers_out', + 'this method works in mod_perl 1.0 too'], + register_cleanup => ['cleanup_register', + ''], + post_connection => ['cleanup_register', + ''], + content => [undef, # XXX: Apache2::Request::what? + 'use CGI.pm or Apache2::Request instead'], + clear_rgy_endav => ['special_list_clear', + ''], + stash_rgy_endav => [undef, + ''], + run_rgy_endav => ['special_list_call', + 'this method is no longer needed'], + seqno => [undef, + 'internal to mod_perl 1.0'], + chdir_file => [undef, # XXX: to be resolved + 'temporary unavailable till the issue with chdir' . + ' in the threaded env is resolved'], + log_reason => ['log_error', + 'not in the Apache 2.0 API'], + READLINE => [undef, # XXX: to be resolved + ''], + send_fd_length => [undef, + 'not in the Apache 2.0 API'], + send_fd => ['sendfile', + 'requires an offset argument'], + is_main => ['main', + 'not in the Apache 2.0 API'], + cgi_var => ['subprocess_env', + 'subprocess_env can be used with mod_perl 1.0'], + cgi_env => ['subprocess_env', + 'subprocess_env can be used with mod_perl 1.0'], + each_byterange => [undef, + 'now handled internally by ap_byterange_filter'], + set_byterange => [undef, + 'now handled internally by ap_byterange_filter'], + + # Apache::File + open => [undef, + ''], + close => [undef, # XXX: also defined in APR::Socket + ''], + tmpfile => [undef, + 'not in the Apache 2.0 API, ' . + 'use File::Temp instead'], + + # Apache::Util + size_string => ['format_size', + ''], + escape_uri => ['unescape_path', + ''], + escape_url => ['escape_path', + 'and requires a pool object'], + unescape_uri => ['unescape_url', + ''], + unescape_url_info => [undef, + 'use CGI::Util::unescape() instead'], + escape_html => [undef, # XXX: will be ap_escape_html + 'ap_escape_html now requires a pool object'], + parsedate => ['parse_http', + ''], + validate_password => ['password_validate', + ''], + + # Apache::Table + #new => ['make', + # ''], # XXX: there are other 'new' methods + + # Apache::Connection + auth_type => ['ap_auth_type', + 'now resides in the request object'], +}; + +sub avail_methods_compat { + return keys %$methods_compat; +} + +sub avail_methods { + return keys %$methods; +} + +sub avail_modules { + my %modules = (); + for my $method (keys %$methods) { + for my $item ( @{ $methods->{$method} }) { + $modules{$item->[MODULE]}++; + } + } + return keys %modules; +} + +sub preload_all_modules { + _get_modules() unless $modules; + eval "require $_" for sort keys %$modules; +} + +sub _print_func { + my $func = shift; + my @args = @_ ? @_ : @ARGV; + no strict 'refs'; + print( ($func->($_))[0]) for @args; +} + +sub print_module { _print_func('lookup_module', @_) } +sub print_object { _print_func('lookup_object', @_) } + +sub print_method { + my @args = @_ ? @_ : @ARGV; + while (@args) { + my $method = shift @args; + my $object = (@args && + (ref($args[0]) || $args[0] =~ /^(Apache2|ModPerl|APR)/)) + ? shift @args + : undef; + print( (lookup_method($method, $object))[0]); + } +} + +sub sep { return '-' x (shift() + 20) . "\n" } + +# what modules contain the passed method. +# an optional object or a reference to it can be passed to help +# resolve situations where there is more than one module containing +# the same method. Inheritance is supported. +sub lookup_method { + my ($method, $object) = @_; + + unless (defined $method) { + my $hint = "No 'method' argument was passed\n"; + return ($hint); + } + + # strip the package name for the fully qualified method + $method =~ s/.+:://; + + if (exists $methods_compat->{$method}) { + my ($replacement, $comment) = @{$methods_compat->{$method}}; + my $hint = "'$method' is not a part of the mod_perl 2.0 API\n"; + $comment = length $comment ? " $comment\n" : ""; + + # some removed methods have no replacement + return $hint . "$comment" unless defined $replacement; + + $hint .= "use '$replacement' instead. $comment"; + + # if fully qualified don't look up its container + return $hint if $replacement =~ /::/; + + my ($modules_hint, @modules) = lookup_method($replacement, $object); + return $hint . $modules_hint; + } + elsif (!exists $methods->{$method}) { + my $hint = "Don't know anything about method '$method'\n"; + return ($hint); + } + + my @items = @{ $methods->{$method} }; + if (@items == 1) { + my $module = $items[0]->[MODULE]; + my $hint = "To use method '$method' add:\n" . "\tuse $module ();\n"; + # we should really check that the method matches the object if + # any was passed, but it may not always work + return ($hint, $module); + } + else { + if (defined $object) { + my $class = ref $object || $object; + for my $item (@items) { + # real class or inheritance + if ($class eq $item->[OBJECT] or + (ref($object) && $object->isa($item->[OBJECT]))) { + my $module = $item->[MODULE]; + my $hint = "To use method '$method' add:\n" . + "\tuse $module ();\n"; + return ($hint, $module); + } + } + # fall-through + local $" = ", "; + my @modules = map $_->[MODULE], @items; + my $hint = "Several modules (@modules) contain method '$method' " . + "but none of them matches class '$class';\n"; + return ($hint); + + } + else { + my %modules = map { $_->[MODULE] => 1 } @items; + # remove dups if any (e.g. $s->add_input_filter and + # $r->add_input_filter are loaded by the same Apache2::Filter) + my @modules = sort keys %modules; + my $hint; + if (@modules == 1) { + $hint = "To use method '$method' add:\n\tuse $modules[0] ();\n"; + return ($hint, $modules[0]); + } + else { + $hint = "There is more than one class with method '$method'\n" . + "try one of:\n" . join '', map {"\tuse $_ ();\n"} @modules; + return ($hint, @modules); + } + } + } +} + +# what methods are contained in the passed module name +sub lookup_module { + my ($module) = shift; + + unless (defined $module) { + my $hint = "no 'module' argument was passed\n"; + return ($hint); + } + + _get_modules() unless $modules; + + unless (exists $modules->{$module}) { + my $hint = "don't know anything about module '$module'\n"; + return ($hint); + } + + my @methods; + my $max_len = 6; + for ( @{ $modules->{$module} } ) { + $max_len = length $_->[0] if length $_->[0] > $max_len; + push @methods, $_->[0]; + } + + my $format = "%-${max_len}s %s\n"; + my $banner = sprintf($format, "Method", "Invoked on object type"); + my $hint = join '', + ("\nModule '$module' contains the following XS methods:\n\n", + $banner, sep(length($banner)), + map( { sprintf $format, $_->[0], $_->[1]||'???'} + @{ $modules->{$module} }), + sep(length($banner))); + + return ($hint, @methods); +} + +# what methods can be invoked on the passed object (or its reference) +sub lookup_object { + my ($object) = shift; + + unless (defined $object) { + my $hint = "no 'object' argument was passed\n"; + return ($hint); + } + + _get_objects() unless $objects; + + # a real object was passed? + $object = ref $object || $object; + + unless (exists $objects->{$object}) { + my $hint = "don't know anything about objects of type '$object'\n"; + return ($hint); + } + + my @methods; + my $max_len = 6; + for ( @{ $objects->{$object} } ) { + $max_len = length $_->[0] if length $_->[0] > $max_len; + push @methods, $_->[0]; + } + + my $format = "%-${max_len}s %s\n"; + my $banner = sprintf($format, "Method", "Module"); + my $hint = join '', + ("\nObjects of type '$object' can invoke the following XS methods:\n\n", + $banner, sep(length($banner)), + map({ sprintf $format, $_->[0], $_->[1]} @{ $objects->{$object} }), + sep(length($banner))); + + return ($hint, @methods); + +} + +1; +EOF + close $fh; +} + +sub write_module_versions_file { + my $self = shift; + + my $file = catfile "lib", "ModPerl", "DummyVersions.pm"; + debug "creating $file"; + open my $fh, ">$file" or die "Can't open $file: $!"; + + my $noedit_warning = $self->ModPerl::Code::noedit_warning_hash(); + print $fh "$noedit_warning\n"; + + my @modules = keys %{ $self->{XS} }; + push @modules, qw(ModPerl::MethodLookup); + + my $len = 0; + for (@modules) { + $len = length $_ if length $_ > $len; + } + + require mod_perl2; + $len += length '$::VERSION'; + for (sort @modules) { + my $ver = module_version($_); + printf $fh "package %s;\n%-${len}s = %s;\n\n", + $_, '$'.$_."::VERSION", $ver; + } +} + +sub generate { + my $self = shift; + + $self->prepare; + + for (qw(ModPerl::WrapXS Apache2 APR ModPerl)) { + $self->write_makefilepl($_); + } + + $self->write_typemap; + + for (qw(typedefs sv_convert)) { + $self->write_typemap_h_file($_); + } + + $self->get_functions; + $self->get_structures; + $self->write_export_file('exp') if Apache2::Build::AIX; + $self->write_export_file('def') if Apache2::Build::WIN32; + + foreach my $module (sort keys %{ $self->{XS} }) { + my $functions = $self->{XS}->{$module}; +# my ($root, $sub) = split '::', $module; +# if (-e "$self->{XS_DIR}/$root/$sub/$sub.xs") { +# $module = join '::', $root, "Wrap$sub"; +# } + $self->write_makefilepl($module); + $self->write_xs($module, $functions); + $self->write_pm($module); + } + + $self->write_lookup_method_file; + $self->write_module_versions_file; +} + +#three .sym files are generated: +#global - global symbols +#ithreads - #ifdef USE_ITHREADS functions +#inline - __inline__ functions +#the inline symbols are needed #ifdef MP_DEBUG +#since __inline__ will be turned off + +my %multi_export = map { $_, 1 } qw(exp); + +sub open_export_files { + my ($self, $name, $ext) = @_; + + my $dir = $self->{XS_DIR}; + my %handles; + my @types = qw(global inline ithreads); + + if ($multi_export{$ext}) { + #write to multiple files + for my $type (@types) { + my $file = "$dir/${name}_$type.$ext"; + + open my $fh, '>', $file or + die "open $file: $!"; + + $handles{$type} = $fh; + } + } + else { + #write to one file + my $file = "$dir/$name.$ext"; + + open my $fh, '>', $file or + die "open $file: $!"; + + for my $type (@types) { + $handles{$type} = $fh; + } + } + + \%handles; +} + +sub func_is_static { + my ($self, $entry) = @_; + if (my $attr = $entry->{attr}) { + return 1 if grep { $_ eq 'static' } @$attr; + } + + #C::Scan doesnt always pickup static __inline__ + return 1 if $entry->{name} =~ /^mpxs_/o; + + return 0; +} + +sub func_is_inline { + my ($self, $entry) = @_; + if (my $attr = $entry->{attr}) { + return 1 if grep { $_ eq '__inline__' } @$attr; + } + return 0; +} + +sub export_file_header_exp { + my $self = shift; + "#!\n"; +} + +sub export_file_format_exp { + my ($self, $val) = @_; + "$val\n"; +} + +sub export_file_header_def { + my $self = shift; + "LIBRARY\n\nEXPORTS\n\n"; +} + +sub export_file_format_def { + my ($self, $val) = @_; + " $val\n"; +} + +my $ithreads_exports = join '|', qw{ +modperl_cmd_interp_ +modperl_interp_ +modperl_list_ +modperl_tipool_ +modperl_svptr_table_clone$ +modperl_mgv_require_module$ +}; + +sub export_func_handle { + my ($self, $entry, $handles) = @_; + + if ($self->func_is_inline($entry)) { + return $handles->{inline}; + } + elsif ($entry->{name} =~ /^($ithreads_exports)/) { + return $handles->{ithreads}; + } + + $handles->{global}; +} + +sub write_export_file { + my ($self, $ext) = @_; + + my %files = ( + modperl => $ModPerl::FunctionTable, + apache2 => $Apache2::FunctionTable, + apr => $APR::FunctionTable, + ); + + my $header = \&{"export_file_header_$ext"}; + my $format = \&{"export_file_format_$ext"}; + + foreach my $key (sort keys %files) { + my $table = $files{$key}; + my $handles = $self->open_export_files($key, $ext); + + my %seen; #only write header once if this is a single file + for my $fh (values %$handles) { + next if $seen{$fh}++; + print $fh $self->$header(); + } + + # add the symbols which aren't the function table + if ($key eq 'modperl') { + my $fh = $handles->{global}; + for my $name (@global_structs) { + print $fh $self->$format($name); + } + } + + for my $entry (@$table) { + next if $self->func_is_static($entry); + my $name = $entry->{name}; + + my $fh = $self->export_func_handle($entry, $handles); + + print $fh $self->$format($name); + } + + %seen = (); #only close handle once if this is a single file + for my $fh (values %$handles) { + next if $seen{$fh}++; + close $fh; + } + } +} + +sub stats { + my $self = shift; + + $self->get_functions; + $self->get_structures; + + my %stats; + + while (my ($module, $functions) = each %{ $self->{XS} }) { + $stats{$module} += @$functions; + if (my $newxs = $self->{newXS}->{$module}) { + $stats{$module} += @$newxs; + } + } + + return \%stats; +} + +sub generate_exports { + my ($self, $fh) = @_; + + if (!$build->should_build_apache) { + print $fh <<"EOF"; +/* This is intentionnaly left blank, only usefull for static build */ +const void *modperl_ugly_hack = NULL; +EOF + return; + } + + print $fh <<"EOF"; +/* + * This is indeed a ugly hack! + * See also src/modules/perl/mod_perl.c for modperl_ugly_hack + * If we don't build such a list of exported API functions, the over-zealous + * linker can and will remove the unused functions completely. In order to + * avoid this, we create this object and modperl_ugly_hack to create a + * dependency between all the exported API and mod_perl.c + */ +const void *modperl_ugly_hack = NULL; +EOF + + for my $entry (@$ModPerl::FunctionTable) { + next if $self->func_is_static($entry); + unless (Apache2::Build::PERL_HAS_ITHREADS) { + next if $entry->{name} =~ /^($ithreads_exports)/; + } + ( my $name ) = $entry->{name} =~ /^modperl_(.*)/; + print $fh <<"EOF"; +#ifndef modperl_$name +const void *modperl_hack_$name = (const void *)modperl_$name; +#endif + +EOF + } +} + +1; +__END__
diff --git a/2_0_13/lib/mod_perl2.pm b/2_0_13/lib/mod_perl2.pm new file mode 100644 index 0000000..b100fe7 --- /dev/null +++ b/2_0_13/lib/mod_perl2.pm
@@ -0,0 +1,61 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package mod_perl2; + +use 5.006; +use strict; + +BEGIN { + our $VERSION = "2.000013"; + our $VERSION_TRIPLET; + + if ($VERSION =~ /(\d+)\.(\d\d\d)(\d+)/) { + my $v1 = $1; + my $v2 = int $2; + my $v3 = int($3 . "0" x (3 - length $3)); + $VERSION_TRIPLET = "$v1.$v2.$v3"; + } + else { + die "bad version: $VERSION"; + } + + # for example this gives us: + # $VERSION : "2.000020" + # int $VERSION : 2.00002 + # $VERSION_TRIPLET: 2.0.20 + + # easy to parse request time API version - use + # $mod_perl2::VERSION for more granularity + our $API_VERSION = 2; +} + +# this stuff is here to assist back compat +# basically, if you +# PerlModule mod_perl2 +# or take similar steps to load mod_perl2 at +# startup you are protected against loading mod_perl.pm +# (either 1.0 or 1.99) at a later time by accident. +$mod_perl::VERSION = $mod_perl2::VERSION; +$INC{"mod_perl.pm"} = __FILE__; + +1; +__END__ + +=head1 NAME + +mod_perl - Embed a Perl interpreter in the Apache/2.x HTTP server +
diff --git a/2_0_13/patches/c-scan.pat b/2_0_13/patches/c-scan.pat new file mode 100644 index 0000000..08efb55 --- /dev/null +++ b/2_0_13/patches/c-scan.pat
@@ -0,0 +1,16 @@ +--- Scan.pm~ Thu Mar 23 06:14:18 2000 ++++ Scan.pm Sun Jan 7 11:56:04 2001 +@@ -400,7 +400,12 @@ + } else { + $vars = parse_vars($chunk); + } +- push @$struct, @$vars; ++ if ($vars) { ++ push @$struct, @$vars; ++ } ++ else { ++ warn "unable to parse chunk: `$chunk'" if $C::Scan::Warn; ++ } + } + $structs->{$structname} = $struct; + $structname;
diff --git a/2_0_13/patches/link-hack.pat b/2_0_13/patches/link-hack.pat new file mode 100644 index 0000000..cf7e757 --- /dev/null +++ b/2_0_13/patches/link-hack.pat
@@ -0,0 +1,46 @@ +Index: src/build/program.mk +=================================================================== +RCS file: /home/cvs/apache-2.0/src/build/program.mk,v +retrieving revision 1.3 +diff -u -u -r1.3 program.mk +--- src/build/program.mk 2000/03/31 07:02:31 1.3 ++++ src/build/program.mk 2000/04/16 23:43:14 +@@ -54,7 +54,10 @@ + # The build environment was provided by Sascha Schumann. + # + ++MP_SRC = ../../modperl-2.0/src/modules/perl ++MP_LDADD = $(MP_SRC)/libmodperl.a `$(MP_SRC)/ldopts` ++ + PROGRAM_OBJECTS = $(PROGRAM_SOURCES:.c=.lo) + + $(PROGRAM_NAME): $(PROGRAM_DEPENDENCIES) $(PROGRAM_OBJECTS) +- $(LINK) $(PROGRAM_LDFLAGS) $(PROGRAM_OBJECTS) $(PROGRAM_LDADD) ++ $(LINK) $(PROGRAM_LDFLAGS) $(PROGRAM_OBJECTS) $(PROGRAM_LDADD) $(MP_LDADD) + +--- src/modules.c~ Wed Apr 12 20:00:23 2000 ++++ src/modules.c Wed Apr 12 20:10:16 2000 +@@ -26,6 +26,7 @@ + extern module auth_module; + extern module setenvif_module; + extern module echo_module; ++extern module perl_module; + + /* + * Modules which implicitly form the +@@ -54,6 +55,7 @@ + &auth_module, + &setenvif_module, + &echo_module, ++ &perl_module, + NULL + }; + +@@ -84,6 +86,7 @@ + &auth_module, + &setenvif_module, + &echo_module, ++ &perl_module, + NULL + }; +
diff --git a/2_0_13/src/modules/perl/mod_perl.c b/2_0_13/src/modules/perl/mod_perl.c new file mode 100644 index 0000000..4edba4a --- /dev/null +++ b/2_0_13/src/modules/perl/mod_perl.c
@@ -0,0 +1,1149 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* make sure that mod_perl won't try to start itself, while it's + * already starting. If the flag's value is 1 * it's still starting, + * when it's 2 it is running */ +static int MP_init_status = 0; + +#define MP_IS_NOT_RUNNING (MP_init_status == 0 ? 1 : 0) +#define MP_IS_STARTING (MP_init_status == 1 ? 1 : 0) +#define MP_IS_RUNNING (MP_init_status == 2 ? 1 : 0) + +/* false while there is only the parent process and may be child + * processes, but no threads around, useful for allowing things that + * don't require locking and won't affect other threads. It should + * become true just before the child_init phase */ +static int MP_threads_started = 0; + +int modperl_threads_started(void) +{ + return MP_threads_started; +} + +static int MP_threaded_mpm = 0; + +int modperl_threaded_mpm(void) +{ + return MP_threaded_mpm; +} + +/* sometimes non-threaded mpm also needs to know whether it's still + * starting up or after post_config) */ +static int MP_post_post_config_phase = 0; + +int modperl_post_post_config_phase(void) +{ + return MP_post_post_config_phase; +} + +#ifndef USE_ITHREADS +static apr_status_t modperl_shutdown(void *data) +{ + modperl_cleanup_data_t *cdata = (modperl_cleanup_data_t *)data; + PerlInterpreter *perl = (PerlInterpreter *)cdata->data; + void **handles; + + handles = modperl_xs_dl_handles_get(aTHX); + + MP_TRACE_i(MP_FUNC, "destroying interpreter=0x%lx", + (unsigned long)perl); + + modperl_perl_destruct(perl); + + modperl_xs_dl_handles_close(handles); + + return APR_SUCCESS; +} +#endif + +static const char *MP_xs_loaders[] = { + "Apache2", "APR", NULL, +}; + +#define MP_xs_loader_name "%s::XSLoader::BOOTSTRAP" + +/* ugly hack to have access to startup pool and server during xs_init */ +static struct { + apr_pool_t *p; + server_rec *s; +} MP_boot_data = {NULL,NULL}; + +#define MP_boot_data_set(pool, server) \ + MP_boot_data.p = pool; \ + MP_boot_data.s = server + +#define MP_dBOOT_DATA \ + apr_pool_t *p = MP_boot_data.p; \ + server_rec *s = MP_boot_data.s + +static void modperl_boot(pTHX_ void *data) +{ + MP_dBOOT_DATA; + int i; + + modperl_env_clear(aTHX); + + modperl_env_default_populate(aTHX); + + modperl_env_configure_server(aTHX_ p, s); + + modperl_perl_core_global_init(aTHX); + + for (i=0; MP_xs_loaders[i]; i++) { + char *name = Perl_form(aTHX_ MP_xs_loader_name, MP_xs_loaders[i]); + newCONSTSUB(PL_defstash, name, newSViv(1)); + } + + /* outside mod_perl this is done by ModPerl::Const.xs */ + newXS("ModPerl::Const::compile", XS_modperl_const_compile, __FILE__); + + /* make sure DynaLoader is loaded before XSLoader + * - to workaround bug in 5.6.1 that can trigger a segv + * when using modperl as a dso + * - also needed when <Perl> sections are loaded from +Parent vhost + */ + modperl_require_module(aTHX_ "DynaLoader", FALSE); + + IoFLUSH_on(PL_stderrgv); /* unbuffer STDERR */ +} + +static void modperl_xs_init(pTHX) +{ + xs_init(aTHX); /* see modperl_xsinit.c */ + + /* XXX: in 5.7.2+ we can call the body of modperl_boot here + * but in 5.6.1 the Perl runtime is not properly setup yet + * so we have to pull this stunt to delay + */ + SAVEDESTRUCTOR_X(modperl_boot, 0); +} + +/* + * the "server_pool" is a subpool of the parent pool (aka "pconf") + * this is where we register the cleanups that teardown the interpreter. + * the parent process will run the cleanups since server_pool is a subpool + * of pconf. we manually clear the server_pool to run cleanups in the + * child processes + * + * the "server_user_pool" is a subpool of the "server_pool", this is + * the pool which is exposed to users, so that they can register + * cleanup callbacks. This is needed so that the perl cleanups won't + * be run before user cleanups are executed. + * + */ +static apr_pool_t *server_pool = NULL; +static apr_pool_t *server_user_pool = NULL; + +apr_pool_t *modperl_server_pool(void) +{ + return server_pool; +} + +apr_pool_t *modperl_server_user_pool(void) +{ + return server_user_pool; +} + +static void set_taint_var(PerlInterpreter *perl) +{ + dTHXa(perl); + +/* 5.7.3+ has a built-in special ${^TAINT}, backport it to 5.6.0+ */ +#if MP_PERL_VERSION_AT_MOST(5, 7, 2) + { + GV *gv = gv_fetchpv("\024AINT", GV_ADDMULTI, SVt_IV); + sv_setiv(GvSV(gv), PL_tainting); + SvREADONLY_on(GvSV(gv)); + } +#endif /* perl v < 5.7.3 */ + +#ifdef MP_COMPAT_1X + { + GV *gv = gv_fetchpv("Apache2::__T", GV_ADDMULTI, SVt_PV); + sv_setiv(GvSV(gv), PL_tainting); + SvREADONLY_on(GvSV(gv)); + } +#endif /* MP_COMPAT_1X */ + +} + +PerlInterpreter *modperl_startup(server_rec *s, apr_pool_t *p) +{ + AV *endav; + dTHXa(NULL); + MP_dSCFG(s); + PerlInterpreter *perl; + int status; + char **argv; + int argc; +#ifndef USE_ITHREADS + modperl_cleanup_data_t *cdata; +#endif + + /* ensure that we start the base server's perl, before vhost's + * one, if modperl_startup was called by vhost before the former + * was started */ + if (MP_init_status != 2) { + server_rec *base_server = modperl_global_get_server_rec(); + PerlInterpreter *base_perl; + + MP_init_status = 2; /* calls itself, so set the flag early */ + base_perl = modperl_startup(base_server, p); + + if (base_server == s ) { + return base_perl; + } + } + +#ifdef MP_TRACE + { + server_rec *base_server = modperl_global_get_server_rec(); + const char *desc = modperl_server_desc(s, p); + if (base_server == s) { + MP_init_status = 1; /* temporarily reset MP_init_status */ + MP_TRACE_i(MP_FUNC, + "starting the parent perl for the base server", desc); + MP_init_status = 2; + } + else { + MP_TRACE_i(MP_FUNC, + "starting the parent perl for vhost %s", desc); + } + } +#endif + +#ifdef MP_USE_GTOP + MP_TRACE_m_do( + modperl_gtop_do_proc_mem_before(MP_FUNC, "perl_parse"); + ); +#endif + + argv = modperl_config_srv_argv_init(scfg, &argc); + + if (!(perl = perl_alloc())) { + perror("perl_alloc"); + exit(1); + } + +#ifdef USE_ITHREADS + aTHX = perl; +#endif + + perl_construct(perl); + + modperl_hash_seed_set(aTHX); + + modperl_io_apache_init(aTHX); + + PL_perl_destruct_level = 2; + + MP_boot_data_set(p, s); + status = perl_parse(perl, modperl_xs_init, argc, argv, NULL); + MP_boot_data_set(NULL, NULL); + + if (status) { + perror("perl_parse"); + exit(1); + } + + modperl_env_init(aTHX); + + /* suspend END blocks to be run at server shutdown */ + endav = PL_endav; + PL_endav = (AV *)NULL; + +/* This was fixed in 5.9.0/5.8.1 (17775), but won't compile after 19122 */ +#if MP_PERL_VERSION(5, 8, 0) && \ + defined(USE_REENTRANT_API) && defined(HAS_CRYPT_R) && defined(__GLIBC__) + /* workaround perl5.8.0/glibc bug */ + PL_reentrant_buffer->_crypt_struct.current_saltbits = 0; +#endif + + /* We need to reset $0 to argv[0] (httpd) since perl_parse() will + * have set it to '-e'. Being magic-aware ensures that some + * OS-specific magic will happen (i.e. setproctitle() on *BSDs) + */ + PL_origalen = strlen(argv[0]) + 1; + sv_setpv_mg(get_sv("0",0), argv[0]); + + perl_run(perl); + +#ifdef USE_ITHREADS + /* base server / virtual host w/ +Parent gets its own mip */ + modperl_interp_init(s, p, perl); + + /* mark the parent perl to be destroyed */ + MpInterpBASE_On(scfg->mip->parent); +#endif + + PL_endav = endav; + + set_taint_var(perl); + + MP_TRACE_i(MP_FUNC, "constructed interpreter=0x%lx", + (unsigned long)perl); + +#ifdef MP_USE_GTOP + MP_TRACE_m_do( + modperl_gtop_do_proc_mem_after(MP_FUNC, "perl_parse"); + ); +#endif + +#ifdef MP_COMPAT_1X + { + char *path, *path1; + apr_finfo_t finfo; + /* 1) push @INC, $ServerRoot */ + av_push(GvAV(PL_incgv), newSVpv(ap_server_root, 0)); + + /* 2) push @INC, $ServerRoot/lib/perl only if it exists */ + apr_filepath_merge(&path, ap_server_root, "lib", + APR_FILEPATH_NATIVE, p); + apr_filepath_merge(&path1, path, "perl", + APR_FILEPATH_NATIVE, p); + if (APR_SUCCESS == apr_stat(&finfo, path1, APR_FINFO_TYPE, p)) { + if (finfo.filetype == APR_DIR) { + av_push(GvAV(PL_incgv), newSVpv(path1, 0)); + } + } + } +#endif /* MP_COMPAT_1X */ + + /* base perl and each vhost +Parent should have this init'ed */ + modperl_handler_anon_init(aTHX_ p); + + if (!modperl_config_apply_PerlRequire(s, scfg, perl, p)) { + exit(1); + } + + if (!modperl_config_apply_PerlModule(s, scfg, perl, p)) { + exit(1); + } + +#ifndef USE_ITHREADS + cdata = modperl_cleanup_data_new(server_pool, (void*)perl); + apr_pool_cleanup_register(server_pool, cdata, + modperl_shutdown, apr_pool_cleanup_null); +#endif + + return perl; +} + +int modperl_init_vhost(server_rec *s, apr_pool_t *p, + server_rec *base_server) +{ + MP_dSCFG(s); + modperl_config_srv_t *base_scfg; + PerlInterpreter *base_perl; + PerlInterpreter *perl; + const char *vhost = modperl_server_desc(s, p); + + if (!scfg) { + MP_TRACE_i(MP_FUNC, "server %s has no mod_perl config", vhost); + return OK; + } + + if (base_server == NULL) { + base_server = modperl_global_get_server_rec(); + } + + MP_TRACE_i(MP_FUNC, "Init vhost %s: s=0x%lx, base_s=0x%lx", + vhost, s, base_server); + + if (base_server == s) { + MP_TRACE_i(MP_FUNC, "base server is not vhost, skipping %s", + vhost); + return OK; + } + + base_scfg = modperl_config_srv_get(base_server); + +#ifdef USE_ITHREADS + perl = base_perl = base_scfg->mip->parent->perl; +#else + perl = base_perl = base_scfg->perl; +#endif /* USE_ITHREADS */ + +#ifdef USE_ITHREADS + + if (scfg->mip) { + MP_TRACE_i(MP_FUNC, "server %s already initialized", vhost); + return OK; + } + + /* the base server could have mod_perl callbacks disabled, but it + * still needs perl to drive the vhosts */ + if (!MpSrvENABLE(scfg) && s->is_virtual) { + MP_TRACE_i(MP_FUNC, "mod_perl disabled for server %s", vhost); + scfg->mip = NULL; + return OK; + } + + PERL_SET_CONTEXT(perl); + modperl_thx_interp_set(perl, base_scfg->mip->parent); + +#endif /* USE_ITHREADS */ + + MP_TRACE_d_do(MpSrv_dump_flags(scfg, s->server_hostname)); + + /* if alloc flags is On, virtual host gets its own parent perl */ + if (MpSrvPARENT(scfg)) { + perl = modperl_startup(s, p); + MP_TRACE_i(MP_FUNC, + "created parent interpreter for VirtualHost %s", + modperl_server_desc(s, p)); + } + else { +#ifdef USE_ITHREADS + /* virtual host w/ +Clone gets its own mip */ + if (MpSrvCLONE(scfg)) { + modperl_interp_init(s, p, perl); + } +#endif + + if (!modperl_config_apply_PerlRequire(s, scfg, perl, p)) { + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (!modperl_config_apply_PerlModule(s, scfg, perl, p)) { + return HTTP_INTERNAL_SERVER_ERROR; + } + } + +#ifdef USE_ITHREADS + if (!scfg->mip) { + /* since mips are created after merge_server_configs() + * need to point to the base mip here if this vhost + * doesn't have its own + */ + MP_TRACE_i(MP_FUNC, "%s mip inherited from %s", + vhost, modperl_server_desc(base_server, p)); + scfg->mip = base_scfg->mip; + } +#endif /* USE_ITHREADS */ + + return OK; +} + +void modperl_init(server_rec *base_server, apr_pool_t *p) +{ + server_rec *s; + PerlInterpreter *base_perl; +#if defined(MP_TRACE) || defined(USE_ITHREADS) + modperl_config_srv_t *base_scfg = modperl_config_srv_get(base_server); +#endif + + MP_TRACE_d_do(MpSrv_dump_flags(base_scfg, + base_server->server_hostname)); + +#ifndef USE_ITHREADS + if (modperl_threaded_mpm()) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, + "cannot use threaded MPM without ithreads enabled Perl"); + exit(1); + } +#endif + + base_perl = modperl_startup(base_server, p); + + for (s=base_server->next; s; s=s->next) { + if (modperl_init_vhost(s, p, base_server) != OK) { + exit(1); /*XXX*/ + } + } + +#ifdef USE_ITHREADS + /* after other parent perls were started in vhosts, make sure that + * the context is set to the base_perl */ + PERL_SET_CONTEXT(base_perl); + modperl_thx_interp_set(base_perl, base_scfg->mip->parent); +#endif + +} + +static int modperl_post_config_require(server_rec *s, apr_pool_t *p) +{ + for (; s; s=s->next) { + MP_dSCFG(s); + if (!modperl_config_apply_PerlPostConfigRequire(s, scfg, p)) { + return FALSE; + } + } + return TRUE; +} + +#ifdef USE_ITHREADS +static void modperl_init_clones(server_rec *s, apr_pool_t *p) +{ +#ifdef MP_TRACE + modperl_config_srv_t *base_scfg = modperl_config_srv_get(s); + char *base_name = modperl_server_desc(s, p); +#endif /* MP_TRACE */ + + if (!modperl_threaded_mpm()) { + MP_TRACE_i(MP_FUNC, "no clones created for non-threaded mpm"); + return; + } + + for (; s; s=s->next) { + MP_dSCFG(s); +#ifdef MP_TRACE + char *name = modperl_server_desc(s, p); +#else + char *name = NULL; +#endif /* MP_TRACE */ + + if (scfg->mip->tipool->idle) { +#ifdef MP_TRACE + if (scfg->mip == base_scfg->mip) { + MP_TRACE_i(MP_FUNC, + "%s interp pool inherited from %s", + name, base_name); + } + else { + MP_TRACE_i(MP_FUNC, + "%s interp pool already initialized", + name); + } +#endif /* MP_TRACE */ + } + else { + MP_TRACE_i(MP_FUNC, "initializing interp pool for %s", + name); + modperl_tipool_init(scfg->mip->tipool); + } + } +} +#endif /* USE_ITHREADS */ + +void modperl_init_globals(server_rec *s, apr_pool_t *pconf) +{ + ap_mpm_query(AP_MPMQ_IS_THREADED, &MP_threaded_mpm); + + MP_TRACE_g(MP_FUNC, "mod_perl globals are configured"); + + modperl_global_init_pconf(pconf, pconf); + modperl_global_init_server_rec(pconf, s); + + modperl_tls_create_request_rec(pconf); + + /* init the counter to 0 */ + modperl_global_anon_cnt_init(pconf); +} + +/* + * modperl_sys_{init,term} are things that happen + * once per-parent process, not per-interpreter + */ +static apr_status_t modperl_sys_init(void) +{ + int argc = 0; + char **argv = NULL, **env = NULL; + + MP_TRACE_i(MP_FUNC, "mod_perl sys init"); + + /* not every OS uses those vars in PERL_SYS_INIT3 macro */ + argc = argc; argv = argv; env = env; + + PERL_SYS_INIT3(&argc, &argv, &env); + +#if 0 /*XXX*/ +#ifdef PTHREAD_ATFORK + if (!ap_exists_config_define("PERL_PTHREAD_ATFORK_DONE")) { + PTHREAD_ATFORK(Perl_atfork_lock, + Perl_atfork_unlock, + Perl_atfork_unlock); + *(char **)apr_array_push(ap_server_config_defines) = + "PERL_PTHREAD_ATFORK_DONE"; + } +#endif +#endif + + /* modifies PL_ppaddr */ + modperl_perl_pp_set_all(); + + return APR_SUCCESS; +} + +static apr_status_t modperl_sys_term(void *data) +{ + /* PERL_SYS_TERM() needs 'my_perl' as of 5.9.5 */ +#if MP_PERL_VERSION_AT_LEAST(5, 9, 5) && defined(USE_ITHREADS) + modperl_cleanup_data_t *cdata = (modperl_cleanup_data_t *)data; + PERL_UNUSED_DECL PerlInterpreter *my_perl = cdata == NULL ? NULL : (PerlInterpreter *)cdata->data; +#endif + MP_init_status = 0; + MP_threads_started = 0; + MP_post_post_config_phase = 0; + + MP_PERL_FREE_THREAD_KEY_WORKAROUND; + + MP_TRACE_i(MP_FUNC, "mod_perl sys term"); + + modperl_perl_pp_unset_all(); + + PERL_SYS_TERM(); + + return APR_SUCCESS; +} + +int modperl_hook_init(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + if (MP_IS_STARTING || MP_IS_RUNNING) { + return OK; + } + + MP_init_status = 1; /* now starting */ + + modperl_restart_count_inc(s); + + apr_pool_create(&server_pool, pconf); + apr_pool_tag(server_pool, "mod_perl server pool"); + + apr_pool_create(&server_user_pool, pconf); + apr_pool_tag(server_user_pool, "mod_perl server user pool"); + + modperl_sys_init(); + apr_pool_cleanup_register(server_pool, NULL, + modperl_sys_term, apr_pool_cleanup_null); + + modperl_init(s, pconf); + + return OK; +} + +/* + * if we need to init earlier than post_config, + * e.g. <Perl> sections or directive handlers. + */ +int modperl_run(void) +{ + return modperl_hook_init(modperl_global_get_pconf(), + NULL, + NULL, + modperl_global_get_server_rec()); +} + +int modperl_is_running(void) +{ + return MP_IS_RUNNING; +} + +int modperl_hook_pre_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp) +{ +#if AP_MODULE_MAGIC_AT_LEAST(20110329,0) + ap_reserve_module_slots_directive("PerlLoadModule"); +#endif + + /* we can't have PerlPreConfigHandler without first configuring mod_perl */ + + /* perl 5.8.1+ */ + modperl_hash_seed_init(p); + + return OK; +} + +static int modperl_hook_pre_connection(conn_rec *c, void *csd) +{ + modperl_input_filter_add_connection(c); + modperl_output_filter_add_connection(c); + return OK; +} + +static int modperl_hook_post_config_last(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + /* in the threaded environment, no server_rec/process_rec + * modifications should be done beyond this point */ +#ifdef USE_ITHREADS + MP_dSCFG(s); + dTHXa(scfg->mip->parent->perl); +#endif + + if (!modperl_post_config_require(s, pconf)) { + exit(1); + } + + if (modperl_threaded_mpm()) { + MP_threads_started = 1; + } + + MP_post_post_config_phase = 1; + +#ifdef MP_TRACE + /* httpd core open_logs handler re-opens s->error_log, which might + * change, even though it still points to the same physical file + * (.e.g on win32 the filehandle will be different. Therefore + * reset the tracing logfile setting here, since this is the + * earliest place, happening after the open_logs phase. + * + * Moreover, we need to dup the filehandle so that when the server + * shuts down, we will be able to log to error_log after Apache + * has closed it (which happens too early for our likening). + */ + { + apr_file_t *dup; + MP_RUN_CROAK(apr_file_dup(&dup, s->error_log, pconf), + "mod_perl core post_config"); + modperl_trace_logfile_set(dup); + } +#endif + +#if MP_PERL_VERSION_AT_LEAST(5, 9, 0) +#define MP_PERL_VERSION_STAMP "Perl/%" SVf +#else +#define MP_PERL_VERSION_STAMP "Perl/v%vd" +#endif + + ap_add_version_component(pconf, MP_VERSION_STRING); + ap_add_version_component(pconf, + Perl_form(aTHX_ MP_PERL_VERSION_STAMP, + PL_patchlevel)); + + modperl_mgv_hash_handlers(pconf, s); + modperl_modglobal_hash_keys(aTHX); + modperl_env_hash_keys(aTHX); +#ifdef USE_ITHREADS + modperl_init_clones(s, pconf); +#endif + +#ifdef MP_NEED_HASH_SEED_FIXUP + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "mod_perl: using Perl HASH_SEED: %"UVuf, MP_init_hash_seed); +#endif + + return OK; +} + +static int modperl_hook_create_request(request_rec *r) +{ + MP_dRCFG; + +#ifdef USE_ITHREADS + /* XXX: this is necessary to make modperl_interp_pool_select() work + * which is used at runtime only to merge dir-configs by + * modperl_module_config_merge(). + * + * Since most requests won't need it it would be good to add some logic + * (cheaper logic in terms of CPU cycles) to identify those cases and + * avoid the hash operation. + */ + MP_TRACE_i(MP_FUNC, "setting userdata MODPERL_R in pool %#lx to %lx", + (unsigned long)r->pool, (unsigned long)r); + (void)apr_pool_userdata_set((void *)r, "MODPERL_R", NULL, r->pool); +#endif + + modperl_config_req_init(r, rcfg); + modperl_config_req_cleanup_register(r, rcfg); + + /* set the default for cgi header parsing On as early as possible + * so $r->content_type in any phase after header_parser could turn + * it off. wb->header_parse will be set to 1 only if this flag + * wasn't turned off and MpDirPARSE_HEADERS is on + */ + MpReqPARSE_HEADERS_On(rcfg); + + return OK; +} + +static int modperl_hook_post_read_request(request_rec *r) +{ +#ifdef USE_ITHREADS + MP_TRACE_i(MP_FUNC, "%s %s:%d%s", + r->method, r->connection->local_addr->hostname, + r->connection->local_addr->port, r->unparsed_uri); +#endif + + /* if 'PerlOptions +GlobalRequest' is outside a container */ + modperl_global_request_cfg_set(r); + + return OK; +} + +static int modperl_hook_header_parser(request_rec *r) +{ + /* if 'PerlOptions +GlobalRequest' is inside a container */ + modperl_global_request_cfg_set(r); + + return OK; +} + +static int modperl_destruct_level = 2; /* default is full tear down */ + +int modperl_perl_destruct_level(void) +{ + return modperl_destruct_level; +} + +#ifdef USE_ITHREADS + +static apr_status_t +modperl_perl_call_endav_mip(pTHX_ modperl_interp_pool_t *mip, + void *data) +{ + modperl_perl_call_endav(aTHX); + return APR_SUCCESS; +} + +#endif /* USE_ITHREADS */ + +static apr_status_t modperl_child_exit(void *data) +{ + char *level = NULL; + server_rec *s = (server_rec *)data; + + modperl_callback_process(MP_CHILD_EXIT_HANDLER, server_pool, s, + MP_HOOK_VOID); + + if ((level = getenv("PERL_DESTRUCT_LEVEL"))) { + modperl_destruct_level = atoi(level); + } + else { + /* default to no teardown in the children */ + modperl_destruct_level = 0; + } + + if (modperl_destruct_level) { + apr_pool_clear(server_pool); + } + else { + /* run the END blocks of this child process if + * modperl_perl_destruct is not called for this process */ +#ifdef USE_ITHREADS + modperl_interp_mip_walk_servers(NULL, s, + modperl_perl_call_endav_mip, + (void*)NULL); +#else + modperl_perl_call_endav(aTHX); +#endif + } + + server_pool = NULL; + + return APR_SUCCESS; +} + +static void modperl_hook_child_init(apr_pool_t *p, server_rec *s) +{ + modperl_perl_init_ids_server(s); + + apr_pool_cleanup_register(p, (void *)s, modperl_child_exit, + apr_pool_cleanup_null); +} + +#define MP_FILTER_HANDLER(f) f, NULL + +void modperl_register_hooks(apr_pool_t *p) +{ + +#ifdef USE_ITHREADS + APR_REGISTER_OPTIONAL_FN(modperl_interp_unselect); + APR_REGISTER_OPTIONAL_FN(modperl_thx_interp_get); +#endif + + /* for <IfDefine MODPERL2> and Apache2->define("MODPERL2") */ + *(char **)apr_array_push(ap_server_config_defines) = + apr_pstrdup(ap_server_config_defines->pool, "MODPERL2"); + + ap_hook_pre_config(modperl_hook_pre_config, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_open_logs(modperl_hook_init, + NULL, NULL, APR_HOOK_FIRST); + + ap_hook_post_config(modperl_hook_post_config_last, + NULL, NULL, APR_HOOK_REALLY_LAST); + + ap_hook_handler(modperl_response_handler, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_handler(modperl_response_handler_cgi, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_insert_filter(modperl_output_filter_add_request, + NULL, NULL, APR_HOOK_LAST); + + ap_hook_insert_filter(modperl_input_filter_add_request, + NULL, NULL, APR_HOOK_LAST); + + ap_register_output_filter(MP_FILTER_REQUEST_OUTPUT_NAME, + MP_FILTER_HANDLER(modperl_output_filter_handler), + AP_FTYPE_RESOURCE); + + ap_register_input_filter(MP_FILTER_REQUEST_INPUT_NAME, + MP_FILTER_HANDLER(modperl_input_filter_handler), + AP_FTYPE_RESOURCE); + + ap_register_output_filter(MP_FILTER_CONNECTION_OUTPUT_NAME, + MP_FILTER_HANDLER(modperl_output_filter_handler), + AP_FTYPE_CONNECTION); + + ap_register_input_filter(MP_FILTER_CONNECTION_INPUT_NAME, + MP_FILTER_HANDLER(modperl_input_filter_handler), + AP_FTYPE_CONNECTION); + + ap_hook_pre_connection(modperl_hook_pre_connection, + NULL, NULL, APR_HOOK_FIRST); + + ap_hook_create_request(modperl_hook_create_request, + NULL, NULL, APR_HOOK_MIDDLE); + + /* both of these hooks need to run really, really first. + * otherwise, the global request_rec will be set up _after_ some + * Perl handlers run. + */ + ap_hook_post_read_request(modperl_hook_post_read_request, + NULL, NULL, MODPERL_HOOK_REALLY_REALLY_FIRST); + + ap_hook_header_parser(modperl_hook_header_parser, + NULL, NULL, MODPERL_HOOK_REALLY_REALLY_FIRST); + + ap_hook_child_init(modperl_hook_child_init, + NULL, NULL, MODPERL_HOOK_REALLY_REALLY_FIRST); + + modperl_register_handler_hooks(); +} + +static const command_rec modperl_cmds[] = { + MP_CMD_SRV_ITERATE("PerlSwitches", switches, "Perl Switches"), + MP_CMD_DIR_ITERATE("PerlModule", modules, "PerlModule"), + MP_CMD_DIR_ITERATE("PerlRequire", requires, "PerlRequire"), + MP_CMD_SRV_ITERATE("PerlConfigRequire", config_requires, "PerlConfigRequire"), + MP_CMD_SRV_ITERATE("PerlPostConfigRequire", post_config_requires, "PerlPostConfigRequire"), +#if AP_SERVER_MAJORVERSION_NUMBER>2 || \ + (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3) + MP_CMD_SRV_TAKE2("PerlAddAuthzProvider", authz_provider, "PerlAddAuthzProvider"), + MP_CMD_SRV_TAKE2("PerlAddAuthnProvider", authn_provider, "PerlAddAuthnProvider"), +#endif + MP_CMD_DIR_ITERATE("PerlOptions", options, "Perl Options"), + MP_CMD_DIR_ITERATE("PerlInitHandler", init_handlers, "Subroutine name"), + MP_CMD_DIR_TAKE2("PerlSetVar", set_var, "PerlSetVar"), + MP_CMD_DIR_ITERATE2("PerlAddVar", add_var, "PerlAddVar"), + MP_CMD_DIR_TAKE2("PerlSetEnv", set_env, "PerlSetEnv"), + MP_CMD_SRV_TAKE1("PerlPassEnv", pass_env, "PerlPassEnv"), + MP_CMD_SRV_RAW_ARGS_ON_READ("<Perl", perl, "Perl Code"), + MP_CMD_SRV_RAW_ARGS("Perl", perldo, "Perl Code"), + + MP_CMD_DIR_TAKE1("PerlSetInputFilter", set_input_filter, + "filter[;filter]"), + MP_CMD_DIR_TAKE1("PerlSetOutputFilter", set_output_filter, + "filter[;filter]"), + + MP_CMD_SRV_RAW_ARGS_ON_READ("=pod", pod, "Start of POD"), + MP_CMD_SRV_RAW_ARGS_ON_READ("=back", pod, "End of =over"), + MP_CMD_SRV_RAW_ARGS_ON_READ("=cut", pod_cut, "End of POD"), + MP_CMD_SRV_RAW_ARGS_ON_READ("__END__", END, "Stop reading config"), + + MP_CMD_SRV_RAW_ARGS("PerlLoadModule", load_module, "A Perl module"), +#ifdef MP_TRACE + MP_CMD_SRV_TAKE1("PerlTrace", trace, "Trace level"), +#endif +#ifdef USE_ITHREADS + MP_CMD_SRV_TAKE1("PerlInterpStart", interp_start, + "Number of Perl interpreters to start"), + MP_CMD_SRV_TAKE1("PerlInterpMax", interp_max, + "Max number of running Perl interpreters"), + MP_CMD_SRV_TAKE1("PerlInterpMaxSpare", interp_max_spare, + "Max number of spare Perl interpreters"), + MP_CMD_SRV_TAKE1("PerlInterpMinSpare", interp_min_spare, + "Min number of spare Perl interpreters"), + MP_CMD_SRV_TAKE1("PerlInterpMaxRequests", interp_max_requests, + "Max number of requests per Perl interpreters"), +#endif +#ifdef MP_COMPAT_1X + MP_CMD_DIR_FLAG("PerlSendHeader", send_header, + "Tell mod_perl to scan output for HTTP headers"), + MP_CMD_DIR_FLAG("PerlSetupEnv", setup_env, + "Turn setup of %ENV On or Off"), + MP_CMD_DIR_ITERATE("PerlHandler", response_handlers, + "Subroutine name"), + MP_CMD_SRV_FLAG("PerlTaintCheck", taint_check, + "Turn on -T switch"), + MP_CMD_SRV_FLAG("PerlWarn", warn, + "Turn on -w switch"), +#endif + MP_CMD_ENTRIES, + { NULL }, +}; + +void modperl_response_init(request_rec *r) +{ + MP_dRCFG; + MP_dDCFG; + modperl_wbucket_t *wb; + + if (!rcfg->wbucket) { + rcfg->wbucket = + (modperl_wbucket_t *)apr_palloc(r->pool, + sizeof(*rcfg->wbucket)); + } + + wb = rcfg->wbucket; + + /* setup buffer for output */ + wb->pool = r->pool; + wb->filters = &r->output_filters; + wb->outcnt = 0; + wb->header_parse = MpDirPARSE_HEADERS(dcfg) && MpReqPARSE_HEADERS(rcfg) + ? 1 : 0; + wb->r = r; +} + +apr_status_t modperl_response_finish(request_rec *r) +{ + MP_dRCFG; + + /* flush output buffer */ + return modperl_wbucket_flush(rcfg->wbucket, FALSE); +} + +static int modperl_response_handler_run(request_rec *r) +{ + int retval; + + modperl_response_init(r); + + retval = modperl_callback_per_dir(MP_RESPONSE_HANDLER, r, MP_HOOK_RUN_FIRST); + + if ((retval == DECLINED) && r->content_type) { + r->handler = r->content_type; /* let http_core or whatever try */ + } + + return retval; +} + +int modperl_response_handler(request_rec *r) +{ + MP_dDCFG; + apr_status_t retval, rc; + MP_dINTERP; + + if (!strEQ(r->handler, "modperl")) { + return DECLINED; + } + + MP_INTERPa(r, r->connection, r->server); + + /* default is -SetupEnv, add if PerlOption +SetupEnv */ + if (MpDirSETUP_ENV(dcfg)) { + modperl_env_request_populate(aTHX_ r); + } + + retval = modperl_response_handler_run(r); + rc = modperl_response_finish(r); + if (rc != APR_SUCCESS) { + retval = rc; + } + + MP_INTERP_PUTBACK(interp, aTHX); + + return retval; +} + +int modperl_response_handler_cgi(request_rec *r) +{ + MP_dDCFG; + GV *h_stdin, *h_stdout; + apr_status_t retval, rc; + MP_dRCFG; + MP_dINTERP; + + if (!strEQ(r->handler, "perl-script")) { + return DECLINED; + } + + MP_INTERPa(r, r->connection, r->server); + + modperl_perl_global_request_save(aTHX_ r); + + /* default is +SetupEnv, skip if PerlOption -SetupEnv */ + if (MpDirSETUP_ENV(dcfg) || !MpDirSeenSETUP_ENV(dcfg)) { + modperl_env_request_populate(aTHX_ r); + } + + /* default is +GlobalRequest, skip if PerlOption -GlobalRequest */ + if (MpDirGLOBAL_REQUEST(dcfg) || !MpDirSeenGLOBAL_REQUEST(dcfg)) { + modperl_global_request_set(r); + } + + /* need to create a block around the IO setup so the temp vars + * will be automatically cleaned up when we are done with IO */ + ENTER;SAVETMPS; + h_stdin = modperl_io_override_stdin(aTHX_ r); + h_stdout = modperl_io_override_stdout(aTHX_ r); + + modperl_env_request_tie(aTHX_ r); + + retval = modperl_response_handler_run(r); + + modperl_env_request_untie(aTHX_ r); + + modperl_perl_global_request_restore(aTHX_ r); + + modperl_io_restore_stdin(aTHX_ h_stdin); + modperl_io_restore_stdout(aTHX_ h_stdout); + FREETMPS;LEAVE; + + MP_INTERP_PUTBACK(interp, aTHX); + + /* flush output buffer after interpreter is putback */ + rc = modperl_response_finish(r); + if (rc != APR_SUCCESS) { + retval = rc; + } + + switch (rcfg->status) { + case HTTP_MOVED_TEMPORARILY: + /* set by modperl_cgi_header_parse */ + retval = HTTP_MOVED_TEMPORARILY; + break; + } + + return retval; +} + +/* This ugly hack pulls in any function listed in + * modperl_exports.c. Otherwise, the over-zealous + * linker would remove unused api functions + */ +const void *modperl_suck_in_ugly_hack(void); +const void *modperl_suck_in_ugly_hack(void) +{ + extern const void *modperl_ugly_hack; + return modperl_ugly_hack; +} + +module AP_MODULE_DECLARE_DATA perl_module = { + STANDARD20_MODULE_STUFF, + modperl_config_dir_create, /* dir config creater */ + modperl_config_dir_merge, /* dir merger --- default is to override */ + modperl_config_srv_create, /* server config */ + modperl_config_srv_merge, /* merge server config */ + modperl_cmds, /* table of config file commands */ + modperl_register_hooks, /* register hooks */ +}; + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/mod_perl.h b/2_0_13/src/modules/perl/mod_perl.h new file mode 100644 index 0000000..e11e7a8 --- /dev/null +++ b/2_0_13/src/modules/perl/mod_perl.h
@@ -0,0 +1,207 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_PERL_H +#define MOD_PERL_H + +#include "modperl_apache_includes.h" +#include "modperl_common_includes.h" +#include "modperl_apache_compat.h" + +#ifdef WIN32 +#define MP_THREADED 1 +#else +#define MP_THREADED (defined(USE_ITHREADS) && APR_HAS_THREADS) +#endif + +extern module AP_MODULE_DECLARE_DATA perl_module; + +#include "modperl_error.h" +#include "modperl_flags.h" +#include "modperl_hooks.h" +#include "modperl_perl_global.h" +#include "modperl_perl_pp.h" +#include "modperl_sys.h" +#include "modperl_const.h" +#include "modperl_constants.h" + +/* both perl and apr have largefile support enabled */ +#if defined(USE_LARGE_FILES) && APR_HAS_LARGE_FILES +#define MP_LARGE_FILES_ENABLED +#endif + +/* both perl and apr have largefile support disabled */ +#if (!defined(USE_LARGE_FILES)) && !APR_HAS_LARGE_FILES +#define MP_LARGE_FILES_DISABLED +#endif + +/* perl largefile support is enabled, apr support is disabled */ +#if defined(USE_LARGE_FILES) && !APR_HAS_LARGE_FILES +#define MP_LARGE_FILES_PERL_ONLY +#endif + +/* apr largefile support is enabled, perl support is disabled */ +#if (!defined(USE_LARGE_FILES)) && APR_HAS_LARGE_FILES +#define MP_LARGE_FILES_APR_ONLY +#endif + +/* conflict due to not have either both perl and apr + * support enabled or both disabled + */ +#if defined(MP_LARGE_FILES_APR_ONLY) || defined(MP_LARGE_FILES_PERL_ONLY) +#define MP_LARGE_FILES_CONFLICT +#endif + +#ifdef MP_USE_GTOP +#include "modperl_gtop.h" +#endif +#include "modperl_time.h" +#include "modperl_types.h" +#include "modperl_util.h" +#include "modperl_config.h" +#include "modperl_cmd.h" +#include "modperl_handler.h" +#include "modperl_callback.h" +#include "modperl_tipool.h" +#include "modperl_interp.h" +#include "modperl_log.h" +#include "modperl_options.h" +#include "modperl_directives.h" +#include "modperl_io.h" +#include "modperl_io_apache.h" +#include "modperl_filter.h" +#include "modperl_bucket.h" +#include "modperl_pcw.h" +#include "modperl_mgv.h" +#include "modperl_global.h" +#include "modperl_env.h" +#include "modperl_cgi.h" +#include "modperl_perl.h" +#include "modperl_svptr_table.h" +#include "modperl_module.h" +#include "modperl_debug.h" + +int modperl_threads_started(void); +int modperl_threaded_mpm(void); +int modperl_post_post_config_phase(void); + +#define MP_CROAK_IF_THREADS_STARTED(what) \ + if (modperl_threads_started()) { \ + Perl_croak(aTHX_ "Can't run '%s' in the threaded " \ + "environment after server startup", what); \ + } + +#define MP_CROAK_IF_THREADED_MPM(what) \ + if (modperl_threaded_mpm()) { \ + Perl_croak(aTHX_ "Can't run '%s' in a threaded mpm", \ + what); \ + } + +#define MP_CROAK_IF_POST_POST_CONFIG_PHASE(what) \ + if (modperl_post_post_config_phase()) { \ + Perl_croak(aTHX_ "Can't run '%s' after server startup", \ + what); \ + } + +int modperl_init_vhost(server_rec *s, apr_pool_t *p, + server_rec *base_server); +void modperl_init(server_rec *s, apr_pool_t *p); +void modperl_init_globals(server_rec *s, apr_pool_t *pconf); +int modperl_run(void); +int modperl_is_running(void); +int modperl_hook_init(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s); +int modperl_hook_pre_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp); +void modperl_register_hooks(apr_pool_t *p); +apr_pool_t *modperl_server_pool(void); +apr_pool_t *modperl_server_user_pool(void); +PerlInterpreter *modperl_startup(server_rec *s, apr_pool_t *p); +int modperl_perl_destruct_level(void); +void xs_init(pTHX); + +void modperl_response_init(request_rec *r); +apr_status_t modperl_response_finish(request_rec *r); +int modperl_response_handler(request_rec *r); +int modperl_response_handler_cgi(request_rec *r); + +#define MgTypeExt(mg) (mg->mg_type == '~') + +typedef void MP_FUNC_NONSTD_T(modperl_var_modify_t) (apr_table_t *, + apr_table_t *, + const char *, + const char *); + +/* we need to hook a few internal things before APR_HOOK_REALLY_FIRST */ +#define MODPERL_HOOK_REALLY_REALLY_FIRST (-20) + +#ifdef USE_ITHREADS +APR_DECLARE_OPTIONAL_FN(apr_status_t,modperl_interp_unselect,(void *)); +APR_DECLARE_OPTIONAL_FN(modperl_interp_t *,modperl_thx_interp_get,(PerlInterpreter *)); +#endif + +/* + * perl context overriding and restoration is required when + * PerlOptions +Parent/+Clone is used in vhosts, and perl is used to + * at the server startup. So that <Perl> sections, PerlLoadModule, + * PerlModule and PerlRequire are all run using the right perl context + * and restore to the original context when they are done. + * + * As of perl-5.8.3 it's unfortunate that it uses PERL_GET_CONTEXT and + * doesn't rely on the passed pTHX internally. When and if perl is + * fixed to always use pTHX if available, this context switching mess + * can be removed. + */ +#ifdef USE_ITHREADS + +#define MP_PERL_CONTEXT_DECLARE \ + PerlInterpreter *orig_perl = NULL; \ + pTHX; + +#define MP_PERL_CONTEXT_STORE \ + orig_perl = PERL_GET_CONTEXT; + +#define MP_PERL_CONTEXT_OVERRIDE(new_perl) \ + aTHX = new_perl; \ + PERL_SET_CONTEXT(aTHX); + +#define MP_PERL_CONTEXT_STORE_OVERRIDE(new_perl) \ + MP_PERL_CONTEXT_STORE; \ + MP_PERL_CONTEXT_OVERRIDE(new_perl) + +#define MP_PERL_CONTEXT_RESTORE \ + if (orig_perl) { \ + PERL_SET_CONTEXT(orig_perl); \ + } + +#else /* #ifdef USE_ITHREADS */ + +#define MP_PERL_CONTEXT_DECLARE +#define MP_PERL_CONTEXT_STORE +#define MP_PERL_CONTEXT_OVERRIDE(new_perl) +#define MP_PERL_CONTEXT_STORE_OVERRIDE(new_perl) +#define MP_PERL_CONTEXT_RESTORE + +#endif /* end of #ifdef USE_ITHREADS */ + +#endif /* MOD_PERL_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_apache_compat.c b/2_0_13/src/modules/perl/modperl_apache_compat.c new file mode 100644 index 0000000..1c1700b --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_apache_compat.c
@@ -0,0 +1,79 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define AP_DECLARE_EXPORT +#include "mod_perl.h" + +/* back compat adjustements for older Apache versions + * BACK_COMPAT_MARKER: make back compat issues easy to find :) + */ + +/* use the following format: + * #if ! AP_MODULE_MAGIC_AT_LEAST(20020903,4) + * [compat code] + * #endif + * and don't forget to insert comments explaining exactly + * which httpd release allows us to remove the compat code + */ + +/* pre-APACHE_2.2.4 */ +#if ! AP_MODULE_MAGIC_AT_LEAST(20051115,4) + +#define modperl_warn_fallback_http_function(ver, fallback) \ + { \ + dTHX; \ + Perl_warn(aTHX_ "%s() not available until httpd/%s " \ + "falling back to %s()", \ + MP_FUNC, ver, fallback); \ + } + +/* added in APACHE_2.2.4 */ +AP_DECLARE(const char *) ap_get_server_description(void) { + modperl_warn_fallback_http_function("2.2.4", "ap_get_server_version"); + return ap_get_server_version(); +} + +AP_DECLARE(const char *) ap_get_server_banner(void) { + modperl_warn_fallback_http_function("2.2.4", "ap_get_server_version"); + return ap_get_server_version(); +} + +#endif /* pre-APACHE_2.2.4 */ + +/* since-APACHE-2.3.0 */ +#if AP_MODULE_MAGIC_AT_LEAST(20060905,0) +#define modperl_warn_deprecated_http_function(ver, fallback) \ + { \ + dTHX; \ + Perl_warn(aTHX_ "%s() is deprecated since httpd/%s " \ + "try using %s() instead", \ + MP_FUNC, ver, fallback); \ + } + +AP_DECLARE(const char *) ap_get_server_version(void) { + modperl_warn_deprecated_http_function("2.3.0", + "ap_get_server_(description|banner)"); + return ap_get_server_banner(); +} + +#endif /* since-APACHE-2.3.0 */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_apache_compat.h b/2_0_13/src/modules/perl/modperl_apache_compat.h new file mode 100644 index 0000000..0d7058b --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_apache_compat.h
@@ -0,0 +1,111 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_APACHE_COMPAT_H +#define MODPERL_APACHE_COMPAT_H + +/* back compat adjustements for older Apache versions */ + +#if !APR_HAS_THREADS +typedef unsigned long apr_os_thread_t; +typedef void * apr_thread_mutex_t; +typedef void * apr_thread_rwlock_t; +#endif + +/* back compat adjustements for older Apache versions + * BACK_COMPAT_MARKER: make back compat issues easy to find :) + */ + +/* use the following format: + * #if ! AP_MODULE_MAGIC_AT_LEAST(20020903,4) + * [compat code] + * #endif + * and don't forget to insert comments explaining exactly + * which httpd release allows us to remove the compat code + */ + +/* pre-APACHE_2.2.4 */ +#if ! AP_MODULE_MAGIC_AT_LEAST(20051115,4) + +/* added in APACHE_2.2.4 */ +AP_DECLARE(const char *) ap_get_server_description(void); +AP_DECLARE(const char *) ap_get_server_banner(void); + +#endif /* pre-APACHE_2.2.4 */ + +/* since-APACHE-2.3.0 */ +#if AP_MODULE_MAGIC_AT_LEAST(20060905,0) + +/* removed in APACHE-2.3.0 */ +AP_DECLARE(const char *) ap_get_server_version(void); + +#endif /* since-APACHE-2.3.0 */ + +/* ap_http_scheme is called ap_http_method in httpd 2.0 */ +#ifndef ap_http_scheme +#define ap_http_scheme(r) ap_http_method(r) +#endif + +#if AP_SERVER_MAJORVERSION_NUMBER>2 || AP_SERVER_MINORVERSION_NUMBER>=2 +#define MP_HTTPD_HAS_OVERRIDE_OPTS +#endif + +#define MP_HTTPD_OVERRIDE_HTACCESS (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES) + +#define MP_HTTPD_OVERRIDE_OPTS_UNSET (-1) +#if AP_SERVER_MAJORVERSION_NUMBER>2 || \ + (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3) + +/* 2.4 API */ +#define MP_HTTPD_OVERRIDE_OPTS_DEFAULT (OPT_UNSET | \ + OPT_ALL | \ + OPT_SYM_OWNER | \ + OPT_MULTI) +#define mp_add_loaded_module(modp, pool, name) \ + ap_add_loaded_module((modp), (pool), (name)) + +#define mp_loglevel(s) ((s)->log.level) +#define mp_module_index_ perl_module.module_index, + +#else +/* 2.2 API */ +#define MP_HTTPD_OVERRIDE_OPTS_DEFAULT (OPT_UNSET | \ + OPT_ALL | \ + OPT_INCNOEXEC | \ + OPT_SYM_OWNER | \ + OPT_MULTI) +#define mp_add_loaded_module(modp, pool, name) \ + ap_add_loaded_module((modp), (pool)) + +#define mp_loglevel(s) ((s)->loglevel) +#define mp_module_index_ + +#define ap_unixd_config unixd_config + +#endif /* 2.4 vs. 2.2 API */ + +#ifndef PROXYREQ_RESPONSE +#define PROXYREQ_RESPONSE (3) +#endif + +#endif /* MODPERL_APACHE_COMPAT_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_apache_includes.h b/2_0_13/src/modules/perl/modperl_apache_includes.h new file mode 100644 index 0000000..a06cc2b --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_apache_includes.h
@@ -0,0 +1,59 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_APACHE_INCLUDES_H +#define MODPERL_APACHE_INCLUDES_H + +/* header files for Apache */ + +#ifndef CORE_PRIVATE +#define CORE_PRIVATE +#endif + +#include "ap_mmn.h" +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_request.h" +#include "http_connection.h" +#include "http_core.h" +#include "http_vhost.h" +#include "ap_mpm.h" + +#include "util_filter.h" + +#include "util_script.h" + +#if !defined(MP_IN_XS) && AP_MODULE_MAGIC_AT_LEAST(20100606, 0) +APLOG_USE_MODULE(perl); +#endif + +#if AP_SERVER_MAJORVERSION_NUMBER>2 || \ + (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3) +#include "ap_provider.h" +#include "mod_auth.h" +#endif + +#endif /* MODPERL_APACHE_INCLUDES_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_apr_compat.h b/2_0_13/src/modules/perl/modperl_apr_compat.h new file mode 100644 index 0000000..e9d5da4 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_apr_compat.h
@@ -0,0 +1,162 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_APR_COMPAT_H +#define MODPERL_APR_COMPAT_H + +/* back compat adjustements for older libapr versions */ + +/* BACK_COMPAT_MARKER: make back compat issues easy to find :) */ + +/* use the following format: + * #if ! AP_MODULE_MAGIC_AT_LEAST(20020903,4) + * [compat code] + * #endif + * and don't forget to insert comments explaining exactly + * which httpd release allows us to remove the compat code + */ + +/* apr_filetype_e entries rename */ + +#ifndef APR_FILETYPE_NOFILE +#define APR_FILETYPE_NOFILE APR_NOFILE +#endif +#ifndef APR_FILETYPE_REG +#define APR_FILETYPE_REG APR_REG +#endif +#ifndef APR_FILETYPE_DIR +#define APR_FILETYPE_DIR APR_DIR +#endif +#ifndef APR_FILETYPE_CHR +#define APR_FILETYPE_CHR APR_CHR +#endif +#ifndef APR_FILETYPE_BLK +#define APR_FILETYPE_BLK APR_BLK +#endif +#ifndef APR_FILETYPE_PIPE +#define APR_FILETYPE_PIPE APR_PIPE +#endif +#ifndef APR_FILETYPE_LNK +#define APR_FILETYPE_LNK APR_LNK +#endif +#ifndef APR_FILETYPE_SOCK +#define APR_FILETYPE_SOCK APR_SOCK +#endif +#ifndef APR_FILETYPE_UNKFILE +#define APR_FILETYPE_UNKFILE APR_UNKFILE +#endif + + +/* apr file permissions group rename (has no enum) */ + +#if defined(APR_USETID) && !defined(APR_FPROT_USETID) +#define APR_FPROT_USETID APR_USETID +#endif +#ifndef APR_FPROT_UREAD +#define APR_FPROT_UREAD APR_UREAD +#endif +#ifndef APR_FPROT_UWRITE +#define APR_FPROT_UWRITE APR_UWRITE +#endif +#ifndef APR_FPROT_UEXECUTE +#define APR_FPROT_UEXECUTE APR_UEXECUTE +#endif +#if defined(APR_GSETID) && !defined(APR_FPROT_GSETID) +#define APR_FPROT_GSETID APR_GSETID +#endif +#ifndef APR_FPROT_GREAD +#define APR_FPROT_GREAD APR_GREAD +#endif +#ifndef APR_FPROT_GWRITE +#define APR_FPROT_GWRITE APR_GWRITE +#endif +#ifndef APR_FPROT_GEXECUTE +#define APR_FPROT_GEXECUTE APR_GEXECUTE +#endif +#if defined(APR_WSTICKY) && !defined(APR_FPROT_WSTICKY) +#define APR_FPROT_WSTICKY APR_WSTICKY +#endif +#ifndef APR_FPROT_WREAD +#define APR_FPROT_WREAD APR_WREAD +#endif +#ifndef APR_FPROT_WWRITE +#define APR_FPROT_WWRITE APR_WWRITE +#endif +#ifndef APR_FPROT_WEXECUTE +#define APR_FPROT_WEXECUTE APR_WEXECUTE +#endif +#ifndef APR_FPROT_OS_DEFAULT +#define APR_FPROT_OS_DEFAULT APR_OS_DEFAULT +#endif +/* APR_FPROT_FILE_SOURCE_PERMS seems to have only an internal apr + * use */ + +/* apr_file_open flag group rename (has no enum) */ + +#ifndef APR_FOPEN_READ +#define APR_FOPEN_READ APR_READ +#endif +#ifndef APR_FOPEN_WRITE +#define APR_FOPEN_WRITE APR_WRITE +#endif +#ifndef APR_FOPEN_CREATE +#define APR_FOPEN_CREATE APR_CREATE +#endif +#ifndef APR_FOPEN_APPEND +#define APR_FOPEN_APPEND APR_APPEND +#endif +#ifndef APR_FOPEN_TRUNCATE +#define APR_FOPEN_TRUNCATE APR_TRUNCATE +#endif +#ifndef APR_FOPEN_BINARY +#define APR_FOPEN_BINARY APR_BINARY +#endif +#ifndef APR_FOPEN_EXCL +#define APR_FOPEN_EXCL APR_EXCL +#endif +#ifndef APR_FOPEN_BUFFERED +#define APR_FOPEN_BUFFERED APR_BUFFERED +#endif +#ifndef APR_FOPEN_DELONCLOSE +#define APR_FOPEN_DELONCLOSE APR_DELONCLOSE +#endif +#ifndef APR_FOPEN_XTHREAD +#define APR_FOPEN_XTHREAD APR_XTHREAD +#endif +#ifndef APR_FOPEN_SHARELOCK +#define APR_FOPEN_SHARELOCK APR_SHARELOCK +#endif +#ifndef APR_FOPEN_NOCLEANUP +#define APR_FOPEN_NOCLEANUP APR_FILE_NOCLEANUP +#endif +#ifndef APR_FOPEN_SENDFILE_ENABLED +#define APR_FOPEN_SENDFILE_ENABLED APR_SENDFILE_ENABLED +#endif +#ifndef APR_FOPEN_LARGEFILE +/* added in 2.0.50 */ +#ifdef APR_LARGEFILE +#define APR_FOPEN_LARGEFILE APR_LARGEFILE +#endif +#endif + +#endif /* MODPERL_APR_COMPAT_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_apr_includes.h b/2_0_13/src/modules/perl/modperl_apr_includes.h new file mode 100644 index 0000000..ec6e3d6 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_apr_includes.h
@@ -0,0 +1,51 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_APR_INCLUDES_H +#define MODPERL_APR_INCLUDES_H + +/* header files for APR */ + +#ifndef CORE_PRIVATE +#define CORE_PRIVATE +#endif + +#include "apr_version.h" +#include "apr_poll.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_uri.h" +#include "apr_date.h" +#include "apr_buckets.h" +#include "apr_time.h" +#include "apr_network_io.h" +#include "apr_general.h" +#include "apr_uuid.h" +#include "apr_env.h" +#include "apu_version.h" +#if APU_MAJOR_VERSION > 1 \ + || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION > 3) +#include "apu_errno.h" +#endif + +#endif /* MODPERL_APR_INCLUDES_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_bucket.c b/2_0_13/src/modules/perl/modperl_bucket.c new file mode 100644 index 0000000..f5f2c98 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_bucket.c
@@ -0,0 +1,165 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* + * modperl_bucket_sv code derived from mod_snake's ModSnakePyBucket + * by Jon Travis + */ + +typedef struct { + apr_bucket_refcount refcount; + SV *sv; + PerlInterpreter *perl; +} modperl_bucket_sv_t; + +static apr_status_t +modperl_bucket_sv_read(apr_bucket *bucket, const char **str, + apr_size_t *len, apr_read_type_e block) +{ + modperl_bucket_sv_t *svbucket = bucket->data; + dTHXa(svbucket->perl); + STRLEN svlen; + char *pv = SvPV(svbucket->sv, svlen); + + *str = pv + bucket->start; + *len = bucket->length; + + if (svlen < bucket->start + bucket->length) { + /* XXX log error? */ + return APR_EGENERAL; + } + + return APR_SUCCESS; +} + +static void modperl_bucket_sv_destroy(void *data) +{ + modperl_bucket_sv_t *svbucket = data; + dTHXa(svbucket->perl); + + if (!apr_bucket_shared_destroy(svbucket)) { + MP_TRACE_f(MP_FUNC, "bucket refcnt=%d", + ((apr_bucket_refcount *)svbucket)->refcount); + return; + } + + MP_TRACE_f(MP_FUNC, "sv=0x%lx, refcnt=%d", + (unsigned long)svbucket->sv, SvREFCNT(svbucket->sv)); + + SvREFCNT_dec(svbucket->sv); + + apr_bucket_free(svbucket); +} + +static +apr_status_t modperl_bucket_sv_setaside(apr_bucket *bucket, apr_pool_t *pool) +{ + modperl_bucket_sv_t *svbucket = bucket->data; + dTHXa(svbucket->perl); + STRLEN svlen; + char *pv = SvPV(svbucket->sv, svlen); + + if (svlen < bucket->start + bucket->length) { + /* XXX log error? */ + return APR_EGENERAL; + } + + pv = apr_pstrmemdup(pool, pv + bucket->start, bucket->length); + if (pv == NULL) { + return APR_ENOMEM; + } + + /* changes bucket guts by reference */ + if (apr_bucket_pool_make(bucket, pv, bucket->length, pool) == NULL) { + return APR_ENOMEM; + } + + modperl_bucket_sv_destroy(svbucket); + return APR_SUCCESS; +} + +static const apr_bucket_type_t modperl_bucket_sv_type = { + "mod_perl SV bucket", 4, +#if MODULE_MAGIC_NUMBER >= 20020602 + APR_BUCKET_DATA, +#endif + modperl_bucket_sv_destroy, + modperl_bucket_sv_read, + modperl_bucket_sv_setaside, + apr_bucket_shared_split, + apr_bucket_shared_copy, +}; + +static apr_bucket *modperl_bucket_sv_make(pTHX_ + apr_bucket *bucket, + SV *sv, + apr_off_t offset, + apr_size_t len) +{ + modperl_bucket_sv_t *svbucket; + + svbucket = apr_bucket_alloc(sizeof(*svbucket), bucket->list); + + bucket = apr_bucket_shared_make(bucket, svbucket, offset, len); + if (!bucket) { + apr_bucket_free(svbucket); + return NULL; + } + +#ifdef USE_ITHREADS + svbucket->perl = aTHX; +#endif + + /* PADTMP SVs belong to perl and can't be stored away, since perl + * is going to reuse them, so we have no choice but to copy the + * data away, before storing sv */ + if (SvPADTMP(sv)) { + STRLEN len; + char *pv = SvPV(sv, len); + svbucket->sv = newSVpvn(pv, len); + } + else { + svbucket->sv = sv; + (void)SvREFCNT_inc(svbucket->sv); + } + + MP_TRACE_f(MP_FUNC, "sv=0x%lx, refcnt=%d", + (unsigned long)svbucket->sv, SvREFCNT(svbucket->sv)); + + bucket->type = &modperl_bucket_sv_type; + return bucket; +} + +apr_bucket *modperl_bucket_sv_create(pTHX_ apr_bucket_alloc_t *list, SV *sv, + apr_off_t offset, apr_size_t len) +{ + apr_bucket *bucket; + + bucket = apr_bucket_alloc(sizeof(*bucket), list); + APR_BUCKET_INIT(bucket); + bucket->list = list; + bucket->free = apr_bucket_free; + return modperl_bucket_sv_make(aTHX_ bucket, sv, offset, len); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_bucket.h b/2_0_13/src/modules/perl/modperl_bucket.h new file mode 100644 index 0000000..f01506a --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_bucket.h
@@ -0,0 +1,30 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_BUCKET_H +#define MODPERL_BUCKET_H + +apr_bucket *modperl_bucket_sv_create(pTHX_ apr_bucket_alloc_t *list, SV *sv, + apr_off_t offset, apr_size_t len); + +#endif /* MODPERL_BUCKET_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_callback.c b/2_0_13/src/modules/perl/modperl_callback.c new file mode 100644 index 0000000..04f4317 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_callback.c
@@ -0,0 +1,397 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +int modperl_callback(pTHX_ modperl_handler_t *handler, apr_pool_t *p, + request_rec *r, server_rec *s, AV *args) +{ + CV *cv = (CV *)NULL; + I32 flags = G_EVAL|G_SCALAR; + dSP; + int count, status = OK; + + /* handler callbacks shouldn't affect each other's taintedness + * state, so start every callback with a clear tainted status + * before and after the callback one of the main problems we are + * trying to solve is that when modperl_croak called (which calls + * perl's croak((char *)NULL) to throw an error object) it leaves + * the interpreter in the tainted state which later affects other + * callbacks that call eval, etc., which triggers perl crash with: + * Insecure dependency in eval while running setgid. Callback + * called exit. + */ + TAINT_NOT; + + if ((status = modperl_handler_resolve(aTHX_ &handler, p, s)) != OK) { + TAINT_NOT; + return status; + } + + ENTER;SAVETMPS; + PUSHMARK(SP); + + if (MpHandlerMETHOD(handler)) { + GV *gv; + if (!handler->mgv_obj) { + Perl_croak(aTHX_ "panic: %s method handler object is NULL!", + modperl_handler_name(handler)); + } + gv = modperl_mgv_lookup(aTHX_ handler->mgv_obj); + XPUSHs(modperl_mgv_sv(gv)); + } + + if (args) { + I32 items = AvFILLp(args) + 1; + + EXTEND(SP, items); + Copy(AvARRAY(args), SP + 1, items, SV*); + SP += items; + } + + PUTBACK; + + if (MpHandlerANON(handler)) { +#ifdef USE_ITHREADS + cv = modperl_handler_anon_get(aTHX_ handler->mgv_obj); +#else + cv = handler->cv; +#endif + } + else { + GV *gv = modperl_mgv_lookup_autoload(aTHX_ handler->mgv_cv, s, p); + if (gv) { + cv = modperl_mgv_cv(gv); + } + else { + const char *name; + modperl_mgv_t *symbol = handler->mgv_cv; + + /* XXX: need to validate *symbol */ + if (symbol && symbol->name) { + name = modperl_mgv_as_string(aTHX_ symbol, p, 0); + } + else { + name = handler->name; + } + + MP_TRACE_h(MP_FUNC, "[%s] lookup of %s failed", + modperl_server_desc(s, p), name); + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "lookup of '%s' failed", name); + status = HTTP_INTERNAL_SERVER_ERROR; + } + } + + if (status == OK) { + count = call_sv((SV*)cv, flags); + + SPAGAIN; + + if (count != 1) { + /* XXX can this really happen with G_EVAL|G_SCALAR? */ + status = OK; + } + else { + SV *status_sv = POPs; + + if (status_sv == &PL_sv_undef) { + /* ModPerl::Util::exit() and Perl_croak internally + * arrange to return PL_sv_undef with G_EVAL|G_SCALAR */ + status = OK; + } + else { + status = SvIVx(status_sv); + } + } + + PUTBACK; + } + + FREETMPS;LEAVE; + + if (SvTRUE(ERRSV)) { + MP_TRACE_h(MP_FUNC, "$@ = %s", SvPV_nolen(ERRSV)); + status = HTTP_INTERNAL_SERVER_ERROR; + } + + if (status == HTTP_INTERNAL_SERVER_ERROR) { + if (r && r->notes) { + apr_table_merge(r->notes, "error-notes", SvPV_nolen(ERRSV)); + } + } + + TAINT_NOT; + + return status; +} + +int modperl_callback_run_handlers(int idx, int type, + request_rec *r, conn_rec *c, + server_rec *s, + apr_pool_t *pconf, + apr_pool_t *plog, + apr_pool_t *ptemp, + modperl_hook_run_mode_e run_mode) +{ + MP_dINTERP; + MP_dSCFG(s); + MP_dDCFG; + MP_dRCFG; + modperl_handler_t **handlers; + apr_pool_t *p = NULL; + MpAV *av, **avp; + int i, status = OK; + const char *desc = NULL; + AV *av_args = (AV *)NULL; + + if (!MpSrvENABLE(scfg)) { + MP_TRACE_h(MP_FUNC, "PerlOff for server %s:%u", + s->server_hostname, s->port); + return DECLINED; + } + + if (r || c) { + p = c ? c->pool : r->pool; + } + else { + p = pconf; + } + + avp = modperl_handler_lookup_handlers(dcfg, scfg, rcfg, p, + type, idx, FALSE, &desc); + + if (!(avp && (av = *avp))) { + MP_TRACE_h(MP_FUNC, "no %s handlers configured (%s)", + desc, r ? r->uri : ""); + return DECLINED; + } + + MP_INTERPa(r, c, s); + + switch (type) { + case MP_HANDLER_TYPE_PER_SRV: + modperl_handler_make_args(aTHX_ &av_args, + "Apache2::RequestRec", r, NULL); + + /* per-server PerlSetEnv and PerlPassEnv - only once per-request */ + if (! MpReqPERL_SET_ENV_SRV(rcfg)) { + modperl_env_configure_request_srv(aTHX_ r); + } + + break; + case MP_HANDLER_TYPE_PER_DIR: + modperl_handler_make_args(aTHX_ &av_args, + "Apache2::RequestRec", r, NULL); + + /* per-server PerlSetEnv and PerlPassEnv - only once per-request */ + if (! MpReqPERL_SET_ENV_SRV(rcfg)) { + modperl_env_configure_request_srv(aTHX_ r); + } + + /* per-directory PerlSetEnv - only once per-request */ + if (! MpReqPERL_SET_ENV_DIR(rcfg)) { + modperl_env_configure_request_dir(aTHX_ r); + } + + break; + case MP_HANDLER_TYPE_PRE_CONNECTION: + case MP_HANDLER_TYPE_CONNECTION: + modperl_handler_make_args(aTHX_ &av_args, + "Apache2::Connection", c, NULL); + break; + case MP_HANDLER_TYPE_FILES: + modperl_handler_make_args(aTHX_ &av_args, + "APR::Pool", pconf, + "APR::Pool", plog, + "APR::Pool", ptemp, + "Apache2::ServerRec", s, NULL); + break; + case MP_HANDLER_TYPE_PROCESS: + modperl_handler_make_args(aTHX_ &av_args, + "APR::Pool", pconf, + "Apache2::ServerRec", s, NULL); + break; + }; + + modperl_callback_current_callback_set(desc); + + MP_TRACE_h(MP_FUNC, "running %d %s handlers", av->nelts, desc); + handlers = (modperl_handler_t **)av->elts; + + for (i=0; i<av->nelts; i++) { + status = modperl_callback(aTHX_ handlers[i], p, r, s, av_args); + + MP_TRACE_h(MP_FUNC, "callback '%s' returned %d", + modperl_handler_name(handlers[i]), status); + + /* follow Apache's lead and let OK terminate the phase for + * MP_HOOK_RUN_FIRST handlers. MP_HOOK_RUN_ALL handlers keep + * going on OK. MP_HOOK_VOID handlers ignore all errors. + */ + + if (run_mode == MP_HOOK_RUN_ALL) { + /* special case */ + if (type == MP_HANDLER_TYPE_FILES && status != OK) { + /* open_logs and post_config require OK return code or + * the server aborts, so we need to log an error in + * case the handler didn't fail but returned something + * different from OK */ + if (SvTRUE(ERRSV)) { + status = modperl_errsv(aTHX_ status, r, s); + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Callback '%s' returned %d, whereas " + "Apache2::Const::OK (%d) is the only valid " + "return value for %s handlers", + modperl_handler_name(handlers[i]), + status, OK, desc); + } + break; + } + /* the normal case: + * OK and DECLINED continue + * errors end the phase + */ + else if ((status != OK) && (status != DECLINED)) { + + status = modperl_errsv(aTHX_ status, r, s); +#ifdef MP_TRACE + if (i+1 != av->nelts) { + MP_TRACE_h(MP_FUNC, "error status %d leaves %d " + "uncalled %s handlers", + status, av->nelts-i-1, desc); + } +#endif + break; + } + } + else if (run_mode == MP_HOOK_RUN_FIRST) { + /* the exceptional case: + * OK and errors end the phase + * DECLINED continues + */ + + if (status == OK) { +#ifdef MP_TRACE + if (i+1 != av->nelts) { + MP_TRACE_h(MP_FUNC, "OK ends the %s stack, " + "leaving %d uncalled %s handlers", + desc, av->nelts-i-1, desc); + } +#endif + break; + } + if (status != DECLINED) { + status = modperl_errsv(aTHX_ status, r, s); +#ifdef MP_TRACE + if (i+1 != av->nelts) { + MP_TRACE_h(MP_FUNC, "error status %d leaves %d " + "uncalled %s handlers", + status, av->nelts-i-1, desc); + } +#endif + break; + } + } + else { + /* the rare case. + * MP_HOOK_VOID handlers completely ignore the return status + * Apache should handle whatever mod_perl returns, + * so there is no need to mess with the status + */ + } + + /* it's possible that during the last callback a new handler + * was pushed onto the same phase it's running from. av needs + * to be updated. + * + * XXX: would be nice to somehow optimize that + */ + avp = modperl_handler_lookup_handlers(dcfg, scfg, rcfg, p, + type, idx, FALSE, NULL); + if (avp && (av = *avp)) { + handlers = (modperl_handler_t **)av->elts; + } + } + + SvREFCNT_dec((SV*)av_args); + + MP_INTERP_PUTBACK(interp, aTHX); + + return status; +} + +int modperl_callback_per_dir(int idx, request_rec *r, + modperl_hook_run_mode_e run_mode) +{ + return modperl_callback_run_handlers(idx, MP_HANDLER_TYPE_PER_DIR, + r, NULL, r->server, + NULL, NULL, NULL, run_mode); +} + +int modperl_callback_per_srv(int idx, request_rec *r, + modperl_hook_run_mode_e run_mode) +{ + return modperl_callback_run_handlers(idx, + MP_HANDLER_TYPE_PER_SRV, + r, NULL, r->server, + NULL, NULL, NULL, run_mode); +} + +int modperl_callback_connection(int idx, conn_rec *c, + modperl_hook_run_mode_e run_mode) +{ + return modperl_callback_run_handlers(idx, + MP_HANDLER_TYPE_CONNECTION, + NULL, c, c->base_server, + NULL, NULL, NULL, run_mode); +} + +int modperl_callback_pre_connection(int idx, conn_rec *c, void *csd, + modperl_hook_run_mode_e run_mode) +{ + return modperl_callback_run_handlers(idx, + MP_HANDLER_TYPE_PRE_CONNECTION, + NULL, c, c->base_server, + NULL, NULL, NULL, run_mode); +} + +void modperl_callback_process(int idx, apr_pool_t *p, server_rec *s, + modperl_hook_run_mode_e run_mode) +{ + modperl_callback_run_handlers(idx, MP_HANDLER_TYPE_PROCESS, + NULL, NULL, s, + p, NULL, NULL, run_mode); +} + +int modperl_callback_files(int idx, + apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s, + modperl_hook_run_mode_e run_mode) +{ + return modperl_callback_run_handlers(idx, MP_HANDLER_TYPE_FILES, + NULL, NULL, s, + pconf, plog, ptemp, run_mode); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_callback.h b/2_0_13/src/modules/perl/modperl_callback.h new file mode 100644 index 0000000..8441b2d --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_callback.h
@@ -0,0 +1,75 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_CALLBACK_H +#define MODPERL_CALLBACK_H + +/* alias some hook names to match Perl*Handler names */ +#define ap_hook_trans ap_hook_translate_name +#define ap_hook_access ap_hook_access_checker +#define ap_hook_authen ap_hook_check_user_id +#define ap_hook_authz ap_hook_auth_checker +#define ap_hook_type ap_hook_type_checker +#define ap_hook_fixup ap_hook_fixups +#define ap_hook_log ap_hook_log_transaction + +#define modperl_callback_current_callback_sv \ + get_sv("Apache2::__CurrentCallback", TRUE) + +#define modperl_callback_current_callback_set(desc) \ + sv_setpv(modperl_callback_current_callback_sv, desc) + +#define modperl_callback_current_callback_get() \ + SvPVX(modperl_callback_current_callback_sv) + +int modperl_callback(pTHX_ modperl_handler_t *handler, apr_pool_t *p, + request_rec *r, server_rec *s, AV *args); + +int modperl_callback_run_handlers(int idx, int type, + request_rec *r, conn_rec *c, server_rec *s, + apr_pool_t *pconf, + apr_pool_t *plog, + apr_pool_t *ptemp, + modperl_hook_run_mode_e run_mode); + +int modperl_callback_per_dir(int idx, request_rec *r, + modperl_hook_run_mode_e run_mode); + +int modperl_callback_per_srv(int idx, request_rec *r, + modperl_hook_run_mode_e run_mode); + +int modperl_callback_connection(int idx, conn_rec *c, + modperl_hook_run_mode_e run_mode); + +int modperl_callback_pre_connection(int idx, conn_rec *c, void *csd, + modperl_hook_run_mode_e run_mode); + +void modperl_callback_process(int idx, apr_pool_t *p, server_rec *s, + modperl_hook_run_mode_e run_mode); + +int modperl_callback_files(int idx, + apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s, + modperl_hook_run_mode_e run_mode); + +#endif /* MODPERL_CALLBACK_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_cgi.c b/2_0_13/src/modules/perl/modperl_cgi.c new file mode 100644 index 0000000..66743e6 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_cgi.c
@@ -0,0 +1,110 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +MP_INLINE int modperl_cgi_header_parse(request_rec *r, char *buffer, + apr_size_t *len, const char **body) +{ + int status; + int termarg; + const char *location; + const char *tmp; + apr_size_t tlen, newln; + + if (!buffer) { + return DECLINED; + } + + /* ap_scan_script_header_err_strs won't handle correctly binary + * data following the headers, e.g. when the terminating /\n\r?\n/ + * is followed by \0\0 which is a part of the response + * body. Therefore we need to separate the headers from the body + * and not rely on ap_scan_script_header_err_strs to do that for + * us. + */ + tmp = buffer; + newln = 0; + tlen = *len; + while (tlen--) { + /* that strange mix of CR and \n (and not LF) copied from + * util_script.c:ap_scan_script_header_err_core + */ + if (*tmp != CR && *tmp != '\n') { + newln = 0; + } + if (*tmp == '\n') { + newln++; + } + tmp++; + if (newln == 2) { + break; + } + } + + if (tmp - buffer >= *len) { + *body = NULL; /* no body along with headers */ + *len = 0; + } + else { + *body = tmp; + *len = *len - (tmp - buffer); + } + + status = ap_scan_script_header_err_strs(r, NULL, NULL, + &termarg, buffer, NULL); + + /* code below from mod_cgi.c */ + location = apr_table_get(r->headers_out, "Location"); + + if (location && (location[0] == '/') && (r->status == 200)) { + r->method = apr_pstrdup(r->pool, "GET"); + r->method_number = M_GET; + + /* We already read the message body (if any), so don't allow + * the redirected request to think it has one. We can ignore + * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. + */ + apr_table_unset(r->headers_in, "Content-Length"); + + ap_internal_redirect_handler(location, r); + + return OK; + } + else if (location && (r->status == 200)) { + MP_dRCFG; + + /* Note that if a script wants to produce its own Redirect + * body, it now has to explicitly *say* "Status: 302" + */ + + /* XXX: this is a hack. + * filter return value doesn't seem to impact anything. + */ + rcfg->status = HTTP_MOVED_TEMPORARILY; + + return HTTP_MOVED_TEMPORARILY; + } + + return status; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_cgi.h b/2_0_13/src/modules/perl/modperl_cgi.h new file mode 100644 index 0000000..4924257 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_cgi.h
@@ -0,0 +1,45 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_CGI_H +#define MODPERL_CGI_H + +/** + * split the HTTP headers from the body (if any) and feed them to + * Apache. Populate the pointer to the remaining data in the buffer + * (body if any or NULL) + * + * @param r request_rec + * @param buffer a string with headers and potentially body + * (could be non-null terminated) + * @param len length of 'buffer' on entry + * length of 'body' on return + * @param body pointer to the body within the 'buffer' on return + * NULL if the buffer contained only headers + * + * @return status + */ +MP_INLINE int modperl_cgi_header_parse(request_rec *r, char *buffer, + apr_size_t *len, const char **body); + +#endif /* MODPERL_CGI_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_cmd.c b/2_0_13/src/modules/perl/modperl_cmd.c new file mode 100644 index 0000000..5b28771 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_cmd.c
@@ -0,0 +1,822 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* This ensures that a given directive is either in Server context + * or in a .htaccess file, usefull for things like PerlRequire + */ +#define MP_CHECK_SERVER_OR_HTACCESS_CONTEXT \ + if (parms->path && (parms->override & ACCESS_CONF)) { \ + ap_directive_t *d = parms->directive; \ + return apr_psprintf(parms->pool, \ + "%s directive not allowed in a %s> block", \ + d->directive, \ + d->parent->directive); \ + } + +static char *modperl_cmd_unclosed_directive(cmd_parms *parms) +{ + return apr_pstrcat(parms->pool, parms->cmd->name, + "> directive missing closing '>'", NULL); +} + +static char *modperl_cmd_too_late(cmd_parms *parms) +{ + return apr_pstrcat(parms->pool, "mod_perl is already running, " + "too late for ", parms->cmd->name, NULL); +} + +char *modperl_cmd_push_handlers(MpAV **handlers, const char *name, + apr_pool_t *p) +{ + modperl_handler_t *h = modperl_handler_new(p, name); + + if (!*handlers) { + *handlers = modperl_handler_array_new(p); + MP_TRACE_d(MP_FUNC, "created handler stack"); + } + + /* XXX parse_handler if Perl is running */ + + modperl_handler_array_push(*handlers, h); + MP_TRACE_d(MP_FUNC, "pushed handler: %s", h->name); + + return NULL; +} + +char *modperl_cmd_push_filter_handlers(MpAV **handlers, + const char *name, + apr_pool_t *p) +{ + modperl_handler_t *h = modperl_handler_new(p, name); + + /* filter modules need to be autoloaded, because their attributes + * need to be known long before the callback is issued + */ + if (*name == '-') { + MP_TRACE_h(MP_FUNC, + "warning: filter handler %s will be not autoloaded. " + "Unless the module defining this handler is explicitly " + "preloaded, filter attributes will be ignored."); + } + else { + MpHandlerAUTOLOAD_On(h); + MP_TRACE_h(MP_FUNC, + "filter handler %s will be autoloaded (to make " + "the filter attributes available)", h->name); + } + + if (!*handlers) { + *handlers = modperl_handler_array_new(p); + MP_TRACE_d(MP_FUNC, "created handler stack"); + } + + modperl_handler_array_push(*handlers, h); + MP_TRACE_d(MP_FUNC, "pushed httpd filter handler: %s", h->name); + + return NULL; +} + +static char *modperl_cmd_push_httpd_filter_handlers(MpAV **handlers, + const char *name, + apr_pool_t *p) +{ + modperl_handler_t *h = modperl_handler_new(p, name); + + /* this is not a real mod_perl handler, we just re-use the + * handlers structure to be able to mix mod_perl and non-mod_perl + * filters */ + MpHandlerFAKE_On(h); + h->attrs = MP_FILTER_HTTPD_HANDLER; + + if (!*handlers) { + *handlers = modperl_handler_array_new(p); + MP_TRACE_d(MP_FUNC, "created handler stack"); + } + + modperl_handler_array_push(*handlers, h); + MP_TRACE_d(MP_FUNC, "pushed httpd filter handler: %s", h->name); + + return NULL; +} + + +#define MP_CMD_SRV_TRACE \ + MP_TRACE_d(MP_FUNC, "%s %s", parms->cmd->name, arg) + +#define MP_CMD_SRV_CHECK \ +MP_CMD_SRV_TRACE; \ +{ \ + const char *err = ap_check_cmd_context(parms, GLOBAL_ONLY); \ + if (err) return err; \ +} + +MP_CMD_SRV_DECLARE(trace) +{ + MP_CMD_SRV_CHECK; + modperl_trace_level_set_apache(parms->server, arg); + return NULL; +} + +/* this test shows whether the perl for the current s is running + * (either base or vhost) */ +static int modperl_vhost_is_running(server_rec *s) +{ +#ifdef USE_ITHREADS + if (s->is_virtual){ + MP_dSCFG(s); + return scfg->mip ? TRUE : FALSE; + } +#endif + + return modperl_is_running(); + +} + +MP_CMD_SRV_DECLARE(switches) +{ + server_rec *s = parms->server; + MP_dSCFG(s); + if (modperl_vhost_is_running(s)) { + return modperl_cmd_too_late(parms); + } + MP_TRACE_d(MP_FUNC, "arg = %s", arg); + + if (!strncasecmp(arg, "+inherit", 8)) { + modperl_cmd_options(parms, mconfig, "+InheritSwitches"); + } + else { + modperl_config_srv_argv_push(arg); + } + return NULL; +} + +MP_CMD_SRV_DECLARE(modules) +{ + MP_dSCFG(parms->server); + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + MP_PERL_CONTEXT_DECLARE; + + MP_CHECK_SERVER_OR_HTACCESS_CONTEXT; + + if (modperl_is_running() && + modperl_init_vhost(parms->server, parms->pool, NULL) != OK) + { + return "init mod_perl vhost failed"; + } + + if (modperl_is_running()) { + char *error = NULL; + + MP_TRACE_d(MP_FUNC, "load PerlModule %s", arg); + + MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl); + if (!modperl_require_module(aTHX_ arg, FALSE)) { + error = SvPVX(ERRSV); + } + else { + modperl_env_sync_srv_env_hash2table(aTHX_ parms->pool, scfg); + modperl_env_sync_dir_env_hash2table(aTHX_ parms->pool, dcfg); + } + MP_PERL_CONTEXT_RESTORE; + + return error; + } + else { + MP_TRACE_d(MP_FUNC, "push PerlModule %s", arg); + *(const char **)apr_array_push(scfg->PerlModule) = arg; + return NULL; + } +} + +MP_CMD_SRV_DECLARE(requires) +{ + MP_dSCFG(parms->server); + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + MP_PERL_CONTEXT_DECLARE; + + MP_CHECK_SERVER_OR_HTACCESS_CONTEXT; + + if (modperl_is_running() && + modperl_init_vhost(parms->server, parms->pool, NULL) != OK) + { + return "init mod_perl vhost failed"; + } + + if (modperl_is_running()) { + char *error = NULL; + + MP_TRACE_d(MP_FUNC, "load PerlRequire %s", arg); + + MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl); + if (!modperl_require_file(aTHX_ arg, FALSE)) { + error = SvPVX(ERRSV); + } + else { + modperl_env_sync_srv_env_hash2table(aTHX_ parms->pool, scfg); + modperl_env_sync_dir_env_hash2table(aTHX_ parms->pool, dcfg); + } + MP_PERL_CONTEXT_RESTORE; + + return error; + } + else { + MP_TRACE_d(MP_FUNC, "push PerlRequire %s", arg); + *(const char **)apr_array_push(scfg->PerlRequire) = arg; + return NULL; + } +} + +MP_CMD_SRV_DECLARE(config_requires) +{ + /* we must init earlier than normal */ + modperl_run(); + + /* PerlConfigFile is only different from PerlRequires by forcing + * an immediate init. + */ + return modperl_cmd_requires(parms, mconfig, arg); +} + +MP_CMD_SRV_DECLARE(post_config_requires) +{ + apr_pool_t *p = parms->temp_pool; + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + MP_dSCFG(parms->server); + + modperl_require_file_t *require = apr_pcalloc(p, sizeof(*require)); + MP_TRACE_d(MP_FUNC, "push PerlPostConfigRequire for %s", arg); + require->file = arg; + require->dcfg = dcfg; + + *(modperl_require_file_t **) + apr_array_push(scfg->PerlPostConfigRequire) = require; + + return NULL; +} + +static void modperl_cmd_addvar_func(apr_table_t *configvars, + apr_table_t *setvars, + const char *key, const char *val) +{ + apr_table_addn(configvars, key, val); +} + +/* Conceptually, setvar is { unsetvar; addvar; } */ + +static void modperl_cmd_setvar_func(apr_table_t *configvars, + apr_table_t *setvars, + const char * key, const char *val) +{ + apr_table_setn(setvars, key, val); + apr_table_setn(configvars, key, val); +} + +static const char *modperl_cmd_modvar(modperl_var_modify_t varfunc, + cmd_parms *parms, + modperl_config_dir_t *dcfg, + const char *arg1, const char *arg2) +{ + varfunc(dcfg->configvars, dcfg->setvars, arg1, arg2); + + MP_TRACE_d(MP_FUNC, "%s DIR: arg1 = %s, arg2 = %s", + parms->cmd->name, arg1, arg2); + + /* make available via Apache2->server->dir_config */ + if (!parms->path) { + MP_dSCFG(parms->server); + varfunc(scfg->configvars, scfg->setvars, arg1, arg2); + + MP_TRACE_d(MP_FUNC, "%s SRV: arg1 = %s, arg2 = %s", + parms->cmd->name, arg1, arg2); + } + + return NULL; +} + +MP_CMD_SRV_DECLARE2(add_var) +{ + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + return modperl_cmd_modvar(modperl_cmd_addvar_func, parms, dcfg, arg1, arg2); +} + +MP_CMD_SRV_DECLARE2(set_var) +{ + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + return modperl_cmd_modvar(modperl_cmd_setvar_func, parms, dcfg, arg1, arg2); +} + +MP_CMD_SRV_DECLARE2(set_env) +{ + MP_dSCFG(parms->server); + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + +#ifdef ENV_IS_CASELESS /* i.e. WIN32 */ + /* we turn off env magic during hv_store later, so do this now, + * else lookups on keys with lowercase characters will fails + * because Perl will uppercase them prior to lookup. + */ + modperl_str_toupper((char *)arg1); +#endif + + MP_TRACE_d(MP_FUNC, "arg1 = %s, arg2 = %s", arg1, arg2); + + if (!parms->path) { + /* will be propagated to environ */ + apr_table_setn(scfg->SetEnv, arg1, arg2); + /* sync SetEnv => %ENV only for the top-level values */ + if (modperl_vhost_is_running(parms->server)) { + MP_PERL_CONTEXT_DECLARE; + MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl); + modperl_env_hv_store(aTHX_ arg1, arg2); + MP_PERL_CONTEXT_RESTORE; + } + } + + apr_table_setn(dcfg->SetEnv, arg1, arg2); + + return NULL; +} + +MP_CMD_SRV_DECLARE(pass_env) +{ + MP_dSCFG(parms->server); + char *val = getenv(arg); + +#ifdef ENV_IS_CASELESS /* i.e. WIN32 */ + /* we turn off env magic during hv_store later, so do this now, + * else lookups on keys with lowercase characters will fails + * because Perl will uppercase them prior to lookup. + */ + modperl_str_toupper((char *)arg); +#endif + + if (val) { + apr_table_setn(scfg->PassEnv, arg, apr_pstrdup(parms->pool, val)); + if (modperl_vhost_is_running(parms->server)) { + MP_PERL_CONTEXT_DECLARE; + MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl); + modperl_env_hv_store(aTHX_ arg, val); + MP_PERL_CONTEXT_RESTORE; + } + MP_TRACE_d(MP_FUNC, "arg = %s, val = %s", arg, val); + } + else { + MP_TRACE_d(MP_FUNC, "arg = %s: not found via getenv()", arg); + } + + return NULL; +} + +MP_CMD_SRV_DECLARE(options) +{ + MP_dSCFG(parms->server); + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + int is_per_dir = parms->path ? 1 : 0; + modperl_options_t *opts = is_per_dir ? dcfg->flags : scfg->flags; + apr_pool_t *p = parms->temp_pool; + const char *error; + + MP_TRACE_d(MP_FUNC, "arg = %s", arg); + if ((error = modperl_options_set(p, opts, arg)) && !is_per_dir) { + /* maybe a per-directory option outside of a container */ + if (modperl_options_set(p, dcfg->flags, arg) == NULL) { + error = NULL; + } + } + + if (error) { + return error; + } + + return NULL; +} + +MP_CMD_SRV_DECLARE(init_handlers) +{ + if (parms->path) { + return modperl_cmd_header_parser_handlers(parms, mconfig, arg); + } + + return modperl_cmd_post_read_request_handlers(parms, mconfig, arg); +} + +#if AP_SERVER_MAJORVERSION_NUMBER>2 || \ + (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3) + +MP_CMD_SRV_DECLARE2(authz_provider) +{ + apr_pool_t *p = parms->pool; + char *name = apr_pstrdup(p, arg1); + char *cb = apr_pstrdup(p, arg2); + + modperl_register_auth_provider_name(p, AUTHZ_PROVIDER_GROUP, name, + AUTHZ_PROVIDER_VERSION, cb, NULL, + AP_AUTH_INTERNAL_PER_CONF); + return NULL; +} + +MP_CMD_SRV_DECLARE2(authn_provider) +{ + apr_pool_t *p = parms->pool; + char *name = apr_pstrdup(p, arg1); + char *cb = apr_pstrdup(p, arg2); + + modperl_register_auth_provider_name(p, AUTHN_PROVIDER_GROUP, name, + AUTHN_PROVIDER_VERSION, cb, NULL, + AP_AUTH_INTERNAL_PER_CONF); + return NULL; +} + +#endif + +static const char *modperl_cmd_parse_args(apr_pool_t *p, + const char *args, + apr_table_t **t) +{ + const char *orig_args = args; + char *pair, *key, *val; + *t = apr_table_make(p, 2); + + while (*(pair = ap_getword(p, &args, ',')) != '\0') { + key = ap_getword_nc(p, &pair, '='); + val = pair; + + if (!(*key && *val)) { + return apr_pstrcat(p, "invalid args spec: ", + orig_args, NULL); + } + + apr_table_set(*t, key, val); + } + + return NULL; +} + +MP_CMD_SRV_DECLARE(perl) +{ + apr_pool_t *p = parms->pool; + const char *endp = ap_strrchr_c(arg, '>'); + const char *errmsg; + char *code = ""; + char line[MAX_STRING_LEN]; + apr_table_t *args; + ap_directive_t **current = mconfig; + int line_num; + + if (!endp) { + return modperl_cmd_unclosed_directive(parms); + } + + MP_CHECK_SERVER_OR_HTACCESS_CONTEXT; + + arg = apr_pstrndup(p, arg, endp - arg); + + if ((errmsg = modperl_cmd_parse_args(p, arg, &args))) { + return errmsg; + } + + line_num = parms->config_file->line_number+1; + while (!ap_cfg_getline(line, sizeof(line), parms->config_file)) { + /*XXX: Not sure how robust this is */ + if (strEQ(line, "</Perl>")) { + break; + } + + /*XXX: Less than optimal */ + code = apr_pstrcat(p, code, line, "\n", NULL); + } + + /* Here, we have to replace our current config node for the next pass */ + if (!*current) { + *current = apr_pcalloc(p, sizeof(**current)); + } + + (*current)->filename = parms->config_file->name; + (*current)->line_num = line_num; + (*current)->directive = apr_pstrdup(p, "Perl"); + (*current)->args = code; + (*current)->data = args; + + return NULL; +} + +#define MP_DEFAULT_PERLSECTION_HANDLER "Apache2::PerlSections" +#define MP_DEFAULT_PERLSECTION_PACKAGE "Apache2::ReadConfig" +#define MP_PERLSECTIONS_SAVECONFIG_SV \ + get_sv("Apache2::PerlSections::Save", FALSE) +#define MP_PERLSECTIONS_SERVER_SV \ + get_sv("Apache2::PerlSections::Server", TRUE) + +MP_CMD_SRV_DECLARE(perldo) +{ + apr_pool_t *p = parms->pool; + server_rec *s = parms->server; + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + apr_table_t *options; + modperl_handler_t *handler = NULL; + const char *pkg_name = NULL; + ap_directive_t *directive = parms->directive; + MP_dSCFG(s); + MP_PERL_CONTEXT_DECLARE; + + if (!(arg && *arg)) { + return NULL; + } + + MP_CHECK_SERVER_OR_HTACCESS_CONTEXT; + + /* we must init earlier than normal */ + modperl_run(); + + if (modperl_init_vhost(s, p, NULL) != OK) { + return "init mod_perl vhost failed"; + } + + MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl); + + /* data will be set by a <Perl> section */ + if ((options = directive->data)) { + const char *pkg_namespace; + const char *pkg_base; + const char *handler_name; + const char *line_header; + + if (!(handler_name = apr_table_get(options, "handler"))) { + handler_name = apr_pstrdup(p, MP_DEFAULT_PERLSECTION_HANDLER); + apr_table_set(options, "handler", handler_name); + } + + handler = modperl_handler_new(p, handler_name); + + if (!(pkg_base = apr_table_get(options, "package"))) { + pkg_base = apr_pstrdup(p, MP_DEFAULT_PERLSECTION_PACKAGE); + } + + pkg_namespace = modperl_file2package(p, directive->filename); + + pkg_name = apr_psprintf(p, "%s::%s::line_%d", + pkg_base, + pkg_namespace, + directive->line_num); + + apr_table_set(options, "package", pkg_name); + + line_header = apr_psprintf(p, "\n#line %d %s\n", + directive->line_num, + directive->filename); + + /* put the code about to be executed in the configured package */ + arg = apr_pstrcat(p, "package ", pkg_name, ";", line_header, + arg, NULL); + } + +#ifdef USE_ITHREADS + MP_TRACE_i(MP_FUNC, "using interp %lx to execute perl section:\n%s", + scfg->mip->parent, arg); +#endif + + { + SV *server = MP_PERLSECTIONS_SERVER_SV; + SV *code = newSVpv(arg, 0); + GV *gv = gv_fetchpv("0", TRUE, SVt_PV); + ENTER;SAVETMPS; + save_scalar(gv); /* local $0 */ +#if MP_PERL_VERSION_AT_LEAST(5, 9, 0) + TAINT_NOT; /* XXX: temp workaround, see my p5p post */ +#endif + sv_setref_pv(server, "Apache2::ServerRec", (void*)s); + sv_setpv_mg(GvSV(gv), directive->filename); + eval_sv(code, G_SCALAR|G_KEEPERR); + SvREFCNT_dec(code); + modperl_env_sync_srv_env_hash2table(aTHX_ p, scfg); + modperl_env_sync_dir_env_hash2table(aTHX_ p, dcfg); + FREETMPS;LEAVE; + } + + if (SvTRUE(ERRSV)) { + MP_PERL_CONTEXT_RESTORE; + return SvPVX(ERRSV); + } + + if (handler) { + int status; + SV *saveconfig = MP_PERLSECTIONS_SAVECONFIG_SV; + AV *args = (AV *)NULL; + + modperl_handler_make_args(aTHX_ &args, + "Apache2::CmdParms", parms, + "APR::Table", options, + NULL); + + status = modperl_callback(aTHX_ handler, p, NULL, s, args); + + SvREFCNT_dec((SV*)args); + + if (!(saveconfig && SvTRUE(saveconfig))) { + modperl_package_unload(aTHX_ pkg_name); + } + + if (status != OK) { + char *error = SvTRUE(ERRSV) ? SvPVX(ERRSV) : + apr_psprintf(p, "<Perl> handler %s failed with status=%d", + handler->name, status); + MP_PERL_CONTEXT_RESTORE; + return error; + } + } + + MP_PERL_CONTEXT_RESTORE; + return NULL; +} + +#define MP_POD_FORMAT(s) \ + (ap_strstr_c(s, "httpd") || ap_strstr_c(s, "apache")) + +MP_CMD_SRV_DECLARE(pod) +{ + char line[MAX_STRING_LEN]; + + if (arg && *arg && !(MP_POD_FORMAT(arg) || strstr("pod", arg))) { + return "Unknown =back format"; + } + + while (!ap_cfg_getline(line, sizeof(line), parms->config_file)) { + if (strEQ(line, "=cut")) { + break; + } + if (strnEQ(line, "=over", 5) && MP_POD_FORMAT(line)) { + break; + } + } + + return NULL; +} + +MP_CMD_SRV_DECLARE(pod_cut) +{ + return "=cut without =pod"; +} + +MP_CMD_SRV_DECLARE(END) +{ + char line[MAX_STRING_LEN]; + + while (!ap_cfg_getline(line, sizeof(line), parms->config_file)) { + /* soak up rest of the file */ + } + + return NULL; +} + +/* + * XXX: the name of this directive may or may not stay. + * need a way to note that a module has config directives. + * don't want to start mod_perl when we see a non-special PerlModule. + */ +MP_CMD_SRV_DECLARE(load_module) +{ + const char *errmsg; + + MP_TRACE_d(MP_FUNC, "PerlLoadModule %s", arg); + + /* we must init earlier than normal */ + modperl_run(); + + if ((errmsg = modperl_cmd_modules(parms, mconfig, arg))) { + return errmsg; + } + + return NULL; +} + +/* propogate filters insertion ala SetInputFilter */ +MP_CMD_SRV_DECLARE(set_input_filter) +{ + MP_dSCFG(parms->server); + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + char *filter; + + if (!MpSrvENABLE(scfg)) { + return apr_pstrcat(parms->pool, + "Perl is disabled for server ", + parms->server->server_hostname, NULL); + } + if (!MpSrvINPUT_FILTER(scfg)) { + return apr_pstrcat(parms->pool, + "PerlSetInputFilter is disabled for server ", + parms->server->server_hostname, NULL); + } + + while (*arg && (filter = ap_getword(parms->pool, &arg, ';'))) { + modperl_cmd_push_httpd_filter_handlers( + &(dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER]), + filter, parms->pool); + } + + return NULL; +} + +/* propogate filters insertion ala SetOutputFilter */ +MP_CMD_SRV_DECLARE(set_output_filter) +{ + MP_dSCFG(parms->server); + modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig; + char *filter; + + if (!MpSrvENABLE(scfg)) { + return apr_pstrcat(parms->pool, + "Perl is disabled for server ", + parms->server->server_hostname, NULL); + } + if (!MpSrvINPUT_FILTER(scfg)) { + return apr_pstrcat(parms->pool, + "PerlSetOutputFilter is disabled for server ", + parms->server->server_hostname, NULL); + } + + while (*arg && (filter = ap_getword(parms->pool, &arg, ';'))) { + modperl_cmd_push_httpd_filter_handlers( + &(dcfg->handlers_per_dir[MP_OUTPUT_FILTER_HANDLER]), + filter, parms->pool); + } + + return NULL; +} + + +#ifdef MP_COMPAT_1X + +MP_CMD_SRV_DECLARE_FLAG(taint_check) +{ + if (flag_on) { + return modperl_cmd_switches(parms, mconfig, "-T"); + } + + return NULL; +} + +MP_CMD_SRV_DECLARE_FLAG(warn) +{ + if (flag_on) { + return modperl_cmd_switches(parms, mconfig, "-w"); + } + + return NULL; +} + +MP_CMD_SRV_DECLARE_FLAG(send_header) +{ + char *arg = flag_on ? "+ParseHeaders" : "-ParseHeaders"; + return modperl_cmd_options(parms, mconfig, arg); +} + +MP_CMD_SRV_DECLARE_FLAG(setup_env) +{ + char *arg = flag_on ? "+SetupEnv" : "-SetupEnv"; + return modperl_cmd_options(parms, mconfig, arg); +} + +#endif /* MP_COMPAT_1X */ + +#ifdef USE_ITHREADS + +#define MP_CMD_INTERP_POOL_IMP(xitem) \ +const char *modperl_cmd_interp_##xitem(cmd_parms *parms, \ + void *mconfig, const char *arg) \ +{ \ + MP_dSCFG(parms->server); \ + int item = atoi(arg); \ + scfg->interp_pool_cfg->xitem = item; \ + MP_TRACE_d(MP_FUNC, "%s %d", parms->cmd->name, item); \ + return NULL; \ +} + +MP_CMD_INTERP_POOL_IMP(start); +MP_CMD_INTERP_POOL_IMP(max); +MP_CMD_INTERP_POOL_IMP(max_spare); +MP_CMD_INTERP_POOL_IMP(min_spare); +MP_CMD_INTERP_POOL_IMP(max_requests); + +#endif /* USE_ITHREADS */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_cmd.h b/2_0_13/src/modules/perl/modperl_cmd.h new file mode 100644 index 0000000..883259d --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_cmd.h
@@ -0,0 +1,150 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_CMD_H +#define MODPERL_CMD_H + +char *modperl_cmd_push_handlers(MpAV **handlers, const char *name, + apr_pool_t *p); + +char *modperl_cmd_push_filter_handlers(MpAV **handlers, + const char *name, + apr_pool_t *p); + +#define MP_CMD_SRV_DECLARE(item) \ + const char *modperl_cmd_##item(cmd_parms *parms, void *mconfig, \ + const char *arg) + +#define MP_CMD_SRV_DECLARE2(item) \ + const char *modperl_cmd_##item(cmd_parms *parms, void *mconfig, \ + const char *arg1, const char *arg2) + +#define MP_CMD_SRV_DECLARE_FLAG(item) \ + const char *modperl_cmd_##item(cmd_parms *parms, \ + void *mconfig, int flag_on) + +MP_CMD_SRV_DECLARE(trace); +MP_CMD_SRV_DECLARE(switches); +MP_CMD_SRV_DECLARE(modules); +MP_CMD_SRV_DECLARE(requires); +MP_CMD_SRV_DECLARE(config_requires); +MP_CMD_SRV_DECLARE(post_config_requires); +#if AP_SERVER_MAJORVERSION_NUMBER>2 || \ + (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3) +MP_CMD_SRV_DECLARE2(authz_provider); +MP_CMD_SRV_DECLARE2(authn_provider); +#endif +MP_CMD_SRV_DECLARE2(set_var); +MP_CMD_SRV_DECLARE2(add_var); +MP_CMD_SRV_DECLARE2(set_env); +MP_CMD_SRV_DECLARE(pass_env); +MP_CMD_SRV_DECLARE(options); +MP_CMD_SRV_DECLARE(init_handlers); +MP_CMD_SRV_DECLARE(perl); +MP_CMD_SRV_DECLARE(perldo); +MP_CMD_SRV_DECLARE(pod); +MP_CMD_SRV_DECLARE(pod_cut); +MP_CMD_SRV_DECLARE(END); +MP_CMD_SRV_DECLARE(load_module); +MP_CMD_SRV_DECLARE(set_input_filter); +MP_CMD_SRV_DECLARE(set_output_filter); + +#ifdef MP_COMPAT_1X + +MP_CMD_SRV_DECLARE_FLAG(taint_check); +MP_CMD_SRV_DECLARE_FLAG(warn); +MP_CMD_SRV_DECLARE_FLAG(send_header); +MP_CMD_SRV_DECLARE_FLAG(setup_env); + +#endif /* MP_COMPAT_1X */ + +#ifdef USE_ITHREADS +MP_CMD_SRV_DECLARE(interp_start); +MP_CMD_SRV_DECLARE(interp_max); +MP_CMD_SRV_DECLARE(interp_max_spare); +MP_CMD_SRV_DECLARE(interp_min_spare); +MP_CMD_SRV_DECLARE(interp_max_requests); + +#endif /* USE_ITHREADS */ + +#define MP_CMD_SRV_RAW_ARGS(name, item, desc) \ + AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \ + RSRC_CONF, desc ) + +#define MP_CMD_SRV_RAW_ARGS_ON_READ(name, item, desc) \ + AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \ + RSRC_CONF|EXEC_ON_READ, desc ) + +#define MP_CMD_SRV_FLAG(name, item, desc) \ + AP_INIT_FLAG( name, modperl_cmd_##item, NULL, \ + RSRC_CONF, desc ) + +#define MP_CMD_SRV_TAKE1(name, item, desc) \ + AP_INIT_TAKE1( name, modperl_cmd_##item, NULL, \ + RSRC_CONF, desc ) + +#define MP_CMD_SRV_TAKE2(name, item, desc) \ + AP_INIT_TAKE2( name, modperl_cmd_##item, NULL, \ + RSRC_CONF, desc ) + +#define MP_CMD_SRV_ITERATE(name, item, desc) \ + AP_INIT_ITERATE( name, modperl_cmd_##item, NULL, \ + RSRC_CONF, desc ) + +#define MP_CMD_SRV_ITERATE_ON_READ(name, item, desc) \ + AP_INIT_ITERATE( name, modperl_cmd_##item, NULL, \ + RSRC_CONF|EXEC_ON_READ, desc ) + +#define MP_CMD_SRV_ITERATE2(name, item, desc) \ + AP_INIT_ITERATE2( name, modperl_cmd_##item, NULL, \ + RSRC_CONF, desc ) + +#define MP_CMD_DIR_TAKE1(name, item, desc) \ + AP_INIT_TAKE1( name, modperl_cmd_##item, NULL, \ + OR_ALL, desc ) + +#define MP_CMD_DIR_TAKE2(name, item, desc) \ + AP_INIT_TAKE2( name, modperl_cmd_##item, NULL, \ + OR_ALL, desc ) + +#define MP_CMD_DIR_ITERATE(name, item, desc) \ + AP_INIT_ITERATE( name, modperl_cmd_##item, NULL, \ + OR_ALL, desc ) + +#define MP_CMD_DIR_ITERATE2(name, item, desc) \ + AP_INIT_ITERATE2( name, modperl_cmd_##item, NULL, \ + OR_ALL, desc ) + +#define MP_CMD_DIR_FLAG(name, item, desc) \ + AP_INIT_FLAG( name, modperl_cmd_##item, NULL, \ + OR_ALL, desc ) + +#define MP_CMD_DIR_RAW_ARGS(name, item, desc) \ + AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \ + OR_ALL, desc ) + +#define MP_CMD_DIR_RAW_ARGS_ON_READ(name, item, desc) \ + AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \ + OR_ALL|EXEC_ON_READ, desc ) + +#endif /* MODPERL_CMD_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_common_debug.c b/2_0_13/src/modules/perl/modperl_common_debug.c new file mode 100644 index 0000000..4ae508e --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_common_debug.c
@@ -0,0 +1,26 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file must not contain any symbols from apache/mod_perl + * (apr and perl are OK) */ +#include "modperl_common_includes.h" + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_common_debug.h b/2_0_13/src/modules/perl/modperl_common_debug.h new file mode 100644 index 0000000..342986b --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_common_debug.h
@@ -0,0 +1,28 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_COMMON_DEBUG_H +#define MODPERL_COMMON_DEBUG_H + + +#endif /* MODPERL_COMMON_DEBUG_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_common_includes.h b/2_0_13/src/modules/perl/modperl_common_includes.h new file mode 100644 index 0000000..971b2bd --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_common_includes.h
@@ -0,0 +1,34 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_COMMON_INCLUDES_H +#define MODPERL_COMMON_INCLUDES_H + +/* header files which are independet of Apache/mod_perl */ + +#include "modperl_apr_includes.h" +#include "modperl_apr_compat.h" +#include "modperl_perl_includes.h" +#include "modperl_common_types.h" + +#endif /* MODPERL_COMMON_INCLUDES_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_common_log.c b/2_0_13/src/modules/perl/modperl_common_log.c new file mode 100644 index 0000000..3bdb359 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_common_log.c
@@ -0,0 +1,131 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modperl_common_includes.h" +#include "modperl_common_log.h" +#include "modperl_debug.h" + +#undef getenv /* from XSUB.h */ + +static apr_file_t *logfile = NULL; + +#ifdef WIN32 +static unsigned long debug_level = 0; +#else +unsigned long MP_debug_level = 0; +#define debug_level MP_debug_level +#endif + +unsigned long modperl_debug_level(void) +{ + return debug_level; +} + +void modperl_trace_logfile_set(apr_file_t *logfile_new) +{ + logfile = logfile_new; +} + +void modperl_trace(const char *func, const char *fmt, ...) +{ + char vstr[8192]; + apr_size_t vstr_len = 0; + va_list args; + + if (!logfile) { + return; + } + + /* for more information on formatting codes see + http://apr.apache.org/docs/apr/1.4/group__apr__lib.html#gad2cd3594aeaafd45931d1034965f48c1 + */ + +#ifndef MP_IN_XS + /* PERL_GET_CONTEXT yields nonsense until the first interpreter is + * created. Hence the modperl_is_running() question. */ + if (modperl_threaded_mpm()) { + if (modperl_threads_started()) { + apr_os_thread_t tid = apr_os_thread_current(); + apr_file_printf(logfile, "[pid=%lu, tid=%pt, perl=%pp] ", + (unsigned long)getpid(), &tid, + modperl_is_running() ? PERL_GET_CONTEXT : NULL); + } + else { + apr_file_printf(logfile, "[pid=%lu, perl=%pp] ", + (unsigned long)getpid(), + modperl_is_running() ? PERL_GET_CONTEXT : NULL); + } + } + else { +#ifdef USE_ITHREADS + apr_file_printf(logfile, "[pid=%lu, perl=%pp] ", + (unsigned long)getpid(), + modperl_is_running() ? PERL_GET_CONTEXT : NULL); +#else + apr_file_printf(logfile, "[pid=%lu] ", (unsigned long)getpid()); +#endif + } +#endif + + if (func && *func) { + apr_file_printf(logfile, "%s: ", func); + } + + va_start(args, fmt); + vstr_len = apr_vsnprintf(vstr, sizeof(vstr), fmt, args); + va_end(args); + + apr_file_write(logfile, vstr, &vstr_len); + apr_file_printf(logfile, "\n"); +} + +void modperl_trace_level_set(apr_file_t *logfile, const char *level) +{ + if (!level) { + if (!(level = getenv("MOD_PERL_TRACE"))) { + return; + } + } + debug_level = 0x0; + + if (strcasecmp(level, "all") == 0) { + debug_level = 0xffffffff; + } + else if (apr_isalpha(level[0])) { + static char debopts[] = MP_TRACE_OPTS; + char *d; + + for (; *level && (d = strchr(debopts, *level)); level++) { + debug_level |= 1 << (d - debopts); + } + } + else { + debug_level = atoi(level); + } + + debug_level |= 0x80000000; + + modperl_trace_logfile_set(logfile); + + MP_TRACE_any_do(MP_TRACE_dump_flags()); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_common_log.h b/2_0_13/src/modules/perl/modperl_common_log.h new file mode 100644 index 0000000..46c9491 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_common_log.h
@@ -0,0 +1,67 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_COMMON_LOG_H +#define MODPERL_COMMON_LOG_H + +#define MP_STRINGIFY(n) MP_STRINGIFY_HELPER(n) +#define MP_STRINGIFY_HELPER(n) #n + +# if defined(__GNUC__) +# if (__GNUC__ > 2) +# define MP_FUNC __func__ +# else +# define MP_FUNC __FUNCTION__ +# endif +# else +# define MP_FUNC __FILE__ ":" MP_STRINGIFY(__LINE__) +# endif + +#include "modperl_apr_includes.h" +#include "apr_lib.h" +#include "modperl_trace.h" + +#ifdef _PTHREAD_H +#define modperl_thread_self() pthread_self() +#else +#define modperl_thread_self() 0 +#endif + +#define MP_TIDF \ +(unsigned long)modperl_thread_self() + +void modperl_trace_logfile_set(apr_file_t *logfile_new); + +unsigned long modperl_debug_level(void); + +#ifdef WIN32 +#define MP_debug_level modperl_debug_level() +#else +extern unsigned long MP_debug_level; +#endif + +void modperl_trace(const char *func, const char *fmt, ...); + +void modperl_trace_level_set(apr_file_t *logfile, const char *level); + +#endif /* MODPERL_COMMON_LOG_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_common_types.h b/2_0_13/src/modules/perl/modperl_common_types.h new file mode 100644 index 0000000..bb4eb6c --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_common_types.h
@@ -0,0 +1,35 @@ + +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_COMMON_TYPES_H +#define MODPERL_COMMON_TYPES_H + +/* subclass apr_uri_t */ +typedef struct { + apr_uri_t uri; + apr_pool_t *pool; + char *path_info; +} modperl_uri_t; + +#endif /* MODPERL_COMMON_TYPES_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_common_util.c b/2_0_13/src/modules/perl/modperl_common_util.c new file mode 100644 index 0000000..c5f285f --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_common_util.c
@@ -0,0 +1,161 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file must not contain any symbols from apache/mod_perl (apr + * and perl are OK). Also try to keep all the mod_perl specific + * functions (even if they don't contain symbols from apache/mod_perl + * on in modperl_util.c, unless we want them elsewhere. That is + * needed in order to keep the libraries used outside mod_perl + * small */ + +#include "modperl_common_util.h" + +/* Prefetch magic requires perl 5.8 */ +#if MP_PERL_VERSION_AT_LEAST(5, 8, 0) + +/* A custom MGVTBL with mg_copy slot filled in allows us to FETCH a + * table entry immediately during iteration. For multivalued keys + * this is essential in order to get the value corresponding to the + * current key, otherwise values() will always report the first value + * repeatedly. With this MGVTBL the keys() list always matches up + * with the values() list, even in the multivalued case. We only + * prefetch the value during iteration, because the prefetch adds + * overhead (an unnecessary FETCH call) to EXISTS and STORE + * operations. This way they are only "penalized" when the perl + * program is iterating via each(), which seems to be a reasonable + * tradeoff. + */ + +MP_INLINE static +int modperl_table_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, + const char *name, int namelen) +{ + /* prefetch the value whenever we're iterating over the keys */ + MAGIC *tie_magic = mg_find(nsv, PERL_MAGIC_tiedelem); + SV *obj = SvRV(tie_magic->mg_obj); + if (SvCUR(obj)) { + SvGETMAGIC(nsv); + } + return 0; +} + + +static const MGVTBL modperl_table_magic_prefetch = {0, 0, 0, 0, 0, + modperl_table_magic_copy}; +#endif /* End of prefetch magic */ + +MP_INLINE SV *modperl_hash_tie(pTHX_ + const char *classname, + SV *tsv, void *p) +{ + SV *hv = (SV*)newHV(); + SV *rsv = sv_newmortal(); + + sv_setref_pv(rsv, classname, p); + + /* Prefetch magic requires perl 5.8 */ +#if MP_PERL_VERSION_AT_LEAST(5, 8, 0) + + sv_magicext(hv, NULL, PERL_MAGIC_ext, NULL, (char *)NULL, -1); + SvMAGIC(hv)->mg_virtual = (MGVTBL *)&modperl_table_magic_prefetch; + SvMAGIC(hv)->mg_flags |= MGf_COPY; + +#endif /* End of prefetch magic */ + + sv_magic(hv, rsv, PERL_MAGIC_tied, (char *)NULL, 0); + + return SvREFCNT_inc(sv_bless(sv_2mortal(newRV_noinc(hv)), + gv_stashpv(classname, TRUE))); +} + +MP_INLINE SV *modperl_hash_tied_object_rv(pTHX_ + const char *classname, + SV *tsv) +{ + if (sv_derived_from(tsv, classname)) { + if (SVt_PVHV == SvTYPE(SvRV(tsv))) { + SV *hv = SvRV(tsv); + MAGIC *mg; + + if (SvMAGICAL(hv)) { + if ((mg = mg_find(hv, PERL_MAGIC_tied))) { + return mg->mg_obj; + } + else { + Perl_warn(aTHX_ "Not a tied hash: (magic=%c)", mg->mg_type); + } + } + else { + Perl_warn(aTHX_ "SV is not tied"); + } + } + else { + return tsv; + } + } + else { + Perl_croak(aTHX_ + "argument is not a blessed reference " + "(expecting an %s derived object)", classname); + } + + return &PL_sv_undef; +} + +MP_INLINE void *modperl_hash_tied_object(pTHX_ + const char *classname, + SV *tsv) +{ + SV *rv = modperl_hash_tied_object_rv(aTHX_ classname, tsv); + if (SvROK(rv)) { + return INT2PTR(void *, SvIVX(SvRV(rv))); + } + else { + return NULL; + } +} + +/* same as Symbol::gensym() */ +SV *modperl_perl_gensym(pTHX_ char *pack) +{ + GV *gv = newGVgen(pack); + SV *rv = newRV((SV*)gv); + (void)hv_delete(gv_stashpv(pack, TRUE), + GvNAME(gv), GvNAMELEN(gv), G_DISCARD); + return rv; +} + +/* XXX: sv_setref_uv does not exist in 5.6.x */ +MP_INLINE SV *modperl_perl_sv_setref_uv(pTHX_ SV *rv, + const char *classname, UV uv) +{ + sv_setuv(newSVrv(rv, classname), uv); + return rv; +} + +MP_INLINE modperl_uri_t *modperl_uri_new(apr_pool_t *p) +{ + modperl_uri_t *uri = (modperl_uri_t *)apr_pcalloc(p, sizeof(*uri)); + uri->pool = p; + return uri; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_common_util.h b/2_0_13/src/modules/perl/modperl_common_util.h new file mode 100644 index 0000000..55f1600 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_common_util.h
@@ -0,0 +1,119 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modperl_common_includes.h" + +#ifndef MODPERL_COMMON_UTIL_H +#define MODPERL_COMMON_UTIL_H + +#ifdef MP_DEBUG +#define MP_INLINE +#else +#define MP_INLINE APR_INLINE +#endif + +#ifdef CYGWIN +#define MP_STATIC +#else +#define MP_STATIC static +#endif + +#ifdef WIN32 +# define MP_FUNC_T(name) (_stdcall *name) +# define MP_FUNC_NONSTD_T(name) (*name) +/* XXX: not all functions get inlined + * so its unclear what to and not to include in the .def files + */ +# undef MP_INLINE +# define MP_INLINE +#else +# define MP_FUNC_T(name) (*name) +# define MP_FUNC_NONSTD_T(name) (*name) +#endif + + +#define MP_SSTRLEN(string) (sizeof(string)-1) + +#ifndef strcaseEQ +# define strcaseEQ(s1,s2) (!strcasecmp(s1,s2)) +#endif +#ifndef strncaseEQ +# define strncaseEQ(s1,s2,l) (!strncasecmp(s1,s2,l)) +#endif + +#ifndef SvCLASS +#define SvCLASS(o) HvNAME(SvSTASH(SvRV(o))) +#endif + +#define SvObjIV(o) SvIV((SV*)SvRV(o)) +#define MgObjIV(m) SvIV((SV*)SvRV(m->mg_obj)) + +#define MP_SvGROW(sv, len) \ + (void)SvUPGRADE(sv, SVt_PV); \ + SvGROW(sv, len+1) + +#define MP_SvCUR_set(sv, len) \ + SvCUR_set(sv, len); \ + *SvEND(sv) = '\0'; \ + SvPOK_only(sv) + +#define MP_magical_untie(sv, mg_flags) \ + mg_flags = SvMAGICAL((SV*)sv); \ + SvMAGICAL_off((SV*)sv) + +#define MP_magical_tie(sv, mg_flags) \ + SvFLAGS((SV*)sv) |= mg_flags + +/* some wrapper macros to detect perl versions + * and prevent code clutter */ +#define MP_PERL_VERSION_AT_LEAST(r, v, s) \ + (PERL_REVISION == r && \ + ((PERL_VERSION == v && PERL_SUBVERSION > s-1) || PERL_VERSION > v)) + +#define MP_PERL_VERSION_AT_MOST(r, v, s) \ + (PERL_REVISION == r && \ + (PERL_VERSION < v || (PERL_VERSION == v && PERL_SUBVERSION < s+1))) + +#define MP_PERL_VERSION(r, v, s) \ + (PERL_REVISION == r && PERL_VERSION == v && PERL_SUBVERSION == s) + +/* tie %hash */ +MP_INLINE SV *modperl_hash_tie(pTHX_ const char *classname, + SV *tsv, void *p); + +/* tied %hash */ +MP_INLINE SV *modperl_hash_tied_object_rv(pTHX_ + const char *classname, + SV *tsv); +/* tied %hash */ +MP_INLINE void *modperl_hash_tied_object(pTHX_ const char *classname, + SV *tsv); + +MP_INLINE SV *modperl_perl_sv_setref_uv(pTHX_ SV *rv, + const char *classname, UV uv); + +MP_INLINE modperl_uri_t *modperl_uri_new(apr_pool_t *p); + +SV *modperl_perl_gensym(pTHX_ char *pack); + +#endif /* MODPERL_COMMON_UTIL_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_config.c b/2_0_13/src/modules/perl/modperl_config.c new file mode 100644 index 0000000..6603065 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_config.c
@@ -0,0 +1,680 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +void *modperl_config_dir_create(apr_pool_t *p, char *dir) +{ + modperl_config_dir_t *dcfg = modperl_config_dir_new(p); + + dcfg->location = dir; + + MP_TRACE_d(MP_FUNC, "dir %s", dir); + + return dcfg; +} + +#define merge_item(item) \ + mrg->item = add->item ? add->item : base->item + +static apr_table_t *modperl_table_overlap(apr_pool_t *p, + apr_table_t *base, + apr_table_t *add) +{ + /* take the base (parent) values, and override with add (child) values, + * generating a new table. entries in add but not in base will be + * added to the new table. all using core apr table routines. + * + * note that this is equivalent to apr_table_overlap except a new + * table is generated, which is required (otherwise we would clobber + * the existing parent or child configurations) + * + * note that this is *not* equivalent to apr_table_overlap, although + * I think it should be, because apr_table_overlap seems to clear + * its first argument when the tables have different pools. I think + * this is wrong -- rici + */ + apr_table_t *merge = apr_table_overlay(p, base, add); + + /* compress will squash each key to the last value in the table. this + * is acceptable for all tables that expect only a single value per key + * such as PerlPassEnv and PerlSetEnv. PerlSetVar/PerlAddVar get their + * own, non-standard, merge routines in merge_table_config_vars. + */ + apr_table_compress(merge, APR_OVERLAP_TABLES_SET); + + return merge; +} + +#define merge_table_overlap_item(item) \ + mrg->item = modperl_table_overlap(p, base->item, add->item) + +static apr_table_t *merge_config_add_vars(apr_pool_t *p, + const apr_table_t *base, + const apr_table_t *unset, + const apr_table_t *add) +{ + apr_table_t *temp = apr_table_copy(p, base); + + const apr_array_header_t *arr; + apr_table_entry_t *entries; + int i; + + /* for each key in unset do apr_table_unset(temp, key); */ + arr = apr_table_elts(unset); + entries = (apr_table_entry_t *)arr->elts; + + /* hopefully this is faster than using apr_table_do */ + for (i = 0; i < arr->nelts; i++) { + if (entries[i].key) { + apr_table_unset(temp, entries[i].key); + } + } + + return apr_table_overlay(p, temp, add); +} + +#define merge_handlers(merge_flag, array) \ + if (merge_flag(mrg)) { \ + mrg->array = modperl_handler_array_merge(p, \ + base->array, \ + add->array); \ + } \ + else { \ + merge_item(array); \ + } + +void *modperl_config_dir_merge(apr_pool_t *p, void *basev, void *addv) +{ + int i; + modperl_config_dir_t + *base = (modperl_config_dir_t *)basev, + *add = (modperl_config_dir_t *)addv, + *mrg = modperl_config_dir_new(p); + + MP_TRACE_d(MP_FUNC, "basev==0x%lx, addv==0x%lx, mrg==0x%lx", + (unsigned long)basev, (unsigned long)addv, + (unsigned long)mrg); + + mrg->flags = modperl_options_merge(p, base->flags, add->flags); + + merge_item(location); + + merge_table_overlap_item(SetEnv); + + /* this is where we merge PerlSetVar and PerlAddVar together */ + mrg->configvars = merge_config_add_vars(p, + base->configvars, + add->setvars, add->configvars); + merge_table_overlap_item(setvars); + + /* XXX: check if Perl*Handler is disabled */ + for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) { + merge_handlers(MpDirMERGE_HANDLERS, handlers_per_dir[i]); + } + + return mrg; +} + +modperl_config_req_t *modperl_config_req_new(request_rec *r) +{ + modperl_config_req_t *rcfg = + (modperl_config_req_t *)apr_pcalloc(r->pool, sizeof(*rcfg)); + + MP_TRACE_d(MP_FUNC, "0x%lx", (unsigned long)rcfg); + + return rcfg; +} + +modperl_config_con_t *modperl_config_con_new(conn_rec *c) +{ + modperl_config_con_t *ccfg = + (modperl_config_con_t *)apr_pcalloc(c->pool, sizeof(*ccfg)); + + MP_TRACE_d(MP_FUNC, "0x%lx", (unsigned long)ccfg); + + return ccfg; +} + +modperl_config_srv_t *modperl_config_srv_new(apr_pool_t *p, server_rec *s) +{ + modperl_config_srv_t *scfg = (modperl_config_srv_t *) + apr_pcalloc(p, sizeof(*scfg)); + + scfg->flags = modperl_options_new(p, MpSrvType); + MpSrvENABLE_On(scfg); /* mod_perl enabled by default */ + MpSrvHOOKS_ALL_On(scfg); /* all hooks enabled by default */ + + scfg->PerlModule = apr_array_make(p, 2, sizeof(char *)); + scfg->PerlRequire = apr_array_make(p, 2, sizeof(char *)); + scfg->PerlPostConfigRequire = + apr_array_make(p, 1, sizeof(modperl_require_file_t *)); + + /* 2 arguments + NULL terminator */ + scfg->argv = apr_array_make(p, 3, sizeof(char *)); + + scfg->setvars = apr_table_make(p, 2); + scfg->configvars = apr_table_make(p, 2); + + scfg->PassEnv = apr_table_make(p, 2); + scfg->SetEnv = apr_table_make(p, 2); + +#ifdef MP_USE_GTOP + scfg->gtop = modperl_gtop_new(p); +#endif + + /* make sure httpd's argv[0] is the first argument so $0 is + * correctly connected to the real thing */ + modperl_config_srv_argv_push(s->process->argv[0]); + + MP_TRACE_d(MP_FUNC, "new scfg: 0x%lx", (unsigned long)scfg); + + return scfg; +} + +modperl_config_dir_t *modperl_config_dir_new(apr_pool_t *p) +{ + modperl_config_dir_t *dcfg = (modperl_config_dir_t *) + apr_pcalloc(p, sizeof(modperl_config_dir_t)); + + dcfg->flags = modperl_options_new(p, MpDirType); + + dcfg->setvars = apr_table_make(p, 2); + dcfg->configvars = apr_table_make(p, 2); + + dcfg->SetEnv = apr_table_make(p, 2); + + MP_TRACE_d(MP_FUNC, "new dcfg: 0x%lx", (unsigned long)dcfg); + + return dcfg; +} + +#ifdef MP_TRACE +static void dump_argv(modperl_config_srv_t *scfg) +{ + int i; + char **argv = (char **)scfg->argv->elts; + modperl_trace(NULL, "modperl_config_srv_argv_init =>"); + for (i=0; i<scfg->argv->nelts; i++) { + modperl_trace(NULL, " %d = %s", i, argv[i]); + } +} +#endif + +char **modperl_config_srv_argv_init(modperl_config_srv_t *scfg, int *argc) +{ + modperl_config_srv_argv_push("-e;0"); + + *argc = scfg->argv->nelts; + + /* perl_parse() expects a NULL terminated argv array */ + modperl_config_srv_argv_push(NULL); + + MP_TRACE_g_do(dump_argv(scfg)); + + return (char **)scfg->argv->elts; +} + +void *modperl_config_srv_create(apr_pool_t *p, server_rec *s) +{ + modperl_config_srv_t *scfg = modperl_config_srv_new(p, s); + + if (!s->is_virtual) { + + /* give a chance to MOD_PERL_TRACE env var to set + * PerlTrace. This place is the earliest point in mod_perl + * configuration parsing, when we have the server object + */ + modperl_trace_level_set_apache(s, NULL); + + /* Must store the global server record as early as possible, + * because if mod_perl happens to be started from within a + * vhost (e.g., PerlLoadModule) the base server record won't + * be available to vhost and things will blow up + */ + modperl_init_globals(s, p); + } + + MP_TRACE_d(MP_FUNC, "p=0x%lx, s=0x%lx, virtual=%d", + p, s, s->is_virtual); + +#ifdef USE_ITHREADS + + scfg->interp_pool_cfg = + (modperl_tipool_config_t *) + apr_pcalloc(p, sizeof(*scfg->interp_pool_cfg)); + + /* XXX: determine reasonable defaults */ + scfg->interp_pool_cfg->start = 3; + scfg->interp_pool_cfg->max_spare = 3; + scfg->interp_pool_cfg->min_spare = 3; + scfg->interp_pool_cfg->max = 5; + scfg->interp_pool_cfg->max_requests = 2000; +#endif /* USE_ITHREADS */ + + scfg->server = s; + + return scfg; +} + +/* XXX: this is not complete */ +void *modperl_config_srv_merge(apr_pool_t *p, void *basev, void *addv) +{ + int i; + modperl_config_srv_t + *base = (modperl_config_srv_t *)basev, + *add = (modperl_config_srv_t *)addv, + *mrg = modperl_config_srv_new(p, add->server); + + MP_TRACE_d(MP_FUNC, "basev==0x%lx, addv==0x%lx, mrg==0x%lx", + (unsigned long)basev, (unsigned long)addv, + (unsigned long)mrg); + + merge_item(modules); + merge_item(PerlModule); + merge_item(PerlRequire); + merge_item(PerlPostConfigRequire); + + merge_table_overlap_item(SetEnv); + merge_table_overlap_item(PassEnv); + + /* this is where we merge PerlSetVar and PerlAddVar together */ + mrg->configvars = merge_config_add_vars(p, + base->configvars, + add->setvars, add->configvars); + merge_table_overlap_item(setvars); + + merge_item(server); + +#ifdef USE_ITHREADS + merge_item(interp_pool_cfg); +#else + merge_item(perl); +#endif + + if (MpSrvINHERIT_SWITCHES(add)) { + /* only inherit base PerlSwitches if explicitly told to */ + mrg->argv = base->argv; + } + else { + mrg->argv = add->argv; + } + + mrg->flags = modperl_options_merge(p, base->flags, add->flags); + + /* XXX: check if Perl*Handler is disabled */ + for (i=0; i < MP_HANDLER_NUM_PER_SRV; i++) { + merge_handlers(MpSrvMERGE_HANDLERS, handlers_per_srv[i]); + } + for (i=0; i < MP_HANDLER_NUM_FILES; i++) { + merge_handlers(MpSrvMERGE_HANDLERS, handlers_files[i]); + } + for (i=0; i < MP_HANDLER_NUM_PROCESS; i++) { + merge_handlers(MpSrvMERGE_HANDLERS, handlers_process[i]); + } + for (i=0; i < MP_HANDLER_NUM_PRE_CONNECTION; i++) { + merge_handlers(MpSrvMERGE_HANDLERS, handlers_pre_connection[i]); + } + for (i=0; i < MP_HANDLER_NUM_CONNECTION; i++) { + merge_handlers(MpSrvMERGE_HANDLERS, handlers_connection[i]); + } + + if (modperl_is_running()) { + if (modperl_init_vhost(mrg->server, p, NULL) != OK) { + exit(1); /*XXX*/ + } + } + +#ifdef USE_ITHREADS + merge_item(mip); +#endif + + return mrg; +} + +/* any per-request cleanup goes here */ + +apr_status_t modperl_config_request_cleanup(pTHX_ request_rec *r) +{ + apr_status_t retval; + MP_dRCFG; + + retval = modperl_callback_per_dir(MP_CLEANUP_HANDLER, r, MP_HOOK_RUN_ALL); + + /* undo changes to %ENV caused by +SetupEnv, perl-script, or + * $r->subprocess_env, so the values won't persist */ + if (MpReqSETUP_ENV(rcfg)) { + modperl_env_request_unpopulate(aTHX_ r); + } + + return retval; +} + +apr_status_t modperl_config_req_cleanup(void *data) +{ + request_rec *r = (request_rec *)data; + apr_status_t rc; + MP_dINTERPa(r, NULL, NULL); + + rc = modperl_config_request_cleanup(aTHX_ r); + + MP_INTERP_PUTBACK(interp, aTHX); + + return rc; +} + +void *modperl_get_perl_module_config(ap_conf_vector_t *cv) +{ + return ap_get_module_config(cv, &perl_module); +} + +void modperl_set_perl_module_config(ap_conf_vector_t *cv, void *cfg) +{ + ap_set_module_config(cv, &perl_module, cfg); +} + +int modperl_config_apply_PerlModule(server_rec *s, + modperl_config_srv_t *scfg, + PerlInterpreter *perl, apr_pool_t *p) +{ + char **entries; + int i; + dTHXa(perl); + + entries = (char **)scfg->PerlModule->elts; + for (i = 0; i < scfg->PerlModule->nelts; i++){ + if (modperl_require_module(aTHX_ entries[i], TRUE)){ + MP_TRACE_d(MP_FUNC, "loaded Perl module %s for server %s", + entries[i], modperl_server_desc(s,p)); + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Can't load Perl module %s for server %s, exiting...", + entries[i], modperl_server_desc(s,p)); + return FALSE; + } + } + + return TRUE; +} + +int modperl_config_apply_PerlRequire(server_rec *s, + modperl_config_srv_t *scfg, + PerlInterpreter *perl, apr_pool_t *p) +{ + char **entries; + int i; + dTHXa(perl); + + entries = (char **)scfg->PerlRequire->elts; + for (i = 0; i < scfg->PerlRequire->nelts; i++){ + if (modperl_require_file(aTHX_ entries[i], TRUE)){ + MP_TRACE_d(MP_FUNC, "loaded Perl file: %s for server %s", + entries[i], modperl_server_desc(s,p)); + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Can't load Perl file: %s for server %s, exiting...", + entries[i], modperl_server_desc(s,p)); + return FALSE; + } + } + + return TRUE; +} + +int modperl_config_apply_PerlPostConfigRequire(server_rec *s, + modperl_config_srv_t *scfg, + apr_pool_t *p) +{ + modperl_require_file_t **requires; + int i; + MP_PERL_CONTEXT_DECLARE; + + requires = (modperl_require_file_t **)scfg->PerlPostConfigRequire->elts; + for (i = 0; i < scfg->PerlPostConfigRequire->nelts; i++){ + int retval; + + MP_PERL_CONTEXT_STORE_OVERRIDE(scfg->mip->parent->perl); + retval = modperl_require_file(aTHX_ requires[i]->file, TRUE); + modperl_env_sync_srv_env_hash2table(aTHX_ p, scfg); + modperl_env_sync_dir_env_hash2table(aTHX_ p, requires[i]->dcfg); + MP_PERL_CONTEXT_RESTORE; + + if (retval) { + MP_TRACE_d(MP_FUNC, "loaded Perl file: %s for server %s", + requires[i]->file, modperl_server_desc(s, p)); + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Can't load Perl file: %s for server %s, exiting...", + requires[i]->file, modperl_server_desc(s, p)); + + return FALSE; + } + } + + return TRUE; +} + +typedef struct { + AV *av; + I32 ix; + PerlInterpreter *perl; +} svav_param_t; + +static +#if AP_MODULE_MAGIC_AT_LEAST(20110329,0) +apr_status_t +#else +void * +#endif +svav_getstr(void *buf, size_t bufsiz, void *param) +{ + svav_param_t *svav_param = (svav_param_t *)param; + dTHXa(svav_param->perl); + AV *av = svav_param->av; + SV *sv; + STRLEN n_a; + + if (svav_param->ix > AvFILL(av)) { +#if AP_MODULE_MAGIC_AT_LEAST(20110329,0) + return APR_EOF; +#else + return NULL; +#endif + } + + sv = AvARRAY(av)[svav_param->ix++]; + SvPV_force(sv, n_a); + + apr_cpystrn(buf, SvPVX(sv), bufsiz); + +#if AP_MODULE_MAGIC_AT_LEAST(20110329,0) + return APR_SUCCESS; +#else + return buf; +#endif +} + +const char *modperl_config_insert(pTHX_ server_rec *s, + apr_pool_t *p, + apr_pool_t *ptmp, + int override, + char *path, + int override_options, + ap_conf_vector_t *conf, + SV *lines) +{ + const char *errmsg; + cmd_parms parms; + svav_param_t svav_parms; + ap_directive_t *conftree = NULL; + + memset(&parms, '\0', sizeof(parms)); + + parms.limited = -1; + parms.server = s; + parms.override = override; + parms.path = apr_pstrdup(p, path); + parms.pool = p; +#ifdef MP_HTTPD_HAS_OVERRIDE_OPTS + if (override_options == MP_HTTPD_OVERRIDE_OPTS_UNSET) { + parms.override_opts = MP_HTTPD_OVERRIDE_OPTS_DEFAULT; + } + else { + parms.override_opts = override_options; + } +#endif + + if (ptmp) { + parms.temp_pool = ptmp; + } + else { + apr_pool_create(&parms.temp_pool, p); + } + + if (!(SvROK(lines) && (SvTYPE(SvRV(lines)) == SVt_PVAV))) { + return "not an array reference"; + } + + svav_parms.av = (AV*)SvRV(lines); + svav_parms.ix = 0; +#ifdef USE_ITHREADS + svav_parms.perl = aTHX; +#endif + + parms.config_file = ap_pcfg_open_custom(p, "mod_perl", + &svav_parms, NULL, + svav_getstr, NULL); + + errmsg = ap_build_config(&parms, p, parms.temp_pool, &conftree); + + if (!errmsg) { + errmsg = ap_walk_config(conftree, &parms, conf); + } + + ap_cfg_closefile(parms.config_file); + + if (ptmp != parms.temp_pool) { + apr_pool_destroy(parms.temp_pool); + } + + return errmsg; +} + +const char *modperl_config_insert_parms(pTHX_ cmd_parms *parms, + SV *lines) +{ + return modperl_config_insert(aTHX_ + parms->server, + parms->pool, + parms->temp_pool, + parms->override, + parms->path, +#ifdef MP_HTTPD_HAS_OVERRIDE_OPTS + parms->override_opts, +#else + MP_HTTPD_OVERRIDE_OPTS_UNSET, +#endif + parms->context, + lines); +} + + +const char *modperl_config_insert_server(pTHX_ server_rec *s, SV *lines) +{ + int override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); + apr_pool_t *p = s->process->pconf; + + return modperl_config_insert(aTHX_ s, p, NULL, override, NULL, + MP_HTTPD_OVERRIDE_OPTS_UNSET, + s->lookup_defaults, lines); +} + +const char *modperl_config_insert_request(pTHX_ + request_rec *r, + SV *lines, + int override, + char *path, + int override_options) +{ + const char *errmsg; + ap_conf_vector_t *dconf = ap_create_per_dir_config(r->pool); + + if (!path) { + /* pass a non-NULL path if nothing else given and for compatibility */ + path = "/"; + } + + errmsg = modperl_config_insert(aTHX_ + r->server, r->pool, r->pool, + override, path, override_options, + dconf, lines); + + if (errmsg) { + return errmsg; + } + + r->per_dir_config = + ap_merge_per_dir_configs(r->pool, + r->per_dir_config, + dconf); + + return NULL; +} + + +/* if r!=NULL check for dir PerlOptions, otherwise check for server + * PerlOptions, (s must be always set) + */ +int modperl_config_is_perl_option_enabled(pTHX_ request_rec *r, + server_rec *s, const char *name) +{ + U32 flag; + + /* XXX: should we test whether perl is disabled for this server? */ + /* if (!MpSrvENABLE(scfg)) { */ + /* return 0; */ + /* } */ + + if (r) { + if ((flag = modperl_flags_lookup_dir(name)) != -1) { + MP_dDCFG; + return MpDirFLAGS(dcfg) & flag ? 1 : 0; + } + else { + Perl_croak(aTHX_ "PerlOptions %s is not a directory option", name); + } + } + else { + if ((flag = modperl_flags_lookup_srv(name)) != -1) { + MP_dSCFG(s); + return MpSrvFLAGS(scfg) & flag ? 1 : 0; + } + else { + Perl_croak(aTHX_ "PerlOptions %s is not a server option", name); + } + } + +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_config.h b/2_0_13/src/modules/perl/modperl_config.h new file mode 100644 index 0000000..9139e20 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_config.h
@@ -0,0 +1,165 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_CONFIG_H +#define MODPERL_CONFIG_H + +void *modperl_config_dir_create(apr_pool_t *p, char *dir); + +void *modperl_config_dir_merge(apr_pool_t *p, void *basev, void *addv); + +modperl_config_srv_t *modperl_config_srv_new(apr_pool_t *p, server_rec *s); + +modperl_config_dir_t *modperl_config_dir_new(apr_pool_t *p); + +modperl_config_req_t *modperl_config_req_new(request_rec *r); + +modperl_config_con_t *modperl_config_con_new(conn_rec *c); + +void *modperl_config_srv_create(apr_pool_t *p, server_rec *s); + +void *modperl_config_srv_merge(apr_pool_t *p, void *basev, void *addv); + +char **modperl_config_srv_argv_init(modperl_config_srv_t *scfg, int *argc); + +#define modperl_config_srv_argv_push(arg) \ + *(const char **)apr_array_push(scfg->argv) = (arg) + +apr_status_t modperl_config_request_cleanup(pTHX_ request_rec *r); + +apr_status_t modperl_config_req_cleanup(void *data); + +/* use a subpool here to ensure that a PerlCleanupHandler is run before + * any other pool cleanup - suppools are destroyed first. Particularly a + * PerlCleanupHandler must run before request pnotes are dropped. + */ +#define modperl_config_req_cleanup_register(r, rcfg) \ + if (r && !MpReqCLEANUP_REGISTERED(rcfg)) { \ + apr_pool_t *p; \ + apr_pool_create(&p, (r)->pool); \ + apr_pool_cleanup_register(p, \ + (void*)(r), \ + modperl_config_req_cleanup, \ + apr_pool_cleanup_null); \ + MpReqCLEANUP_REGISTERED_On(rcfg); \ + } + +void *modperl_get_perl_module_config(ap_conf_vector_t *cv); +void modperl_set_perl_module_config(ap_conf_vector_t *cv, void *cfg); + +#if defined(MP_IN_XS) && defined(WIN32) +# define modperl_get_module_config(v) \ + modperl_get_perl_module_config((v)) + +# define modperl_set_module_config(v, c) \ + modperl_set_perl_module_config((v), (c)) +#else +# define modperl_get_module_config(v) \ + ap_get_module_config((v), &perl_module) + +# define modperl_set_module_config(v, c) \ + ap_set_module_config((v), &perl_module, (c)) +#endif + +#define modperl_config_req_init(r, rcfg) \ + if (!(rcfg)) { \ + (rcfg) = modperl_config_req_new(r); \ + modperl_set_module_config((r)->request_config, (rcfg)); \ + } + +#define modperl_config_req_get(r) \ + (r ? (modperl_config_req_t *) \ + modperl_get_module_config((r)->request_config) : NULL) + +#define MP_dRCFG \ + modperl_config_req_t *rcfg = modperl_config_req_get(r) + +#define modperl_config_con_init(c, ccfg) \ + if (!ccfg) { \ + ccfg = modperl_config_con_new(c); \ + modperl_set_module_config((c)->conn_config, (ccfg)); \ + } + +#define modperl_config_con_get(c) \ + (c ? (modperl_config_con_t *) \ + modperl_get_module_config((c)->conn_config) : NULL) + +#define MP_dCCFG \ + modperl_config_con_t *ccfg = modperl_config_con_get(c) + +#define modperl_config_dir_get(r) \ + (r ? (modperl_config_dir_t *) \ + modperl_get_module_config((r)->per_dir_config) : NULL) + +#define modperl_config_dir_get_defaults(s) \ + (modperl_config_dir_t *) \ + modperl_get_module_config((s)->lookup_defaults) + +#define MP_dDCFG \ + modperl_config_dir_t *dcfg = modperl_config_dir_get(r) + +#define modperl_config_srv_get(s) \ + (modperl_config_srv_t *) \ + modperl_get_module_config(s->module_config) + +#define MP_dSCFG(s) \ + modperl_config_srv_t *scfg = modperl_config_srv_get(s) + +int modperl_config_apply_PerlModule(server_rec *s, + modperl_config_srv_t *scfg, + PerlInterpreter *perl, apr_pool_t *p); + +int modperl_config_apply_PerlRequire(server_rec *s, + modperl_config_srv_t *scfg, + PerlInterpreter *perl, apr_pool_t *p); + +int modperl_config_apply_PerlPostConfigRequire(server_rec *s, + modperl_config_srv_t *scfg, + apr_pool_t *p); + +const char *modperl_config_insert(pTHX_ server_rec *s, + apr_pool_t *p, + apr_pool_t *ptmp, + int override, + char *path, + int override_options, + ap_conf_vector_t *conf, + SV *lines); + +const char *modperl_config_insert_parms(pTHX_ cmd_parms *parms, + SV *lines); + +const char *modperl_config_insert_server(pTHX_ server_rec *s, SV *lines); + +const char *modperl_config_insert_request(pTHX_ + request_rec *r, + SV *lines, + int override, + char *path, + int override_options); + +int modperl_config_is_perl_option_enabled(pTHX_ request_rec *r, + server_rec *s, const char *name); + + +#endif /* MODPERL_CONFIG_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_const.c b/2_0_13/src/modules/perl/modperl_const.c new file mode 100644 index 0000000..209226b --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_const.c
@@ -0,0 +1,140 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" +#include "modperl_const.h" + +typedef SV *(*constants_lookup)(pTHX_ const char *); +typedef const char ** (*constants_group_lookup)(const char *); + +static void new_constsub(pTHX_ constants_lookup lookup, + HV *caller_stash, HV *stash, + const char *name) +{ + int name_len = strlen(name); + GV **gvp = (GV **)hv_fetch(stash, name, name_len, TRUE); + + /* dont redefine */ + if (!isGV(*gvp) || !GvCV(*gvp)) { + SV *val = (*lookup)(aTHX_ name); + +#if 0 + Perl_warn(aTHX_ "newCONSTSUB(%s, %s, %s)\n", + HvNAME(stash), name, SvPV_nolen(val)); +#endif + + newCONSTSUB(stash, (char *)name, val); +#ifdef GvSHARED + GvSHARED_on(*gvp); +#endif + } + + /* export into callers namespace */ + if (caller_stash) { + GV *alias = *(GV **)hv_fetch(caller_stash, + (char *)name, name_len, TRUE); + + if (!isGV(alias)) { + gv_init(alias, caller_stash, name, name_len, TRUE); + } + +#ifdef MUTABLE_CV + GvCV_set(alias, MUTABLE_CV(SvREFCNT_inc(GvCV(*gvp)))); +#else + GvCV_set(alias, (CV*)(SvREFCNT_inc(GvCV(*gvp)))); +#endif + } +} + +int modperl_const_compile(pTHX_ const char *classname, + const char *arg, + const char *name) +{ + HV *stash = gv_stashpv(classname, TRUE); + HV *caller_stash = (HV *)NULL; + constants_lookup lookup; + constants_group_lookup group_lookup; + + if (strnEQ(classname, "APR", 3)) { + lookup = modperl_constants_lookup_apr_const; + group_lookup = modperl_constants_group_lookup_apr_const; + } + else if (strnEQ(classname, "Apache2", 7)) { + lookup = modperl_constants_lookup_apache2_const; + group_lookup = modperl_constants_group_lookup_apache2_const; + } + else { + lookup = modperl_constants_lookup_modperl; + group_lookup = modperl_constants_group_lookup_modperl; + } + + if (*arg != '-') { + /* only export into callers namespace without -compile arg */ + caller_stash = gv_stashpv(arg, TRUE); + } + + if (*name == ':') { + int i; + const char **group; + + name++; + + group = (*group_lookup)(name); + + for (i=0; group[i]; i++) { + new_constsub(aTHX_ lookup, caller_stash, stash, group[i]); + } + } + else { + if (*name == '&') { + name++; + } + new_constsub(aTHX_ lookup, caller_stash, stash, name); + } + + return 1; +} + +XS(XS_modperl_const_compile) +{ + I32 i; + STRLEN n_a; + char *stashname = HvNAME(GvSTASH(CvGV(cv))); + const char *classname, *arg; + dXSARGS; + + if (items < 2) { + Perl_croak(aTHX_ "Usage: %s->compile(...)", stashname); + } + + classname = *(stashname + 1) == 'P' + ? "APR::Const" + : (*stashname == 'A' ? "Apache2::Const" : "ModPerl"); + arg = SvPV(ST(1),n_a); + + for (i=2; i<items; i++) { + (void)modperl_const_compile(aTHX_ classname, arg, SvPV(ST(i), n_a)); + } + + XSRETURN_EMPTY; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_const.h b/2_0_13/src/modules/perl/modperl_const.h new file mode 100644 index 0000000..f6ef50c --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_const.h
@@ -0,0 +1,40 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_CONST_H +#define MODPERL_CONST_H + +#include "modperl_constants.h" + +int modperl_const_compile(pTHX_ const char *classname, + const char *arg, + const char *name); + +XS(XS_modperl_const_compile); + +#define MP_newModPerlConstXS(name) \ + newXS(name "::Const::compile", \ + CvXSUB(get_cv("ModPerl::Const::compile", TRUE)), \ + __FILE__) + +#endif /* MODPERL_CONST_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_debug.c b/2_0_13/src/modules/perl/modperl_debug.c new file mode 100644 index 0000000..8b880d9 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_debug.c
@@ -0,0 +1,84 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +char *modperl_server_desc(server_rec *s, apr_pool_t *p) +{ + return apr_psprintf(p, "%s:%u", s->server_hostname, s->port); +} + +#ifdef MP_TRACE +void modperl_apr_table_dump(pTHX_ apr_table_t *table, char *name) +{ + int i, tmp_len, len = 0; + char *fmt; + const apr_array_header_t *array = apr_table_elts(table); + apr_table_entry_t *elts = (apr_table_entry_t *)array->elts; + + modperl_trace(MP_FUNC, "*** Contents of table '%s' ***", name); + for (i = 0; i < array->nelts; i++) { + if (elts[i].key && elts[i].val) { + tmp_len = strlen(elts[i].key); + if (tmp_len > len) { + len = tmp_len; + } + } + } + /* dump the table with keys aligned */ + fmt = Perl_form(aTHX_ "%%-%ds => %%s", len); + + for (i = 0; i < array->nelts; i++) { + if (!elts[i].key || !elts[i].val) { + continue; + } + modperl_trace(MP_FUNC, fmt, elts[i].key, elts[i].val); + } + modperl_trace(MP_FUNC, ""); +} +#endif + +#ifdef MP_TRACE +void modperl_perl_modglobal_dump(pTHX) +{ + HV *hv = PL_modglobal; + AV *val; + char *key; + I32 klen; + hv_iterinit(hv); + + MP_TRACE_g(MP_FUNC, "|-------- PL_modglobal --------"); +#ifdef USE_ITHREADS + MP_TRACE_g(MP_FUNC, "| perl 0x%lx", (unsigned long)aTHX); +#endif + MP_TRACE_g(MP_FUNC, "| PL_modglobal 0x%lx", + (unsigned long)PL_modglobal); + + while ((val = (AV*)hv_iternextsv(hv, &key, &klen))) { + MP_TRACE_g(MP_FUNC, "| %s => 0x%lx", key, val); + } + + MP_TRACE_g(MP_FUNC, "|-------- PL_modglobal --------"); + +} +#endif + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_debug.h b/2_0_13/src/modules/perl/modperl_debug.h new file mode 100644 index 0000000..da7fc4b --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_debug.h
@@ -0,0 +1,49 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_DEBUG_H +#define MODPERL_DEBUG_H + +#include "mod_perl.h" + +#ifdef MP_DEBUG +# define MP_ASSERT(exp) ap_assert(exp) +#else +# define MP_ASSERT(exp) ((void)0) +#endif + +#ifdef USE_ITHREADS +# define MP_ASSERT_CONTEXT(perl) MP_ASSERT((perl) == PERL_GET_CONTEXT) +#else +# define MP_ASSERT_CONTEXT(perl) ((void)0) +#endif + +char *modperl_server_desc(server_rec *s, apr_pool_t *p); + +#ifdef MP_TRACE +void modperl_apr_table_dump(pTHX_ apr_table_t *table, char *name); +/* dump the contents of PL_modglobal */ +void modperl_perl_modglobal_dump(pTHX); +#endif + +#endif /* MODPERL_DEBUG_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_env.c b/2_0_13/src/modules/perl/modperl_env.c new file mode 100644 index 0000000..62d4030 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_env.c
@@ -0,0 +1,727 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +#define EnvMgOK ((SV*)ENVHV && SvMAGIC((SV*)ENVHV)) +#define EnvMgObj (EnvMgOK ? SvMAGIC((SV*)ENVHV)->mg_ptr : NULL) +#define EnvMgLen (EnvMgOK ? SvMAGIC((SV*)ENVHV)->mg_len : 0) +#define EnvMgObjSet(val){ \ + if (EnvMgOK) SvMAGIC((SV*)ENVHV)->mg_ptr = (char *)val;} +#define EnvMgLenSet(val) {\ + if (EnvMgOK) SvMAGIC((SV*)ENVHV)->mg_len = val;} + +/* XXX: move to utils? */ +static unsigned long modperl_interp_address(pTHX) +{ +#ifdef USE_ITHREADS + return (unsigned long)aTHX; +#else + return (unsigned long)0; /* just one interpreter */ +#endif +} + +#define MP_ENV_HV_STORE(hv, key, val) STMT_START { \ + I32 klen = strlen(key); \ + SV **svp = hv_fetch(hv, key, klen, FALSE); \ + SV *sv; \ + \ + if (svp) { \ + sv_setpv(*svp, val); \ + } \ + else { \ + sv = newSVpv(val, 0); \ + (void)hv_store(hv, key, klen, sv, FALSE); \ + modperl_envelem_tie(sv, key, klen); \ + svp = &sv; \ + } \ + MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";", key, val); \ + \ + SvTAINTED_on(*svp); \ + } STMT_END + +void modperl_env_hv_store(pTHX_ const char *key, const char *val) +{ + MP_ENV_HV_STORE(ENVHV, key, val); +} + +static MP_INLINE +void modperl_env_hv_delete(pTHX_ HV *hv, char *key) +{ + I32 klen = strlen(key); + if (hv_exists(hv, key, klen)) { + (void)hv_delete(hv, key, strlen(key), G_DISCARD); + } +} + +typedef struct { + const char *key; + I32 klen; + const char *val; + I32 vlen; + U32 hash; +} modperl_env_ent_t; + +#define MP_ENV_ENT(k,v) \ +{ k, MP_SSTRLEN(k), v, MP_SSTRLEN(v), 0 } + +static modperl_env_ent_t MP_env_const_vars[] = { + MP_ENV_ENT("MOD_PERL", MP_VERSION_STRING), + MP_ENV_ENT("MOD_PERL_API_VERSION", MP_API_VERSION), + { NULL } +}; + +void modperl_env_hash_keys(pTHX) +{ + modperl_env_ent_t *ent = MP_env_const_vars; + + while (ent->key) { + PERL_HASH(ent->hash, ent->key, ent->klen); + MP_TRACE_e(MP_FUNC, "[0x%lx] PERL_HASH: %s (len: %d)", + modperl_interp_address(aTHX), ent->key, ent->klen); + ent++; + } +} + +void modperl_env_clear(pTHX) +{ + HV *hv = ENVHV; + U32 mg_flags; + + modperl_env_untie(mg_flags); + + MP_TRACE_e(MP_FUNC, "[0x%lx] %%ENV = ();", modperl_interp_address(aTHX)); + + hv_clear(hv); + + modperl_env_tie(mg_flags); +} + +#define MP_ENV_HV_STORE_TABLE_ENTRY(hv, elt) \ + MP_ENV_HV_STORE(hv, elt.key, elt.val); + +static void modperl_env_table_populate(pTHX_ apr_table_t *table) +{ + HV *hv = ENVHV; + U32 mg_flags; + int i; + const apr_array_header_t *array; + apr_table_entry_t *elts; + + modperl_env_init(aTHX); + modperl_env_untie(mg_flags); + + array = apr_table_elts(table); + elts = (apr_table_entry_t *)array->elts; + + for (i = 0; i < array->nelts; i++) { + if (!elts[i].key || !elts[i].val) { + continue; + } + MP_ENV_HV_STORE_TABLE_ENTRY(hv, elts[i]); + } + + modperl_env_tie(mg_flags); +} + +static void modperl_env_table_unpopulate(pTHX_ apr_table_t *table) +{ + HV *hv = ENVHV; + U32 mg_flags; + int i; + const apr_array_header_t *array; + apr_table_entry_t *elts; + + modperl_env_untie(mg_flags); + + array = apr_table_elts(table); + elts = (apr_table_entry_t *)array->elts; + + for (i = 0; i < array->nelts; i++) { + if (!elts[i].key) { + continue; + } + modperl_env_hv_delete(aTHX_ hv, elts[i].key); + MP_TRACE_e(MP_FUNC, "delete $ENV{%s};", elts[i].key); + } + + modperl_env_tie(mg_flags); +} + +/* see the comment in modperl_env_sync_env_hash2table */ +static void modperl_env_sync_table(pTHX_ apr_table_t *table) +{ + int i; + const apr_array_header_t *array; + apr_table_entry_t *elts; + HV *hv = ENVHV; + SV **svp; + + array = apr_table_elts(table); + elts = (apr_table_entry_t *)array->elts; + + for (i = 0; i < array->nelts; i++) { + if (!elts[i].key) { + continue; + } + svp = hv_fetch(hv, elts[i].key, strlen(elts[i].key), FALSE); + if (svp) { + apr_table_set(table, elts[i].key, SvPV_nolen(*svp)); + MP_TRACE_e(MP_FUNC, "(Set|Pass)Env '%s' '%s'", elts[i].key, + SvPV_nolen(*svp)); + } + } + TAINT_NOT; /* SvPV_* causes the taint issue */ +} + +/* Make per-server PerlSetEnv and PerlPassEnv in sync with %ENV at + * config time (if perl is running), by copying %ENV values to the + * PerlSetEnv and PerlPassEnv tables (only for keys which are already + * in those tables) + */ +void modperl_env_sync_srv_env_hash2table(pTHX_ apr_pool_t *p, + modperl_config_srv_t *scfg) +{ + modperl_env_sync_table(aTHX_ scfg->SetEnv); + modperl_env_sync_table(aTHX_ scfg->PassEnv); +} + +void modperl_env_sync_dir_env_hash2table(pTHX_ apr_pool_t *p, + modperl_config_dir_t *dcfg) +{ + modperl_env_sync_table(aTHX_ dcfg->SetEnv); +} + +/* list of environment variables to pass by default */ +static const char *MP_env_pass_defaults[] = { + "PATH", "TZ", NULL +}; + +void modperl_env_configure_server(pTHX_ apr_pool_t *p, server_rec *s) +{ + MP_dSCFG(s); + int i = 0; + + /* make per-server PerlSetEnv and PerlPassEnv entries visible + * to %ENV at config time + */ + + for (i=0; MP_env_pass_defaults[i]; i++) { + const char *key = MP_env_pass_defaults[i]; + char *val; + + if (apr_table_get(scfg->SetEnv, key) || + apr_table_get(scfg->PassEnv, key)) + { + continue; /* already configured */ + } + + if ((val = getenv(key))) { + apr_table_set(scfg->PassEnv, key, val); + } + } + + MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]" + "\n\t@ENV{keys scfg->SetEnv} = values scfg->SetEnv;", + modperl_interp_address(aTHX), + modperl_server_desc(s, p)); + modperl_env_table_populate(aTHX_ scfg->SetEnv); + + MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]" + "\n\t@ENV{keys scfg->PassEnv} = values scfg->PassEnv;", + modperl_interp_address(aTHX), + modperl_server_desc(s, p)); + modperl_env_table_populate(aTHX_ scfg->PassEnv); +} + +#define overlay_subprocess_env(r, tab) \ + r->subprocess_env = apr_table_overlay(r->pool, \ + r->subprocess_env, \ + tab) + +void modperl_env_configure_request_dir(pTHX_ request_rec *r) +{ + MP_dRCFG; + MP_dDCFG; + + /* populate %ENV and r->subprocess_env with per-directory + * PerlSetEnv entries. + * + * note that per-server PerlSetEnv entries, as well as + * PerlPassEnv entries (which are only per-server), are added + * to %ENV and r->subprocess_env via modperl_env_configure_request_srv + */ + + if (!apr_is_empty_table(dcfg->SetEnv)) { + apr_table_t *setenv_copy; + + /* add per-directory PerlSetEnv entries to %ENV + * collisions with per-server PerlSetEnv entries are + * resolved via the nature of a Perl hash + */ + MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]" + "\n\t@ENV{keys dcfg->SetEnv} = values dcfg->SetEnv;", + modperl_interp_address(aTHX), + modperl_server_desc(r->server, r->pool)); + modperl_env_table_populate(aTHX_ dcfg->SetEnv); + + /* make sure the entries are in the subprocess_env table as well. + * we need to use apr_table_overlap (not apr_table_overlay) because + * r->subprocess_env might have per-server PerlSetEnv entries in it + * and using apr_table_overlay would generate duplicate entries. + * in order to use apr_table_overlap, though, we need to copy the + * the dcfg table so that pool requirements are satisfied */ + + setenv_copy = apr_table_copy(r->pool, dcfg->SetEnv); + apr_table_overlap(r->subprocess_env, setenv_copy, APR_OVERLAP_TABLES_SET); + } + + MpReqPERL_SET_ENV_DIR_On(rcfg); +} + +void modperl_env_configure_request_srv(pTHX_ request_rec *r) +{ + MP_dRCFG; + MP_dSCFG(r->server); + + /* populate %ENV and r->subprocess_env with per-server PerlSetEnv + * and PerlPassEnv entries. + * + * although both are setup in %ENV in modperl_request_configure_server + * %ENV will be reset via modperl_env_request_unpopulate. + */ + + if (!apr_is_empty_table(scfg->SetEnv)) { + MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]" + "\n\t@ENV{keys scfg->SetEnv} = values scfg->SetEnv;", + modperl_interp_address(aTHX), + modperl_server_desc(r->server, r->pool)); + modperl_env_table_populate(aTHX_ scfg->SetEnv); + + overlay_subprocess_env(r, scfg->SetEnv); + } + + if (!apr_is_empty_table(scfg->PassEnv)) { + MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s]" + "\n\t@ENV{keys scfg->PassEnv} = values scfg->PassEnv;", + modperl_interp_address(aTHX), + modperl_server_desc(r->server, r->pool)); + modperl_env_table_populate(aTHX_ scfg->PassEnv); + + overlay_subprocess_env(r, scfg->PassEnv); + } + + MpReqPERL_SET_ENV_SRV_On(rcfg); +} + +void modperl_env_default_populate(pTHX) +{ + modperl_env_ent_t *ent = MP_env_const_vars; + HV *hv = ENVHV; + U32 mg_flags; + + modperl_env_untie(mg_flags); + + while (ent->key) { + SV *sv = newSVpvn(ent->val, ent->vlen); + (void)hv_store(hv, ent->key, ent->klen, + sv, ent->hash); + MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";", ent->key, ent->val); + modperl_envelem_tie(sv, ent->key, ent->klen); + ent++; + } + + modperl_env_tie(mg_flags); +} + +void modperl_env_request_populate(pTHX_ request_rec *r) +{ + MP_dRCFG; + + /* this is called under the following conditions + * - if PerlOptions +SetupEnv + * - if $r->subprocess_env() is called in a void context with no args + * + * normally, %ENV is only populated once per request (if at all) - + * just prior to content generation if +SetupEnv. + * + * however, in the $r->subprocess_env() case it will be called + * more than once - once for each void call, and once again just + * prior to content generation. while costly, the multiple + * passes are required, otherwise void calls would prohibit later + * phases from populating %ENV with new subprocess_env table entries + */ + + MP_TRACE_e(MP_FUNC, "\t[0x%lx/%s%s]" + "\n\t@ENV{keys r->subprocess_env} = values r->subprocess_env;", + modperl_interp_address(aTHX), + modperl_server_desc(r->server, r->pool), r->uri); + + /* we can eliminate some of the cost by only doing CGI variables once + * per-request no matter how many times $r->subprocess_env() is called + */ + if (! MpReqSETUP_ENV(rcfg)) { + + ap_add_common_vars(r); + ap_add_cgi_vars(r); + + } + + modperl_env_table_populate(aTHX_ r->subprocess_env); + + /* don't set up CGI variables again this request. + * this also triggers modperl_env_request_unpopulate, which + * resets %ENV between requests - see modperl_config_request_cleanup + */ + MpReqSETUP_ENV_On(rcfg); +} + +void modperl_env_request_unpopulate(pTHX_ request_rec *r) +{ + MP_dRCFG; + + /* unset only once */ + if (!MpReqSETUP_ENV(rcfg)) { + return; + } + + MP_TRACE_e(MP_FUNC, + "\n\t[0x%lx/%s%s]\n\tdelete @ENV{keys r->subprocess_env};", + modperl_interp_address(aTHX), + modperl_server_desc(r->server, r->pool), r->uri); + modperl_env_table_unpopulate(aTHX_ r->subprocess_env); + + MpReqSETUP_ENV_Off(rcfg); +} + +void modperl_env_request_tie(pTHX_ request_rec *r) +{ + EnvMgObjSet(r); + EnvMgLenSet(-1); + +#ifdef MP_PERL_HV_GMAGICAL_AWARE + MP_TRACE_e(MP_FUNC, "[0x%lx] tie %%ENV, $r\t (%s%s)", + modperl_interp_address(aTHX), + modperl_server_desc(r->server, r->pool), r->uri); + SvGMAGICAL_on((SV*)ENVHV); +#endif +} + +void modperl_env_request_untie(pTHX_ request_rec *r) +{ + EnvMgObjSet(NULL); + +#ifdef MP_PERL_HV_GMAGICAL_AWARE + MP_TRACE_e(MP_FUNC, "[0x%lx] untie %%ENV; # from r\t (%s%s)", + modperl_interp_address(aTHX), + modperl_server_desc(r->server, r->pool), r->uri); + SvGMAGICAL_off((SV*)ENVHV); +#endif +} + +/* handy access to perl's original virtual tables + */ +#define MP_PL_vtbl_call(name, meth) \ + PL_vtbl_##name.svt_##meth(aTHX_ sv, mg) + +#define MP_dENV_KEY \ + STRLEN klen; \ + const char *key = (const char *)MgPV(mg,klen) + +#define MP_dENV_VAL \ + STRLEN vlen; \ + const char *val = (const char *)SvPV(sv,vlen) + +/* + * XXX: what we do here might change: + * - make it optional for %ENV to be tied to r->subprocess_env + * - make it possible to modify environ + * - we could allow modification of environ if mpm isn't threaded + * - we could allow modification of environ if variable isn't a CGI + * variable (still could cause problems) + */ +/* + * problems we are trying to solve: + * - environ is shared between threads + * + Perl does not serialize access to environ + * + even if it did, CGI variables cannot be shared between threads! + * problems we create by trying to solve above problems: + * - a forked process will not inherit the current %ENV + * - C libraries might rely on environ, e.g. DBD::Oracle + */ +static int modperl_env_magic_set_all(pTHX_ SV *sv, MAGIC *mg) +{ + request_rec *r = (request_rec *)EnvMgObj; + + if (r) { + if (PL_localizing) { + /* local %ENV = (FOO => 'bar', BIZ => 'baz') */ + HE *entry; + STRLEN n_a; + + hv_iterinit((HV*)sv); + while ((entry = hv_iternext((HV*)sv))) { + I32 keylen; + apr_table_set(r->subprocess_env, + hv_iterkey(entry, &keylen), + SvPV(hv_iterval((HV*)sv, entry), n_a)); + MP_TRACE_e(MP_FUNC, "[0x%lx] localizing: %s => %s", + modperl_interp_address(aTHX), + hv_iterkey(entry, &keylen), + SvPV(hv_iterval((HV*)sv, entry), n_a)); + } + } + } + else { +#ifdef MP_TRACE + HE *entry; + STRLEN n_a; + + MP_TRACE_e(MP_FUNC, "\n\t[0x%lx] populating %%ENV:", + modperl_interp_address(aTHX)); + + hv_iterinit((HV*)sv); + + while ((entry = hv_iternext((HV*)sv))) { + I32 keylen; + MP_TRACE_e(MP_FUNC, "$ENV{%s} = \"%s\";", + hv_iterkey(entry, &keylen), + SvPV(hv_iterval((HV*)sv, entry), n_a)); + } +#endif + return MP_PL_vtbl_call(env, set); + } + + return 0; +} + +static int modperl_env_magic_clear_all(pTHX_ SV *sv, MAGIC *mg) +{ + request_rec *r = (request_rec *)EnvMgObj; + + if (r) { + apr_table_clear(r->subprocess_env); + MP_TRACE_e(MP_FUNC, "[0x%lx] clearing all magic off r->subprocess_env", + modperl_interp_address(aTHX)); + } + else { + MP_TRACE_e(MP_FUNC, "[0x%lx] %%ENV = ();", + modperl_interp_address(aTHX)); + return MP_PL_vtbl_call(env, clear); + } + + return 0; +} + +static int modperl_env_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, const char *name, I32 namlen) +{ + MP_TRACE_e(MP_FUNC, "setting up %%ENV element magic"); + sv_magicext(nsv, mg->mg_obj, toLOWER(mg->mg_type), &MP_vtbl_envelem, name, namlen); + + return 1; +} + +static int modperl_env_magic_local_all(pTHX_ SV *nsv, MAGIC *mg) +{ + MAGIC *nmg; + MP_TRACE_e(MP_FUNC, "localizing %%ENV"); + nmg = sv_magicext(nsv, mg->mg_obj, mg->mg_type, &MP_vtbl_env, (char*)NULL, 0); + nmg->mg_ptr = mg->mg_ptr; + nmg->mg_flags |= MGf_COPY; +#if (PERL_REVISION == 5 && PERL_VERSION == 8 && PERL_SUBVERSION > 8) || \ + MP_PERL_VERSION_AT_LEAST(5, 9, 3) + nmg->mg_flags |= MGf_LOCAL; +#endif + + return 1; +} + +static int modperl_env_magic_set(pTHX_ SV *sv, MAGIC *mg) +{ + request_rec *r = (request_rec *)EnvMgObj; + + if (r) { + MP_dENV_KEY; + MP_dENV_VAL; + apr_table_set(r->subprocess_env, key, val); + MP_TRACE_e(MP_FUNC, "[0x%lx] r->subprocess_env set: %s => %s", + modperl_interp_address(aTHX), key, val); + } + else { +#ifdef MP_TRACE + MP_dENV_KEY; + MP_dENV_VAL; + MP_TRACE_e(MP_FUNC, + "[0x%lx] $ENV{%s} = \"%s\";", + modperl_interp_address(aTHX), key, val); +#endif + return MP_PL_vtbl_call(envelem, set); + } + + return 0; +} + +static int modperl_env_magic_clear(pTHX_ SV *sv, MAGIC *mg) +{ + request_rec *r = (request_rec *)EnvMgObj; + + if (r) { + MP_dENV_KEY; + apr_table_unset(r->subprocess_env, key); + MP_TRACE_e(MP_FUNC, "[0x%lx] r->subprocess_env unset: %s", + modperl_interp_address(aTHX), key); + } + else { +#ifdef MP_TRACE + MP_dENV_KEY; + MP_TRACE_e(MP_FUNC, "[0x%lx] delete $ENV{%s};", + modperl_interp_address(aTHX), key); +#endif + return MP_PL_vtbl_call(envelem, clear); + } + + return 0; +} + +#ifdef MP_PERL_HV_GMAGICAL_AWARE +static int modperl_env_magic_get(pTHX_ SV *sv, MAGIC *mg) +{ + request_rec *r = (request_rec *)EnvMgObj; + + if (r) { + MP_dENV_KEY; + const char *val; + + if ((val = apr_table_get(r->subprocess_env, key))) { + sv_setpv(sv, val); + MP_TRACE_e(MP_FUNC, + "[0x%lx] r->subprocess_env get: %s => %s", + modperl_interp_address(aTHX), key, val); + } + else { + sv_setsv(sv, &PL_sv_undef); + MP_TRACE_e(MP_FUNC, + "[0x%lx] r->subprocess_env get: %s => undef", + modperl_interp_address(aTHX), key); + } + } + else { + /* there is no svt_get in PL_vtbl_envelem */ +#ifdef MP_TRACE + MP_dENV_KEY; + MP_TRACE_e(MP_FUNC, + "[0x%lx] there is no svt_get in PL_vtbl_envelem: %s", + modperl_interp_address(aTHX), key); +#endif + } + + return 0; +} +#endif + +/* override %ENV virtual tables with our own */ +MGVTBL MP_vtbl_env = { + 0, + modperl_env_magic_set_all, + 0, + modperl_env_magic_clear_all, + 0, + modperl_env_magic_copy, + 0, + modperl_env_magic_local_all +}; + +MGVTBL MP_vtbl_envelem = { + 0, + modperl_env_magic_set, + 0, + modperl_env_magic_clear, + 0 +}; + +void modperl_env_init(pTHX) +{ + MAGIC *mg; + + /* Find the 'E' magic on %ENV */ + if (!PL_envgv) + return; + if (!SvRMAGICAL(ENVHV)) + return; + mg = mg_find((const SV *)ENVHV, PERL_MAGIC_env); + if (!mg) + return; + + /* Ignore it if it isn't perl's original version */ + if (mg->mg_virtual != &PL_vtbl_env) + return; + + MP_TRACE_e(MP_FUNC, "env_init - ptr: %x obj: %x flags: %x", + mg->mg_ptr, mg->mg_obj, mg->mg_flags); + + /* Remove it */ +#if MP_PERL_VERSION_AT_LEAST(5, 13, 6) + mg_free_type((SV*)ENVHV, PERL_MAGIC_env); +#else + mg_free((SV*)ENVHV); +#endif + + /* Add our version instead */ + mg = sv_magicext((SV*)ENVHV, (SV*)NULL, PERL_MAGIC_env, &MP_vtbl_env, (char*)NULL, 0); + mg->mg_flags |= MGf_COPY; +#if (PERL_REVISION == 5 && PERL_VERSION == 8 && PERL_SUBVERSION > 8) || \ + MP_PERL_VERSION_AT_LEAST(5, 9, 3) + mg->mg_flags |= MGf_LOCAL; +#endif +} + +void modperl_env_unload(pTHX) +{ + MAGIC *mg; + + /* Find the 'E' magic on %ENV */ + if (!PL_envgv) + return; + if (!SvRMAGICAL(ENVHV)) + return; + mg = mg_find((const SV *)ENVHV, PERL_MAGIC_env); + if (!mg) + return; + + /* Ignore it if it isn't our version */ + if (mg->mg_virtual != &MP_vtbl_env) + return; + + MP_TRACE_e(MP_FUNC, "env_unload - ptr: %x obj: %x flags: %x", + mg->mg_ptr, mg->mg_obj, mg->mg_flags); + + /* Remove it */ +#if MP_PERL_VERSION_AT_LEAST(5, 13, 6) + mg_free_type((SV*)ENVHV, PERL_MAGIC_env); +#else + mg_free((SV*)ENVHV); +#endif + + /* Restore perl's original version */ + sv_magicext((SV*)ENVHV, (SV*)NULL, PERL_MAGIC_env, &PL_vtbl_env, (char*)NULL, 0); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_env.h b/2_0_13/src/modules/perl/modperl_env.h new file mode 100644 index 0000000..3f8f60b --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_env.h
@@ -0,0 +1,75 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_ENV_H +#define MODPERL_ENV_H + +#ifndef ENVHV +# define ENVHV GvHV(PL_envgv) +#endif + +#define modperl_env_untie(mg_flags) \ + MP_magical_untie(ENVHV, mg_flags) + +#define modperl_env_tie(mg_flags) \ + MP_magical_tie(ENVHV, mg_flags) + +#define modperl_envelem_tie(sv, key, klen) \ + sv_magicext(sv, (SV *)NULL, PERL_MAGIC_envelem, &MP_vtbl_envelem, key, klen) + +void modperl_env_hash_keys(pTHX); + +void modperl_env_clear(pTHX); + +void modperl_env_hv_store(pTHX_ const char *key, const char *val); + +void modperl_env_sync_srv_env_hash2table(pTHX_ apr_pool_t *p, + modperl_config_srv_t *scfg); + +void modperl_env_sync_dir_env_hash2table(pTHX_ apr_pool_t *p, + modperl_config_dir_t *dcfg); + +void modperl_env_configure_server(pTHX_ apr_pool_t *p, server_rec *s); + +void modperl_env_configure_request_srv(pTHX_ request_rec *r); + +void modperl_env_configure_request_dir(pTHX_ request_rec *r); + +void modperl_env_default_populate(pTHX); + +void modperl_env_request_populate(pTHX_ request_rec *r); + +void modperl_env_request_unpopulate(pTHX_ request_rec *r); + +void modperl_env_request_tie(pTHX_ request_rec *r); + +void modperl_env_request_untie(pTHX_ request_rec *r); + +void modperl_env_init(pTHX); + +void modperl_env_unload(pTHX); + +extern MGVTBL MP_vtbl_env; +extern MGVTBL MP_vtbl_envelem; + +#endif /* MODPERL_ENV_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_error.c b/2_0_13/src/modules/perl/modperl_error.c new file mode 100644 index 0000000..2f83216 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_error.c
@@ -0,0 +1,102 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +static const char *MP_error_strings[] = { + "exit was called", /* MODPERL_RC_EXIT */ + "filter handler has failed", /* MODPERL_FILTER_ERROR */ +}; + +#define MP_error_strings_size \ + sizeof(MP_error_strings) / sizeof(MP_error_strings[0]) + +char *modperl_error_strerror(pTHX_ apr_status_t rc) +{ + char *ptr; + char buf[256]; + + if (rc >= APR_OS_START_USERERR && + rc < APR_OS_START_USERERR + MP_error_strings_size) { + /* custom mod_perl errors */ + ptr = (char*)MP_error_strings[(int)(rc - APR_OS_START_USERERR)]; + } + else { + /* apache apr errors */ + ptr = apr_strerror(rc, buf, sizeof(buf)); + } + + /* must copy the string and not return a pointer to the local + * address. Using a single (per interpreter) static buffer. + */ + return Perl_form(aTHX_ "%s", ptr ? ptr : "unknown error"); +} + + +/* modperl_croak notes: under -T we can't really do anything when die + * was called in the stacked eval_sv (which is the case when a + * response handler calls a filter handler and that filter calls die + * ""). for example trying to require a file in modperl_croak(), will + * cause 'panic: POPSTACK' and the process will exit. Dave fixed that + * in perl Change 23209 by davem@davem-percy on 2004/08/09 19:48:57, + * which will hopefully appear in perl 5.8.6. for now workaround this + * perl bug by setting the taint mode off for the APR/Error loading. + */ + +/* croak with $@ as a APR::Error object + * rc - set to apr_status_t value + * file - set to the callers filename + * line - set to the callers line number + * func - set to the function name + */ +void modperl_croak(pTHX_ apr_status_t rc, const char* func) +{ + HV *stash; + HV *data; + int is_tainted = PL_tainted; + + /* see the explanation above */ + if (is_tainted) { + TAINT_NOT; + } + Perl_require_pv(aTHX_ "APR/Error.pm"); + if (is_tainted) { + TAINT; + } + + if (SvTRUE(ERRSV)) { + Perl_croak(aTHX_ (char *)NULL); + } + + stash = gv_stashpvn("APR::Error", 10, FALSE); + data = newHV(); + /* $@ = bless {}, "APR::Error"; */ + sv_setsv(ERRSV, sv_bless(newRV_noinc((SV*)data), stash)); + + sv_setiv(*hv_fetch(data, "rc", 2, 1), rc); + sv_setpv(*hv_fetch(data, "file", 4, 1), CopFILE(PL_curcop)); + sv_setiv(*hv_fetch(data, "line", 4, 1), CopLINE(PL_curcop)); + sv_setpv(*hv_fetch(data, "func", 4, 1), func); + + Perl_croak(aTHX_ (char *)NULL); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_error.h b/2_0_13/src/modules/perl/modperl_error.h new file mode 100644 index 0000000..0a4d82c --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_error.h
@@ -0,0 +1,115 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_ERROR_H +#define MODPERL_ERROR_H + +/*** mod_perl custom errors come here ***/ + +/* to check whether $@ is set by ModPerl::Util::exit */ +#define MODPERL_RC_EXIT APR_OS_START_USERERR + 0 +/* indicate the filter error problem */ +#define MODPERL_FILTER_ERROR APR_OS_START_USERERR + 1 + +/** + * return the string representation of the error code + * @param rc error code + * @return the error string + * + * The return value must be immediately copied unless used only in a + * limited visible scope where it's clear that Perl_form() is not + * called again (which could happen indirectly). If unsure, copy. + */ +char *modperl_error_strerror(pTHX_ apr_status_t rc); + +void modperl_croak(pTHX_ apr_status_t rc, const char* func); + +#ifdef USE_ITHREADS +#define MP_PUTBACK_IF_USED() STMT_START \ + { \ + modperl_interp_t *interp = modperl_thx_interp_get(aTHX); \ + if (interp && interp->refcnt > 1) { \ + modperl_interp_unselect(interp); \ + } \ + } STMT_END +#else +#define MP_PUTBACK_IF_USED() NOOP +#endif + +#define MP_CROAK_PUTBACK(rc, func) STMT_START \ + { \ + MP_PUTBACK_IF_USED(); \ + modperl_croak(aTHX_ rc, func); \ + } STMT_END + +#define MP_RUN_CROAK(rc_run, func) STMT_START \ + { \ + apr_status_t rc = rc_run; \ + if (rc != APR_SUCCESS) { \ + modperl_croak(aTHX_ rc, func); \ + } \ + } STMT_END + +#define MP_RUN_CROAK_PUTBACK(rc_run, func) STMT_START \ + { \ + apr_status_t rc = rc_run; \ + if (rc != APR_SUCCESS) { \ + MP_PUTBACK_IF_USED(); \ + modperl_croak(aTHX_ rc, func); \ + } \ + } STMT_END + +#define MP_RUN_CROAK_RESET_OK(s, rc_run, func) STMT_START \ + { \ + apr_status_t rc = rc_run; \ + if (rc != APR_SUCCESS) { \ + if (APR_STATUS_IS_ECONNRESET(rc) || \ + APR_STATUS_IS_ECONNABORTED(rc)) { \ + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, \ + "%s got: %s", func, \ + modperl_error_strerror(aTHX_ rc)); \ + } \ + else { \ + modperl_croak(aTHX_ rc, func); \ + } \ + } \ + } STMT_END + +#define MP_RUN_CROAK_RESET_OK_PUTBACK(s, rc_run, func) STMT_START \ + { \ + apr_status_t rc = rc_run; \ + if (rc != APR_SUCCESS) { \ + if (APR_STATUS_IS_ECONNRESET(rc) || \ + APR_STATUS_IS_ECONNABORTED(rc)) { \ + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, \ + "%s got: %s", func, \ + modperl_error_strerror(aTHX_ rc)); \ + } \ + else { \ + MP_PUTBACK_IF_USED(); \ + modperl_croak(aTHX_ rc, func); \ + } \ + } \ + } STMT_END + +#endif /* MODPERL_ERROR_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_filter.c b/2_0_13/src/modules/perl/modperl_filter.c new file mode 100644 index 0000000..76be3e0 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_filter.c
@@ -0,0 +1,1301 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* helper funcs */ + +#define MP_FILTER_NAME_FORMAT " %s\n\n\t" + +#define MP_FILTER_NAME(f) \ + (is_modperl_filter(f) \ + ? modperl_handler_name( \ + ((modperl_filter_ctx_t *)(f)->ctx)->handler) \ + : (f)->frec->name) + +#define MP_FILTER_TYPE(filter) \ + (is_modperl_filter(filter->f) \ + ? ((modperl_filter_ctx_t *)(filter)->f->ctx)->handler->attrs & \ + MP_FILTER_CONNECTION_HANDLER ? "connection" : "request" \ + : "unknown") + +#define MP_FILTER_MODE(filter) \ + (filter->mode == MP_INPUT_FILTER_MODE ? "input" : "output") + +#define MP_FILTER_POOL(f) f->r ? f->r->pool : f->c->pool + +/* allocate wbucket memory using a sub-pool and not a ap_filter_t + * pool, since we may need many of these if the filter is invoked + * multiple times */ +#define WBUCKET_INIT(filter) \ + if (!filter->wbucket) { \ + modperl_wbucket_t *wb = \ + (modperl_wbucket_t *)apr_pcalloc(filter->temp_pool, \ + sizeof(*wb)); \ + wb->pool = filter->pool; \ + wb->filters = &(filter->f->next); \ + wb->outcnt = 0; \ + wb->r = NULL; \ + wb->header_parse = 0; \ + filter->wbucket = wb; \ + } + +#define FILTER_FREE(filter) \ + apr_pool_destroy(filter->temp_pool); + +/* Save the value of $@ if it was set */ +#define MP_FILTER_SAVE_ERRSV(tmpsv) \ + if (SvTRUE(ERRSV)) { \ + tmpsv = newSVsv(ERRSV); \ + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT \ + "Saving $@='%s'", \ + MP_FILTER_NAME(filter->f), \ + SvPVX(tmpsv) \ + ); \ + } + +/* Restore previously saved value of $@. if there was a filter error + * it'd have been logged by modperl_errsv call following + * modperl_callback */ +#define MP_FILTER_RESTORE_ERRSV(tmpsv) \ + if (tmpsv) { \ + sv_setsv(ERRSV, tmpsv); \ + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT \ + "Restoring $@='%s'", \ + MP_FILTER_NAME(filter->f), \ + SvPVX(tmpsv) \ + ); \ + } + +/* this function is for tracing only, it's not optimized for performance */ +static int is_modperl_filter(ap_filter_t *f) +{ + const char *name = f->frec->name; + + /* frec->name is always lowercased */ + if (!strcasecmp(name, MP_FILTER_CONNECTION_INPUT_NAME) || + !strcasecmp(name, MP_FILTER_CONNECTION_OUTPUT_NAME) || + !strcasecmp(name, MP_FILTER_REQUEST_INPUT_NAME) || + !strcasecmp(name, MP_FILTER_REQUEST_OUTPUT_NAME) ) { + return 1; + } + else { + return 0; + } +} + + +MP_INLINE static apr_status_t send_input_eos(modperl_filter_t *filter) +{ + apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc; + apr_bucket *b = apr_bucket_eos_create(ba); + APR_BRIGADE_INSERT_TAIL(filter->bb_out, b); + ((modperl_filter_ctx_t *)filter->f->ctx)->sent_eos = 1; + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "write out: EOS bucket", MP_FILTER_NAME(filter->f)); + return APR_SUCCESS; +} + +MP_INLINE static apr_status_t send_input_flush(modperl_filter_t *filter) +{ + apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc; + apr_bucket *b = apr_bucket_flush_create(ba); + APR_BRIGADE_INSERT_TAIL(filter->bb_out, b); + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "write out: FLUSH bucket", MP_FILTER_NAME(filter->f)); + return APR_SUCCESS; +} + +MP_INLINE static apr_status_t send_output_eos(ap_filter_t *f) +{ + apr_bucket_alloc_t *ba = f->c->bucket_alloc; + apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f), + ba); + apr_bucket *b = apr_bucket_eos_create(ba); + APR_BRIGADE_INSERT_TAIL(bb, b); + ((modperl_filter_ctx_t *)f->ctx)->sent_eos = 1; + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "write out: EOS bucket in separate bb", MP_FILTER_NAME(f)); + return ap_pass_brigade(f->next, bb); +} + +MP_INLINE static apr_status_t send_output_flush(ap_filter_t *f) +{ + apr_bucket_alloc_t *ba = f->c->bucket_alloc; + apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f), + ba); + apr_bucket *b = apr_bucket_flush_create(ba); + APR_BRIGADE_INSERT_TAIL(bb, b); + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "write out: FLUSH bucket in separate bb", MP_FILTER_NAME(f)); + return ap_pass_brigade(f, bb); +} + +/* simple buffer api */ + +MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *wb, + const char *buf, apr_size_t len, + int add_flush_bucket) +{ + apr_bucket_alloc_t *ba = (*wb->filters)->c->bucket_alloc; + apr_bucket_brigade *bb; + apr_bucket *bucket; + + /* reset the counter to 0 as early as possible and in one place, + * since this function will always either pass the data out (and + * it has 'len' already) or return an error. + */ + wb->outcnt = 0; + + if (wb->header_parse) { + request_rec *r = wb->r; + const char *body; + int status; + + MP_TRACE_f(MP_FUNC, "parsing headers: %db [%s]", len, + MP_TRACE_STR_TRUNC(wb->pool, buf, len)); + + status = modperl_cgi_header_parse(r, (char *)buf, &len, &body); + + wb->header_parse = 0; /* only once per-request */ + + if (status == HTTP_MOVED_TEMPORARILY) { + return APR_SUCCESS; /* XXX: HTTP_MOVED_TEMPORARILY ? */ + } + else if (status != OK) { + ap_log_error(APLOG_MARK, APLOG_WARNING, + 0, r->server, "%s did not send an HTTP header", + r->uri); + r->status = status; + /* XXX: body == NULL here */ + return APR_SUCCESS; + } + else if (!len) { + return APR_SUCCESS; + } + + buf = body; + } + + /* this is a note for filter writers who may decide that there is + * a bug in mod_perl. We send a transient bucket. That means that + * this bucket can't be stored inside a filter without copying the + * data in it. This is done automatically by apr_bucket_setaside, + * which is written exactly for the purpose to make setaside + * operation transparent to the kind of bucket. + */ + bucket = apr_bucket_transient_create(buf, len, ba); + bb = apr_brigade_create(wb->pool, ba); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + + if (add_flush_bucket) { + /* append the flush bucket rather then calling ap_rflush, to + * prevent a creation of yet another bb, which will cause an + * extra call for each filter in the chain */ + apr_bucket *bucket = apr_bucket_flush_create(ba); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + } + + MP_TRACE_f(MP_FUNC, "\n\n\twrite out: %db [%s]" + "\t\tfrom %s\n\t\tto %s filter handler", + len, + MP_TRACE_STR_TRUNC(wb->pool, buf, len), + ((wb->r && wb->filters == &wb->r->output_filters) + ? "response handler" : "current filter handler"), + MP_FILTER_NAME(*(wb->filters))); + + return ap_pass_brigade(*(wb->filters), bb); +} + +/* flush data if any, + * if add_flush_bucket is TRUE + * if there is data to flush + * a flush bucket is added to the tail of bb with data + * else + * a flush bucket is sent in its own bb + * else + * nothing is sent + */ +MP_INLINE apr_status_t modperl_wbucket_flush(modperl_wbucket_t *wb, + int add_flush_bucket) +{ + apr_status_t rv = APR_SUCCESS; + + if (wb->outcnt) { + rv = modperl_wbucket_pass(wb, wb->outbuf, wb->outcnt, + add_flush_bucket); + } + else if (add_flush_bucket) { + rv = send_output_flush(*(wb->filters)); + } + + return rv; +} + +MP_INLINE apr_status_t modperl_wbucket_write(pTHX_ modperl_wbucket_t *wb, + const char *buf, + apr_size_t *wlen) +{ + apr_size_t len = *wlen; + *wlen = 0; + + if ((len + wb->outcnt) > sizeof(wb->outbuf)) { + apr_status_t rv; + if ((rv = modperl_wbucket_flush(wb, FALSE)) != APR_SUCCESS) { + return rv; + } + } + + if (len >= sizeof(wb->outbuf)) { + *wlen = len; + return modperl_wbucket_pass(wb, buf, len, FALSE); + } + else { + memcpy(&wb->outbuf[wb->outcnt], buf, len); + wb->outcnt += len; + *wlen = len; + return APR_SUCCESS; + } +} + +/* generic filter routines */ + +/* all ap_filter_t filter cleanups should go here */ +static apr_status_t modperl_filter_f_cleanup(void *data) +{ + ap_filter_t *f = (ap_filter_t *)data; + modperl_filter_ctx_t *ctx = (modperl_filter_ctx_t *)(f->ctx); + + /* mod_perl filter ctx cleanup */ + if (ctx->data){ +#ifdef USE_ITHREADS + dTHXa(ctx->interp->perl); +// MP_ASSERT_CONTEXT(aTHX); +#endif + if (SvOK(ctx->data) && SvREFCNT(ctx->data)) { + SvREFCNT_dec(ctx->data); + ctx->data = NULL; + } + MP_INTERP_PUTBACK(ctx->interp, aTHX); + } + + return APR_SUCCESS; +} + +modperl_filter_t *modperl_filter_new(ap_filter_t *f, + apr_bucket_brigade *bb, + modperl_filter_mode_e mode, + ap_input_mode_t input_mode, + apr_read_type_e block, + apr_off_t readbytes) +{ + apr_pool_t *p = MP_FILTER_POOL(f); + apr_pool_t *temp_pool; + modperl_filter_t *filter; + + /* we can't allocate memory from the pool here, since potentially + * a filter can be called hundreds of times during the same + * request/connection resulting in enormous memory demands + * (sizeof(*filter)*number of invocations). so we use a sub-pool + * which will get destroyed at the end of each modperl_filter + * invocation. + */ + apr_status_t rv = apr_pool_create(&temp_pool, p); + if (rv != APR_SUCCESS) { + /* XXX: how do we handle the error? assert? */ + return NULL; + } + filter = (modperl_filter_t *)apr_pcalloc(temp_pool, sizeof(*filter)); + +#ifdef MP_DEBUG + apr_pool_tag(temp_pool, "mod_perl temp filter"); +#endif + + filter->temp_pool = temp_pool; + filter->mode = mode; + filter->f = f; + filter->pool = p; + filter->wbucket = NULL; + + if (mode == MP_INPUT_FILTER_MODE) { + filter->bb_in = NULL; + filter->bb_out = bb; + filter->input_mode = input_mode; + filter->block = block; + filter->readbytes = readbytes; + } + else { + filter->bb_in = bb; + filter->bb_out = NULL; + } + + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "new: %s %s filter (modperl_filter_t *0x%lx), " + "f (ap_filter_t *0x%lx)", + MP_FILTER_NAME(f), + MP_FILTER_TYPE(filter), + MP_FILTER_MODE(filter), + (unsigned long)filter, + (unsigned long)filter->f); + + return filter; +} + +static void modperl_filter_mg_set(pTHX_ SV *obj, modperl_filter_t *filter) +{ + sv_magic(SvRV(obj), (SV *)NULL, PERL_MAGIC_ext, NULL, -1); + SvMAGIC(SvRV(obj))->mg_ptr = (char *)filter; +} + +modperl_filter_t *modperl_filter_mg_get(pTHX_ SV *obj) +{ + MAGIC *mg = mg_find(SvRV(obj), PERL_MAGIC_ext); + return mg ? (modperl_filter_t *)mg->mg_ptr : NULL; +} + +/* eval "package Foo; \&init_handler" */ +int modperl_filter_resolve_init_handler(pTHX_ modperl_handler_t *handler, + apr_pool_t *p) +{ + char *init_handler_pv_code = NULL; + + if (handler->mgv_cv) { + GV *gv = modperl_mgv_lookup(aTHX_ handler->mgv_cv); + if (gv) { + CV *cv = modperl_mgv_cv(gv); + if (cv && SvMAGICAL(cv)) { + MAGIC *mg = mg_find((SV*)(cv), PERL_MAGIC_ext); + init_handler_pv_code = mg ? mg->mg_ptr : NULL; + } + else { + /* XXX: should we complain in such a case? */ + return 0; + } + } + } + + if (init_handler_pv_code) { + char *package_name = + modperl_mgv_as_string(aTHX_ handler->mgv_cv, p, 1); + /* fprintf(stderr, "PACKAGE: %s\n", package_name ); */ + + /* eval the code in the parent handler's package's context */ + char *code = apr_pstrcat(p, "package ", package_name, ";", + init_handler_pv_code, NULL); + SV *sv; + modperl_handler_t *init_handler; + + ENTER;SAVETMPS; + sv = eval_pv(code, TRUE); + /* fprintf(stderr, "code: %s\n", code); */ + init_handler = modperl_handler_new_from_sv(aTHX_ p, sv); + FREETMPS;LEAVE; + + if (init_handler) { + modperl_mgv_resolve(aTHX_ init_handler, p, init_handler->name, 1); + + MP_TRACE_h(MP_FUNC, "found init handler %s", + modperl_handler_name(init_handler)); + + if (!(init_handler->attrs & MP_FILTER_INIT_HANDLER)) { + Perl_croak(aTHX_ "handler %s doesn't have " + "the FilterInitHandler attribute set", + modperl_handler_name(init_handler)); + } + + handler->next = init_handler; + return 1; + } + else { + Perl_croak(aTHX_ "failed to eval code: %s", code); + + } + } + + return 1; +} + +static int modperl_run_filter_init(ap_filter_t *f, + modperl_filter_mode_e mode, + modperl_handler_t *handler) +{ + AV *args = (AV *)NULL; + int status; + + request_rec *r = f->r; + conn_rec *c = f->c; + server_rec *s = r ? r->server : c->base_server; + apr_pool_t *p = r ? r->pool : c->pool; + modperl_filter_t *filter = modperl_filter_new(f, NULL, mode, 0, 0, 0); + + MP_dINTERPa(r, c, s); + + MP_TRACE_h(MP_FUNC, "running filter init handler %s", + modperl_handler_name(handler)); + + modperl_handler_make_args(aTHX_ &args, + "Apache2::Filter", f, + NULL); + + modperl_filter_mg_set(aTHX_ AvARRAY(args)[0], filter); + + /* XXX filter_init return status is propagated back to Apache over + * in C land, making it possible to use filter_init to return, say, + * BAD_REQUEST. this implementation, however, ignores the return status + * even though we're trapping it here - modperl_filter_add_request sees + * the error and propagates it, but modperl_output_filter_add_request + * is void so the error is lost */ + if ((status = modperl_callback(aTHX_ handler, p, r, s, args)) != OK) { + status = modperl_errsv(aTHX_ status, r, s); + } + + FILTER_FREE(filter); + SvREFCNT_dec((SV*)args); + + MP_INTERP_PUTBACK(interp, aTHX); + + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "return: %d", modperl_handler_name(handler), status); + + return status; +} + +int modperl_run_filter(modperl_filter_t *filter) +{ + AV *args = (AV *)NULL; + SV *errsv = (SV *)NULL; + int status; + modperl_handler_t *handler = + ((modperl_filter_ctx_t *)filter->f->ctx)->handler; + + request_rec *r = filter->f->r; + conn_rec *c = filter->f->c; + server_rec *s = r ? r->server : c->base_server; + apr_pool_t *p = r ? r->pool : c->pool; + + MP_dINTERPa(r, c, s); + + MP_FILTER_SAVE_ERRSV(errsv); + + modperl_handler_make_args(aTHX_ &args, + "Apache2::Filter", filter->f, + "APR::Brigade", + (filter->mode == MP_INPUT_FILTER_MODE + ? filter->bb_out + : filter->bb_in), + NULL); + + modperl_filter_mg_set(aTHX_ AvARRAY(args)[0], filter); + + if (filter->mode == MP_INPUT_FILTER_MODE) { + av_push(args, newSViv(filter->input_mode)); + av_push(args, newSViv(filter->block)); + av_push(args, newSViv(filter->readbytes)); + } + + /* while filters are VOID handlers, we need to log any errors, + * because most perl coders will forget to check the return errors + * from read() and print() calls. and if the caller is not a perl + * program they won't make any sense of ERRSV or $! + */ + if ((status = modperl_callback(aTHX_ handler, p, r, s, args)) != OK) { + status = modperl_errsv(aTHX_ status, r, s); + } + + SvREFCNT_dec((SV*)args); + + /* when the streaming filter is invoked it should be able to send + * extra data, after the read in a while() loop is finished. + * Therefore we need to postpone propogating the EOS bucket, up + * until the filter handler is returned and only then send the EOS + * bucket if the stream had one. + */ + if (filter->seen_eos) { + filter->eos = 1; + filter->seen_eos = 0; + } + + if (filter->mode == MP_INPUT_FILTER_MODE) { + if (filter->bb_in) { + if (status == DECLINED) { + /* make sure the filter doesn't try to make mod_perl + * pass the bucket brigade through after it called + * $f->read(), since it causes a pre-fetch of the + * bb */ + MP_CROAK_PUTBACK(MODPERL_FILTER_ERROR, + "a filter calling $f->read " + "must return OK and not DECLINED"); + } + /* in the streaming mode filter->bb_in is populated on the + * first modperl_input_filter_read, so it must be + * destroyed at the end of the filter invocation + */ + apr_brigade_destroy(filter->bb_in); + filter->bb_in = NULL; + } + MP_RUN_CROAK_RESET_OK_PUTBACK(s, modperl_input_filter_flush(filter), + "Apache2::Filter internal flush"); + } + else { + MP_RUN_CROAK_RESET_OK_PUTBACK(s, modperl_output_filter_flush(filter), + "Apache2::Filter internal flush"); + } + + MP_FILTER_RESTORE_ERRSV(errsv); + + MP_INTERP_PUTBACK(interp, aTHX); + + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "return: %d", modperl_handler_name(handler), status); + + return status; +} + +/* unrolled APR_BRIGADE_FOREACH loop */ + +#define MP_FILTER_EMPTY(filter) \ + APR_BRIGADE_EMPTY(filter->bb_in) + +#define MP_FILTER_SENTINEL(filter) \ + APR_BRIGADE_SENTINEL(filter->bb_in) + +#define MP_FILTER_FIRST(filter) \ + APR_BRIGADE_FIRST(filter->bb_in) + +#define MP_FILTER_NEXT(filter) \ + APR_BUCKET_NEXT(filter->bucket) + +#define MP_FILTER_IS_EOS(filter) \ + APR_BUCKET_IS_EOS(filter->bucket) + +#define MP_FILTER_IS_FLUSH(filter) \ + APR_BUCKET_IS_FLUSH(filter->bucket) + +MP_INLINE static int get_bucket(modperl_filter_t *filter) +{ + if (!filter->bb_in || MP_FILTER_EMPTY(filter)) { + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "read in: bucket brigade is empty", + MP_FILTER_NAME(filter->f)); + return 0; + } + + if (!filter->bucket) { + filter->bucket = MP_FILTER_FIRST(filter); + } + else if (filter->bucket != MP_FILTER_SENTINEL(filter)) { + filter->bucket = MP_FILTER_NEXT(filter); + } + + if (filter->bucket == MP_FILTER_SENTINEL(filter)) { + filter->bucket = NULL; + /* can't destroy bb_in since the next read will need a brigade + * to try to read from */ + apr_brigade_cleanup(filter->bb_in); + return 0; + } + + if (MP_FILTER_IS_EOS(filter)) { + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "read in: EOS bucket", + MP_FILTER_NAME(filter->f)); + + filter->seen_eos = 1; + /* there should be only one EOS sent, modperl_filter_read will + * not come here, since filter->seen_eos is set + */ + return 0; + } + else if (MP_FILTER_IS_FLUSH(filter)) { + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "read in: FLUSH bucket", + MP_FILTER_NAME(filter->f)); + filter->flush = 1; + return 0; + } + else { + return 1; + } +} + + +MP_INLINE static apr_size_t modperl_filter_read(pTHX_ + modperl_filter_t *filter, + SV *buffer, + apr_size_t wanted) +{ + int num_buckets = 0; + apr_size_t len = 0; + + (void)SvUPGRADE(buffer, SVt_PV); + SvCUR(buffer) = 0; + + /* calling SvPOK_only here may leave buffer an invalid state since + * SvPVX may be NULL. But it's very likely that something is copied. + * So, we turn the POK flag on here. Later we check if SvPVX is NULL + * and turn the flag off again if so. */ + SvPOK_only(buffer); + + /* sometimes the EOS bucket arrives in the same brigade with other + * buckets, so that particular read() will not return 0 and will + * be called again if called in the while ($filter->read(...)) + * loop. In that case we return 0. + */ + if (filter->seen_eos) { + return 0; + } + + /* modperl_brigade_dump(filter->bb_in, NULL); */ + + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "wanted: %db", + MP_FILTER_NAME(filter->f), + wanted); + + if (filter->remaining) { + if (filter->remaining >= wanted) { + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "eating and returning %d [%s]\n\tof " + "remaining %db", + MP_FILTER_NAME(filter->f), + wanted, + MP_TRACE_STR_TRUNC(filter->pool, filter->leftover, wanted), + filter->remaining); + SvGROW(buffer, wanted+1); + sv_catpvn(buffer, filter->leftover, wanted); + filter->leftover += wanted; + filter->remaining -= wanted; + return wanted; + } + else { + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "eating remaining %db", + MP_FILTER_NAME(filter->f), + filter->remaining); + SvGROW(buffer, filter->remaining+1); + sv_catpvn(buffer, filter->leftover, filter->remaining); + len = filter->remaining; + filter->remaining = 0; + filter->leftover = NULL; + } + } + + while (1) { + const char *buf; + apr_size_t buf_len; + + if (!get_bucket(filter)) { + break; + } + + num_buckets++; + + filter->rc = apr_bucket_read(filter->bucket, &buf, &buf_len, 0); + + if (filter->rc == APR_SUCCESS) { + MP_TRACE_f(MP_FUNC, + MP_FILTER_NAME_FORMAT + "read in: %s bucket with %db (0x%lx)", + MP_FILTER_NAME(filter->f), + filter->bucket->type->name, + buf_len, + (unsigned long)filter->bucket); + } + else { + SvREFCNT_dec(buffer); + modperl_croak(aTHX_ filter->rc, "Apache2::Filter::read"); + } + + if (buf_len) { + if ((SvCUR(buffer) + buf_len) >= wanted) { + int nibble = wanted - SvCUR(buffer); + SvGROW(buffer, SvCUR(buffer)+nibble+1); + sv_catpvn(buffer, buf, nibble); + filter->leftover = (char *)buf+nibble; + filter->remaining = buf_len - nibble; + len += nibble; + break; + } + else { + len += buf_len; + SvGROW(buffer, SvCUR(buffer)+buf_len+1); + sv_catpvn(buffer, buf, buf_len); + } + } + } + + if (!SvPVX(buffer)) { + SvPOK_off(buffer); + } + + MP_TRACE_f(MP_FUNC, + MP_FILTER_NAME_FORMAT + "return: %db from %d bucket%s [%s]\n\t(%db leftover)", + MP_FILTER_NAME(filter->f), + len, num_buckets, ((num_buckets == 1) ? "" : "s"), + MP_TRACE_STR_TRUNC(filter->pool, SvPVX(buffer), len), + filter->remaining); + + return len; +} + +MP_INLINE apr_size_t modperl_input_filter_read(pTHX_ + modperl_filter_t *filter, + SV *buffer, + apr_size_t wanted) +{ + apr_size_t len = 0; + + if (!filter->bb_in) { + /* This should be read only once per handler invocation! */ + filter->bb_in = apr_brigade_create(filter->pool, + filter->f->c->bucket_alloc); + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "retrieving bb: 0x%lx", + MP_FILTER_NAME(filter->f), + (unsigned long)(filter->bb_in)); + MP_RUN_CROAK(ap_get_brigade(filter->f->next, filter->bb_in, + filter->input_mode, filter->block, + filter->readbytes), + "Apache2::Filter::read"); + } + + len = modperl_filter_read(aTHX_ filter, buffer, wanted); + + if (filter->flush && len == 0) { + /* if len > 0 then $filter->write will flush */ + apr_status_t rc = modperl_input_filter_flush(filter); + if (rc != APR_SUCCESS) { + SvREFCNT_dec(buffer); + modperl_croak(aTHX_ rc, "Apache2::Filter::read"); + } + } + + return len; +} + + +MP_INLINE apr_size_t modperl_output_filter_read(pTHX_ + modperl_filter_t *filter, + SV *buffer, + apr_size_t wanted) +{ + apr_size_t len = 0; + len = modperl_filter_read(aTHX_ filter, buffer, wanted); + + if (filter->flush && len == 0) { + /* if len > 0 then $filter->write will flush */ + apr_status_t rc = modperl_output_filter_flush(filter); + if (rc != APR_SUCCESS) { + SvREFCNT_dec(buffer); + modperl_croak(aTHX_ rc, "Apache2::Filter::read"); + } + } + + return len; +} + + +MP_INLINE apr_status_t modperl_input_filter_flush(modperl_filter_t *filter) +{ + if (((modperl_filter_ctx_t *)filter->f->ctx)->sent_eos) { + /* no data should be sent after EOS has been sent */ + return filter->rc; + } + + if (filter->flush) { + filter->rc = send_input_flush(filter); + filter->flush = 0; + } + + if (filter->eos) { + filter->rc = send_input_eos(filter); + filter->eos = 0; + } + + return filter->rc; +} + +MP_INLINE apr_status_t modperl_output_filter_flush(modperl_filter_t *filter) +{ + int add_flush_bucket = FALSE; + + if (((modperl_filter_ctx_t *)filter->f->ctx)->sent_eos) { + /* no data should be sent after EOS has been sent */ + return filter->rc; + } + + if (filter->flush) { + add_flush_bucket = TRUE; + filter->flush = 0; + } + + WBUCKET_INIT(filter); + filter->rc = modperl_wbucket_flush(filter->wbucket, add_flush_bucket); + if (filter->rc != APR_SUCCESS) { + return filter->rc; + } + + if (filter->eos) { + filter->rc = send_output_eos(filter->f); + if (filter->bb_in) { + apr_brigade_destroy(filter->bb_in); + filter->bb_in = NULL; + } + filter->eos = 0; + } + + return filter->rc; +} + +MP_INLINE apr_status_t modperl_input_filter_write(pTHX_ + modperl_filter_t *filter, + const char *buf, + apr_size_t *len) +{ + apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc; + char *copy = apr_pmemdup(filter->pool, buf, *len); + apr_bucket *bucket = apr_bucket_transient_create(copy, *len, ba); + MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT + "write out: %db [%s]:", + MP_FILTER_NAME(filter->f), *len, + MP_TRACE_STR_TRUNC(filter->pool, copy, *len)); + APR_BRIGADE_INSERT_TAIL(filter->bb_out, bucket); + /* modperl_brigade_dump(filter->bb_out, NULL); */ + return APR_SUCCESS; +} + +MP_INLINE apr_status_t modperl_output_filter_write(pTHX_ + modperl_filter_t *filter, + const char *buf, + apr_size_t *len) +{ + WBUCKET_INIT(filter); + + return modperl_wbucket_write(aTHX_ filter->wbucket, buf, len); +} + +apr_status_t modperl_output_filter_handler(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + modperl_filter_t *filter; + int status; + + if (((modperl_filter_ctx_t *)f->ctx)->sent_eos) { + MP_TRACE_f(MP_FUNC, + MP_FILTER_NAME_FORMAT + "write_out: EOS was already sent, " + "passing through the brigade", + MP_FILTER_NAME(f)); + return ap_pass_brigade(f->next, bb); + } + else { + filter = modperl_filter_new(f, bb, MP_OUTPUT_FILTER_MODE, + 0, 0, 0); + status = modperl_run_filter(filter); + FILTER_FREE(filter); + } + + switch (status) { + case OK: + return APR_SUCCESS; + case DECLINED: + return ap_pass_brigade(f->next, bb); + default: + return status; /*XXX*/ + } +} + +apr_status_t modperl_input_filter_handler(ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t input_mode, + apr_read_type_e block, + apr_off_t readbytes) +{ + modperl_filter_t *filter; + int status; + + if (((modperl_filter_ctx_t *)f->ctx)->sent_eos) { + MP_TRACE_f(MP_FUNC, + MP_FILTER_NAME_FORMAT + "write out: EOS was already sent, " + "passing through the brigade", + MP_FILTER_NAME(f)); + return ap_get_brigade(f->next, bb, input_mode, block, readbytes); + } + else { + filter = modperl_filter_new(f, bb, MP_INPUT_FILTER_MODE, + input_mode, block, readbytes); + status = modperl_run_filter(filter); + FILTER_FREE(filter); + } + + switch (status) { + case OK: + return APR_SUCCESS; + case DECLINED: + return ap_get_brigade(f->next, bb, input_mode, block, readbytes); + case HTTP_INTERNAL_SERVER_ERROR: + /* XXX: later may introduce separate error codes for + * modperl_run_filter and modperl_run_filter_init */ + return MODPERL_FILTER_ERROR; + default: + return status; /*XXX*/ + } +} + +static int modperl_filter_add_connection(conn_rec *c, + int idx, + const char *name, + modperl_filter_add_t addfunc, + const char *type) +{ + modperl_config_dir_t *dcfg = + modperl_config_dir_get_defaults(c->base_server); + MpAV *av; + + if ((av = dcfg->handlers_per_dir[idx])) { + modperl_handler_t **handlers = (modperl_handler_t **)av->elts; + int i; + + for (i=0; i<av->nelts; i++) { + modperl_filter_ctx_t *ctx; + ap_filter_t *f; + + /* process non-mod_perl filter handlers */ + if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) { + + /* non-mp2 filters below PROTOCOL level can't be added + * at the connection level, so we need to go through + * the pain of figuring out the type of the filter */ + ap_filter_rec_t *frec; + char *normalized_name = apr_pstrdup(c->pool, + handlers[i]->name); + ap_str_tolower(normalized_name); + frec = idx == MP_INPUT_FILTER_HANDLER + ? ap_get_input_filter_handle(normalized_name) + : ap_get_output_filter_handle(normalized_name); + if (frec && frec->ftype < AP_FTYPE_PROTOCOL) { + MP_TRACE_f(MP_FUNC, "a non-mod_perl %s handler %s " + "skipped (not a connection filter)", + type, handlers[i]->name); + continue; + } + + addfunc(handlers[i]->name, NULL, NULL, c); + MP_TRACE_f(MP_FUNC, + "a non-mod_perl %s handler %s configured " + "(connection)", type, handlers[i]->name); + continue; + } + + /* skip non-connection level filters, e.g. request filters + * configured outside the resource container */ + if (!(handlers[i]->attrs & MP_FILTER_CONNECTION_HANDLER)) { + MP_TRACE_f(MP_FUNC, + "%s is not a FilterConnection handler, skipping", + handlers[i]->name); + continue; + } + + ctx = (modperl_filter_ctx_t *)apr_pcalloc(c->pool, sizeof(*ctx)); + ctx->handler = handlers[i]; + + f = addfunc(name, (void*)ctx, NULL, c); + + /* ap_filter_t filter cleanup */ + apr_pool_cleanup_register(c->pool, (void *)f, + modperl_filter_f_cleanup, + apr_pool_cleanup_null); + + if (handlers[i]->attrs & MP_FILTER_HAS_INIT_HANDLER && + handlers[i]->next) { + int status = modperl_run_filter_init( + f, + (idx == MP_INPUT_FILTER_HANDLER + ? MP_INPUT_FILTER_MODE : MP_OUTPUT_FILTER_MODE), + handlers[i]->next); + if (status != OK) { + return status; + } + } + + MP_TRACE_h(MP_FUNC, "%s handler %s configured (connection)", + type, handlers[i]->name); + } + + return OK; + } + + MP_TRACE_h(MP_FUNC, "no %s handlers configured (connection)", type); + + return DECLINED; +} + +static int modperl_filter_add_request(request_rec *r, + int idx, + const char *name, + modperl_filter_add_t addfunc, + const char *type, + ap_filter_t *filters) +{ + MP_dDCFG; + MpAV *av; + + if ((av = dcfg->handlers_per_dir[idx])) { + modperl_handler_t **handlers = (modperl_handler_t **)av->elts; + int i; + + for (i=0; i<av->nelts; i++) { + modperl_filter_ctx_t *ctx; + int registered = 0; + ap_filter_t *f; + + /* process non-mod_perl filter handlers */ + if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) { + addfunc(handlers[i]->name, NULL, r, r->connection); + MP_TRACE_f(MP_FUNC, + "a non-mod_perl %s handler %s configured (%s)", + type, handlers[i]->name, r->uri); + continue; + } + + /* skip non-request level filters, e.g. connection filters + * configured outside the resource container, merged into + * resource's dcfg->handlers_per_dir[] entry. + */ + if ((handlers[i]->attrs & MP_FILTER_CONNECTION_HANDLER)) { + MP_TRACE_f(MP_FUNC, + "%s is not a FilterRequest handler, skipping", + handlers[i]->name); + continue; + } + + /* XXX: I fail to see where this feature is used, since + * modperl_filter_add_connection doesn't register request + * filters. may be it'll be still useful when the same + * filter handler is configured to run more than once? + * e.g. snooping filter [stas] */ + f = filters; + while (f) { + const char *fname = f->frec->name; + + /* XXX: I think this won't work as f->frec->name gets + * lowercased when added to the chain */ + if (*fname == 'M' && strEQ(fname, name)) { + modperl_handler_t *ctx_handler = + ((modperl_filter_ctx_t *)f->ctx)->handler; + + if (modperl_handler_equal(ctx_handler, handlers[i])) { + /* skip if modperl_filter_add_connection + * already registered this handler + * XXX: set a flag in the modperl_handler_t instead + */ + registered = 1; + break; + } + } + + f = f->next; + } + + if (registered) { + MP_TRACE_f(MP_FUNC, + "%s %s already registered", + handlers[i]->name, type); + continue; + } + + ctx = (modperl_filter_ctx_t *)apr_pcalloc(r->pool, sizeof(*ctx)); + ctx->handler = handlers[i]; + + f = addfunc(name, (void*)ctx, r, r->connection); + + /* ap_filter_t filter cleanup */ + apr_pool_cleanup_register(r->pool, (void *)f, + modperl_filter_f_cleanup, + apr_pool_cleanup_null); + + if (handlers[i]->attrs & MP_FILTER_HAS_INIT_HANDLER && + handlers[i]->next) { + int status = modperl_run_filter_init( + f, + (idx == MP_INPUT_FILTER_HANDLER + ? MP_INPUT_FILTER_MODE : MP_OUTPUT_FILTER_MODE), + handlers[i]->next); + if (status != OK) { + return status; + } + } + + MP_TRACE_h(MP_FUNC, "%s handler %s configured (%s)", + type, handlers[i]->name, r->uri); + } + + return OK; + } + + MP_TRACE_h(MP_FUNC, "no %s handlers configured (%s)", + type, r->uri); + + return DECLINED; +} + +void modperl_output_filter_add_connection(conn_rec *c) +{ + modperl_filter_add_connection(c, + MP_OUTPUT_FILTER_HANDLER, + MP_FILTER_CONNECTION_OUTPUT_NAME, + ap_add_output_filter, + "OutputFilter"); +} + +void modperl_output_filter_add_request(request_rec *r) +{ + modperl_filter_add_request(r, + MP_OUTPUT_FILTER_HANDLER, + MP_FILTER_REQUEST_OUTPUT_NAME, + ap_add_output_filter, + "OutputFilter", + r->connection->output_filters); +} + +void modperl_input_filter_add_connection(conn_rec *c) +{ + modperl_filter_add_connection(c, + MP_INPUT_FILTER_HANDLER, + MP_FILTER_CONNECTION_INPUT_NAME, + ap_add_input_filter, + "InputFilter"); +} + +void modperl_input_filter_add_request(request_rec *r) +{ + modperl_filter_add_request(r, + MP_INPUT_FILTER_HANDLER, + MP_FILTER_REQUEST_INPUT_NAME, + ap_add_input_filter, + "InputFilter", + r->connection->input_filters); +} + +void modperl_filter_runtime_add(pTHX_ request_rec *r, conn_rec *c, + const char *name, + modperl_filter_mode_e mode, + modperl_filter_add_t addfunc, + SV *callback, const char *type) +{ + apr_pool_t *pool = r ? r->pool : c->pool; + modperl_handler_t *handler = + modperl_handler_new_from_sv(aTHX_ pool, callback); + + if (handler) { + ap_filter_t *f; + modperl_filter_ctx_t *ctx = + (modperl_filter_ctx_t *)apr_pcalloc(pool, sizeof(*ctx)); + + ctx->handler = handler; + f = addfunc(name, (void*)ctx, r, c); + + /* ap_filter_t filter cleanup */ + apr_pool_cleanup_register(pool, (void *)f, + modperl_filter_f_cleanup, + apr_pool_cleanup_null); + + /* has to resolve early so we can check for init functions */ + if (!modperl_mgv_resolve(aTHX_ handler, pool, handler->name, TRUE)) { + Perl_croak(aTHX_ "unable to resolve handler %s\n", + modperl_handler_name(handler)); + } + + /* verify that the filter handler is of the right kind */ + if (r == NULL) { + /* needs to have the FilterConnectionHandler attribute */ + if (!(handler->attrs & MP_FILTER_CONNECTION_HANDLER)) { + Perl_croak(aTHX_ "Can't add connection filter handler '%s' " + "since it doesn't have the " + "FilterConnectionHandler attribute set", + modperl_handler_name(handler)); + } + } + else { + /* needs to have the FilterRequestHandler attribute, but + * since by default request filters are not required to + * have the FilterRequestHandler attribute, croak only if + * some other attribute is set, but not + * FilterRequestHandler */ + if (handler->attrs && + !(handler->attrs & MP_FILTER_REQUEST_HANDLER)) { + Perl_croak(aTHX_ "Can't add request filter handler '%s' " + "since it doesn't have the " + "FilterRequestHandler attribute set", + modperl_handler_name(handler)); + } + } + + if (handler->attrs & MP_FILTER_HAS_INIT_HANDLER && handler->next) { + int status = modperl_run_filter_init(f, mode, handler->next); + if (status != OK) { + modperl_croak(aTHX_ status, strEQ("InputFilter", type) + ? "Apache2::Filter::add_input_filter" + : "Apache2::Filter::add_output_filter"); + } + } + + MP_TRACE_h(MP_FUNC, "%s handler %s configured (connection)", + type, name); + + return; + } + + Perl_croak(aTHX_ "unable to resolve handler 0x%lx\n", + (unsigned long)callback); +} + +void modperl_brigade_dump(apr_bucket_brigade *bb, apr_file_t *file) +{ + apr_bucket *bucket; + int i = 0; +#ifndef WIN32 + if (file == NULL) { + file = modperl_global_get_server_rec()->error_log; + } + + apr_file_printf(file, "dump of brigade 0x%lx\n", (unsigned long)bb); + + for (bucket = APR_BRIGADE_FIRST(bb); + bucket != APR_BRIGADE_SENTINEL(bb); + bucket = APR_BUCKET_NEXT(bucket)) + { + apr_file_printf(file, + " %d: bucket=%s(0x%lx), length=%ld, data=0x%lx\n", + i, bucket->type->name, + (unsigned long)bucket, + (long)bucket->length, + (unsigned long)bucket->data); + /* apr_file_printf(file, " : %s\n", (char *)bucket->data); */ + + i++; + } +#endif +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_filter.h b/2_0_13/src/modules/perl/modperl_filter.h new file mode 100644 index 0000000..939f054 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_filter.h
@@ -0,0 +1,123 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_FILTER_H +#define MODPERL_FILTER_H + +#define MP_FILTER_CONNECTION_OUTPUT_NAME "MODPERL_CONNECTION_OUTPUT" +#define MP_FILTER_CONNECTION_INPUT_NAME "MODPERL_CONNECTION_INPUT" + +#define MP_FILTER_REQUEST_OUTPUT_NAME "MODPERL_REQUEST_OUTPUT" +#define MP_FILTER_REQUEST_INPUT_NAME "MODPERL_REQUEST_INPUT" + +#define MP_FILTER_CONNECTION_HANDLER 0x01 +#define MP_FILTER_REQUEST_HANDLER 0x02 +#define MP_FILTER_HAS_INIT_HANDLER 0x04 +#define MP_FILTER_INIT_HANDLER 0x08 +#define MP_FILTER_HTTPD_HANDLER 0x10 + +typedef ap_filter_t * MP_FUNC_T(modperl_filter_add_t) (const char *, void *, + request_rec *, + conn_rec *); + +/* simple buffer api */ +MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *b, + const char *buf, apr_size_t len, + int add_flush_bucket); + +MP_INLINE apr_status_t modperl_wbucket_flush(modperl_wbucket_t *b, + int add_flush_bucket); + +MP_INLINE apr_status_t modperl_wbucket_write(pTHX_ + modperl_wbucket_t *b, + const char *buf, + apr_size_t *wlen); + +/* generic filter routines */ + +modperl_filter_t *modperl_filter_new(ap_filter_t *f, + apr_bucket_brigade *bb, + modperl_filter_mode_e mode, + ap_input_mode_t input_mode, + apr_read_type_e block, + apr_off_t readbytes); + +modperl_filter_t *modperl_filter_mg_get(pTHX_ SV *obj); + +int modperl_filter_resolve_init_handler(pTHX_ modperl_handler_t *handler, + apr_pool_t *p); + +int modperl_run_filter(modperl_filter_t *filter); + +/* output filters */ +apr_status_t modperl_output_filter_handler(ap_filter_t *f, + apr_bucket_brigade *bb); + +void modperl_output_filter_add_connection(conn_rec *c); + +void modperl_output_filter_add_request(request_rec *r); + +MP_INLINE apr_status_t modperl_output_filter_flush(modperl_filter_t *filter); +MP_INLINE apr_status_t modperl_input_filter_flush(modperl_filter_t *filter); + + +MP_INLINE apr_size_t modperl_output_filter_read(pTHX_ + modperl_filter_t *filter, + SV *buffer, + apr_size_t wanted); + +MP_INLINE apr_status_t modperl_output_filter_write(pTHX_ + modperl_filter_t *filter, + const char *buf, + apr_size_t *len); + +void modperl_brigade_dump(apr_bucket_brigade *bb, apr_file_t *file); + +/* input filters */ +apr_status_t modperl_input_filter_handler(ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t input_mode, + apr_read_type_e block, + apr_off_t readbytes); + +void modperl_input_filter_add_connection(conn_rec *c); + +void modperl_input_filter_add_request(request_rec *r); + +MP_INLINE apr_size_t modperl_input_filter_read(pTHX_ + modperl_filter_t *filter, + SV *buffer, + apr_size_t wanted); + +MP_INLINE apr_status_t modperl_input_filter_write(pTHX_ + modperl_filter_t *filter, + const char *buf, + apr_size_t *len); + +void modperl_filter_runtime_add(pTHX_ request_rec *r, conn_rec *c, + const char *name, + modperl_filter_mode_e mode, + modperl_filter_add_t addfunc, + SV *callback, const char *type); + +#endif /* MODPERL_FILTER_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_global.c b/2_0_13/src/modules/perl/modperl_global.c new file mode 100644 index 0000000..750110c --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_global.c
@@ -0,0 +1,312 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +void modperl_global_request_cfg_set(request_rec *r) +{ + MP_dDCFG; + MP_dRCFG; + + /* only if PerlOptions +GlobalRequest and not done already */ + if (MpDirGLOBAL_REQUEST(dcfg) && !MpReqSET_GLOBAL_REQUEST(rcfg)) { + modperl_global_request_set(r); + } +} + +void modperl_global_request_set(request_rec *r) +{ + MP_dRCFG; + request_rec *old_r = NULL; + + /* reset old value, important for subrequests */ + (void)modperl_tls_get_request_rec(&old_r); + modperl_tls_reset_cleanup_request_rec(r->pool, old_r); + + modperl_tls_set_request_rec(r); + + /* so 'PerlOptions +GlobalRequest' doesnt wipe us out */ + MpReqSET_GLOBAL_REQUEST_On(rcfg); +} + +/* get/set */ +request_rec *modperl_global_request(pTHX_ SV *svr) +{ + request_rec *cur = NULL; + apr_status_t status = modperl_tls_get_request_rec(&cur); + if (status != APR_SUCCESS) { + /* an internal problem */ + Perl_croak(aTHX_ "failed to retrieve the request object"); + } + + if (GIMME_V != G_VOID && !cur) { + /* wrong configuration */ + Perl_croak(aTHX_ "Global $r object is not available. Set:\n" + "\tPerlOptions +GlobalRequest\nin httpd.conf"); + } + + if (svr) { + modperl_global_request_obj_set(aTHX_ svr); + } + + return cur; +} + +void modperl_global_request_obj_set(pTHX_ SV *svr) +{ + /* XXX: support sublassing */ + request_rec *r = modperl_sv2request_rec(aTHX_ svr); + modperl_global_request_set(r); +} + +#if MP_THREADED +static apr_status_t modperl_global_cleanup(void *data) +{ + modperl_global_t *global = (modperl_global_t *)data; + + MP_TRACE_g(MP_FUNC, "destroy lock for %s", global->name); + MUTEX_DESTROY(&global->glock); + + return APR_SUCCESS; +} +#endif + +void modperl_global_init(modperl_global_t *global, apr_pool_t *p, + void *data, const char *name) +{ + Zero(global, 1, modperl_global_t); + + global->data = data; + global->name = name; + +#if MP_THREADED + MUTEX_INIT(&global->glock); + + apr_pool_cleanup_register(p, (void *)global, + modperl_global_cleanup, + apr_pool_cleanup_null); +#endif + + MP_TRACE_g(MP_FUNC, "init %s", name); +} + +void modperl_global_lock(modperl_global_t *global) +{ +#if MP_THREADED + MP_TRACE_g(MP_FUNC, "locking %s", global->name); + MUTEX_LOCK(&global->glock); +#endif +} + +void modperl_global_unlock(modperl_global_t *global) +{ +#if MP_THREADED + MP_TRACE_g(MP_FUNC, "unlocking %s", global->name); + MUTEX_UNLOCK(&global->glock); +#endif +} + +void *modperl_global_get(modperl_global_t *global) +{ + return global->data; +} + +void modperl_global_set(modperl_global_t *global, void *data) +{ + global->data = data; +} + +/* hopefully there wont be many of these */ + +#define MP_GLOBAL_IMPL(gname, type) \ + \ +static modperl_global_t MP_global_##gname; \ + \ +void modperl_global_init_##gname(apr_pool_t *p, \ + type gname) \ +{ \ + modperl_global_init(&MP_global_##gname, p, \ + (void *)gname, #gname); \ +} \ + \ +void modperl_global_lock_##gname(void) \ +{ \ + modperl_global_lock(&MP_global_##gname); \ +} \ + \ +void modperl_global_unlock_##gname(void) \ +{ \ + modperl_global_unlock(&MP_global_##gname); \ +} \ + \ +type modperl_global_get_##gname(void) \ +{ \ + return (type ) \ + modperl_global_get(&MP_global_##gname); \ +} \ + \ +void modperl_global_set_##gname(void *data) \ +{ \ + modperl_global_set(&MP_global_##gname, data); \ +} \ + +MP_GLOBAL_IMPL(pconf, apr_pool_t *) +MP_GLOBAL_IMPL(server_rec, server_rec *) + + + + + +/*** anon handlers code ***/ + +static modperl_global_t MP_global_anon_cnt; + +void modperl_global_anon_cnt_init(apr_pool_t *p) +{ + int *data = (int *)apr_pcalloc(p, sizeof(int)); + *data = 0; + modperl_global_init(&MP_global_anon_cnt, p, (void *)data, "anon_cnt"); +} + +int modperl_global_anon_cnt_next(void) +{ + int next; + /* XXX: inline lock/unlock? */ + modperl_global_lock(&MP_global_anon_cnt); + + next = ++*(int *)(MP_global_anon_cnt.data); + + modperl_global_unlock(&MP_global_anon_cnt); + + return next; +} + + + +/*** TLS ***/ + +#if MP_THREADED +static apr_status_t modperl_tls_cleanup(void *data) +{ + return apr_threadkey_private_delete((apr_threadkey_t *)data); +} +#endif + +apr_status_t modperl_tls_create(apr_pool_t *p, modperl_tls_t **key) +{ +#if MP_THREADED + apr_status_t status = apr_threadkey_private_create(key, NULL, p); + apr_pool_cleanup_register(p, (void *)*key, + modperl_tls_cleanup, + apr_pool_cleanup_null); + return status; +#else + *key = apr_pcalloc(p, sizeof(**key)); + return APR_SUCCESS; +#endif +} + +apr_status_t modperl_tls_get(modperl_tls_t *key, void **data) +{ +#if MP_THREADED + if (!key) { + *data = NULL; + return APR_SUCCESS; + } + return apr_threadkey_private_get(data, key); +#else + *data = modperl_global_get((modperl_global_t *)key); + return APR_SUCCESS; +#endif +} + +apr_status_t modperl_tls_set(modperl_tls_t *key, void *data) +{ +#if MP_THREADED + return apr_threadkey_private_set(data, key); +#else + modperl_global_set((modperl_global_t *)key, data); + return APR_SUCCESS; +#endif +} + +typedef struct { + modperl_tls_t *key; + void *data; +} modperl_tls_cleanup_data_t; + +static apr_status_t modperl_tls_reset(void *data) +{ + modperl_tls_cleanup_data_t *cdata = + (modperl_tls_cleanup_data_t *)data; + return modperl_tls_set(cdata->key, cdata->data); +} + +void modperl_tls_reset_cleanup(apr_pool_t *p, modperl_tls_t *key, + void *data) +{ + modperl_tls_cleanup_data_t *cdata = + (modperl_tls_cleanup_data_t *)apr_palloc(p, sizeof(*cdata)); + + cdata->key = key; + cdata->data = data; + + apr_pool_cleanup_register(p, (void *)cdata, + modperl_tls_reset, + apr_pool_cleanup_null); +} + +/* hopefully there wont be many of these either */ + +#define MP_TLS_IMPL(gname, type) \ + \ +static modperl_tls_t *MP_tls_##gname; \ + \ +apr_status_t \ +modperl_tls_create_##gname(apr_pool_t *p) \ +{ \ + return modperl_tls_create(p, &MP_tls_##gname); \ +} \ + \ +apr_status_t modperl_tls_get_##gname(type *data) \ +{ \ + void *ptr; \ + apr_status_t status = \ + modperl_tls_get(MP_tls_##gname, &ptr); \ + *data = (type )ptr; \ + return status; \ +} \ + \ +apr_status_t modperl_tls_set_##gname(void *data) \ +{ \ + return modperl_tls_set(MP_tls_##gname, data); \ +} \ + \ +void modperl_tls_reset_cleanup_##gname(apr_pool_t *p, \ + type data) \ +{ \ + modperl_tls_reset_cleanup(p, MP_tls_##gname, \ + (void *)data); \ +} + +MP_TLS_IMPL(request_rec, request_rec *) + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_global.h b/2_0_13/src/modules/perl/modperl_global.h new file mode 100644 index 0000000..8d4f05a --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_global.h
@@ -0,0 +1,90 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_GLOBAL_H +#define MODPERL_GLOBAL_H + +typedef struct { +#if MP_THREADED + perl_mutex glock; +#endif + int flags; + void *data; + const char *name; +} modperl_global_t; + +#if MP_THREADED +typedef apr_threadkey_t modperl_tls_t; +#else +typedef modperl_global_t modperl_tls_t; +#endif + +void modperl_global_request_cfg_set(request_rec *r); + +request_rec *modperl_global_request(pTHX_ SV *svr); + +void modperl_global_request_set(request_rec *r); + +void modperl_global_request_obj_set(pTHX_ SV *svr); + +void modperl_global_init(modperl_global_t *global, apr_pool_t *p, + void *data, const char *name); + +void modperl_global_lock(modperl_global_t *global); + +void modperl_global_unlock(modperl_global_t *global); + +void *modperl_global_get(modperl_global_t *global); + +void modperl_global_set(modperl_global_t *global, void *data); + +#define MP_GLOBAL_DECL(gname, type) \ + void modperl_global_init_##gname(apr_pool_t *p, type gname); \ + void modperl_global_lock_##gname(void); \ + void modperl_global_unlock_##gname(void); \ + type modperl_global_get_##gname(void); \ + void modperl_global_set_##gname(void *) + +/* modperl_global_get_pconf returns a thread un-safe object */ +MP_GLOBAL_DECL(pconf, apr_pool_t *); + +/* modperl_global_get_server_rec returns a thread un-safe object */ +MP_GLOBAL_DECL(server_rec, server_rec *); + +void modperl_global_anon_cnt_init(apr_pool_t *p); +int modperl_global_anon_cnt_next(void); + +apr_status_t modperl_tls_create(apr_pool_t *p, modperl_tls_t **key); +apr_status_t modperl_tls_get(modperl_tls_t *key, void **data); +apr_status_t modperl_tls_set(modperl_tls_t *key, void *data); +void modperl_tls_reset_cleanup(apr_pool_t *p, modperl_tls_t *key, void *data); + +#define MP_TLS_DECL(gname, type) \ +apr_status_t modperl_tls_create_##gname(apr_pool_t *p); \ +apr_status_t modperl_tls_get_##gname(type *data); \ +apr_status_t modperl_tls_set_##gname(void *data); \ +void modperl_tls_reset_cleanup_##gname(apr_pool_t *p, type data) + +MP_TLS_DECL(request_rec, request_rec *); + +#endif /* MODPERL_GLOBAL_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_gtop.c b/2_0_13/src/modules/perl/modperl_gtop.c new file mode 100644 index 0000000..170cfd1 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_gtop.c
@@ -0,0 +1,154 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +#ifdef MP_USE_GTOP + +static int modperl_gtop_size_string(size_t size, char *size_string) +{ + if (size == (size_t)-1) { + apr_snprintf(size_string, MP_GTOP_SSS, "-"); + } + else if (!size) { + apr_snprintf(size_string, MP_GTOP_SSS, "0k"); + } + else if (size < 1024) { + apr_snprintf(size_string, MP_GTOP_SSS, "1k"); + } + else if (size < 1048576) { + apr_snprintf(size_string, MP_GTOP_SSS, "%dk", + (int)(size + 512) / 1024); + } + else if (size < 103809024) { + apr_snprintf(size_string, MP_GTOP_SSS, "%.1fM", + size / 1048576.0); + } + else { + apr_snprintf(size_string, MP_GTOP_SSS, "%dM", + (int)(size + 524288) / 1048576); + } + + return 1; +} + +static apr_status_t modperl_gtop_exit(void *data) +{ + glibtop_close(); + return APR_SUCCESS; +} + +modperl_gtop_t *modperl_gtop_new(apr_pool_t *p) +{ + modperl_gtop_t *gtop = + (modperl_gtop_t *)apr_pcalloc(p, sizeof(*gtop)); + + gtop->pid = getpid(); + glibtop_init(); + apr_pool_cleanup_register(p, NULL, + modperl_gtop_exit, apr_pool_cleanup_null); + + return gtop; +} + +void modperl_gtop_get_proc_mem_before(modperl_gtop_t *gtop) +{ + glibtop_get_proc_mem(>op->before.proc_mem, gtop->pid); +} + +void modperl_gtop_get_proc_mem_after(modperl_gtop_t *gtop) +{ + glibtop_get_proc_mem(>op->after.proc_mem, gtop->pid); +} + +#define modperl_gtop_diff(item) \ +(gtop->after.item - gtop->before.item) + +#define ss_fmt "size=%s, vsize=%s, resident=%s, share=%s, rss=%s" + +#define SS_TYPE_BEFORE 1 +#define SS_TYPE_AFTER 2 +#define SS_TYPE_DIFF 3 + +/* + * XXX: this is pretty ugly, + * but avoids allocating buffers for the size string + */ +static void modperl_gtop_proc_mem_size_string(modperl_gtop_t *gtop, int type) +{ + int is_diff = (type == SS_TYPE_DIFF); + glibtop_proc_mem *pm = NULL; + + if (!is_diff) { + pm = (type == SS_TYPE_BEFORE) ? + >op->before.proc_mem : >op->after.proc_mem; + } + +#define ss_call(item) \ + modperl_gtop_size_string(is_diff ? \ + modperl_gtop_diff(proc_mem.item) : pm->item, \ + gtop->proc_mem_ss.item) + + ss_call(size); + ss_call(vsize); + ss_call(resident); + ss_call(share); + ss_call(rss); +#undef ss_call +} + +void modperl_gtop_report_proc_mem(modperl_gtop_t *gtop, + char *when, const char *func, char *msg) +{ +#define ss_item(item) gtop->proc_mem_ss.item + + fprintf(stderr, "%s : %s %s: " ss_fmt "\n", + func, (msg ? msg : ""), when, + ss_item(size), + ss_item(vsize), + ss_item(resident), + ss_item(share), + ss_item(rss)); + +#undef ss_item +} + +void modperl_gtop_report_proc_mem_diff(modperl_gtop_t *gtop, const char *func, char *msg) +{ + modperl_gtop_proc_mem_size_string(gtop, SS_TYPE_DIFF); + modperl_gtop_report_proc_mem(gtop, "diff", func, msg); +} + +void modperl_gtop_report_proc_mem_before(modperl_gtop_t *gtop, const char *func, char *msg) +{ + modperl_gtop_proc_mem_size_string(gtop, SS_TYPE_BEFORE); + modperl_gtop_report_proc_mem(gtop, "before", func, msg); +} + +void modperl_gtop_report_proc_mem_after(modperl_gtop_t *gtop, const char *func, char *msg) +{ + modperl_gtop_proc_mem_size_string(gtop, SS_TYPE_AFTER); + modperl_gtop_report_proc_mem(gtop, "after", func, msg); +} + +#endif /* MP_USE_GTOP */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_gtop.h b/2_0_13/src/modules/perl/modperl_gtop.h new file mode 100644 index 0000000..61554de --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_gtop.h
@@ -0,0 +1,81 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_GTOP_H +#define MODPERL_GTOP_H + +#ifndef MP_TRACE +# undef MP_USE_GTOP +#endif + +#ifdef MP_USE_GTOP +/* prevent undef symbol errors (glibtop_error_vr) */ +#define __GLIBTOP_ERROR_H__ +#include <glibtop.h> +#include <glibtop/open.h> +#include <glibtop/close.h> +#ifndef GTOP_2_5_PLUS +#include <glibtop/xmalloc.h> +#endif +#include <glibtop/parameter.h> +#include <glibtop/union.h> +#include <glibtop/sysdeps.h> + +#define MP_GTOP_SSS 16 + +typedef struct { + char size[MP_GTOP_SSS]; + char vsize[MP_GTOP_SSS]; + char resident[MP_GTOP_SSS]; + char share[MP_GTOP_SSS]; + char rss[MP_GTOP_SSS]; +} modperl_gtop_proc_mem_ss; + +typedef struct { + glibtop_union before; + glibtop_union after; + pid_t pid; + modperl_gtop_proc_mem_ss proc_mem_ss; +} modperl_gtop_t; + +modperl_gtop_t *modperl_gtop_new(apr_pool_t *p); +void modperl_gtop_get_proc_mem_before(modperl_gtop_t *gtop); +void modperl_gtop_get_proc_mem_after(modperl_gtop_t *gtop); +void modperl_gtop_report_proc_mem(modperl_gtop_t *gtop, + char *when, const char *func, char *msg); +void modperl_gtop_report_proc_mem_diff(modperl_gtop_t *gtop, const char* func, char *msg); +void modperl_gtop_report_proc_mem_before(modperl_gtop_t *gtop, const char* func, char *msg); +void modperl_gtop_report_proc_mem_after(modperl_gtop_t *gtop, const char* func, char *msg); + +#define modperl_gtop_do_proc_mem_before(func, msg) \ + modperl_gtop_get_proc_mem_before(scfg->gtop); \ + modperl_gtop_report_proc_mem_before(scfg->gtop, func, msg) + +#define modperl_gtop_do_proc_mem_after(func, msg) \ + modperl_gtop_get_proc_mem_after(scfg->gtop); \ + modperl_gtop_report_proc_mem_after(scfg->gtop, func, msg); \ + modperl_gtop_report_proc_mem_diff(scfg->gtop, func, msg) + +#endif /* MP_USE_GTOP */ + +#endif /* MODPERL_GTOP_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_handler.c b/2_0_13/src/modules/perl/modperl_handler.c new file mode 100644 index 0000000..fe935d7 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_handler.c
@@ -0,0 +1,642 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +modperl_handler_t *modperl_handler_new(apr_pool_t *p, const char *name) +{ + modperl_handler_t *handler = + (modperl_handler_t *)apr_pcalloc(p, sizeof(*handler)); + + switch (*name) { + case '+': + ++name; + MpHandlerAUTOLOAD_On(handler); + break; + case '-': + ++name; + /* XXX: currently a noop; should disable autoload of given handler + * if PerlOptions +AutoLoad is configured + * see: modperl_hash_handlers in modperl_mgv.c + */ + MpHandlerAUTOLOAD_Off(handler); + break; + } + + /* not necessary due to apr_pcalloc */ + /* handler->cv = NULL; */ + handler->name = name; + MP_TRACE_h(MP_FUNC, "new handler %s", handler->name); + + return handler; +} + +/* How anon-subs are handled: + * We have two ways anon-subs can be registered + * A) at startup from httpd.conf: + * PerlTransHandler 'sub { ... }' + * B) run-time perl code + * $r->push_handlers(PerlTransHandler => sub { .... }); + * $s->push_handlers(PerlTransHandler => sub { .... }); + * + * In the case of non-threaded perl, we just compile A or grab B and + * store it in the mod_perl struct and call it when it's used. No + * problems here + * + * In the case of threads, things get more complicated. we no longer + * can store the CV value of the compiled anon-sub, since when + * perl_clone is called each interpreter will have a different CV + * value. since we need to be able to have 1 entry for each anon-sub + * across all interpreters a different solution is needed. to remind + * in the case of named subs, we just store the name of the sub and + * look its corresponding CV when we need it. + * + * The used solution: each process has a global counter, which always + * grows. Every time a new anon-sub is encountered, a new ID is + * allocated from that process-global counter and that ID is stored in + * the mod_perl struct. The compiled CV is stored as + * $PL_modglobal{ANONSUB}{$id} = CV; + * when perl_clone is called, each clone will clone that CV value, but + * we will still be able to find it, since we stored it in the + * hash. so we retrieve the CV value, whatever it is and we run it. + * + * that explanation can be written and run in perl: + * + * use threads; + * our %h; + * $h{x} = eval 'sub { print qq[this is sub @_\n] }'; + * $h{x}->("main"); + * threads->new(sub { $h{x}->(threads->self->tid)}); + * + * XXX: more nuances will follow + */ + +void modperl_handler_anon_init(pTHX_ apr_pool_t *p) +{ + modperl_modglobal_key_t *gkey = + modperl_modglobal_lookup(aTHX_ "ANONSUB"); + MP_TRACE_h(MP_FUNC, "init $PL_modglobal{ANONSUB} = []"); + (void)MP_MODGLOBAL_STORE_HV(gkey); +} + +/* allocate and populate the anon handler sub-struct */ +MP_INLINE modperl_mgv_t *modperl_handler_anon_next(pTHX_ apr_pool_t *p) +{ + /* re-use modperl_mgv_t entry which is otherwise is not used + * by anon handlers */ + modperl_mgv_t *anon = + (modperl_mgv_t *)apr_pcalloc(p, sizeof(*anon)); + + anon->name = apr_psprintf(p, "anon%d", modperl_global_anon_cnt_next()); + anon->len = strlen(anon->name); + PERL_HASH(anon->hash, anon->name, anon->len); + + MP_TRACE_h(MP_FUNC, "new anon handler: '%s'", anon->name); + return anon; +} + +MP_INLINE void modperl_handler_anon_add(pTHX_ modperl_mgv_t *anon, CV *cv) +{ + modperl_modglobal_key_t *gkey = + modperl_modglobal_lookup(aTHX_ "ANONSUB"); + HE *he = MP_MODGLOBAL_FETCH(gkey); + HV *hv; + + if (!(he && (hv = (HV*)HeVAL(he)))) { + Perl_croak(aTHX_ "modperl_handler_anon_add: " + "can't find ANONSUB top entry (get)"); + } + + SvREFCNT_inc(cv); + if (!(*hv_store(hv, anon->name, anon->len, (SV*)cv, anon->hash))) { + SvREFCNT_dec(cv); + Perl_croak(aTHX_ "hv_store of anonsub '%s' has failed!", anon->name); + } + + MP_TRACE_h(MP_FUNC, "anonsub '%s' added", anon->name); +} + +MP_INLINE CV *modperl_handler_anon_get(pTHX_ modperl_mgv_t *anon) +{ + modperl_modglobal_key_t *gkey = + modperl_modglobal_lookup(aTHX_ "ANONSUB"); + HE *he = MP_MODGLOBAL_FETCH(gkey); + HV *hv; + SV *sv; + + if (!(he && (hv = (HV*)HeVAL(he)))) { + Perl_croak(aTHX_ "modperl_handler_anon_get: " + "can't find ANONSUB top entry (get)"); + } + + if ((he = hv_fetch_he(hv, anon->name, anon->len, anon->hash))) { + sv = HeVAL(he); + MP_TRACE_h(MP_FUNC, "anonsub gets name '%s'", anon->name); + } + else { + Perl_croak(aTHX_ "can't find ANONSUB's '%s' entry", anon->name); + } + + return (CV*)sv; +} + +static +modperl_handler_t *modperl_handler_new_anon(pTHX_ apr_pool_t *p, CV *cv) +{ + modperl_handler_t *handler = + (modperl_handler_t *)apr_pcalloc(p, sizeof(*handler)); + MpHandlerPARSED_On(handler); + MpHandlerANON_On(handler); + +#ifdef USE_ITHREADS + handler->cv = NULL; + handler->name = NULL; + handler->mgv_obj = modperl_handler_anon_next(aTHX_ p); + modperl_handler_anon_add(aTHX_ handler->mgv_obj, cv); +#else + /* it's safe to cache and later use the cv, since the same perl + * interpeter is always used */ + SvREFCNT_inc((SV*)cv); + handler->cv = cv; + handler->name = NULL; + + MP_TRACE_h(MP_FUNC, "new cached cv anon handler"); +#endif + + return handler; +} + +MP_INLINE +const char *modperl_handler_name(modperl_handler_t *handler) +{ + /* a handler containing an anonymous sub doesn't have a normal sub + * name */ + if (handler->name) { + return handler->name; + } + else { + /* anon sub stores the internal modperl name in mgv_obj */ + return handler->mgv_obj ? handler->mgv_obj->name : "anonsub"; + } +} + + +int modperl_handler_resolve(pTHX_ modperl_handler_t **handp, + apr_pool_t *p, server_rec *s) +{ + int duped=0; + modperl_handler_t *handler = *handp; + +#ifdef USE_ITHREADS + if (modperl_threaded_mpm() && p && + !MpHandlerPARSED(handler) && !MpHandlerDYNAMIC(handler)) { + /* + * under threaded mpm we cannot update the handler structure + * at request time without locking, so just copy it + */ + handler = *handp = modperl_handler_dup(p, handler); + duped = 1; + } +#endif + + MP_TRACE_h_do(MpHandler_dump_flags(handler, + modperl_handler_name(handler))); + + if (!MpHandlerPARSED(handler)) { + apr_pool_t *rp = duped ? p : s->process->pconf; + MpHandlerAUTOLOAD_On(handler); + + MP_TRACE_h(MP_FUNC, + "[%s] handler %s hasn't yet been resolved, " + "attempting to resolve using %s pool 0x%lx", + modperl_server_desc(s, p), + modperl_handler_name(handler), + duped ? "current" : "server conf", + (unsigned long)rp); + + if (!modperl_mgv_resolve(aTHX_ handler, rp, handler->name, FALSE)) { + modperl_errsv_prepend(aTHX_ + "failed to resolve handler `%s': ", + handler->name); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + return OK; +} + +modperl_handler_t *modperl_handler_dup(apr_pool_t *p, + modperl_handler_t *h) +{ + MP_TRACE_h(MP_FUNC, "dup handler %s", modperl_handler_name(h)); + return modperl_handler_new(p, h->name); +} + +int modperl_handler_equal(modperl_handler_t *h1, modperl_handler_t *h2) +{ + if (h1->mgv_cv && h2->mgv_cv) { + return modperl_mgv_equal(h1->mgv_cv, h2->mgv_cv); + } + return strEQ(h1->name, h2->name); +} + +MpAV *modperl_handler_array_merge(apr_pool_t *p, MpAV *base_a, MpAV *add_a) +{ + int i, j; + modperl_handler_t **base_h, **add_h; + MpAV *mrg_a; + + if (!add_a) { + return base_a; + } + + if (!base_a) { + return add_a; + } + + mrg_a = apr_array_copy(p, base_a); + + base_h = (modperl_handler_t **)base_a->elts; + add_h = (modperl_handler_t **)add_a->elts; + + for (i=0; i<base_a->nelts; i++) { + for (j=0; j<add_a->nelts; j++) { + if (modperl_handler_equal(base_h[i], add_h[j])) { + MP_TRACE_d(MP_FUNC, "both base and new config contain %s", + add_h[j]->name); + } + else { + modperl_handler_array_push(mrg_a, add_h[j]); + MP_TRACE_d(MP_FUNC, "base does not contain %s", + add_h[j]->name); + } + } + } + + return mrg_a; +} + +void modperl_handler_make_args(pTHX_ AV **avp, ...) +{ + va_list args; + + if (!*avp) { + *avp = newAV(); /* XXX: cache an intialized AV* per-request */ + } + + va_start(args, avp); + + for (;;) { + char *classname = va_arg(args, char *); + void *ptr; + SV *sv; + + if (classname == NULL) { + break; + } + + ptr = va_arg(args, void *); + + switch (*classname) { + case 'A': + if (strEQ(classname, "APR::Table")) { + sv = modperl_hash_tie(aTHX_ classname, (SV *)NULL, ptr); + break; + } + case 'I': + if (strEQ(classname, "IV")) { + sv = ptr ? newSViv(PTR2IV(ptr)) : &PL_sv_undef; + break; + } + case 'P': + if (strEQ(classname, "PV")) { + sv = ptr ? newSVpv((char *)ptr, 0) : &PL_sv_undef; + break; + } + case 'H': + if (strEQ(classname, "HV")) { + sv = newRV_noinc((SV*)ptr); + break; + } + default: + sv = modperl_ptr2obj(aTHX_ classname, ptr); + break; + } + + av_push(*avp, sv); + } + + va_end(args); +} + +#define set_desc(dtype) \ + if (desc) *desc = modperl_handler_desc_##dtype(idx) + +/* We should be able to use PERL_GET_CONTEXT here. The rcfg condition + * makes sure there is a request being processed. The action > GET part + * means it is a $r->set_handlers or $r->push_handlers operation. This + * can only happen if called by perl code. + */ +#define check_modify(dtype) \ + if ((action > MP_HANDLER_ACTION_GET) && rcfg) { \ + dTHXa(PERL_GET_CONTEXT); \ + MP_ASSERT(aTHX+0); \ + Perl_croak(aTHX_ "too late to modify %s handlers", \ + modperl_handler_desc_##dtype(idx)); \ + } + +/* + * generic function to lookup handlers for use in modperl_callback(), + * $r->{push,set,get}_handlers, $s->{push,set,get}_handlers + * $s->push/set at startup time are the same as configuring Perl*Handlers + * $r->push/set at request time will create entries in r->request_config + * push will first merge with configured handlers, unless an entry + * in r->request_config already exists. in this case, push or set has + * already been called for the given handler, + * r->request_config entries then override those in r->per_dir_config + */ + +MpAV **modperl_handler_lookup_handlers(modperl_config_dir_t *dcfg, + modperl_config_srv_t *scfg, + modperl_config_req_t *rcfg, + apr_pool_t *p, + int type, int idx, + modperl_handler_action_e action, + const char **desc) +{ + MpAV **avp = NULL, **ravp = NULL; + + switch (type) { + case MP_HANDLER_TYPE_PER_DIR: + avp = &dcfg->handlers_per_dir[idx]; + if (rcfg) { + ravp = &rcfg->handlers_per_dir[idx]; + } + set_desc(per_dir); + break; + case MP_HANDLER_TYPE_PER_SRV: + avp = &scfg->handlers_per_srv[idx]; + if (rcfg) { + ravp = &rcfg->handlers_per_srv[idx]; + } + set_desc(per_srv); + break; + case MP_HANDLER_TYPE_PRE_CONNECTION: + avp = &scfg->handlers_pre_connection[idx]; + check_modify(pre_connection); + set_desc(pre_connection); + break; + case MP_HANDLER_TYPE_CONNECTION: + avp = &scfg->handlers_connection[idx]; + check_modify(connection); + set_desc(connection); + break; + case MP_HANDLER_TYPE_FILES: + avp = &scfg->handlers_files[idx]; + check_modify(files); + set_desc(files); + break; + case MP_HANDLER_TYPE_PROCESS: + avp = &scfg->handlers_process[idx]; + check_modify(files); + set_desc(process); + break; + }; + + if (!avp) { + /* should never happen */ +#if 0 + fprintf(stderr, "PANIC: no such handler type: %d\n", type); +#endif + return NULL; + } + + switch (action) { + case MP_HANDLER_ACTION_GET: + /* just a lookup */ + break; + case MP_HANDLER_ACTION_PUSH: + if (ravp) { + if (!*ravp) { + if (*avp) { + /* merge with existing configured handlers */ + *ravp = apr_array_copy(p, *avp); + } + else { + /* no request handlers have been previously pushed or set */ + *ravp = modperl_handler_array_new(p); + } + } + } + else if (!*avp) { + /* directly modify the configuration at startup time */ + *avp = modperl_handler_array_new(p); + } + break; + case MP_HANDLER_ACTION_SET: + if (ravp) { + if (*ravp) { + /* wipe out existing pushed/set request handlers */ + (*ravp)->nelts = 0; + } + else { + /* no request handlers have been previously pushed or set */ + *ravp = modperl_handler_array_new(p); + } + } + else if (*avp) { + /* wipe out existing configuration, only at startup time */ + (*avp)->nelts = 0; + } + else { + /* no configured handlers for this phase */ + *avp = modperl_handler_array_new(p); + } + break; + } + + return (ravp && *ravp) ? ravp : avp; +} + +MpAV **modperl_handler_get_handlers(request_rec *r, conn_rec *c, server_rec *s, + apr_pool_t *p, const char *name, + modperl_handler_action_e action) +{ + MP_dSCFG(s); + MP_dDCFG; + MP_dRCFG; + + int idx, type; + + if (!r) { + /* so $s->{push,set}_handlers can configured request-time handlers */ + dcfg = modperl_config_dir_get_defaults(s); + } + + if ((idx = modperl_handler_lookup(name, &type)) == DECLINED) { + return FALSE; + } + + return modperl_handler_lookup_handlers(dcfg, scfg, rcfg, p, + type, idx, + action, NULL); +} + +modperl_handler_t *modperl_handler_new_from_sv(pTHX_ apr_pool_t *p, SV *sv) +{ + char *name = NULL; + GV *gv; + + if (SvROK(sv)) { + sv = SvRV(sv); + } + + switch (SvTYPE(sv)) { + case SVt_PV: + name = SvPVX(sv); + return modperl_handler_new(p, apr_pstrdup(p, name)); + break; + case SVt_PVCV: + if (CvANON((CV*)sv)) { + return modperl_handler_new_anon(aTHX_ p, (CV*)sv); + } + if (!(gv = CvGV((CV*)sv))) { + Perl_croak(aTHX_ "can't resolve the code reference"); + } + name = apr_pstrcat(p, HvNAME(GvSTASH(gv)), "::", GvNAME(gv), NULL); + return modperl_handler_new(p, name); + default: + break; + }; + + return NULL; +} + +int modperl_handler_push_handlers(pTHX_ apr_pool_t *p, + MpAV *handlers, SV *sv) +{ + modperl_handler_t *handler = modperl_handler_new_from_sv(aTHX_ p, sv); + + if (handler) { + modperl_handler_array_push(handlers, handler); + return TRUE; + } + + MP_TRACE_h(MP_FUNC, "unable to push_handler 0x%lx", + (unsigned long)sv); + + return FALSE; +} + +/* convert array header of modperl_handlers_t's to AV ref of CV refs */ +SV *modperl_handler_perl_get_handlers(pTHX_ MpAV **handp, apr_pool_t *p) +{ + AV *av = newAV(); + int i; + modperl_handler_t **handlers; + + if (!(handp && *handp)) { + return &PL_sv_undef; + } + + av_extend(av, (*handp)->nelts - 1); + + handlers = (modperl_handler_t **)(*handp)->elts; + + for (i=0; i<(*handp)->nelts; i++) { + modperl_handler_t *handler = NULL; + GV *gv; + + if (MpHandlerPARSED(handlers[i])) { + handler = handlers[i]; + } + else { +#ifdef USE_ITHREADS + if (!MpHandlerDYNAMIC(handlers[i])) { + handler = modperl_handler_dup(p, handlers[i]); + } +#endif + if (!handler) { + handler = handlers[i]; + } + + if (!modperl_mgv_resolve(aTHX_ handler, p, handler->name, TRUE)) { + MP_TRACE_h(MP_FUNC, "failed to resolve handler %s", + handler->name); + } + + } + + if (handler->mgv_cv) { + if ((gv = modperl_mgv_lookup(aTHX_ handler->mgv_cv))) { + CV *cv = modperl_mgv_cv(gv); + av_push(av, newRV_inc((SV*)cv)); + } + } + else { + av_push(av, newSVpv(handler->name, 0)); + } + } + + return newRV_noinc((SV*)av); +} + +#define push_sv_handler \ + if ((modperl_handler_push_handlers(aTHX_ p, *handlers, sv))) { \ + MpHandlerDYNAMIC_On(modperl_handler_array_last(*handlers)); \ + } + +/* allow push/set of single cv ref or array ref of cv refs */ +int modperl_handler_perl_add_handlers(pTHX_ + request_rec *r, + conn_rec *c, + server_rec *s, + apr_pool_t *p, + const char *name, + SV *sv, + modperl_handler_action_e action) +{ + I32 i; + AV *av = (AV *)NULL; + MpAV **handlers = + modperl_handler_get_handlers(r, c, s, + p, name, action); + + if (!(handlers && *handlers)) { + return FALSE; + } + + if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV)) { + av = (AV*)SvRV(sv); + + for (i=0; i <= AvFILL(av); i++) { + sv = *av_fetch(av, i, FALSE); + push_sv_handler; + } + } + else { + push_sv_handler; + } + + return TRUE; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_handler.h b/2_0_13/src/modules/perl/modperl_handler.h new file mode 100644 index 0000000..af3a8dd --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_handler.h
@@ -0,0 +1,94 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_HANDLER_H +#define MODPERL_HANDLER_H + +typedef enum { + MP_HANDLER_ACTION_GET, + MP_HANDLER_ACTION_PUSH, + MP_HANDLER_ACTION_SET +} modperl_handler_action_e; + +void modperl_handler_anon_init(pTHX_ apr_pool_t *p); +MP_INLINE modperl_mgv_t *modperl_handler_anon_next(pTHX_ apr_pool_t *p); +MP_INLINE void modperl_handler_anon_add(pTHX_ modperl_mgv_t *anon, CV *cv); +MP_INLINE CV *modperl_handler_anon_get(pTHX_ modperl_mgv_t *anon); + +#define modperl_handler_array_new(p) \ +apr_array_make(p, 1, sizeof(modperl_handler_t *)) + +#define modperl_handler_array_push(handlers, h) \ +*(modperl_handler_t **)apr_array_push(handlers) = h + +#define modperl_handler_array_item(handlers, idx) \ +((modperl_handler_t **)(handlers)->elts)[idx] + +#define modperl_handler_array_last(handlers) \ +modperl_handler_array_item(handlers, ((handlers)->nelts - 1)) + +modperl_handler_t *modperl_handler_new(apr_pool_t *p, const char *name); + +modperl_handler_t *modperl_handler_new_from_sv(pTHX_ apr_pool_t *p, SV *sv); + +MP_INLINE const char *modperl_handler_name(modperl_handler_t *handler); + +int modperl_handler_resolve(pTHX_ modperl_handler_t **handp, + apr_pool_t *p, server_rec *s); + +modperl_handler_t *modperl_handler_dup(apr_pool_t *p, + modperl_handler_t *h); + +int modperl_handler_equal(modperl_handler_t *h1, modperl_handler_t *h2); + +MpAV *modperl_handler_array_merge(apr_pool_t *p, MpAV *base_a, MpAV *add_a); + +void modperl_handler_make_args(pTHX_ AV **avp, ...); + +MpAV **modperl_handler_lookup_handlers(modperl_config_dir_t *dcfg, + modperl_config_srv_t *scfg, + modperl_config_req_t *rcfg, + apr_pool_t *p, + int type, int idx, + modperl_handler_action_e action, + const char **desc); + +MpAV **modperl_handler_get_handlers(request_rec *r, conn_rec *c,server_rec *s, + apr_pool_t *p, const char *name, + modperl_handler_action_e action); + +int modperl_handler_push_handlers(pTHX_ apr_pool_t *p, + MpAV *handlers, SV *sv); + +SV *modperl_handler_perl_get_handlers(pTHX_ MpAV **handp, apr_pool_t *p); + +int modperl_handler_perl_add_handlers(pTHX_ + request_rec *r, + conn_rec *c, + server_rec *s, + apr_pool_t *p, + const char *name, + SV *sv, + modperl_handler_action_e action); + +#endif /* MODPERL_HANDLER_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_interp.c b/2_0_13/src/modules/perl/modperl_interp.c new file mode 100644 index 0000000..35f5cea --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_interp.c
@@ -0,0 +1,565 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* + * XXX: this is not the most efficent interpreter pool implementation + * but it will do for proof-of-concept + */ + +#ifdef USE_ITHREADS + +void modperl_interp_clone_init(modperl_interp_t *interp) +{ + dTHXa(interp->perl); + + MpInterpCLONED_On(interp); + + MP_ASSERT_CONTEXT(aTHX); + + /* clear @DynaLoader::dl_librefs so we only dlclose() those + * which are opened by the clone + */ + modperl_xs_dl_handles_clear(aTHX); +} + +modperl_interp_t *modperl_interp_new(modperl_interp_pool_t *mip, + PerlInterpreter *perl) +{ + UV clone_flags = CLONEf_KEEP_PTR_TABLE; + modperl_interp_t *interp = + (modperl_interp_t *)malloc(sizeof(*interp)); + + memset(interp, '\0', sizeof(*interp)); + + interp->mip = mip; + interp->refcnt = 0; + + if (perl) { +#ifdef MP_USE_GTOP + MP_dSCFG(mip->server); + MP_TRACE_m_do( + modperl_gtop_do_proc_mem_before(MP_FUNC, "perl_clone"); + ); +#endif + +#if defined(WIN32) && defined(CLONEf_CLONE_HOST) + clone_flags |= CLONEf_CLONE_HOST; +#endif + + PERL_SET_CONTEXT(perl); + + interp->perl = perl_clone(perl, clone_flags); + + MP_ASSERT_CONTEXT(interp->perl); + + { + PTR_TBL_t *source = modperl_module_config_table_get(perl, FALSE); + if (source) { + PTR_TBL_t *table = modperl_svptr_table_clone(interp->perl, + perl, + source); + + modperl_module_config_table_set(interp->perl, table); + } + } + + /* + * we keep the PL_ptr_table past perl_clone so it can be used + * within modperl_svptr_table_clone. Perl_sv_dup() uses it. + * Don't confuse our svptr_table with Perl's ptr_table. They + * are different things, although they use the same type. + */ + if ((clone_flags & CLONEf_KEEP_PTR_TABLE)) { + dTHXa(interp->perl); + ptr_table_free(PL_ptr_table); + PL_ptr_table = NULL; + } + + modperl_interp_clone_init(interp); + + PERL_SET_CONTEXT(perl); + +#ifdef MP_USE_GTOP + MP_TRACE_m_do( + modperl_gtop_do_proc_mem_after(MP_FUNC, "perl_clone"); + ); +#endif + } + + MP_TRACE_i(MP_FUNC, "0x%lx / perl: 0x%lx / parent perl: 0x%lx", + (unsigned long)interp, (unsigned long)interp->perl, + (unsigned long)perl); + + return interp; +} + +void modperl_interp_destroy(modperl_interp_t *interp) +{ + void **handles; + dTHXa(interp->perl); + + PERL_SET_CONTEXT(interp->perl); + + MP_TRACE_i(MP_FUNC, "interp == 0x%lx / perl: 0x%lx", + (unsigned long)interp, (unsigned long)interp->perl); + + if (MpInterpIN_USE(interp)) { + MP_TRACE_i(MP_FUNC, "*error - still in use!*"); + } + + handles = modperl_xs_dl_handles_get(aTHX); + + modperl_perl_destruct(interp->perl); + + modperl_xs_dl_handles_close(handles); + + free(interp); +} + +apr_status_t modperl_interp_cleanup(void *data) +{ + modperl_interp_destroy((modperl_interp_t *)data); + return APR_SUCCESS; +} + +modperl_interp_t *modperl_interp_get(server_rec *s) +{ + MP_dSCFG(s); + modperl_interp_t *interp = NULL; + modperl_interp_pool_t *mip = scfg->mip; + modperl_list_t *head; + + head = modperl_tipool_pop(mip->tipool); + interp = (modperl_interp_t *)head->data; + + MP_TRACE_i(MP_FUNC, "head == 0x%lx, parent == 0x%lx", + (unsigned long)head, (unsigned long)mip->parent); + + MP_TRACE_i(MP_FUNC, "selected 0x%lx (perl==0x%lx)", + (unsigned long)interp, + (unsigned long)interp->perl); + +#ifdef MP_TRACE + interp->tid = MP_TIDF; + MP_TRACE_i(MP_FUNC, "thread == 0x%lx", interp->tid); +#endif + + MpInterpIN_USE_On(interp); + + return interp; +} + +apr_status_t modperl_interp_pool_destroy(void *data) +{ + modperl_interp_pool_t *mip = (modperl_interp_pool_t *)data; + + if (mip->tipool) { + modperl_tipool_destroy(mip->tipool); + mip->tipool = NULL; + } + + if (MpInterpBASE(mip->parent)) { + /* multiple mips might share the same parent + * make sure its only destroyed once + */ + MP_TRACE_i(MP_FUNC, "parent == 0x%lx", + (unsigned long)mip->parent); + + modperl_interp_destroy(mip->parent); + } + + return APR_SUCCESS; +} + +static void *interp_pool_grow(modperl_tipool_t *tipool, void *data) +{ + modperl_interp_pool_t *mip = (modperl_interp_pool_t *)data; + MP_TRACE_i(MP_FUNC, "adding new interpreter to the pool"); + return (void *)modperl_interp_new(mip, mip->parent->perl); +} + +static void interp_pool_shrink(modperl_tipool_t *tipool, void *data, + void *item) +{ + modperl_interp_destroy((modperl_interp_t *)item); +} + +static void interp_pool_dump(modperl_tipool_t *tipool, void *data, + modperl_list_t *listp) +{ + while (listp) { + modperl_interp_t *interp = (modperl_interp_t *)listp->data; + MP_TRACE_i(MP_FUNC, "listp==0x%lx, interp==0x%lx, requests=%d", + (unsigned long)listp, (unsigned long)interp, + interp->num_requests); + listp = listp->next; + } +} + +static modperl_tipool_vtbl_t interp_pool_func = { + interp_pool_grow, + interp_pool_grow, + interp_pool_shrink, + interp_pool_shrink, + interp_pool_dump, +}; + +void modperl_interp_init(server_rec *s, apr_pool_t *p, + PerlInterpreter *perl) +{ + apr_pool_t *server_pool = modperl_server_pool(); + pTHX; + MP_dSCFG(s); + modperl_interp_pool_t *mip = + (modperl_interp_pool_t *)apr_pcalloc(p, sizeof(*mip)); + + MP_TRACE_i(MP_FUNC, "server=%s", modperl_server_desc(s, p)); + + if (modperl_threaded_mpm()) { + mip->tipool = modperl_tipool_new(p, scfg->interp_pool_cfg, + &interp_pool_func, mip); + } + + mip->server = s; + mip->parent = modperl_interp_new(mip, NULL); + aTHX = mip->parent->perl = perl; + + /* this happens post-config in mod_perl.c:modperl_init_clones() */ + /* modperl_tipool_init(tipool); */ + + apr_pool_cleanup_register(server_pool, (void*)mip, + modperl_interp_pool_destroy, + apr_pool_cleanup_null); + + scfg->mip = mip; +} + +apr_status_t modperl_interp_unselect(void *data) +{ + modperl_interp_t *interp = (modperl_interp_t *)data; + modperl_interp_pool_t *mip = interp->mip; + + MP_ASSERT(interp && MpInterpIN_USE(interp) && interp->refcnt > 0); + MP_TRACE_i(MP_FUNC, "unselect(interp=%pp): refcnt=%d", + interp, interp->refcnt); + + --interp->refcnt; + + if (interp->refcnt > 0) { + MP_TRACE_i(MP_FUNC, "interp=0x%lx, refcnt=%d -- interp still in use", + (unsigned long)interp, interp->refcnt); + return APR_SUCCESS; + } + + if (!MpInterpIN_USE(interp)){ + MP_TRACE_i(MP_FUNC, "interp=0x%pp, refcnt=%d -- interp already not in use", + interp, interp->refcnt); + return APR_SUCCESS; + } + + MpInterpIN_USE_Off(interp); + + modperl_thx_interp_set(interp->perl, NULL); +#ifdef MP_DEBUG + PERL_SET_CONTEXT(NULL); +#endif + + if (interp == mip->parent) { + MP_TRACE_i(MP_FUNC, "parent interp=%pp freed", interp); + } + else { + interp->ccfg->interp = NULL; + modperl_tipool_putback_data(mip->tipool, data, interp->num_requests); + MP_TRACE_i(MP_FUNC, "interp=%pp freed, tipool(size=%ld, in_use=%ld)", + interp, mip->tipool->size, mip->tipool->in_use); + } + + return APR_SUCCESS; +} + +/* XXX: + * interp is marked as in_use for the scope of the pool it is + * stashed in. this is done to avoid the tipool->tlock whenever + * possible. neither approach is ideal. + */ +#define MP_INTERP_KEY "MODPERL_INTERP" + +#define get_interp(p) \ + (void)apr_pool_userdata_get((void **)&interp, MP_INTERP_KEY, p) + +#define set_interp(p) \ + (void)apr_pool_userdata_set((void *)interp, MP_INTERP_KEY, \ + modperl_interp_unselect, \ + p) + +modperl_interp_t *modperl_interp_pool_get(apr_pool_t *p) +{ + modperl_interp_t *interp = NULL; + get_interp(p); + return interp; +} + +void modperl_interp_pool_set(apr_pool_t *p, + modperl_interp_t *interp) +{ + (void)apr_pool_userdata_set((void *)interp, MP_INTERP_KEY, NULL, p); +} + +/* + * used in the case where we don't have a request_rec or conn_rec, + * such as for directive handlers per-{dir,srv} create and merge. + * "request time pool" is most likely a request_rec->pool. + */ +modperl_interp_t *modperl_interp_pool_select(apr_pool_t *p, + server_rec *s) +{ + int is_startup = (p == s->process->pconf); + modperl_interp_t *interp = NULL; + + if (is_startup) { + MP_dSCFG(s); + if (scfg) { + MP_TRACE_i(MP_FUNC, "using parent interpreter at startup"); + + if (!scfg->mip) { + /* we get here if directive handlers are invoked + * before server merge. + */ + modperl_init_vhost(s, p, NULL); + if (!scfg->mip) { + /* FIXME: We get here if global "server_rec" == s, scfg->mip + * is not created then. I'm not sure if that's bug or + * bad/good design decicision. For now just return NULL. + */ + return NULL; + } + } + + interp = scfg->mip->parent; + } + else { + if (!(interp = modperl_interp_pool_get(p))) { + interp = modperl_interp_get(s); + modperl_interp_pool_set(p, interp); + + MP_TRACE_i(MP_FUNC, "set interp %pp in pconf pool %pp", + interp, p); + } + else { + MP_TRACE_i(MP_FUNC, "found interp %pp in pconf pool %pp", + interp, p); + } + } + + MpInterpIN_USE_On(interp); + interp->refcnt++; + /* set context (THX) for this thread */ + PERL_SET_CONTEXT(interp->perl); + /* let the perl interpreter point back to its interp */ + modperl_thx_interp_set(interp->perl, interp); + + return interp; + } + else { + request_rec *r; + apr_pool_userdata_get((void **)&r, "MODPERL_R", p); + MP_ASSERT(r); + MP_TRACE_i(MP_FUNC, "found userdata MODPERL_R in pool %#lx as %lx", + (unsigned long)r->pool, (unsigned long)r); + return modperl_interp_select(r, NULL, NULL); + } +} + +modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, + server_rec *s) +{ + MP_dSCFG((r ? s=r->server : c ? s=c->base_server : s)); + MP_dDCFG; + modperl_config_con_t *ccfg; + const char *desc = NULL; + modperl_interp_t *interp = NULL; + apr_pool_t *p = NULL; + + /* What does the following condition mean? + * (r || c): if true we are at runtime. There is some kind of request + * being processed. + * threaded_mpm: self-explanatory + * + * Thus, it is true if we are either at initialization time or at runtime + * but with prefork-MPM. */ + if (!((r || c) && modperl_threaded_mpm())) { + interp = scfg->mip->parent; + MpInterpIN_USE_On(interp); + interp->refcnt++; + /* XXX: if no VirtualHosts w/ PerlOptions +Parent we can skip this */ + PERL_SET_CONTEXT(interp->perl); + /* let the perl interpreter point back to its interp */ + modperl_thx_interp_set(interp->perl, interp); + + MP_TRACE_i(MP_FUNC, + "using parent 0x%pp (perl=0x%pp) for %s:%d refcnt set to %d", + interp, interp->perl, s->server_hostname, s->port, + interp->refcnt); + return interp; + } + + if(!c) c = r->connection; + ccfg = modperl_config_con_get(c); + + if (ccfg && ccfg->interp) { + ccfg->interp->refcnt++; + + MP_TRACE_i(MP_FUNC, + "found interp 0x%lx in con config, refcnt incremented to %d", + (unsigned long)ccfg->interp, ccfg->interp->refcnt); + /* set context (THX) for this thread */ + PERL_SET_CONTEXT(ccfg->interp->perl); + /* modperl_thx_interp_set() is not called here because the interp + * already belongs to the perl interpreter + */ + return ccfg->interp; + } + + MP_TRACE_i(MP_FUNC, + "fetching interp for %s:%d", s->server_hostname, s->port); + interp = modperl_interp_get(s); + MP_TRACE_i(MP_FUNC, " --> got %pp (perl=%pp)", interp, interp->perl); + ++interp->num_requests; /* should only get here once per request */ + interp->refcnt = 1; + + /* set context (THX) for this thread */ + PERL_SET_CONTEXT(interp->perl); + /* let the perl interpreter point back to its interp */ + modperl_thx_interp_set(interp->perl, interp); + + /* make sure ccfg is initialized */ + modperl_config_con_init(c, ccfg); + ccfg->interp = interp; + interp->ccfg = ccfg; + + MP_TRACE_i(MP_FUNC, + "pulled interp %pp (perl=%pp) from mip, num_requests is %d", + interp, interp->perl, interp->num_requests); + + return interp; +} + +/* currently up to the caller if mip needs locking */ +void modperl_interp_mip_walk(PerlInterpreter *current_perl, + PerlInterpreter *parent_perl, + modperl_interp_pool_t *mip, + modperl_interp_mip_walker_t walker, + void *data) +{ + modperl_list_t *head = mip->tipool ? mip->tipool->idle : NULL; + + if (!current_perl) { + current_perl = PERL_GET_CONTEXT; + } + + if (parent_perl) { + PERL_SET_CONTEXT(parent_perl); + walker(parent_perl, mip, data); + } + + while (head) { + PerlInterpreter *perl = ((modperl_interp_t *)head->data)->perl; + PERL_SET_CONTEXT(perl); + walker(perl, mip, data); + head = head->next; + } + + PERL_SET_CONTEXT(current_perl); +} + +void modperl_interp_mip_walk_servers(PerlInterpreter *current_perl, + server_rec *base_server, + modperl_interp_mip_walker_t walker, + void *data) +{ + server_rec *s = base_server->next; + modperl_config_srv_t *base_scfg = modperl_config_srv_get(base_server); + PerlInterpreter *base_perl = base_scfg->mip->parent->perl; + + modperl_interp_mip_walk(current_perl, base_perl, + base_scfg->mip, walker, data); + + while (s) { + MP_dSCFG(s); + PerlInterpreter *perl = scfg->mip->parent->perl; + modperl_interp_pool_t *mip = scfg->mip; + + /* skip vhosts who share parent perl */ + if (perl == base_perl) { + perl = NULL; + } + + /* skip vhosts who share parent mip */ + if (scfg->mip == base_scfg->mip) { + mip = NULL; + } + + if (perl || mip) { + modperl_interp_mip_walk(current_perl, perl, + mip, walker, data); + } + + s = s->next; + } +} + +#define MP_THX_INTERP_KEY "modperl2::thx_interp_key" +modperl_interp_t *modperl_thx_interp_get(pTHX) +{ + modperl_interp_t *interp; + SV **svp = hv_fetch(PL_modglobal, MP_THX_INTERP_KEY, + strlen(MP_THX_INTERP_KEY), 0); + if (!svp) return NULL; + interp = INT2PTR(modperl_interp_t *, SvIV(*svp)); + return interp; +} + +void modperl_thx_interp_set(pTHX_ modperl_interp_t *interp) +{ + (void)hv_store(PL_modglobal, MP_THX_INTERP_KEY, strlen(MP_THX_INTERP_KEY), + newSViv(PTR2IV(interp)), 0); + return; +} + +#else + +void modperl_interp_init(server_rec *s, apr_pool_t *p, + PerlInterpreter *perl) +{ + MP_dSCFG(s); + scfg->perl = perl; +} + +apr_status_t modperl_interp_cleanup(void *data) +{ + return APR_SUCCESS; +} + +#endif /* USE_ITHREADS */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_interp.h b/2_0_13/src/modules/perl/modperl_interp.h new file mode 100644 index 0000000..f3f4037 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_interp.h
@@ -0,0 +1,158 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_INTERP_H +#define MODPERL_INTERP_H + +void modperl_interp_init(server_rec *s, apr_pool_t *p, + PerlInterpreter *perl); + +apr_status_t modperl_interp_cleanup(void *data); + +#ifdef USE_ITHREADS + +modperl_interp_t *modperl_thx_interp_get(PerlInterpreter *thx); +void modperl_thx_interp_set(PerlInterpreter *thx, modperl_interp_t *interp); + +void modperl_interp_clone_init(modperl_interp_t *interp); + +modperl_interp_t *modperl_interp_new(modperl_interp_pool_t *mip, + PerlInterpreter *perl); + +void modperl_interp_destroy(modperl_interp_t *interp); + +modperl_interp_t *modperl_interp_get(server_rec *s); + +apr_status_t modperl_interp_unselect(void *data); + +modperl_interp_t *modperl_interp_pool_get(apr_pool_t *p); + +void modperl_interp_pool_set(apr_pool_t *p, + modperl_interp_t *interp); + +modperl_interp_t *modperl_interp_pool_select(apr_pool_t *p, + server_rec *s); + +modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, + server_rec *s); + +#define MP_dINTERP pTHX; modperl_interp_t *interp = NULL + +#define MP_INTERPa(r, c, s) \ + MP_TRACE_i(MP_FUNC, "selecting interp: r=%pp, c=%pp, s=%pp", \ + (r), (c), (s)); \ + interp = modperl_interp_select((r), (c), (s)); \ + if (interp) { \ + MP_TRACE_i(MP_FUNC, " --> got (0x%pp)->refcnt=%d, perl=%pp", \ + interp, interp->refcnt, interp->perl); \ + aTHX = interp->perl; \ + } \ + else { \ + aTHX = NULL; \ + MP_TRACE_i(MP_FUNC, " --> failed"); \ + } \ + NOOP + +#define MP_dINTERPa(r, c, s) \ + MP_dINTERP; \ + MP_INTERPa((r), (c), (s)) + +#define MP_INTERP_POOLa(p, s) \ + MP_TRACE_i(MP_FUNC, "selecting interp: p=%pp, s=%pp", (p), (s)); \ + interp = modperl_interp_pool_select((p), (s)); \ + if (interp) { \ + MP_TRACE_i(MP_FUNC, " --> got (0x%pp)->refcnt=%d", \ + interp, interp->refcnt); \ + aTHX = interp->perl; \ + } \ + else { \ + aTHX = NULL; \ + MP_TRACE_i(MP_FUNC, " --> failed"); \ + } \ + NOOP + +#define MP_dINTERP_POOLa(p, s) \ + MP_dINTERP; \ + MP_INTERP_POOLa((p), (s)) + +#ifdef MP_DEBUG +#define MP_INTERP_PUTBACK(interp, thx) \ + MP_TRACE_i(MP_FUNC, "unselecting interp: (0x%pp)->refcnt=%ld", \ + (interp), (interp)->refcnt); \ + modperl_interp_unselect(interp); \ + interp = NULL; \ + if( thx ) thx = NULL +#else /* MP_DEBUG */ +#define MP_INTERP_PUTBACK(interp, thx) \ + modperl_interp_unselect(interp) +#endif + +#define MP_INTERP_REFCNT_inc(interp) (interp)->refcnt++ + +#define MP_INTERP_REFCNT_dec(interp) MP_INTERP_PUTBACK(interp, NULL) + +#define MP_HAS_INTERP(interp) (interp != NULL) + +#define MP_aTHX aTHX + +apr_status_t modperl_interp_pool_destroy(void *data); + +typedef apr_status_t (*modperl_interp_mip_walker_t)(pTHX_ + modperl_interp_pool_t *mip, + void *data); + +void modperl_interp_mip_walk(PerlInterpreter *current_perl, + PerlInterpreter *parent_perl, + modperl_interp_pool_t *mip, + modperl_interp_mip_walker_t walker, + void *data); + +void modperl_interp_mip_walk_servers(PerlInterpreter *current_perl, + server_rec *base_server, + modperl_interp_mip_walker_t walker, + void *data); +#else + +#define MP_dINTERP dNOOP + +#define MP_INTERPa(r, c, s) NOOP + +#define MP_dINTERPa(r, c, s) NOOP + +#define MP_INTERP_POOLa(p, s) NOOP + +#define MP_dINTERP_POOLa(p, s) NOOP + +#define MP_INTERP_PUTBACK(interp, thx) NOOP + +#define MP_INTERP_REFCNT_inc(interp) NOOP + +#define MP_INTERP_REFCNT_dec(interp) NOOP + +#define MP_HAS_INTERP(interp) (1) + +#define MP_aTHX 0 + +#endif /* USE_ITHREADS */ + +#endif /* MODPERL_INTERP_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_io.c b/2_0_13/src/modules/perl/modperl_io.c new file mode 100644 index 0000000..7a0baf0 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_io.c
@@ -0,0 +1,183 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +#define TIEHANDLE(handle,r) \ +modperl_io_handle_tie(aTHX_ handle, "Apache2::RequestRec", (void *)r) + +#define TIED(handle) \ +modperl_io_handle_tied(aTHX_ handle, "Apache2::RequestRec") + +MP_INLINE void modperl_io_handle_tie(pTHX_ GV *handle, + char *classname, void *ptr) +{ + SV *obj = modperl_ptr2obj(aTHX_ classname, ptr); + + modperl_io_handle_untie(aTHX_ handle); + + sv_magic(TIEHANDLE_SV(handle), obj, PERL_MAGIC_tiedscalar, (char *)NULL, 0); + + SvREFCNT_dec(obj); /* since sv_magic did SvREFCNT_inc */ + + MP_TRACE_r(MP_FUNC, "tie *%s(0x%lx) => %s, REFCNT=%d", + GvNAME(handle), (unsigned long)handle, classname, + SvREFCNT(TIEHANDLE_SV(handle))); +} + +MP_INLINE GV *modperl_io_tie_stdin(pTHX_ request_rec *r) +{ +#if defined(MP_IO_TIE_SFIO) + /* XXX */ +#else + dHANDLE("STDIN"); + + if (TIED(handle)) { + return handle; + } + + TIEHANDLE(handle, r); + + return handle; +#endif +} + +MP_INLINE GV *modperl_io_tie_stdout(pTHX_ request_rec *r) +{ +#if defined(MP_IO_TIE_SFIO) + /* XXX */ +#else + dHANDLE("STDOUT"); + + if (TIED(handle)) { + return handle; + } + + IoFLUSH_off(PL_defoutgv); /* $|=0 */ + + TIEHANDLE(handle, r); + + return handle; +#endif +} + +MP_INLINE int modperl_io_handle_tied(pTHX_ GV *handle, char *classname) +{ + MAGIC *mg; + SV *sv = TIEHANDLE_SV(handle); + + if (SvMAGICAL(sv) && (mg = mg_find(sv, PERL_MAGIC_tiedscalar))) { + char *package = HvNAME(SvSTASH((SV*)SvRV(mg->mg_obj))); + + if (!strEQ(package, classname)) { + MP_TRACE_r(MP_FUNC, "%s tied to %s", GvNAME(handle), package); + return TRUE; + } + } + + return FALSE; +} + +MP_INLINE void modperl_io_handle_untie(pTHX_ GV *handle) +{ +#ifdef MP_TRACE + if (mg_find(TIEHANDLE_SV(handle), PERL_MAGIC_tiedscalar)) { + MP_TRACE_r(MP_FUNC, "untie *%s(0x%lx), REFCNT=%d", + GvNAME(handle), (unsigned long)handle, + SvREFCNT(TIEHANDLE_SV(handle))); + } +#endif + + sv_unmagic(TIEHANDLE_SV(handle), PERL_MAGIC_tiedscalar); +} + +MP_INLINE static void +modperl_io_perlio_override_stdhandle(pTHX_ request_rec *r, int mode) +{ + dHANDLE(mode == O_RDONLY ? "STDIN" : "STDOUT"); + int status; + SV *sv = sv_newmortal(); + + MP_TRACE_o(MP_FUNC, "start STD%s", mode == O_RDONLY ? "IN" : "OUT"); + + save_gp(handle, 1); + + sv_setref_pv(sv, "Apache2::RequestRec", (void*)r); + status = do_openn(handle, mode == O_RDONLY ? "<:Apache2" : ">:Apache2", + 9, FALSE, mode, 0, (PerlIO *)NULL, &sv, 1); + if (status == 0) { + Perl_croak(aTHX_ "Failed to open STD%s: %" SVf, + mode == O_RDONLY ? "IN" : "OUT", get_sv("!", TRUE)); + } + + MP_TRACE_o(MP_FUNC, "end STD%s", mode==O_RDONLY ? "IN" : "OUT"); +} + +MP_INLINE static void +modperl_io_perlio_restore_stdhandle(pTHX_ int mode) +{ + GV *handle_orig = gv_fetchpv(mode == O_RDONLY ? "STDIN" : "STDOUT", + FALSE, SVt_PVIO); + + MP_TRACE_o(MP_FUNC, "start STD%s", mode == O_RDONLY ? "IN" : "OUT"); + + /* since closing unflushed STDOUT may trigger a subrequest + * (e.g. via mod_include), resulting in potential another response + * handler call, which may try to close STDOUT too. We will + * segfault, if that subrequest doesn't return before the the top + * level STDOUT is attempted to be closed. To prevent this + * situation always explicitly flush STDOUT, before reopening it. + */ + if (mode != O_RDONLY && + GvIOn(handle_orig) && IoOFP(GvIOn(handle_orig)) && + (PerlIO_flush(IoOFP(GvIOn(handle_orig))) == -1)) { + Perl_croak(aTHX_ "Failed to flush STDOUT: %" SVf, get_sv("!", TRUE)); + } + + /* close the overriding filehandle */ + do_close(handle_orig, FALSE); + + MP_TRACE_o(MP_FUNC, "end STD%s", mode == O_RDONLY ? "IN" : "OUT"); +} + +MP_INLINE GV *modperl_io_perlio_override_stdin(pTHX_ request_rec *r) +{ + modperl_io_perlio_override_stdhandle(aTHX_ r, O_RDONLY); + return NULL; +} + +MP_INLINE GV *modperl_io_perlio_override_stdout(pTHX_ request_rec *r) +{ + modperl_io_perlio_override_stdhandle(aTHX_ r, O_WRONLY); + return NULL; +} + +MP_INLINE void modperl_io_perlio_restore_stdin(pTHX_ GV *handle) +{ + modperl_io_perlio_restore_stdhandle(aTHX_ O_RDONLY); +} + +MP_INLINE void modperl_io_perlio_restore_stdout(pTHX_ GV *handle) +{ + modperl_io_perlio_restore_stdhandle(aTHX_ O_WRONLY); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_io.h b/2_0_13/src/modules/perl/modperl_io.h new file mode 100644 index 0000000..cfb9402 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_io.h
@@ -0,0 +1,84 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_IO_H +#define MODPERL_IO_H + +#include "modperl_io_apache.h" + +/* + * bleedperl change #11639 switch tied handle magic + * from living in the gv to the GvIOp(gv), so we have to deal + * with both to support 5.6.x + */ +#if MP_PERL_VERSION_AT_LEAST(5, 7, 0) +# define TIEHANDLE_SV(handle) (SV*)GvIOp((SV*)handle) +#else +# define TIEHANDLE_SV(handle) (SV*)handle +#endif + +#define dHANDLE(name) GV *handle = gv_fetchpv(name, TRUE, SVt_PVIO) + +#define IoFLUSH_off(gv) \ +IoFLAGS(GvIOp((gv))) &= ~IOf_FLUSH + +#define IoFLUSH_on(gv) \ +IoFLAGS(GvIOp((gv))) |= IOf_FLUSH + +#define IoFLUSH(gv) \ +(IoFLAGS(GvIOp((gv))) & IOf_FLUSH) + +MP_INLINE void modperl_io_handle_tie(pTHX_ GV *handle, + char *classname, void *ptr); +MP_INLINE GV *modperl_io_tie_stdout(pTHX_ request_rec *r); + +MP_INLINE GV *modperl_io_tie_stdin(pTHX_ request_rec *r); + +MP_INLINE int modperl_io_handle_tied(pTHX_ GV *handle, char *classname); + +MP_INLINE void modperl_io_handle_untie(pTHX_ GV *handle); + +MP_INLINE GV *modperl_io_perlio_override_stdin(pTHX_ request_rec *r); + +MP_INLINE GV *modperl_io_perlio_override_stdout(pTHX_ request_rec *r); + +MP_INLINE void modperl_io_perlio_restore_stdin(pTHX_ GV *handle); + +MP_INLINE void modperl_io_perlio_restore_stdout(pTHX_ GV *handle); + +#if defined(MP_IO_TIE_SFIO) + /* XXX */ +#elif defined(MP_IO_TIE_PERLIO) +#define modperl_io_override_stdin modperl_io_perlio_override_stdin +#define modperl_io_override_stdout modperl_io_perlio_override_stdout +#define modperl_io_restore_stdin modperl_io_perlio_restore_stdin +#define modperl_io_restore_stdout modperl_io_perlio_restore_stdout +#else +#define modperl_io_override_stdin modperl_io_tie_stdin +#define modperl_io_override_stdout modperl_io_tie_stdout +#define modperl_io_restore_stdin modperl_io_handle_untie +#define modperl_io_restore_stdout modperl_io_handle_untie +#endif + + +#endif /* MODPERL_IO_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_io_apache.c b/2_0_13/src/modules/perl/modperl_io_apache.c new file mode 100644 index 0000000..c10031c --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_io_apache.c
@@ -0,0 +1,343 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +#ifdef MP_IO_TIE_PERLIO + +/*************************** + * The PerlIO Apache layer * + ***************************/ + +/* PerlIO ":Apache2" layer is used to use the Apache callbacks to read + * from STDIN and write to STDOUT. The PerlIO API is documented in + * perliol.pod */ + +typedef struct { + struct _PerlIO base; + request_rec *r; +} PerlIOApache; + +/* _open just allocates the layer, _pushed does the real job of + * filling the data in */ +static PerlIO * +PerlIOApache_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers, IV n, + const char *mode, int fd, int imode, int perm, + PerlIO *f, int narg, SV **args) +{ + if (!f) { + f = PerlIO_allocate(aTHX); + } + if ( (f = PerlIO_push(aTHX_ f, self, mode, args[0])) ) { + PerlIOBase(f)->flags |= PERLIO_F_OPEN; + } + + MP_TRACE_o(MP_FUNC, "mode %s", mode); + + return f; +} + +/* this callback is used by pushed() and binmode() to add the layer */ +static IV +PerlIOApache_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, + PerlIO_funcs *tab) +{ + IV code; + PerlIOApache *st = PerlIOSelf(f, PerlIOApache); + + if (arg) { + st->r = modperl_sv2request_rec(aTHX_ arg); + MP_TRACE_o(MP_FUNC, "stored request_rec obj: 0x%lx", st->r); + } + else { + Perl_croak(aTHX_"failed to insert the :Apache2 layer. " + "Apache2::RequestRec object argument is required"); + /* XXX: try to get Apache2->request? */ + } + + /* this method also sets the right flags according to the + * 'mode' */ + code = PerlIOBase_pushed(aTHX_ f, mode, (SV *)NULL, tab); + + return code; +} + +static SV * +PerlIOApache_getarg(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags) +{ + PerlIOApache *st = PerlIOSelf(f, PerlIOApache); + SV *sv; + + if (!st->r) { + Perl_croak(aTHX_ "an attempt to getarg from a stale io handle"); + } + + sv = newSV(0); + sv_setref_pv(sv, "Apache2::RequestRec", (void*)(st->r)); + + MP_TRACE_o(MP_FUNC, "retrieved request_rec obj: 0x%lx", st->r); + + return sv; +} + +static IV +PerlIOApache_fileno(pTHX_ PerlIO *f) +{ + /* XXX: we could return STDIN => 0, STDOUT => 1, but that wouldn't + * be correct, as the IO goes through the socket, may be we should + * return the filedescriptor of the socket? + * + * -1 in this case indicates that the layer cannot provide fileno + */ + MP_TRACE_o(MP_FUNC, "did nothing"); + return -1; +} + +static SSize_t +PerlIOApache_read(pTHX_ PerlIO *f, void *vbuf, Size_t count) +{ + PerlIOApache *st = PerlIOSelf(f, PerlIOApache); + request_rec *r = st->r; + + if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD) || + PerlIOBase(f)->flags & (PERLIO_F_EOF|PERLIO_F_ERROR)) { + return 0; + } + + return modperl_request_read(aTHX_ r, (char*)vbuf, count); +} + +static SSize_t +PerlIOApache_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count) +{ + PerlIOApache *st = PerlIOSelf(f, PerlIOApache); + modperl_config_req_t *rcfg = modperl_config_req_get(st->r); + apr_size_t bytes = 0; + + if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE)) { + return 0; + } + + MP_CHECK_WBUCKET_INIT("print"); + + MP_TRACE_o(MP_FUNC, "%4db [%s]", count, + MP_TRACE_STR_TRUNC(rcfg->wbucket->pool, vbuf, count)); + + MP_RUN_CROAK(modperl_wbucket_write(aTHX_ rcfg->wbucket, vbuf, &count), + ":Apache2 IO write"); + + bytes += count; + + return (SSize_t) bytes; +} + +static IV +PerlIOApache_flush(pTHX_ PerlIO *f) +{ + PerlIOApache *st = PerlIOSelf(f, PerlIOApache); + modperl_config_req_t *rcfg; + + if (!st->r) { + Perl_warn(aTHX_ "an attempt to flush a stale IO handle"); + return -1; + } + + /* no flush on readonly io handle */ + if (! (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) ) { + return -1; + } + + rcfg = modperl_config_req_get(st->r); + + MP_CHECK_WBUCKET_INIT("flush"); + + MP_TRACE_o(MP_FUNC, "%4db [%s]", rcfg->wbucket->outcnt, + MP_TRACE_STR_TRUNC(rcfg->wbucket->pool, + rcfg->wbucket->outbuf, + rcfg->wbucket->outcnt)); + + MP_RUN_CROAK_RESET_OK(st->r->server, + modperl_wbucket_flush(rcfg->wbucket, FALSE), + ":Apache2 IO flush"); + + return 0; +} + +/* 5.8.0 doesn't export PerlIOBase_noop_fail, so we duplicate it here */ +static IV PerlIOApache_noop_fail(pTHX_ PerlIO *f) +{ + return -1; +} + +static IV +PerlIOApache_close(pTHX_ PerlIO *f) +{ + IV code = PerlIOBase_close(aTHX_ f); + PerlIOApache *st = PerlIOSelf(f, PerlIOApache); + + MP_TRACE_o(MP_FUNC, "done with request_rec obj: 0x%lx", st->r); + /* prevent possible bugs where a stale r will be attempted to be + * reused (e.g. dupped filehandle) */ + st->r = NULL; + + return code; +} + +static IV +PerlIOApache_popped(pTHX_ PerlIO *f) +{ + /* XXX: just temp for tracing */ + MP_TRACE_o(MP_FUNC, "done"); + return PerlIOBase_popped(aTHX_ f); +} + + +static PerlIO_funcs PerlIO_Apache = { + sizeof(PerlIO_funcs), + "Apache2", + sizeof(PerlIOApache), + PERLIO_K_MULTIARG | PERLIO_K_RAW, + PerlIOApache_pushed, + PerlIOApache_popped, + PerlIOApache_open, + PerlIOBase_binmode, + PerlIOApache_getarg, + PerlIOApache_fileno, + PerlIOBase_dup, + PerlIOApache_read, + PerlIOBase_unread, + PerlIOApache_write, + NULL, /* can't seek on STD{IN|OUT}, fail on call*/ + NULL, /* can't tell on STD{IN|OUT}, fail on call*/ + PerlIOApache_close, + PerlIOApache_flush, + PerlIOApache_noop_fail, /* fill */ + PerlIOBase_eof, + PerlIOBase_error, + PerlIOBase_clearerr, + PerlIOBase_setlinebuf, + NULL, /* get_base */ + NULL, /* get_bufsiz */ + NULL, /* get_ptr */ + NULL, /* get_cnt */ + NULL, /* set_ptrcnt */ +}; + +/* ***** End of PerlIOApache tab ***** */ + +MP_INLINE void modperl_io_apache_init(pTHX) +{ + PerlIO_define_layer(aTHX_ &PerlIO_Apache); +} + +#endif /* defined MP_IO_TIE_PERLIO */ + +/****** Other request IO functions *******/ + + +MP_INLINE SSize_t modperl_request_read(pTHX_ request_rec *r, + char *buffer, Size_t len) +{ + SSize_t total = 0; + Size_t wanted = len; + int seen_eos = 0; + char *tmp = buffer; + apr_bucket_brigade *bb; + + if (len <= 0) { + return 0; + } + + bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + if (bb == NULL) { + r->connection->keepalive = AP_CONN_CLOSE; + Perl_croak(aTHX_ "failed to create bucket brigade"); + } + + do { + apr_size_t read; + apr_status_t rc; + + rc = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + APR_BLOCK_READ, len); + if (rc != APR_SUCCESS) { + /* if we fail here, we want to stop trying to read data + * from the client. + */ + r->connection->keepalive = AP_CONN_CLOSE; + apr_brigade_destroy(bb); + modperl_croak(aTHX_ rc, "Apache2::RequestIO::read"); + } + + /* If this fails, it means that a filter is written + * incorrectly and that it needs to learn how to properly + * handle APR_BLOCK_READ requests by returning data when + * requested. + */ + if (APR_BRIGADE_EMPTY(bb)) { + apr_brigade_destroy(bb); + /* we can't tell which filter is broken, since others may + * just pass data through */ + Perl_croak(aTHX_ "Apache2::RequestIO::read: " + "Aborting read from client. " + "One of the input filters is broken. " + "It returned an empty bucket brigade for " + "the APR_BLOCK_READ mode request"); + } + + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { + seen_eos = 1; + } + + read = len; + rc = apr_brigade_flatten(bb, tmp, &read); + if (rc != APR_SUCCESS) { + apr_brigade_destroy(bb); + modperl_croak(aTHX_ rc, "Apache2::RequestIO::read"); + } + + total += read; + tmp += read; + len -= read; + + /* XXX: what happens if the downstream filter returns more + * data than the caller has asked for? We can't return more + * data than requested, so it needs to be stored somewhere and + * dealt with on the subsequent calls to this function. or may + * be we should just assert, blaming a bad filter. at the + * moment I couldn't find a spec telling whether it's wrong + * for the filter to return more data than it was asked for in + * the AP_MODE_READBYTES mode. + */ + + apr_brigade_cleanup(bb); + + } while (len > 0 && !seen_eos); + + apr_brigade_destroy(bb); + + MP_TRACE_o(MP_FUNC, "wanted %db, read %db [%s]", wanted, total, + MP_TRACE_STR_TRUNC(r->pool, buffer, total)); + + return total; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_io_apache.h b/2_0_13/src/modules/perl/modperl_io_apache.h new file mode 100644 index 0000000..a372222 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_io_apache.h
@@ -0,0 +1,67 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_IO_APACHE_H +#define MODPERL_IO_APACHE_H + +#ifdef PERLIO_LAYERS + +#include "perliol.h" +/* XXX: should this be a Makefile.PL config option? */ +#define MP_IO_TIE_PERLIO + +#include "apr_portable.h" +#include "apr_file_io.h" +#include "apr_errno.h" + +typedef enum { + MODPERL_IO_APACHE_HOOK_READ, + MODPERL_IO_APACHE_HOOK_WRITE +} modperl_io_apache_hook_e; + +#define PERLIO_Apache_DEBUG + +MP_INLINE void modperl_io_apache_init(pTHX); + +#else /* #ifdef PERLIO_LAYERS */ + +#define modperl_io_apache_init(pTHX) + +#endif /* #ifdef PERLIO_LAYERS */ + +/** + * read 'len' bytes from the request record 'r' into 'buffer' + * + * this call will block until all 'len' bytes are read, eof is reached + * or will return an error otherwise + * + * @param r request record + * @param buffer preallocated buffer of size 'len' to store the data in + * @param len how many bytes to read + * @return how many bytes were read, + * -1 on error (in which case ERRSV ($!) is set) + */ +MP_INLINE SSize_t modperl_request_read(pTHX_ request_rec *r, + char *buffer, Size_t len); + +#endif /* MODPERL_IO_APACHE_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_log.c b/2_0_13/src/modules/perl/modperl_log.c new file mode 100644 index 0000000..a806e00 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_log.c
@@ -0,0 +1,24 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modperl_log.h" + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_log.h b/2_0_13/src/modules/perl/modperl_log.h new file mode 100644 index 0000000..7e5f303 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_log.h
@@ -0,0 +1,54 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_LOG_H +#define MODPERL_LOG_H + +#include "modperl_common_log.h" +#include "modperl_apache_includes.h" + +#define modperl_trace_level_set_apache(s, level) \ + modperl_trace_level_set(s->error_log, level); + +#define modperl_log_warn(s, msg) \ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "%s", msg) + +#define modperl_log_error(s, msg) \ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "%s", msg) + +#define modperl_log_notice(s, msg) \ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "%s", msg) + +#define modperl_log_debug(s, msg) \ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%s", msg) + +#define modperl_log_reason(r, msg, file) \ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, \ + "access to %s failed for %s, reason: %s", \ + file, \ + ap_get_remote_host(r->connection, \ + r->per_dir_config, REMOTE_NAME, \ + NULL), \ + msg) + +#endif /* MODPERL_LOG_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_mgv.c b/2_0_13/src/modules/perl/modperl_mgv.c new file mode 100644 index 0000000..c6286f0 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_mgv.c
@@ -0,0 +1,541 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* + * mgv = ModPerl Glob Value || Mostly Glob Value + * as close to GV as we can get without actually using a GV + * need config structures to be free of Perl structures + */ + +#define modperl_mgv_new_w_name(mgv, p, n, copy) \ + mgv = modperl_mgv_new(p); \ + mgv->len = strlen(n); \ + mgv->name = (copy ? apr_pstrndup(p, n, mgv->len) : n) + +#define modperl_mgv_new_name(mgv, p, n) \ + modperl_mgv_new_w_name(mgv, p, n, 1) + +#define modperl_mgv_new_namen(mgv, p, n) \ + modperl_mgv_new_w_name(mgv, p, n, 0) + +int modperl_mgv_equal(modperl_mgv_t *mgv1, + modperl_mgv_t *mgv2) +{ + for (; mgv1 && mgv2; mgv1=mgv1->next, mgv2=mgv2->next) { + if (mgv1->hash != mgv2->hash) { + return FALSE; + } + if (mgv1->len != mgv2->len) { + return FALSE; + } + if (memNE(mgv1->name, mgv2->name, mgv1->len)) { + return FALSE; + } + } + + return TRUE; +} + +modperl_mgv_t *modperl_mgv_new(apr_pool_t *p) +{ + return (modperl_mgv_t *)apr_pcalloc(p, sizeof(modperl_mgv_t)); +} + +#define modperl_mgv_get_next(mgv) \ + if (mgv->name) { \ + mgv->next = modperl_mgv_new(p); \ + mgv = mgv->next; \ + } + +#define modperl_mgv_hash(mgv) \ + PERL_HASH(mgv->hash, mgv->name, mgv->len) + /* MP_TRACE_h(MP_FUNC, "%s...hash=%ld", mgv->name, mgv->hash) */ + +modperl_mgv_t *modperl_mgv_compile(pTHX_ apr_pool_t *p, + register const char *name) +{ + register const char *namend; + I32 len; + modperl_mgv_t *symbol = modperl_mgv_new(p); + modperl_mgv_t *mgv = symbol; + + /* @mgv = split '::', $name */ + for (namend = name; *namend; namend++) { + if (*namend == ':' && namend[1] == ':') { + if ((len = (namend - name)) > 0) { + modperl_mgv_get_next(mgv); + mgv->name = apr_palloc(p, len+3); + Copy(name, mgv->name, len, char); + mgv->name[len++] = ':'; + mgv->name[len++] = ':'; + mgv->name[len] = '\0'; + mgv->len = len; + modperl_mgv_hash(mgv); + } + name = namend + 2; + } + } + + modperl_mgv_get_next(mgv); + + mgv->len = namend - name; + mgv->name = apr_pstrndup(p, name, mgv->len); + modperl_mgv_hash(mgv); + + return symbol; +} + +void modperl_mgv_append(pTHX_ apr_pool_t *p, modperl_mgv_t *symbol, + const char *name) +{ + modperl_mgv_t *mgv = symbol; + + while (mgv->next) { + mgv = mgv->next; + } + + mgv->name = apr_pstrcat(p, mgv->name, "::", NULL); + mgv->len += 2; + modperl_mgv_hash(mgv); + + mgv->next = modperl_mgv_compile(aTHX_ p, name); +} + +/* faster replacement for gv_fetchpv() */ +GV *modperl_mgv_lookup(pTHX_ modperl_mgv_t *symbol) +{ + HV *stash = PL_defstash; + modperl_mgv_t *mgv; + + if (!symbol->hash) { + /* special case for MyClass->handler */ + return (GV*)sv_2mortal(newSVpvn(symbol->name, symbol->len)); + } + + for (mgv = symbol; mgv; mgv = mgv->next) { + HE *he = hv_fetch_he(stash, mgv->name, mgv->len, mgv->hash); + if (he) { + if (mgv->next) { + stash = GvHV((GV *)HeVAL(he)); + } + else { + return (GV *)HeVAL(he); + } + } + else { + return (GV *)NULL; + } + } + + return (GV *)NULL; +} + +#ifdef USE_ITHREADS +MP_INLINE GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol, + server_rec *s, apr_pool_t *p) +{ + MP_dSCFG(s); + GV *gv = modperl_mgv_lookup(aTHX_ symbol); + + if (gv || !MpSrvPARENT(scfg)) { + return gv; + } + + /* + * this VirtualHost has its own parent interpreter + * must require the module again with this server's THX + */ + modperl_mgv_require_module(aTHX_ symbol, s, p); + + return modperl_mgv_lookup(aTHX_ symbol); +} +#else +MP_INLINE GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol, + server_rec *s, apr_pool_t *p) +{ + return modperl_mgv_lookup(aTHX_ symbol); +} +#endif + +/* currently used for complex filters attributes parsing */ +/* XXX: may want to generalize it for any handlers */ +#define MODPERL_MGV_DEEP_RESOLVE(handler, p) \ + if (handler->attrs & MP_FILTER_HAS_INIT_HANDLER) { \ + modperl_filter_resolve_init_handler(aTHX_ handler, p); \ + } + +int modperl_mgv_resolve(pTHX_ modperl_handler_t *handler, + apr_pool_t *p, const char *name, int logfailure) +{ + CV *cv; + GV *gv; + HV *stash = (HV *)NULL; + char *handler_name = "handler"; + char *tmp; + + if (MpHandlerANON(handler)) { + /* already resolved anonymous handler */ + return 1; + } + + if (strnEQ(name, "sub ", 4)) { + SV *sv; + CV *cv; + MpHandlerPARSED_On(handler); + MpHandlerANON_On(handler); + + ENTER;SAVETMPS; + sv = eval_pv(name, TRUE); + if (!(SvROK(sv) && (cv = (CV*)SvRV(sv)) && (CvFLAGS(cv) & CVf_ANON))) { + + Perl_croak(aTHX_ "expected anonymous sub, got '%s'\n", name); + } + +#ifdef USE_ITHREADS + handler->cv = NULL; + handler->name = NULL; + handler->mgv_obj = modperl_handler_anon_next(aTHX_ p); + modperl_handler_anon_add(aTHX_ handler->mgv_obj, cv); + MP_TRACE_h(MP_FUNC, "new anon handler"); +#else + SvREFCNT_inc(cv); + handler->cv = cv; + handler->name = NULL; + MP_TRACE_h(MP_FUNC, "new cached-cv anon handler"); +#endif + + FREETMPS;LEAVE; + + return 1; + } + + if ((tmp = strstr((char *)name, "->"))) { + int package_len = strlen(name) - strlen(tmp); + char *package = apr_pstrndup(p, name, package_len); + + name = package; + handler_name = &tmp[2]; + + MpHandlerMETHOD_On(handler); + + if (*package == '$') { + GV *gv; + SV *obj; + + handler->mgv_obj = modperl_mgv_compile(aTHX_ p, package + 1); + gv = modperl_mgv_lookup(aTHX_ handler->mgv_obj); + obj = gv ? GvSV(gv) : (SV *)NULL; + + if (SvTRUE(obj)) { + if (SvROK(obj) && sv_isobject(obj)) { + stash = SvSTASH(SvRV(obj)); + MpHandlerOBJECT_On(handler); + MP_TRACE_h(MP_FUNC, "handler object %s isa %s", + package, HvNAME(stash)); + } + else { + MP_TRACE_h(MP_FUNC, "%s is not an object, pv=%s", + package, SvPV_nolen(obj)); + return 0; + } + } + else { + MP_TRACE_h(MP_FUNC, "failed to thaw %s", package); + return 0; + } + } + + if (!stash) { + if ((stash = gv_stashpvn(package, package_len, FALSE))) { + MP_TRACE_h(MP_FUNC, "handler method %s isa %s", + name, HvNAME(stash)); + } + } + } + else { + if ((cv = get_cv(name, FALSE))) { + handler->attrs = *modperl_code_attrs(aTHX_ cv); + handler->mgv_cv = + modperl_mgv_compile(aTHX_ p, HvNAME(GvSTASH(CvGV(cv)))); + modperl_mgv_append(aTHX_ p, handler->mgv_cv, GvNAME(CvGV(cv))); + MpHandlerPARSED_On(handler); + MODPERL_MGV_DEEP_RESOLVE(handler, p); + return 1; + } + } + + if (!stash && MpHandlerAUTOLOAD(handler)) { + if (!modperl_perl_module_loaded(aTHX_ name)) { /* not in %INC */ + MP_TRACE_h(MP_FUNC, + "package %s not in %INC, attempting to load it", + name); + + if (modperl_require_module(aTHX_ name, logfailure)) { + MP_TRACE_h(MP_FUNC, "loaded %s package", name); + } + else { + if (logfailure) { + /* the caller doesn't handle the error checking */ + Perl_croak(aTHX_ "failed to load %s package\n", name); + } + else { + /* the caller handles the error checking */ + MP_TRACE_h(MP_FUNC, "failed to load %s package", name); + return 0; + } + } + } + else { + MP_TRACE_h(MP_FUNC, "package %s seems to be loaded", name); + } + } + + /* try to lookup the stash only after loading the module, to avoid + * the case where a stash is autovivified by a user before the + * module was loaded, preventing from loading the module + */ + if (!(stash || (stash = gv_stashpv(name, FALSE)))) { + MP_TRACE_h(MP_FUNC, "%s's stash is not found", name); + return 0; + } + + if ((gv = gv_fetchmethod(stash, handler_name)) && (cv = GvCV(gv))) { + if (CvFLAGS(cv) & CVf_METHOD) { /* sub foo : method {}; */ + MpHandlerMETHOD_On(handler); + } + + if (!stash) { + return 0; + } + + + if (MpHandlerMETHOD(handler) && !handler->mgv_obj) { + char *name = HvNAME(stash); + if (!name) { + name = ""; + } + modperl_mgv_new_name(handler->mgv_obj, p, name); + } + + handler->attrs = *modperl_code_attrs(aTHX_ cv); + /* note: this is the real function after @ISA lookup */ + handler->mgv_cv = modperl_mgv_compile(aTHX_ p, HvNAME(GvSTASH(gv))); + modperl_mgv_append(aTHX_ p, handler->mgv_cv, handler_name); + + MpHandlerPARSED_On(handler); + MP_TRACE_h(MP_FUNC, "found `%s' in class `%s' as a %s", + handler_name, HvNAME(stash), + MpHandlerMETHOD(handler) ? "method" : "function"); + MODPERL_MGV_DEEP_RESOLVE(handler, p); + return 1; + } + + /* at least modperl_hash_handlers needs to verify that an + * autoloaded-marked handler needs to be loaded, since it doesn't + * check success failure, and handlers marked to be autoloaded are + * the same as PerlModule and the failure should be fatal */ + if (MpHandlerAUTOLOAD(handler)) { + Perl_croak(aTHX_ "failed to resolve handler %s\n", name); + } + +#ifdef MP_TRACE + /* complain only if the class was actually loaded/created */ + if (stash) { + MP_TRACE_h(MP_FUNC, "`%s' not found in class `%s'", + handler_name, name); + } +#endif + + return 0; +} + +modperl_mgv_t *modperl_mgv_last(modperl_mgv_t *symbol) +{ + while (symbol->next) { + symbol = symbol->next; + } + + return symbol; +} + +char *modperl_mgv_last_name(modperl_mgv_t *symbol) +{ + symbol = modperl_mgv_last(symbol); + return symbol->name; +} + +char *modperl_mgv_as_string(pTHX_ modperl_mgv_t *symbol, + apr_pool_t *p, int package) +{ + char *string, *ptr; + modperl_mgv_t *mgv; + int len = 0; + + for (mgv = symbol; (package ? mgv->next : mgv); mgv = mgv->next) { + len += mgv->len; + } + + ptr = string = apr_palloc(p, len+1); + + for (mgv = symbol; (package ? mgv->next : mgv); mgv = mgv->next) { + Copy(mgv->name, ptr, mgv->len, char); + ptr += mgv->len; + } + + if (package) { + *(ptr-2) = '\0'; /* trim trailing :: */ + } + else { + *ptr = '\0'; + } + + return string; +} + +#ifdef USE_ITHREADS +int modperl_mgv_require_module(pTHX_ modperl_mgv_t *symbol, + server_rec *s, apr_pool_t *p) +{ + char *package = + modperl_mgv_as_string(aTHX_ symbol, p, 1); + + if (modperl_require_module(aTHX_ package, TRUE)) { + MP_TRACE_h(MP_FUNC, "reloaded %s for server %s", + package, modperl_server_desc(s, p)); + return TRUE; + } + + return FALSE; +} +#endif + +/* precompute the hash(es) for handler names, preload handlers + * configured to be autoloaded */ +static void modperl_hash_handlers(pTHX_ apr_pool_t *p, server_rec *s, + MpAV *entry, void *data) +{ + MP_dSCFG(s); + int i; + modperl_handler_t **handlers; + + if (!entry) { + return; + } + + handlers = (modperl_handler_t **)entry->elts; + + for (i=0; i < entry->nelts; i++) { + modperl_handler_t *handler = handlers[i]; + + if (MpHandlerFAKE(handler)) { + /* do nothing with fake handlers */ + } + else if (MpHandlerPARSED(handler)) { +#ifdef USE_ITHREADS + if ((MpSrvPARENT(scfg) && MpSrvAUTOLOAD(scfg)) + && !modperl_mgv_lookup(aTHX_ handler->mgv_cv)) { + /* + * this VirtualHost has its own parent interpreter + * must require the module again with this server's THX + */ + modperl_mgv_require_module(aTHX_ handler->mgv_cv, + s, p); + } +#endif + MP_TRACE_h(MP_FUNC, "%s already resolved in server %s", + modperl_handler_name(handler), + modperl_server_desc(s, p)); + } + else { + if (MpSrvAUTOLOAD(scfg)) { + MpHandlerAUTOLOAD_On(handler); + } + + modperl_mgv_resolve(aTHX_ handler, p, handler->name, TRUE); + } + } +} + +static int modperl_hash_handlers_dir(apr_pool_t *p, server_rec *s, + void *cfg, char *d, void *data) +{ + int i; + modperl_config_dir_t *dir_cfg = (modperl_config_dir_t *)cfg; + dTHXa(data); + + if (!dir_cfg) { + return 1; + } + + for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) { + modperl_hash_handlers(aTHX_ p, s, dir_cfg->handlers_per_dir[i], data); + } + + return 1; +} + +static int modperl_hash_handlers_srv(apr_pool_t *p, server_rec *s, + void *cfg, void *data) +{ + int i; + modperl_config_srv_t *scfg = (modperl_config_srv_t *)cfg; + dTHXa(data); + + for (i=0; i < MP_HANDLER_NUM_PER_SRV; i++) { + modperl_hash_handlers(aTHX_ p, s, + scfg->handlers_per_srv[i], data); + } + + for (i=0; i < MP_HANDLER_NUM_PROCESS; i++) { + modperl_hash_handlers(aTHX_ p, s, + scfg->handlers_process[i], data); + } + + for (i=0; i < MP_HANDLER_NUM_CONNECTION; i++) { + modperl_hash_handlers(aTHX_ p, s, + scfg->handlers_connection[i], data); + } + + for (i=0; i < MP_HANDLER_NUM_FILES; i++) { + modperl_hash_handlers(aTHX_ p, s, + scfg->handlers_files[i], data); + } + + return 1; +} + +void modperl_mgv_hash_handlers(apr_pool_t *p, server_rec *s) +{ + MP_dINTERPa(NULL, NULL, s); + ap_pcw_walk_config(p, s, &perl_module, +#ifdef USE_ITHREADS + aTHX, +#else + NULL, +#endif + modperl_hash_handlers_dir, + modperl_hash_handlers_srv); + MP_INTERP_PUTBACK(interp, aTHX); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_mgv.h b/2_0_13/src/modules/perl/modperl_mgv.h new file mode 100644 index 0000000..50ce5b8 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_mgv.h
@@ -0,0 +1,65 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_MGV_H +#define MODPERL_MGV_H + +modperl_mgv_t *modperl_mgv_new(apr_pool_t *p); + +int modperl_mgv_equal(modperl_mgv_t *mgv1, + modperl_mgv_t *mgv2); + +modperl_mgv_t *modperl_mgv_compile(pTHX_ apr_pool_t *p, const char *name); + +GV *modperl_mgv_lookup(pTHX_ modperl_mgv_t *symbol); + +GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol, + server_rec *s, apr_pool_t *p); + +int modperl_mgv_resolve(pTHX_ modperl_handler_t *handler, + apr_pool_t *p, const char *name, int logfailure); + +void modperl_mgv_append(pTHX_ apr_pool_t *p, modperl_mgv_t *symbol, + const char *name); + +modperl_mgv_t *modperl_mgv_last(modperl_mgv_t *symbol); + +char *modperl_mgv_last_name(modperl_mgv_t *symbol); + +char *modperl_mgv_as_string(pTHX_ modperl_mgv_t *symbol, + apr_pool_t *p, int package); + +#ifdef USE_ITHREADS +int modperl_mgv_require_module(pTHX_ modperl_mgv_t *symbol, + server_rec *s, apr_pool_t *p); +#endif + +void modperl_mgv_hash_handlers(apr_pool_t *p, server_rec *s); + +#define modperl_mgv_sv(sv) \ +(isGV(sv) ? GvSV(sv) : (SV*)sv) + +#define modperl_mgv_cv(sv) \ +GvCV(sv) + +#endif /* MODPERL_MGV_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_module.c b/2_0_13/src/modules/perl/modperl_module.c new file mode 100644 index 0000000..e804bad --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_module.c
@@ -0,0 +1,911 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +typedef struct { + modperl_mgv_t *dir_create; + modperl_mgv_t *dir_merge; + modperl_mgv_t *srv_create; + modperl_mgv_t *srv_merge; + int namelen; +} modperl_module_info_t; + +typedef struct { + server_rec *server; + modperl_module_info_t *minfo; +} modperl_module_cfg_t; + +#define MP_MODULE_INFO(modp) \ + (modperl_module_info_t *)modp->dynamic_load_handle + +#define MP_MODULE_CFG_MINFO(ptr) \ + ((modperl_module_cfg_t *)ptr)->minfo + +static modperl_module_cfg_t *modperl_module_cfg_new(apr_pool_t *p) +{ + modperl_module_cfg_t *cfg = + (modperl_module_cfg_t *)apr_pcalloc(p, sizeof(*cfg)); + + return cfg; +} + +static modperl_module_cmd_data_t *modperl_module_cmd_data_new(apr_pool_t *p) +{ + modperl_module_cmd_data_t *cmd_data = + (modperl_module_cmd_data_t *)apr_pcalloc(p, sizeof(*cmd_data)); + + return cmd_data; +} + +static void *modperl_module_config_dir_create(apr_pool_t *p, char *dir) +{ + return modperl_module_cfg_new(p); +} + +static void *modperl_module_config_srv_create(apr_pool_t *p, server_rec *s) +{ + return modperl_module_cfg_new(p); +} + +static SV **modperl_module_config_hash_get(pTHX_ int create) +{ + SV **svp; + + /* XXX: could make this lookup faster */ + svp = hv_fetch(PL_modglobal, + "ModPerl::Module::ConfigTable", + MP_SSTRLEN("ModPerl::Module::ConfigTable"), + create); + + return svp; +} + +void modperl_module_config_table_set(pTHX_ PTR_TBL_t *table) +{ + SV **svp = modperl_module_config_hash_get(aTHX_ TRUE); + sv_setiv(*svp, PTR2IV(table)); +} + +PTR_TBL_t *modperl_module_config_table_get(pTHX_ int create) +{ + PTR_TBL_t *table = NULL; + + SV *sv, **svp = modperl_module_config_hash_get(aTHX_ create); + + if (!svp) { + return NULL; + } + + sv = *svp; + if (!SvIOK(sv) && create) { + table = modperl_svptr_table_new(aTHX); + sv_setiv(sv, PTR2IV(table)); + } + else { + table = INT2PTR(PTR_TBL_t *, SvIV(sv)); + } + + return table; +} + +typedef struct { +#ifdef USE_ITHREADS + modperl_interp_t *interp; +#endif + PTR_TBL_t *table; + void *ptr; +} config_obj_cleanup_t; + +/* + * any per-dir CREATE or MERGE that happens at request time + * needs to be removed from the pointer table. + */ +static apr_status_t modperl_module_config_obj_cleanup(void *data) +{ + config_obj_cleanup_t *cleanup = + (config_obj_cleanup_t *)data; +#ifdef USE_ITHREADS + dTHXa(cleanup->interp->perl); + MP_ASSERT_CONTEXT(aTHX); +#endif + + modperl_svptr_table_delete(aTHX_ cleanup->table, cleanup->ptr); + + MP_TRACE_c(MP_FUNC, "deleting ptr %pp from table %pp", + cleanup->ptr, cleanup->table); + + MP_INTERP_PUTBACK(cleanup->interp, aTHX); + + return APR_SUCCESS; +} + +static void modperl_module_config_obj_cleanup_register(pTHX_ + apr_pool_t *p, + PTR_TBL_t *table, + void *ptr) +{ + config_obj_cleanup_t *cleanup = + (config_obj_cleanup_t *)apr_palloc(p, sizeof(*cleanup)); + + cleanup->table = table; + cleanup->ptr = ptr; +#ifdef USE_ITHREADS + cleanup->interp = modperl_thx_interp_get(aTHX); + MP_INTERP_REFCNT_inc(cleanup->interp); +#endif + + apr_pool_cleanup_register(p, cleanup, + modperl_module_config_obj_cleanup, + apr_pool_cleanup_null); +} + +#define MP_CFG_MERGE_DIR 1 +#define MP_CFG_MERGE_SRV 2 + +/* + * XXX: vhosts may have different parent interpreters. + */ +static void *modperl_module_config_merge(apr_pool_t *p, + void *basev, void *addv, + int type) +{ + GV *gv; + modperl_mgv_t *method; + modperl_module_cfg_t *mrg = NULL, + *tmp, + *base = (modperl_module_cfg_t *)basev, + *add = (modperl_module_cfg_t *)addv; + server_rec *s; + int is_startup; + PTR_TBL_t *table; + SV *mrg_obj = (SV *)NULL, *base_obj, *add_obj; + MP_dINTERP; + + /* if the module is loaded in vhost, base==NULL */ + tmp = (base && base->server) ? base : add; + + if (tmp && !tmp->server) { + /* no directives for this module were encountered so far */ + return basev; + } + + s = tmp->server; + is_startup = (p == s->process->pconf); + + MP_INTERP_POOLa(p, s); + + table = modperl_module_config_table_get(aTHX_ TRUE); + base_obj = modperl_svptr_table_fetch(aTHX_ table, base); + add_obj = modperl_svptr_table_fetch(aTHX_ table, add); + + if (!base_obj || (base_obj == add_obj)) { + MP_INTERP_PUTBACK(interp, aTHX); + return addv; + } + + mrg = modperl_module_cfg_new(p); + memcpy(mrg, tmp, sizeof(*mrg)); + + method = (type == MP_CFG_MERGE_DIR) ? + mrg->minfo->dir_merge : + mrg->minfo->srv_merge; + + if (method && (gv = modperl_mgv_lookup(aTHX_ method))) { + int count; + dSP; + + MP_TRACE_c(MP_FUNC, "calling %s->%s", + SvCLASS(base_obj), modperl_mgv_last_name(method)); + + ENTER;SAVETMPS; + PUSHMARK(sp); + XPUSHs(base_obj);XPUSHs(add_obj); + + PUTBACK; + count = call_sv((SV*)GvCV(gv), G_EVAL|G_SCALAR); + SPAGAIN; + + if (count == 1) { + mrg_obj = SvREFCNT_inc(POPs); + } + + PUTBACK; + FREETMPS;LEAVE; + + if (SvTRUE(ERRSV)) { + /* XXX: should die here. */ + (void)modperl_errsv(aTHX_ HTTP_INTERNAL_SERVER_ERROR, + NULL, NULL); + } + } + else { + mrg_obj = SvREFCNT_inc(add_obj); + } + + modperl_svptr_table_store(aTHX_ table, mrg, mrg_obj); + + if (!is_startup) { + modperl_module_config_obj_cleanup_register(aTHX_ p, table, mrg); + } + + MP_INTERP_PUTBACK(interp, aTHX); + + return (void *)mrg; +} + +static void *modperl_module_config_dir_merge(apr_pool_t *p, + void *basev, void *addv) +{ + return modperl_module_config_merge(p, basev, addv, + MP_CFG_MERGE_DIR); +} + +static void *modperl_module_config_srv_merge(apr_pool_t *p, + void *basev, void *addv) +{ + return modperl_module_config_merge(p, basev, addv, + MP_CFG_MERGE_SRV); +} + +#define modperl_bless_cmd_parms(parms) \ + sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::CmdParms", (void *)parms)) + +static const char * +modperl_module_config_create_obj(pTHX_ + apr_pool_t *p, + PTR_TBL_t *table, + modperl_module_cfg_t *cfg, + modperl_module_cmd_data_t *info, + modperl_mgv_t *method, + cmd_parms *parms, + SV **obj) +{ + const char *mname = info->modp->name; + modperl_module_info_t *minfo = MP_MODULE_INFO(info->modp); + GV *gv; + int is_startup = (p == parms->server->process->pconf); + + /* + * XXX: if MPM is not threaded, we could modify the + * modperl_module_cfg_t * directly and avoid the ptr_table + * altogether. + */ + if ((*obj = (SV*)modperl_svptr_table_fetch(aTHX_ table, cfg))) { + /* object already exists */ + return NULL; + } + + MP_TRACE_c(MP_FUNC, "%s cfg=0x%lx for %s.%s", + method ? modperl_mgv_last_name(method) : "NULL", + (unsigned long)cfg, mname, parms->cmd->name); + + /* used by merge functions to get a Perl interp */ + cfg->server = parms->server; + cfg->minfo = minfo; + + if (method && (gv = modperl_mgv_lookup(aTHX_ method))) { + int count; + dSP; + + ENTER;SAVETMPS; + PUSHMARK(sp); + XPUSHs(sv_2mortal(newSVpv(mname, minfo->namelen))); + XPUSHs(modperl_bless_cmd_parms(parms)); + + PUTBACK; + count = call_sv((SV*)GvCV(gv), G_EVAL|G_SCALAR); + SPAGAIN; + + if (count == 1) { + *obj = SvREFCNT_inc(POPs); + } + + PUTBACK; + FREETMPS;LEAVE; + + if (SvTRUE(ERRSV)) { + return SvPVX(ERRSV); + } + } + else { + HV *stash = gv_stashpvn(mname, minfo->namelen, FALSE); + /* return bless {}, $class */ + *obj = newRV_noinc((SV*)newHV()); + *obj = sv_bless(*obj, stash); + } + + if (!is_startup) { + modperl_module_config_obj_cleanup_register(aTHX_ p, table, cfg); + } + + modperl_svptr_table_store(aTHX_ table, cfg, *obj); + + return NULL; +} + +#define PUSH_STR_ARG(arg) \ + if (arg) XPUSHs(sv_2mortal(newSVpv(arg,0))) + +static const char *modperl_module_cmd_take123(cmd_parms *parms, + void *mconfig, + const char *one, + const char *two, + const char *three) +{ + modperl_module_cfg_t *cfg = (modperl_module_cfg_t *)mconfig; + const char *retval = NULL, *errmsg; + const command_rec *cmd = parms->cmd; + server_rec *s = parms->server; + apr_pool_t *p = parms->pool; + modperl_module_cmd_data_t *info = + (modperl_module_cmd_data_t *)cmd->cmd_data; + modperl_module_info_t *minfo = MP_MODULE_INFO(info->modp); + modperl_module_cfg_t *srv_cfg; + int modules_alias = 0; + int count; + PTR_TBL_t *table; + SV *obj = (SV *)NULL; + MP_dINTERP_POOLa(p, s); + + table = modperl_module_config_table_get(aTHX_ TRUE); + + if (s->is_virtual) { + MP_dSCFG(s); + + /* if the Perl module is loaded in the base server and a vhost + * has configuration directives from that module, but no + * mod_perl.c directives, scfg == NULL when + * modperl_module_cmd_take123 is run. If the directive + * callback wants to do something with the mod_perl config + * object, it'll segfault, since it doesn't exist yet, because + * this happens before server configs are merged. So we create + * a temp struct and fill it in with things that might be + * needed by the Perl callback. + */ + if (!scfg) { + scfg = modperl_config_srv_new(p, s); + modperl_set_module_config(s->module_config, scfg); + scfg->server = s; + } + + /* if PerlLoadModule Foo is called from the base server, but + * Foo's directives are used inside a vhost, we need to + * temporary link to the base server config's 'modules' + * member. e.g. so Apache2::Module->get_config() can be called + * from a custom directive's callback, before the server/vhost + * config merge is performed + */ + if (!scfg->modules) { + modperl_config_srv_t *base_scfg = + modperl_config_srv_get(modperl_global_get_server_rec()); + if (base_scfg->modules) { + scfg->modules = base_scfg->modules; + modules_alias = 1; + } + } + + } + + errmsg = modperl_module_config_create_obj(aTHX_ p, table, cfg, info, + minfo->dir_create, + parms, &obj); + + if (errmsg) { + MP_INTERP_PUTBACK(interp, aTHX); + return errmsg; + } + + if (obj) { + MP_TRACE_c(MP_FUNC, "found per-dir obj=0x%lx for %s.%s", + (unsigned long)obj, + info->modp->name, cmd->name); + } + + /* XXX: could delay creation of srv_obj until + * Apache2::ModuleConfig->get is called. + */ + srv_cfg = ap_get_module_config(s->module_config, info->modp); + + if (srv_cfg) { + SV *srv_obj; + errmsg = modperl_module_config_create_obj(aTHX_ p, table, srv_cfg, info, + minfo->srv_create, + parms, &srv_obj); + if (errmsg) { + MP_INTERP_PUTBACK(interp, aTHX); + return errmsg; + } + + if (srv_obj) { + MP_TRACE_c(MP_FUNC, "found per-srv obj=0x%lx for %s.%s", + (unsigned long)srv_obj, + info->modp->name, cmd->name); + } + } + + { + dSP; + ENTER;SAVETMPS; + PUSHMARK(SP); + EXTEND(SP, 2); + + PUSHs(obj); + PUSHs(modperl_bless_cmd_parms(parms)); + + if (cmd->args_how != NO_ARGS) { + PUSH_STR_ARG(one); + PUSH_STR_ARG(two); + PUSH_STR_ARG(three); + } + + PUTBACK; + count = call_method(info->func_name, G_EVAL|G_SCALAR); + SPAGAIN; + + if (count == 1) { + SV *sv = POPs; + if (SvPOK(sv) && strEQ(SvPVX(sv), DECLINE_CMD)) { + retval = DECLINE_CMD; + } + } + + PUTBACK; + FREETMPS;LEAVE; + } + + if (SvTRUE(ERRSV)) { + retval = SvPVX(ERRSV); + } + + MP_INTERP_PUTBACK(interp, aTHX); + + if (modules_alias) { + MP_dSCFG(s); + /* unalias the temp aliasing */ + scfg->modules = NULL; + } + + return retval; +} + +static const char *modperl_module_cmd_take1(cmd_parms *parms, + void *mconfig, + const char *one) +{ + return modperl_module_cmd_take123(parms, mconfig, one, NULL, NULL); +} + +static const char *modperl_module_cmd_take2(cmd_parms *parms, + void *mconfig, + const char *one, + const char *two) +{ + return modperl_module_cmd_take123(parms, mconfig, one, two, NULL); +} + +static const char *modperl_module_cmd_flag(cmd_parms *parms, + void *mconfig, + int flag) +{ + char buf[2]; + + apr_snprintf(buf, sizeof(buf), "%d", flag); + + return modperl_module_cmd_take123(parms, mconfig, buf, NULL, NULL); +} + +static const char *modperl_module_cmd_no_args(cmd_parms *parms, + void *mconfig) +{ + return modperl_module_cmd_take123(parms, mconfig, NULL, NULL, NULL); +} + +#define modperl_module_cmd_raw_args modperl_module_cmd_take1 +#define modperl_module_cmd_iterate modperl_module_cmd_take1 +#define modperl_module_cmd_iterate2 modperl_module_cmd_take2 +#define modperl_module_cmd_take12 modperl_module_cmd_take2 +#define modperl_module_cmd_take23 modperl_module_cmd_take123 +#define modperl_module_cmd_take3 modperl_module_cmd_take123 +#define modperl_module_cmd_take13 modperl_module_cmd_take123 + +#if defined(AP_HAVE_DESIGNATED_INITIALIZER) +# define modperl_module_cmd_func_set(cmd, name) \ + cmd->func.name = modperl_module_cmd_##name +#else +# define modperl_module_cmd_func_set(cmd, name) \ + cmd->func = modperl_module_cmd_##name +#endif + +static int modperl_module_cmd_lookup(command_rec *cmd) +{ + switch (cmd->args_how) { + case TAKE1: + case ITERATE: + modperl_module_cmd_func_set(cmd, take1); + break; + case TAKE2: + case ITERATE2: + case TAKE12: + modperl_module_cmd_func_set(cmd, take2); + break; + case TAKE3: + case TAKE23: + case TAKE123: + case TAKE13: + modperl_module_cmd_func_set(cmd, take3); + break; + case RAW_ARGS: + modperl_module_cmd_func_set(cmd, raw_args); + break; + case FLAG: + modperl_module_cmd_func_set(cmd, flag); + break; + case NO_ARGS: + modperl_module_cmd_func_set(cmd, no_args); + break; + default: + return FALSE; + } + + return TRUE; +} + +static apr_status_t modperl_module_remove(void *data) +{ + module *modp = (module *)data; + + ap_remove_loaded_module(modp); + + return APR_SUCCESS; +} + +static const char *modperl_module_cmd_fetch(pTHX_ SV *obj, + const char *name, SV **retval) +{ + const char *errmsg = NULL; + + if (*retval) { + SvREFCNT_dec(*retval); + *retval = (SV *)NULL; + } + + if (sv_isobject(obj)) { + int count; + dSP; + ENTER;SAVETMPS; + PUSHMARK(SP); + XPUSHs(obj); + PUTBACK; + + count = call_method(name, G_EVAL|G_SCALAR); + + SPAGAIN; + + if (count == 1) { + SV *sv = POPs; + if (SvTRUE(sv)) { + *retval = SvREFCNT_inc(sv); + } + } + + if (!*retval) { + errmsg = Perl_form(aTHX_ "%s->%s did not return a %svalue", + SvCLASS(obj), name, count ? "true " : ""); + } + + PUTBACK; + FREETMPS;LEAVE; + + if (SvTRUE(ERRSV)) { + errmsg = SvPVX(ERRSV); + } + } + else if (SvROK(obj) && (SvTYPE(SvRV(obj)) == SVt_PVHV)) { + HV *hv = (HV*)SvRV(obj); + SV **svp = hv_fetch(hv, name, strlen(name), 0); + + if (svp) { + *retval = SvREFCNT_inc(*svp); + } + else { + errmsg = Perl_form(aTHX_ "HASH key %s does not exist", name); + } + } + else { + errmsg = "command entry is not an object or a HASH reference"; + } + + return errmsg; +} + +static const char *modperl_module_add_cmds(apr_pool_t *p, server_rec *s, + module *modp, SV *mod_cmds) +{ + const char *errmsg; + apr_array_header_t *cmds; + command_rec *cmd; + AV *module_cmds; + I32 i, fill; + MP_dINTERPa(NULL, NULL, s); + module_cmds = (AV*)SvRV(mod_cmds); + + fill = AvFILL(module_cmds); + cmds = apr_array_make(p, fill+1, sizeof(command_rec)); + + for (i=0; i<=fill; i++) { + SV *val = (SV *)NULL; + STRLEN len; + SV *obj = AvARRAY(module_cmds)[i]; + modperl_module_cmd_data_t *info = modperl_module_cmd_data_new(p); + + info->modp = modp; + + cmd = apr_array_push(cmds); + + if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "name", &val))) { + MP_INTERP_PUTBACK(interp, aTHX); + return errmsg; + } + + cmd->name = apr_pstrdup(p, SvPV(val, len)); + + if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "args_how", &val))) { + /* XXX default based on $self->func prototype */ + cmd->args_how = TAKE1; /* default */ + } + else { + if (SvIOK(val)) { + cmd->args_how = SvIV(val); + } + else { + cmd->args_how = + SvIV(modperl_constants_lookup_apache2_const(aTHX_ SvPV(val, len))); + } + } + + if (!modperl_module_cmd_lookup(cmd)) { + MP_INTERP_PUTBACK(interp, aTHX); + return apr_psprintf(p, + "no command function defined for args_how=%d", + cmd->args_how); + } + + if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "func", &val))) { + info->func_name = cmd->name; /* default */ + } + else { + info->func_name = apr_pstrdup(p, SvPV(val, len)); + } + + if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "req_override", &val))) { + cmd->req_override = OR_ALL; /* default */ + } + else { + if (SvIOK(val)) { + cmd->req_override = SvIV(val); + } + else { + cmd->req_override = + SvIV(modperl_constants_lookup_apache2_const(aTHX_ SvPV(val, len))); + } + } + + if ((errmsg = modperl_module_cmd_fetch(aTHX_ obj, "errmsg", &val))) { + /* default */ + /* XXX generate help msg based on args_how */ + cmd->errmsg = apr_pstrcat(p, cmd->name, " command", NULL); + } + else { + cmd->errmsg = apr_pstrdup(p, SvPV(val, len)); + } + + cmd->cmd_data = info; + + /* no default if undefined */ + if (!(errmsg = modperl_module_cmd_fetch(aTHX_ obj, "cmd_data", &val))) { + info->cmd_data = apr_pstrdup(p, SvPV(val, len)); + } + + if (val) { + SvREFCNT_dec(val); + val = (SV *)NULL; + } + } + + cmd = apr_array_push(cmds); + cmd->name = NULL; + + modp->cmds = (command_rec *)cmds->elts; + + MP_INTERP_PUTBACK(interp, aTHX); + return NULL; +} + +static void modperl_module_insert(module *modp) +{ + /* + * insert after mod_perl, rather the top of the list. + * (see ap_add_module; does not insert into ap_top_module list if + * m->next != NULL) + * this way, modperl config merging happens before this module. + */ + + modp->next = perl_module.next; + perl_module.next = modp; +} + +#define MP_isGV(gv) (gv && isGV(gv)) + +static modperl_mgv_t *modperl_module_fetch_method(pTHX_ + apr_pool_t *p, + module *modp, + const char *method) +{ + modperl_mgv_t *mgv; + + HV *stash = gv_stashpv(modp->name, FALSE); + GV *gv = gv_fetchmethod_autoload(stash, method, FALSE); + + MP_TRACE_c(MP_FUNC, "looking for method %s in package `%s'...%sfound", + method, modp->name, + MP_isGV(gv) ? "" : "not "); + + if (!MP_isGV(gv)) { + return NULL; + } + + mgv = modperl_mgv_compile(aTHX_ p, + apr_pstrcat(p, + modp->name, "::", method, NULL)); + + return mgv; +} + +const char *modperl_module_add(apr_pool_t *p, server_rec *s, + const char *name, SV *mod_cmds) +{ + MP_dSCFG(s); + const char *errmsg; + module *modp; + modperl_module_info_t *minfo; + MP_dINTERPa(NULL, NULL, s); + modp = (module *)apr_pcalloc(p, sizeof(*modp)); + minfo = (modperl_module_info_t *)apr_pcalloc(p, sizeof(*minfo)); + + /* STANDARD20_MODULE_STUFF */ + modp->version = MODULE_MAGIC_NUMBER_MAJOR; + modp->minor_version = MODULE_MAGIC_NUMBER_MINOR; + modp->module_index = -1; + modp->name = apr_pstrdup(p, name); + modp->magic = MODULE_MAGIC_COOKIE; + + /* use this slot for our context */ + modp->dynamic_load_handle = minfo; + + /* + * XXX: we should lookup here if the Perl methods exist, + * and set these pointers only if they do. + */ + modp->create_dir_config = modperl_module_config_dir_create; + modp->merge_dir_config = modperl_module_config_dir_merge; + modp->create_server_config = modperl_module_config_srv_create; + modp->merge_server_config = modperl_module_config_srv_merge; + + minfo->namelen = strlen(name); + + minfo->dir_create = + modperl_module_fetch_method(aTHX_ p, modp, "DIR_CREATE"); + + minfo->dir_merge = + modperl_module_fetch_method(aTHX_ p, modp, "DIR_MERGE"); + + minfo->srv_create = + modperl_module_fetch_method(aTHX_ p, modp, "SERVER_CREATE"); + + minfo->srv_merge = + modperl_module_fetch_method(aTHX_ p, modp, "SERVER_MERGE"); + + modp->cmds = NULL; + + if ((errmsg = modperl_module_add_cmds(p, s, modp, mod_cmds))) { + MP_INTERP_PUTBACK(interp, aTHX); + return errmsg; + } + + modperl_module_insert(modp); + + mp_add_loaded_module(modp, p, modp->name); + + apr_pool_cleanup_register(p, modp, modperl_module_remove, + apr_pool_cleanup_null); + + ap_single_module_configure(p, s, modp); + + if (!scfg->modules) { + scfg->modules = apr_hash_make(p); + } + + apr_hash_set(scfg->modules, apr_pstrdup(p, name), APR_HASH_KEY_STRING, modp); + +#ifdef USE_ITHREADS + /* + * if the Perl module is loaded in the base server and a vhost + * has configuration directives from that module, but no mod_perl.c + * directives, scfg == NULL when modperl_module_cmd_take123 is run. + * this happens before server configs are merged, so we stash a pointer + * to what will be merged as the parent interp later. i.e. "safe hack" + */ + if (!modperl_interp_pool_get(p)) { + /* for vhosts */ + MP_TRACE_i(MP_FUNC, "set interp 0x%lx in pconf pool 0x%lx", + (unsigned long)scfg->mip->parent, (unsigned long)p); + modperl_interp_pool_set(p, scfg->mip->parent); + } +#endif + + MP_INTERP_PUTBACK(interp, aTHX); + return NULL; +} + +SV *modperl_module_config_get_obj(pTHX_ SV *pmodule, server_rec *s, + ap_conf_vector_t *v) +{ + MP_dSCFG(s); + module *modp; + const char *name; + void *ptr; + PTR_TBL_t *table; + SV *obj; + + if (!v) { + v = s->module_config; + } + + if (SvROK(pmodule)) { + name = SvCLASS(pmodule); + } + else { + STRLEN n_a; + name = SvPV(pmodule, n_a); + } + + if (!(scfg->modules && + (modp = apr_hash_get(scfg->modules, name, APR_HASH_KEY_STRING)))) { + return &PL_sv_undef; + } + + if (!(ptr = ap_get_module_config(v, modp))) { + return &PL_sv_undef; + } + + if (!(table = modperl_module_config_table_get(aTHX_ FALSE))) { + return &PL_sv_undef; + } + + if (!(obj = modperl_svptr_table_fetch(aTHX_ table, ptr))) { + return &PL_sv_undef; + } + + return obj; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_module.h b/2_0_13/src/modules/perl/modperl_module.h new file mode 100644 index 0000000..41e8312 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_module.h
@@ -0,0 +1,37 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_MODULE_H +#define MODPERL_MODULE_H + +PTR_TBL_t *modperl_module_config_table_get(pTHX_ int create); + +void modperl_module_config_table_set(pTHX_ PTR_TBL_t *table); + +const char *modperl_module_add(apr_pool_t *p, server_rec *s, + const char *name, SV *mod_cmds); + +SV *modperl_module_config_get_obj(pTHX_ SV *pmodule, server_rec *s, + ap_conf_vector_t *v); + +#endif /* MODPERL_MODULE_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_options.c b/2_0_13/src/modules/perl/modperl_options.c new file mode 100644 index 0000000..5077ec4 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_options.c
@@ -0,0 +1,157 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* re-use the ->unset field to determine options type */ +#define MpOptionsType(o) (o)->unset +#define MpOptionsTypeDir(o) MpOptionsType(o) == MpDir_f_UNSET +#define MpOptionsTypeSrv(o) MpOptionsType(o) == MpSrv_f_UNSET +#define MpOptionsTypeDir_set(o) MpOptionsType(o) = MpDir_f_UNSET +#define MpOptionsTypeSrv_set(o) MpOptionsType(o) = MpSrv_f_UNSET +#define MP_OPTIONS_TYPE_DIR MpDir_f_UNSET +#define MP_OPTIONS_TYPE_SRV MpSrv_f_UNSET + +static modperl_opts_t flags_lookup(modperl_options_t *o, + const char *str) +{ + switch (MpOptionsType(o)) { + case MP_OPTIONS_TYPE_SRV: + return modperl_flags_lookup_srv(str); + case MP_OPTIONS_TYPE_DIR: + return modperl_flags_lookup_dir(str); + default: + return '\0'; + }; +} + +static const char *type_lookup(modperl_options_t *o) +{ + switch (MpOptionsType(o)) { + case MP_OPTIONS_TYPE_SRV: + return "server"; + case MP_OPTIONS_TYPE_DIR: + return "directory"; + default: + return "unknown"; + }; +} + +modperl_options_t *modperl_options_new(apr_pool_t *p, int type) +{ + modperl_options_t *options = + (modperl_options_t *)apr_pcalloc(p, sizeof(*options)); + + options->opts = options->unset = + (type == MpSrvType ? MpSrv_f_UNSET : MpDir_f_UNSET); + + return options; +} + +const char *modperl_options_set(apr_pool_t *p, modperl_options_t *o, + const char *str) +{ + modperl_opts_t opt; + char action = '\0'; + const char *error = NULL; + + if (*str == '+' || *str == '-') { + action = *(str++); + } + + if ((opt = flags_lookup(o, str)) == -1) { + error = apr_pstrcat(p, "Invalid per-", type_lookup(o), + " PerlOption: ", str, NULL); + + if (MpOptionsTypeDir(o)) { + modperl_options_t dummy; + MpOptionsTypeSrv_set(&dummy); + + if (flags_lookup(&dummy, str) == -1) { + error = apr_pstrcat(p, error, + " (only allowed per-server)", + NULL); + } + } + + return error; + } +#ifndef USE_ITHREADS + else if (MpOptionsTypeSrv(o)) { + if (MpSrvOPT_ITHREAD_ONLY(opt)) { + return apr_pstrcat(p, "PerlOption `", str, + "' requires an ithreads enabled Perl", NULL); + } + } +#endif + + o->opts_seen |= opt; + + if (action == '-') { + o->opts_remove |= opt; + o->opts_add &= ~opt; + o->opts &= ~opt; + } + else if (action == '+') { + o->opts_add |= opt; + o->opts_remove &= ~opt; + o->opts |= opt; + } + else { + o->opts |= opt; + } + + return NULL; +} + +modperl_options_t *modperl_options_merge(apr_pool_t *p, + modperl_options_t *base, + modperl_options_t *add) +{ + modperl_options_t *conf = modperl_options_new(p, 0); + memcpy((char *)conf, (const char *)base, sizeof(*base)); + + if (add->opts & add->unset) { + /* there was no explicit setting of add->opts, so we merge + * preserve the invariant (opts_add & opts_remove) == 0 + */ + conf->opts_add = + (conf->opts_add & ~add->opts_remove) | add->opts_add; + conf->opts_remove = + (conf->opts_remove & ~add->opts_add) | add->opts_remove; + conf->opts = + (conf->opts & ~conf->opts_remove) | conf->opts_add; + } + else { + /* otherwise we just copy, because an explicit opts setting + * overrides all earlier +/- modifiers + */ + conf->opts = add->opts; + conf->opts_add = add->opts_add; + conf->opts_remove = add->opts_remove; + } + + conf->opts_seen |= add->opts_seen; + + return conf; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_options.h b/2_0_13/src/modules/perl/modperl_options.h new file mode 100644 index 0000000..62d23da --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_options.h
@@ -0,0 +1,36 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_OPTIONS_H +#define MODPERL_OPTIONS_H + +modperl_options_t *modperl_options_new(apr_pool_t *p, int type); + +const char *modperl_options_set(apr_pool_t *p, modperl_options_t *o, + const char *s); + +modperl_options_t *modperl_options_merge(apr_pool_t *p, + modperl_options_t *base, + modperl_options_t *new); + +#endif /* MODPERL_OPTIONS_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_pcw.c b/2_0_13/src/modules/perl/modperl_pcw.c new file mode 100644 index 0000000..0c247b0 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_pcw.c
@@ -0,0 +1,149 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* + * pcw == Parsed Config Walker + * generic functions for walking parsed config using callbacks + */ + +void ap_pcw_walk_location_config(apr_pool_t *pconf, server_rec *s, + core_server_config *sconf, + module *modp, + ap_pcw_dir_cb_t dir_cb, void *data) +{ + int i; + ap_conf_vector_t **urls; + + if( !sconf->sec_url ) return; + + urls = (ap_conf_vector_t **)sconf->sec_url->elts; + + for (i = 0; i < sconf->sec_url->nelts; i++) { + core_dir_config *conf = + ap_get_module_config(urls[i], &core_module); + void *dir_cfg = ap_get_module_config(urls[i], modp); + + if (!dir_cb(pconf, s, dir_cfg, conf->d, data)) { + break; + } + } +} + +void ap_pcw_walk_directory_config(apr_pool_t *pconf, server_rec *s, + core_server_config *sconf, + module *modp, + ap_pcw_dir_cb_t dir_cb, void *data) +{ + int i; + ap_conf_vector_t **dirs; + + if( !sconf->sec_dir ) return; + + dirs = (ap_conf_vector_t **)sconf->sec_dir->elts; + + for (i = 0; i < sconf->sec_dir->nelts; i++) { + core_dir_config *conf = + ap_get_module_config(dirs[i], &core_module); + void *dir_cfg = ap_get_module_config(dirs[i], modp); + + if (!dir_cb(pconf, s, dir_cfg, conf->d, data)) { + break; + } + } +} + +void ap_pcw_walk_files_config(apr_pool_t *pconf, server_rec *s, + core_dir_config *dconf, + module *modp, + ap_pcw_dir_cb_t dir_cb, void *data) +{ + int i; + ap_conf_vector_t **dirs; + + if( !dconf->sec_file ) return; + + dirs = (ap_conf_vector_t **)dconf->sec_file->elts; + + for (i = 0; i < dconf->sec_file->nelts; i++) { + core_dir_config *conf = + ap_get_module_config(dirs[i], &core_module); + void *dir_cfg = ap_get_module_config(dirs[i], modp); + + if (!dir_cb(pconf, s, dir_cfg, conf->d, data)) { + break; + } + } +} + +void ap_pcw_walk_default_config(apr_pool_t *pconf, server_rec *s, + module *modp, + ap_pcw_dir_cb_t dir_cb, void *data) +{ + core_dir_config *conf = + ap_get_module_config(s->lookup_defaults, &core_module); + void *dir_cfg = + ap_get_module_config(s->lookup_defaults, modp); + + dir_cb(pconf, s, dir_cfg, conf->d, data); +} + +void ap_pcw_walk_server_config(apr_pool_t *pconf, server_rec *s, + module *modp, + ap_pcw_srv_cb_t srv_cb, void *data) +{ + void *cfg = ap_get_module_config(s->module_config, modp); + + if (!cfg) { + return; + } + + srv_cb(pconf, s, cfg, data); +} + +void ap_pcw_walk_config(apr_pool_t *pconf, server_rec *s, + module *modp, void *data, + ap_pcw_dir_cb_t dir_cb, ap_pcw_srv_cb_t srv_cb) +{ + for (; s; s = s->next) { + core_dir_config *dconf = + ap_get_module_config(s->lookup_defaults, + &core_module); + + core_server_config *sconf = + ap_get_module_config(s->module_config, + &core_module); + + if (dir_cb) { + ap_pcw_walk_location_config(pconf, s, sconf, modp, dir_cb, data); + ap_pcw_walk_directory_config(pconf, s, sconf, modp, dir_cb, data); + ap_pcw_walk_files_config(pconf, s, dconf, modp, dir_cb, data); + ap_pcw_walk_default_config(pconf, s, modp, dir_cb, data); + } + + if (srv_cb) { + ap_pcw_walk_server_config(pconf, s, modp, srv_cb, data); + } + } +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_pcw.h b/2_0_13/src/modules/perl/modperl_pcw.h new file mode 100644 index 0000000..4e97acf --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_pcw.h
@@ -0,0 +1,60 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_PCW_H +#define MODPERL_PCW_H + +typedef int (*ap_pcw_dir_cb_t) (apr_pool_t *, server_rec *, + void *, char *, void *); + +typedef int (*ap_pcw_srv_cb_t) (apr_pool_t *, server_rec *, + void *, void *); + +void ap_pcw_walk_location_config(apr_pool_t *pconf, server_rec *s, + core_server_config *sconf, + module *modp, + ap_pcw_dir_cb_t dir_cb, void *data); + +void ap_pcw_walk_directory_config(apr_pool_t *pconf, server_rec *s, + core_server_config *sconf, + module *modp, + ap_pcw_dir_cb_t dir_cb, void *data); + +void ap_pcw_walk_files_config(apr_pool_t *pconf, server_rec *s, + core_dir_config *dconf, + module *modp, + ap_pcw_dir_cb_t dir_cb, void *data); + +void ap_pcw_walk_default_config(apr_pool_t *pconf, server_rec *s, + module *modp, + ap_pcw_dir_cb_t dir_cb, void *data); + +void ap_pcw_walk_server_config(apr_pool_t *pconf, server_rec *s, + module *modp, + ap_pcw_srv_cb_t srv_cb, void *data); + +void ap_pcw_walk_config(apr_pool_t *pconf, server_rec *s, + module *modp, void *data, + ap_pcw_dir_cb_t dir_cb, ap_pcw_srv_cb_t srv_cb); + +#endif /* MODPERL_PCW_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_perl.c b/2_0_13/src/modules/perl/modperl_perl.c new file mode 100644 index 0000000..9ec744f --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_perl.c
@@ -0,0 +1,291 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* this module contains mod_perl small tweaks to the Perl runtime + * others (larger tweaks) are in their own modules, e.g. modperl_env.c + */ + +typedef struct { + const char *name; + const char *sub_name; + const char *core_name; +} modperl_perl_core_global_t; + +#define MP_PERL_CORE_GLOBAL_ENT(name) \ +{ name, "ModPerl::Util::" name, "CORE::GLOBAL::" name } + +static modperl_perl_core_global_t MP_perl_core_global_entries[] = { + MP_PERL_CORE_GLOBAL_ENT("exit"), + { NULL }, +}; + +XS(XS_ModPerl__Util_exit); /* prototype to pass -Wmissing-prototypes */ +XS(XS_ModPerl__Util_exit) +{ + dXSARGS; + int status; + if (items < 0 || items > 1) { + Perl_croak(aTHX_ "Usage: ModPerl::Util::exit(status=0)"); + } + /* default: 0 */ + status = items < 1 ? 0 : (int)SvIV(ST(0)); + modperl_perl_exit(aTHX_ status); + + XSRETURN_EMPTY; +} + +void modperl_perl_core_global_init(pTHX) +{ + modperl_perl_core_global_t *cglobals = MP_perl_core_global_entries; + + while (cglobals->name) { + GV *gv = gv_fetchpv(cglobals->core_name, TRUE, SVt_PVCV); +#ifdef MUTABLE_CV + GvCV_set(gv, + MUTABLE_CV(SvREFCNT_inc(get_cv(cglobals->sub_name, TRUE)))); +#else + GvCV_set(gv, + (CV*)(SvREFCNT_inc(get_cv(cglobals->sub_name, TRUE)))); +#endif + GvIMPORTED_CV_on(gv); + cglobals++; + } + + newXS("ModPerl::Util::exit", XS_ModPerl__Util_exit, __FILE__); +} + +static void modperl_perl_ids_get(modperl_perl_ids_t *ids) +{ + ids->pid = (I32)getpid(); +#ifdef MP_MAINTAIN_PPID + ids->ppid = (I32)getppid(); +#endif +#ifndef WIN32 + ids->uid = getuid(); + ids->euid = geteuid(); + ids->gid = getgid(); + ids->egid = getegid(); + + MP_TRACE_r(MP_FUNC, + "pid=%d, " +#ifdef MP_MAINTAIN_PPID + "ppid=%d, " +#endif + "uid=%" Uid_t_f ", euid=%" Uid_t_f ", " + "gid=%" Gid_t_f ", egid=%" Gid_t_f, + (int)ids->pid, +#ifdef MP_MAINTAIN_PPID + (int)ids->ppid, +#endif + ids->uid, ids->euid, + ids->gid, ids->egid); +#endif /* #ifndef WIN32 */ +} + +static void modperl_perl_init_ids(pTHX_ modperl_perl_ids_t *ids) +{ + sv_setiv(GvSV(gv_fetchpv("$", TRUE, SVt_PV)), ids->pid); + +#if !MP_PERL_VERSION_AT_LEAST(5, 16, 0) +#ifndef WIN32 + PL_uid = ids->uid; + PL_euid = ids->euid; + PL_gid = ids->gid; + PL_egid = ids->egid; +#endif +#ifdef MP_MAINTAIN_PPID + PL_ppid = ids->ppid; +#endif +#endif +} + + +#ifdef USE_ITHREADS + +static apr_status_t modperl_perl_init_ids_mip(pTHX_ modperl_interp_pool_t *mip, + void *data) +{ + modperl_perl_init_ids(aTHX_ (modperl_perl_ids_t *)data); + return APR_SUCCESS; +} + +#endif /* USE_ITHREADS */ + +void modperl_perl_init_ids_server(server_rec *s) +{ + modperl_perl_ids_t ids; + modperl_perl_ids_get(&ids); +#ifdef USE_ITHREADS + modperl_interp_mip_walk_servers(NULL, s, + modperl_perl_init_ids_mip, + (void*)&ids); +#else + modperl_perl_init_ids(aTHX_ &ids); +#endif +} + +void modperl_perl_destruct(PerlInterpreter *perl) +{ + char **orig_environ = NULL; + PTR_TBL_t *module_commands; + dTHXa(perl); + + PERL_SET_CONTEXT(perl); + + modperl_perl_call_endav(aTHX); + + PL_perl_destruct_level = modperl_perl_destruct_level(); + +#ifdef USE_ENVIRON_ARRAY + /* XXX: otherwise Perl may try to free() environ multiple times + * but it wasn't Perl that modified environ + * at least, not if modperl is doing things right + * this is a bug in Perl. + */ +# ifdef WIN32 + /* + * PL_origenviron = environ; doesn't work under win32 service. + * we pull a different stunt here that has the same effect of + * tricking perl into _not_ freeing the real 'environ' array. + * instead temporarily swap with a dummy array we malloc + * here which is ok to let perl free. + */ + orig_environ = environ; + environ = safemalloc(2 * sizeof(char *)); + environ[0] = NULL; +# else + PL_origenviron = environ; +# endif +#endif + + { + dTHXa(perl); + + if ((module_commands = modperl_module_config_table_get(aTHX_ FALSE))) { + modperl_svptr_table_destroy(aTHX_ module_commands); + } + } + + modperl_env_unload(aTHX); + + perl_destruct(perl); + + /* XXX: big bug in 5.6.1 fixed in 5.7.2+ + * XXX: try to find a workaround for 5.6.1 + */ +#if defined(WIN32) && !defined(CLONEf_CLONE_HOST) +# define MP_NO_PERL_FREE +#endif + +#ifndef MP_NO_PERL_FREE + perl_free(perl); +#endif + +#ifdef USE_ENVIRON_ARRAY + if (orig_environ) { + environ = orig_environ; + } +#endif +} + +void modperl_perl_call_endav(pTHX) +{ + if (PL_endav) { + modperl_perl_call_list(aTHX_ PL_endav, "END"); + } +} + +#if !(MP_PERL_VERSION_AT_MOST(5, 8, 0)) && \ + (defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)) +#define MP_NEED_HASH_SEED_FIXUP +#endif + +#ifdef MP_NEED_HASH_SEED_FIXUP +static UV MP_init_hash_seed = 0; +static bool MP_init_hash_seed_set = FALSE; +#endif + +/* see modperl_hash_seed_set() */ +void modperl_hash_seed_init(apr_pool_t *p) +{ +#ifdef MP_NEED_HASH_SEED_FIXUP + char *s; + /* check if there is a specific hash seed passed via the env var + * and if that's the case -- use it */ + apr_status_t rv = apr_env_get(&s, "PERL_HASH_SEED", p); + if (rv == APR_SUCCESS) { + if (s) { + while (isSPACE(*s)) s++; + } + if (s && isDIGIT(*s)) { + MP_init_hash_seed = (UV)Atol(s); /* XXX: Atoul()? */ + MP_init_hash_seed_set = TRUE; + } + } + + /* calculate our own random hash seed */ + if (!MP_init_hash_seed_set) { + apr_uuid_t *uuid = (apr_uuid_t *)apr_palloc(p, sizeof(apr_uuid_t)); + char buf[APR_UUID_FORMATTED_LENGTH + 1]; + int i; + + apr_initialize(); + apr_uuid_get(uuid); + apr_uuid_format(buf, uuid); + /* fprintf(stderr, "UUID: %s\n", buf); */ + + /* XXX: need a better alg to convert uuid string into a seed */ + for (i=0; buf[i]; i++){ + MP_init_hash_seed += (UV)(i+1)*(buf[i]+MP_init_hash_seed); + } + + MP_init_hash_seed_set = TRUE; + } +#endif +} + +/* before 5.8.1, perl was using HASH_SEED=0, starting from 5.8.1 + * it randomizes if perl was compiled with ccflags -DUSE_HASH_SEED + * or -DUSE_HASH_SEED_EXPLICIT, in which case we need to tell perl + * to use the same seed everywhere */ +void modperl_hash_seed_set(pTHX) +{ +#ifdef MP_NEED_HASH_SEED_FIXUP + if (MP_init_hash_seed_set) { +#if MP_PERL_VERSION_AT_LEAST(5, 17, 6) + memcpy(PL_hash_seed, &MP_init_hash_seed, + sizeof(PL_hash_seed) > sizeof(MP_init_hash_seed) ? + sizeof(MP_init_hash_seed) : sizeof(PL_hash_seed)); + PL_hash_seed_set = MP_init_hash_seed_set; +#elif MP_PERL_VERSION_AT_LEAST(5, 8, 2) + PL_rehash_seed = MP_init_hash_seed; + PL_rehash_seed_set = MP_init_hash_seed_set; +#else + PL_hash_seed = MP_init_hash_seed; + PL_hash_seed_set = MP_init_hash_seed_set; +#endif + } +#endif +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_perl.h b/2_0_13/src/modules/perl/modperl_perl.h new file mode 100644 index 0000000..d91ab5f --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_perl.h
@@ -0,0 +1,71 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_PERL_H +#define MODPERL_PERL_H + +/* starting from 5.8.1 perl caches ppids, so we need to maintain our + * own. some distros fetch fake 5.8.0 with changes from 5.8.1, so we + * need to do that for those fake 5.8.0 as well. real 5.8.0 doesn't + * have THREADS_HAVE_PIDS defined. + */ +#if MP_PERL_VERSION_AT_LEAST(5, 8, 0) && THREADS_HAVE_PIDS +#define MP_MAINTAIN_PPID +#endif + +typedef struct { + I32 pid; + Uid_t uid, euid; + Gid_t gid, egid; +#ifdef MP_MAINTAIN_PPID + Uid_t ppid; +#endif +} modperl_perl_ids_t; + +void modperl_perl_core_global_init(pTHX); + +void modperl_perl_init_ids_server(server_rec *s); + +void modperl_perl_destruct(PerlInterpreter *perl); + +void modperl_perl_call_endav(pTHX); + +void modperl_hash_seed_init(apr_pool_t *p); + +void modperl_hash_seed_set(pTHX); + +#ifndef GvCV_set +# define GvCV_set(gv, cv) (GvCV(gv)=(cv)) +#endif +#ifndef GvGP_set +# define GvGP_set(gv, gp) (GvGP(gv)=(gp)) +#endif + +#ifndef Newx +# define Newx(v,n,t) New(0,v,n,t) +#endif +#ifndef Newxz +# define Newxz(v,n,t) Newz(0,v,n,t) +#endif + +#endif /* MODPERL_PERL_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_perl_global.c b/2_0_13/src/modules/perl/modperl_perl_global.c new file mode 100644 index 0000000..f52e42c --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_perl_global.c
@@ -0,0 +1,503 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* XXX: PL_modglobal thingers might be useful elsewhere */ + +#define MP_MODGLOBAL_ENT(key) \ + {key, "ModPerl::" key, MP_SSTRLEN("ModPerl::") + MP_SSTRLEN(key), 0} + +static modperl_modglobal_key_t MP_modglobal_keys[] = { + MP_MODGLOBAL_ENT("END"), + MP_MODGLOBAL_ENT("ANONSUB"), + { NULL }, +}; + +void modperl_modglobal_hash_keys(pTHX) +{ + modperl_modglobal_key_t *gkey = MP_modglobal_keys; + + while (gkey->name) { + PERL_HASH(gkey->hash, gkey->val, gkey->len); + gkey++; + } +} + +modperl_modglobal_key_t *modperl_modglobal_lookup(pTHX_ const char *name) +{ + modperl_modglobal_key_t *gkey = MP_modglobal_keys; + + while (gkey->name) { + if (strEQ(gkey->name, name)) { + return gkey; + } + gkey++; + } + + return NULL; +} + +static void modperl_perl_global_init(pTHX_ modperl_perl_globals_t *globals) +{ + globals->env.gv = PL_envgv; + globals->inc.gv = PL_incgv; + globals->defout.gv = PL_defoutgv; + globals->rs.sv = &PL_rs; + globals->end.av = &PL_endav; + globals->end.key = MP_MODGLOBAL_END; +} + +/* + * if (exists $PL_modglobal{$key}{$package}) { + * return $PL_modglobal{$key}{$package}; + * } + * elsif ($autovivify) { + * return $PL_modglobal{$key}{$package} = []; + * } + * else { + * return (AV *)NULL; # a null pointer in C of course :) + * } + */ +static AV *modperl_perl_global_avcv_fetch(pTHX_ modperl_modglobal_key_t *gkey, + const char *package, I32 packlen, + I32 autovivify) +{ + HE *he = MP_MODGLOBAL_FETCH(gkey); + HV *hv; + + if (!(he && (hv = (HV*)HeVAL(he)))) { + if (autovivify) { + hv = MP_MODGLOBAL_STORE_HV(gkey); + } + else { + return (AV *)NULL; + } + } + + if ((he = hv_fetch_he(hv, (char *)package, packlen, 0))) { + return (AV*)HeVAL(he); + } + else { + if (autovivify) { + return (AV*)*hv_store(hv, package, packlen, (SV*)newAV(), 0); + } + else { + return (AV *)NULL; + } + } +} + +/* autovivify $PL_modglobal{$key}{$package} if it doesn't exist yet, + * so that in modperl_perl_global_avcv_set we will know whether to + * store blocks in it or keep them in the original list. + * + * For example in the case of END blocks, if + * $PL_modglobal{END}{$package} exists, modperl_perl_global_avcv_set + * will push newly encountered END blocks to it, otherwise it'll keep + * them in PL_endav. + */ +void modperl_perl_global_avcv_register(pTHX_ modperl_modglobal_key_t *gkey, + const char *package, I32 packlen) +{ + AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey, + package, packlen, TRUE); + + MP_TRACE_g(MP_FUNC, "register PL_modglobal %s::%s (has %d entries)", + package, (char*)gkey->name, av ? 1+av_len(av) : 0); +} + +/* if (exists $PL_modglobal{$key}{$package}) { + * for my $cv (@{ $PL_modglobal{$key}{$package} }) { + * $cv->(); + * } + * } + */ +void modperl_perl_global_avcv_call(pTHX_ modperl_modglobal_key_t *gkey, + const char *package, I32 packlen) +{ + AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey, package, packlen, + FALSE); + + MP_TRACE_g(MP_FUNC, "run PL_modglobal %s::%s (has %d entries)", + package, (char*)gkey->name, av ? 1+av_len(av) : 0); + + if (av) { + modperl_perl_call_list(aTHX_ av, gkey->name); + } +} + + +/* if (exists $PL_modglobal{$key}{$package}) { + * @{ $PL_modglobal{$key}{$package} } = (); + * } + */ +void modperl_perl_global_avcv_clear(pTHX_ modperl_modglobal_key_t *gkey, + const char *package, I32 packlen) +{ + AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey, + package, packlen, FALSE); + + MP_TRACE_g(MP_FUNC, "clear PL_modglobal %s::%s (has %d entries)", + package, (char*)gkey->name, av ? 1+av_len(av) : 0); + + if (av) { + av_clear(av); + } +} + +static int modperl_perl_global_avcv_set(pTHX_ SV *sv, MAGIC *mg) +{ + AV *mav, *av = (AV*)sv; + const char *package = HvNAME(PL_curstash); + I32 packlen = strlen(package); + modperl_modglobal_key_t *gkey = + (modperl_modglobal_key_t *)mg->mg_ptr; + + /* the argument sv, is the original list perl was operating on. + * (e.g. PL_endav). So now if we find that we have package/cv name + * (e.g. Foo/END) registered for set-aside, we remove the cv that + * was just unshifted in and push it into + * $PL_modglobal{$key}{$package}. Otherwise we do nothing, which + * keeps the unshifted cv (e.g. END block) in its original av + * (e.g. PL_endav) + */ + + mav = modperl_perl_global_avcv_fetch(aTHX_ gkey, package, packlen, FALSE); + + if (!mav) { + MP_TRACE_g(MP_FUNC, "%s::%s is not going to PL_modglobal", + package, (char*)gkey->name); + /* keep it in the tied list (e.g. PL_endav) */ + return 1; + } + + MP_TRACE_g(MP_FUNC, "%s::%s is going into PL_modglobal", + package, (char*)gkey->name); + + sv = av_shift(av); + + /* push @{ $PL_modglobal{$key}{$package} }, $cv */ + av_store(mav, AvFILLp(mav)+1, sv); + + /* print scalar @{ $PL_modglobal{$key}{$package} } */ + MP_TRACE_g(MP_FUNC, "%s::%s av now has %d entries", + package, (char*)gkey->name, 1+av_len(mav)); + + return 1; +} + +static MGVTBL modperl_vtbl_global_avcv_t = { + 0, + modperl_perl_global_avcv_set, + 0, 0, 0, +}; + +static void modperl_perl_global_avcv_tie(pTHX_ modperl_modglobal_key_e key, + AV *av) +{ + if (!SvMAGIC((SV*)av)) { + MAGIC *mg; + Newxz(mg, 1, MAGIC); + mg->mg_virtual = &modperl_vtbl_global_avcv_t; + mg->mg_ptr = (char *)&MP_modglobal_keys[key]; + mg->mg_len = -1; /* prevent free() of mg->mg_ptr */ + SvMAGIC((SV*)av) = mg; + } + + SvSMAGICAL_on((SV*)av); +} + +static void modperl_perl_global_avcv_untie(pTHX_ AV *av) +{ + SvSMAGICAL_off((SV*)av); +} + +static void +modperl_perl_global_avcv_save(pTHX_ modperl_perl_global_avcv_t *avcv) +{ + if (!*avcv->av) { + *avcv->av = newAV(); + } + + modperl_perl_global_avcv_tie(aTHX_ avcv->key, *avcv->av); +} + +static void +modperl_perl_global_avcv_restore(pTHX_ modperl_perl_global_avcv_t *avcv) +{ + modperl_perl_global_avcv_untie(aTHX_ *avcv->av); +} + +/* + * newHVhv is not good enough since it does not copy magic. + * XXX: 5.8.0+ newHVhv has some code thats faster than hv_iternext + */ +static HV *copyENV(pTHX_ HV *ohv) +{ + HE *entry, *hv_eiter; + I32 hv_riter; + register HV *hv; + STRLEN hv_max = HvMAX(ohv); + STRLEN hv_fill = HvFILL(ohv); + + hv = newHV(); + while (hv_max && hv_max + 1 >= hv_fill * 2) { + hv_max = hv_max / 2; /* Is always 2^n-1 */ + } + + HvMAX(hv) = hv_max; + + if (!hv_fill) { + return hv; + } + + hv_riter = HvRITER(ohv); /* current root of iterator */ + hv_eiter = HvEITER(ohv); /* current entry of iterator */ + + hv_iterinit(ohv); + while ((entry = hv_iternext(ohv))) { + SV *sv = newSVsv(HeVAL(entry)); + modperl_envelem_tie(sv, HeKEY(entry), HeKLEN(entry)); + (void)hv_store(hv, HeKEY(entry), HeKLEN(entry), + sv, HeHASH(entry)); + } + + HvRITER(ohv) = hv_riter; + HvEITER(ohv) = hv_eiter; + + hv_magic(hv, (GV *)NULL, 'E'); + + TAINT_NOT; + + return hv; +} + +static void +modperl_perl_global_gvhv_save(pTHX_ modperl_perl_global_gvhv_t *gvhv) +{ + HV *hv = GvHV(gvhv->gv); +#if 0 + U32 mg_flags; + MAGIC *mg = SvMAGIC(hv); + + /* + * there should only be a small number of entries in %ENV + * at this point: modperl_env.c:modperl_env_const_vars[], + * PerlPassEnv and top-level PerlSetEnv + * XXX: still; could have have something faster than newHVhv() + * especially if we add another GVHV to the globals table that + * might have more entries + */ + + /* makes newHVhv() faster in bleedperl */ + MP_magical_untie(hv, mg_flags); + + gvhv->tmphv = newHVhv(hv); + TAINT_NOT; + + /* reapply magic flags */ + MP_magical_tie(hv, mg_flags); + MP_magical_tie(gvhv->tmphv, mg_flags); + + if (mg && mg->mg_type && !SvMAGIC(gvhv->tmphv)) { + /* propagate SvMAGIC(hv) to SvMAGIC(gvhv->tmphv) */ + /* XXX: maybe newHVhv should do this? */ + hv_magic(gvhv->tmphv, (GV *)NULL, mg->mg_type); + } +#else + gvhv->tmphv = copyENV(aTHX_ hv); +#endif + + gvhv->orighv = hv; + GvHV(gvhv->gv) = gvhv->tmphv; +} + +static void +modperl_perl_global_gvhv_restore(pTHX_ modperl_perl_global_gvhv_t *gvhv) +{ + U32 mg_flags; + + GvHV(gvhv->gv) = gvhv->orighv; + + /* loose magic for hv_clear() + * e.g. for %ENV don't want to clear environ array + */ + MP_magical_untie(gvhv->tmphv, mg_flags); + SvREFCNT_dec(gvhv->tmphv); + + /* avoiding -Wall warning */ + mg_flags = mg_flags; +} + +static void +modperl_perl_global_gvav_save(pTHX_ modperl_perl_global_gvav_t *gvav) +{ + gvav->origav = GvAV(gvav->gv); + gvav->tmpav = newAV(); + modperl_perl_av_push_elts_ref(aTHX_ gvav->tmpav, gvav->origav); + GvAV(gvav->gv) = gvav->tmpav; +} + +static void +modperl_perl_global_gvav_restore(pTHX_ modperl_perl_global_gvav_t *gvav) +{ + GvAV(gvav->gv) = gvav->origav; + SvREFCNT_dec(gvav->tmpav); +} + +static void +modperl_perl_global_gvio_save(pTHX_ modperl_perl_global_gvio_t *gvio) +{ + gvio->flags = IoFLAGS(GvIOp(gvio->gv)); +} + +static void +modperl_perl_global_gvio_restore(pTHX_ modperl_perl_global_gvio_t *gvio) +{ + IoFLAGS(GvIOp(gvio->gv)) = gvio->flags; +} + +static void +modperl_perl_global_svpv_save(pTHX_ modperl_perl_global_svpv_t *svpv) +{ + svpv->cur = SvCUR(*svpv->sv); + strncpy(svpv->pv, SvPVX(*svpv->sv), sizeof(svpv->pv)); +} + +static void +modperl_perl_global_svpv_restore(pTHX_ modperl_perl_global_svpv_t *svpv) +{ + sv_setpvn(*svpv->sv, svpv->pv, svpv->cur); +} + +typedef enum { + MP_GLOBAL_AVCV, + MP_GLOBAL_GVHV, + MP_GLOBAL_GVAV, + MP_GLOBAL_GVIO, + MP_GLOBAL_SVPV +} modperl_perl_global_types_e; + +typedef struct { + char *name; + int offset; + modperl_perl_global_types_e type; +} modperl_perl_global_entry_t; + +#define MP_GLOBAL_OFFSET(m) \ + STRUCT_OFFSET(modperl_perl_globals_t, m) + +static modperl_perl_global_entry_t MP_perl_global_entries[] = { + {"END", MP_GLOBAL_OFFSET(end), MP_GLOBAL_AVCV}, /* END */ + {"ENV", MP_GLOBAL_OFFSET(env), MP_GLOBAL_GVHV}, /* %ENV */ + {"INC", MP_GLOBAL_OFFSET(inc), MP_GLOBAL_GVAV}, /* @INC */ + {"STDOUT", MP_GLOBAL_OFFSET(defout), MP_GLOBAL_GVIO}, /* $| */ + {"/", MP_GLOBAL_OFFSET(rs), MP_GLOBAL_SVPV}, /* $/ */ + {NULL} +}; + +#define MP_PERL_GLOBAL_SAVE(type, ptr) \ + modperl_perl_global_##type##_save( \ + aTHX_ (modperl_perl_global_##type##_t *)&(*ptr)) + +#define MP_PERL_GLOBAL_RESTORE(type, ptr) \ + modperl_perl_global_##type##_restore( \ + aTHX_ (modperl_perl_global_##type##_t *)&(*ptr)) + +#define MP_dGLOBAL_PTR(globals, entries) \ + apr_uint64_t **ptr = (apr_uint64_t **) \ + ((char *)globals + (int)(long)entries->offset) + +static void modperl_perl_global_save(pTHX_ modperl_perl_globals_t *globals, + modperl_perl_global_entry_t *entries) +{ + modperl_perl_global_init(aTHX_ globals); + + while (entries->name) { + MP_dGLOBAL_PTR(globals, entries); + + switch (entries->type) { + case MP_GLOBAL_AVCV: + MP_PERL_GLOBAL_SAVE(avcv, ptr); + break; + case MP_GLOBAL_GVHV: + MP_PERL_GLOBAL_SAVE(gvhv, ptr); + break; + case MP_GLOBAL_GVAV: + MP_PERL_GLOBAL_SAVE(gvav, ptr); + break; + case MP_GLOBAL_GVIO: + MP_PERL_GLOBAL_SAVE(gvio, ptr); + break; + case MP_GLOBAL_SVPV: + MP_PERL_GLOBAL_SAVE(svpv, ptr); + break; + } + + entries++; + } +} + +static void modperl_perl_global_restore(pTHX_ modperl_perl_globals_t *globals, + modperl_perl_global_entry_t *entries) +{ + while (entries->name) { + MP_dGLOBAL_PTR(globals, entries); + + switch (entries->type) { + case MP_GLOBAL_AVCV: + MP_PERL_GLOBAL_RESTORE(avcv, ptr); + break; + case MP_GLOBAL_GVHV: + MP_PERL_GLOBAL_RESTORE(gvhv, ptr); + break; + case MP_GLOBAL_GVAV: + MP_PERL_GLOBAL_RESTORE(gvav, ptr); + break; + case MP_GLOBAL_GVIO: + MP_PERL_GLOBAL_RESTORE(gvio, ptr); + break; + case MP_GLOBAL_SVPV: + MP_PERL_GLOBAL_RESTORE(svpv, ptr); + break; + } + + entries++; + } +} + +void modperl_perl_global_request_save(pTHX_ request_rec *r) +{ + MP_dRCFG; + modperl_perl_global_save(aTHX_ &rcfg->perl_globals, + MP_perl_global_entries); +} + +void modperl_perl_global_request_restore(pTHX_ request_rec *r) +{ + MP_dRCFG; + modperl_perl_global_restore(aTHX_ &rcfg->perl_globals, + MP_perl_global_entries); + +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_perl_global.h b/2_0_13/src/modules/perl/modperl_perl_global.h new file mode 100644 index 0000000..5f1fc44 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_perl_global.h
@@ -0,0 +1,98 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_PERL_GLOBAL_H +#define MODPERL_PERL_GLOBAL_H + +#define MP_MODGLOBAL_FETCH(gkey) \ + hv_fetch_he(PL_modglobal, (char *)gkey->val, gkey->len, gkey->hash) + +#define MP_MODGLOBAL_STORE_HV(gkey) \ + (HV*)*hv_store(PL_modglobal, gkey->val, gkey->len, \ + (SV*)newHV(), gkey->hash) + +typedef struct { + const char *name; + const char *val; + I32 len; + U32 hash; +} modperl_modglobal_key_t; + +typedef enum { + MP_MODGLOBAL_END +} modperl_modglobal_key_e; + +typedef struct { + AV **av; + modperl_modglobal_key_e key; +} modperl_perl_global_avcv_t; + +typedef struct { + GV *gv; + AV *tmpav; + AV *origav; +} modperl_perl_global_gvav_t; + +typedef struct { + GV *gv; + HV *tmphv; + HV *orighv; +} modperl_perl_global_gvhv_t; + +typedef struct { + GV *gv; + char flags; +} modperl_perl_global_gvio_t; + +typedef struct { + SV **sv; + char pv[256]; /* XXX: only need enough for $/ at the moment */ + I32 cur; +} modperl_perl_global_svpv_t; + +typedef struct { + modperl_perl_global_avcv_t end; + modperl_perl_global_gvhv_t env; + modperl_perl_global_gvav_t inc; + modperl_perl_global_gvio_t defout; + modperl_perl_global_svpv_t rs; +} modperl_perl_globals_t; + +void modperl_modglobal_hash_keys(pTHX); + +modperl_modglobal_key_t *modperl_modglobal_lookup(pTHX_ const char *name); + +void modperl_perl_global_request_save(pTHX_ request_rec *r); + +void modperl_perl_global_request_restore(pTHX_ request_rec *r); + +void modperl_perl_global_avcv_register(pTHX_ modperl_modglobal_key_t *gkey, + const char *package, I32 packlen); + +void modperl_perl_global_avcv_call(pTHX_ modperl_modglobal_key_t *gkey, + const char *package, I32 packlen); + +void modperl_perl_global_avcv_clear(pTHX_ modperl_modglobal_key_t *gkey, + const char *package, I32 packlen); + +#endif + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_perl_includes.h b/2_0_13/src/modules/perl/modperl_perl_includes.h new file mode 100644 index 0000000..3b85b49 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_perl_includes.h
@@ -0,0 +1,148 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_PERL_INCLUDES_H +#define MODPERL_PERL_INCLUDES_H + +/* header files for Perl */ + +#ifndef PERL_NO_GET_CONTEXT +# define PERL_NO_GET_CONTEXT +#endif + +#define PERLIO_NOT_STDIO 0 + +#include "config.h" + +/* + * sizeof(struct PerlInterpreter) changes #ifdef USE_LARGE_FILES + * apache-2.0 cannot be compiled with lfs because of sendfile.h + * the PERL_CORE optimization is a no-no in this case + */ +#if defined(USE_ITHREADS) && !defined(USE_LARGE_FILES) +# define PERL_CORE +#endif + +#ifdef MP_SOURCE_SCAN +/* XXX: C::Scan does not properly remove __attribute__ within + * function prototypes; so we just rip them all out via cpp + */ +# undef __attribute__ +# define __attribute__(arg) + +# ifdef MP_SOURCE_SCAN_NEED_ITHREADS +/* just need to have pTHX_ defined for proper prototypes */ +# define USE_ITHREADS +# endif +#endif + +#ifdef WIN32 +# define uid_t perl_uid_t +# define gid_t perl_gid_t +# ifdef exit +# undef exit +# endif +#endif + +/* needed starting from 5.8.2 to access the PERL_HASH_INTERNAL macro + * in hv.h. we use it in modperl_util.c */ +#define PERL_HASH_INTERNAL_ACCESS + +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#if defined(WIN32) && defined(USE_LARGE_FILES) +# ifdef malloc +# undef malloc +# endif +# ifdef free +# undef free +# endif +#endif + +#include "modperl_perl_unembed.h" + +/* avoiding -Wall warning */ + +#undef dNOOP +#define dNOOP extern int __attribute__ ((unused)) Perl___notused___modperl + +#ifndef G_METHOD +# define G_METHOD 64 +#endif + +#ifndef PERL_MAGIC_tied +# define PERL_MAGIC_tied 'P' +#endif + +#ifndef PERL_MAGIC_tiedscalar +# define PERL_MAGIC_tiedscalar 'q' +#endif + +#ifndef PERL_MAGIC_ext +# define PERL_MAGIC_ext '~' +#endif + +#if defined(__APPLE__) && !defined(PERL_CORE) && !defined(environ) +# include <crt_externs.h> +# define environ (*_NSGetEnviron()) +#endif + +/* sv_copypv was added in perl 5.7.3 */ +#ifndef sv_copypv +# define sv_copypv(dsv, ssv) \ + STMT_START { \ + STRLEN len; \ + char *s; \ + s = SvPV(ssv, len); \ + sv_setpvn(dsv, s, len); \ + if (SvUTF8(ssv)) { \ + SvUTF8_on(dsv); \ + } \ + else { \ + SvUTF8_off(dsv); \ + } \ + } STMT_END +#endif + + +/* perl bug workaround: with USE_ITHREADS perl leaks pthread_key_t on + * every reload of libperl.{a,so} (it's allocated on the very first + * perl_alloc() and never freed). This becomes a problem on apache + * restart: if the OS limit is 1024, 1024 restarts later things will + * start crashing */ +/* XXX: once and if it's fixed in perl, we need to disable it for the + * versions that have it fixed, otherwise it'll crash because it'll be + * freed twice */ +#ifdef USE_ITHREADS +#define MP_PERL_FREE_THREAD_KEY_WORKAROUND \ + if (PL_curinterp) { \ + FREE_THREAD_KEY; \ + PL_curinterp = NULL; \ + } +#else +#define MP_PERL_FREE_THREAD_KEY_WORKAROUND +#endif + +#endif /* MODPERL_PERL_INCLUDES_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_perl_pp.c b/2_0_13/src/modules/perl/modperl_perl_pp.c new file mode 100644 index 0000000..881d99e --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_perl_pp.c
@@ -0,0 +1,122 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +static enum opcode MP_pp_map[] = { +#ifdef MP_REFGEN_FIXUP + OP_SREFGEN, +#endif + OP_REQUIRE +}; + +typedef OP * (*modperl_pp_t)(pTHX); + +static modperl_pp_t MP_PERL_ppaddr[MP_OP_max]; + +#ifdef MP_REFGEN_FIXUP + +/* + * nasty workaround for bug fixed in bleedperl (11536 + 11553) + * XXX: when 5.8.0 is released + stable, we will require 5.8.0 + * if ithreads are enabled. + */ + +static OP *modperl_pp_srefgen(pTHX) +{ + dSP; + OP *o; + SV *sv = *SP; + + if (SvPADTMP(sv) && IS_PADGV(sv)) { + /* prevent S_refto from making a copy of the GV, + * tricking it to SvREFCNT_inc and point to this one instead. + */ + SvPADTMP_off(sv); + } + else { + sv = (SV *)NULL; + } + + /* o = Perl_pp_srefgen(aTHX) */ + o = MP_PERL_ppaddr[MP_OP_SREFGEN](aTHX); + + if (sv) { + /* restore original flags */ + SvPADTMP_on(sv); + } + + return o; +} + +#endif /* MP_REFGEN_FIXUP */ + +static OP *modperl_pp_require(pTHX) +{ + /* nothing yet */ + return MP_PERL_ppaddr[MP_OP_REQUIRE](aTHX); +} + +static modperl_pp_t MP_ppaddr[] = { +#ifdef MP_REFGEN_FIXUP + modperl_pp_srefgen, +#endif + modperl_pp_require +}; + +void modperl_perl_pp_set(modperl_perl_opcode_e idx) +{ + int pl_idx = MP_pp_map[idx]; + + /* save original */ + MP_PERL_ppaddr[idx] = PL_ppaddr[pl_idx]; + + /* replace with our own */ + PL_ppaddr[pl_idx] = MP_ppaddr[idx]; +} + +void modperl_perl_pp_set_all(void) +{ + int i; + + for (i=0; i<MP_OP_max; i++) { + modperl_perl_pp_set(i); + } +} + +void modperl_perl_pp_unset(modperl_perl_opcode_e idx) +{ + int pl_idx = MP_pp_map[idx]; + + /* restore original */ + PL_ppaddr[pl_idx] = MP_PERL_ppaddr[idx]; +} + +void modperl_perl_pp_unset_all(void) +{ + int i; + + for (i=0; i<MP_OP_max; i++) { + modperl_perl_pp_unset(i); + } +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_perl_pp.h b/2_0_13/src/modules/perl/modperl_perl_pp.h new file mode 100644 index 0000000..2386c3e --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_perl_pp.h
@@ -0,0 +1,50 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_PERL_PP_H +#define MODPERL_PERL_PP_H + +#define MP_PERL_BRANCH(r, v) \ + (PERL_REVISION == r && PERL_VERSION == v) + +#if defined(USE_ITHREADS) && MP_PERL_BRANCH(5, 6) +# define MP_REFGEN_FIXUP +#endif + +typedef enum { +#ifdef MP_REFGEN_FIXUP + MP_OP_SREFGEN, +#endif + MP_OP_REQUIRE, + MP_OP_max +} modperl_perl_opcode_e; + +void modperl_perl_pp_set(modperl_perl_opcode_e idx); + +void modperl_perl_pp_set_all(void); + +void modperl_perl_pp_unset(modperl_perl_opcode_e idx); + +void modperl_perl_pp_unset_all(void); + +#endif /* MODPERL_PERL_PP_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_perl_unembed.h b/2_0_13/src/modules/perl/modperl_perl_unembed.h new file mode 100644 index 0000000..4db14a5 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_perl_unembed.h
@@ -0,0 +1,52 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_PERL_UNEMBED_H +#define MODPERL_PERL_UNEMBED_H + +#ifdef PERL_CORE +# ifndef croak +# define croak Perl_croak_nocontext +# endif +#endif + +/* avoiding namespace collisions */ + +/* from XSUB.h */ +/* mod_perl.c calls exit() in a few places */ +#undef exit +/* modperl_tipool.c references abort() */ +#undef abort +/* these three clash with apr bucket structure member names */ +#undef link +#undef read +#undef free +/* modperl_perl.c */ +#ifdef WIN32 +# undef getpid +# undef getenv +#endif + +#undef list + +#endif /* MODPERL_PERL_UNEMBED_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_svptr_table.c b/2_0_13/src/modules/perl/modperl_svptr_table.c new file mode 100644 index 0000000..e63a3b8 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_svptr_table.c
@@ -0,0 +1,312 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* + * modperl_svptr_table api is an add-on to the Perl ptr_table_ api. + * we use a PTR_TBL_t to map config structures (e.g. from parsed + * httpd.conf or .htaccess), where each interpreter needs to have its + * own copy of the Perl SV object. we do not use an HV* for this, because + * the HV keys must be SVs with a string value, too much overhead. + * we do not use an apr_hash_t because they only have the lifetime of + * the pool used to create them. which may or may not be the same lifetime + * of the objects we need to lookup. + */ + +#ifdef USE_ITHREADS + +#if MP_PERL_BRANCH(5, 6) +# define my_sv_dup(s, p) SvREFCNT_inc(sv_dup(s)) + +typedef struct { + AV *stashes; + UV flags; + PerlInterpreter *proto_perl; +} CLONE_PARAMS; + +#else +# ifdef sv_dup_inc +# define my_sv_dup(s, p) sv_dup_inc(s, p) +# else +# define my_sv_dup(s, p) SvREFCNT_inc(sv_dup(s, p)) +# endif +#endif + +/* + * copy a PTR_TBL_t whos PTR_TBL_ENT_t values are SVs. + * the SVs are dup-ed so each interpreter has its own copy. + */ +PTR_TBL_t *modperl_svptr_table_clone(pTHX_ PerlInterpreter *proto_perl, + PTR_TBL_t *source) +{ + UV i; + PTR_TBL_t *tbl; + PTR_TBL_ENT_t **src_ary, **dst_ary; + CLONE_PARAMS parms; + + Newxz(tbl, 1, PTR_TBL_t); + tbl->tbl_max = source->tbl_max; + tbl->tbl_items = source->tbl_items; + Newxz(tbl->tbl_ary, tbl->tbl_max + 1, PTR_TBL_ENT_t *); + + dst_ary = tbl->tbl_ary; + src_ary = source->tbl_ary; + + Zero(&parms, 1, CLONE_PARAMS); + parms.flags = 0; + parms.stashes = newAV(); + + for (i=0; i < source->tbl_max; i++, dst_ary++, src_ary++) { + PTR_TBL_ENT_t *src_ent, *dst_ent=NULL; + + if (!*src_ary) { + continue; + } + + for (src_ent = *src_ary; + src_ent; + src_ent = src_ent->next) + { + if (dst_ent == NULL) { + Newxz(dst_ent, 1, PTR_TBL_ENT_t); + *dst_ary = dst_ent; + } + else { + Newxz(dst_ent->next, 1, PTR_TBL_ENT_t); + dst_ent = dst_ent->next; + } + + /* key is just a pointer we do not modify, no need to copy */ + dst_ent->oldval = src_ent->oldval; + + dst_ent->newval = my_sv_dup((SV*)src_ent->newval, &parms); + } + } + + SvREFCNT_dec(parms.stashes); + + return tbl; +} + +#endif + +/* + * need to free the SV values in addition to ptr_table_free + */ +void modperl_svptr_table_destroy(pTHX_ PTR_TBL_t *tbl) +{ + UV i; + PTR_TBL_ENT_t **ary = tbl->tbl_ary; + + for (i=0; i < tbl->tbl_max; i++, ary++) { + PTR_TBL_ENT_t *ent; + + if (!*ary) { + continue; + } + + for (ent = *ary; ent; ent = ent->next) { + if (!ent->newval) { + continue; + } + + SvREFCNT_dec((SV*)ent->newval); + ent->newval = NULL; + } + } + + modperl_svptr_table_free(aTHX_ tbl); +} + +/* + * the Perl ptr_table_ api does not provide a function to remove + * an entry from the table. we need to SvREFCNT_dec the SV value + * anyhow. + */ +void modperl_svptr_table_delete(pTHX_ PTR_TBL_t *tbl, void *key) +{ + PTR_TBL_ENT_t *entry, **oentry; + UV hash = PTR2UV(key); + + oentry = &tbl->tbl_ary[hash & tbl->tbl_max]; + entry = *oentry; + + for (; entry; oentry = &entry->next, entry = *oentry) { + if (entry->oldval == key) { + *oentry = entry->next; + SvREFCNT_dec((SV*)entry->newval); + Safefree(entry); + tbl->tbl_items--; + return; + } + } +} + +/* + * XXX: the following are a copy of the Perl 5.8.0 Perl_ptr_table api + * renamed s/Perl_ptr/modperl_svptr/g; + * two reasons: + * these functions do not exist without -DUSE_ITHREADS + * the clear/free functions do not exist in 5.6.x + */ + +/* create a new pointer-mapping table */ + +PTR_TBL_t * +modperl_svptr_table_new(pTHX) +{ + PTR_TBL_t *tbl; + Newxz(tbl, 1, PTR_TBL_t); + tbl->tbl_max = 511; + tbl->tbl_items = 0; + Newxz(tbl->tbl_ary, tbl->tbl_max + 1, PTR_TBL_ENT_t*); + return tbl; +} + +/* map an existing pointer using a table */ + +void * +modperl_svptr_table_fetch(pTHX_ PTR_TBL_t *tbl, void *sv) +{ + PTR_TBL_ENT_t *tblent; + UV hash = PTR2UV(sv); + MP_ASSERT(tbl); + tblent = tbl->tbl_ary[hash & tbl->tbl_max]; + for (; tblent; tblent = tblent->next) { + if (tblent->oldval == sv) + return tblent->newval; + } + return (void*)NULL; +} + +/* add a new entry to a pointer-mapping table */ + +void +modperl_svptr_table_store(pTHX_ PTR_TBL_t *tbl, void *oldv, void *newv) +{ + PTR_TBL_ENT_t *tblent, **otblent; + /* XXX this may be pessimal on platforms where pointers aren't good + * hash values e.g. if they grow faster in the most significant + * bits */ + UV hash = PTR2UV(oldv); + bool i = 1; + + MP_ASSERT(tbl); + otblent = &tbl->tbl_ary[hash & tbl->tbl_max]; + for (tblent = *otblent; tblent; i=0, tblent = tblent->next) { + if (tblent->oldval == oldv) { + tblent->newval = newv; + return; + } + } + Newxz(tblent, 1, PTR_TBL_ENT_t); + tblent->oldval = oldv; + tblent->newval = newv; + tblent->next = *otblent; + *otblent = tblent; + tbl->tbl_items++; + if (i && tbl->tbl_items > tbl->tbl_max) + modperl_svptr_table_split(aTHX_ tbl); +} + +/* double the hash bucket size of an existing ptr table */ + +void +modperl_svptr_table_split(pTHX_ PTR_TBL_t *tbl) +{ + PTR_TBL_ENT_t **ary = tbl->tbl_ary; + UV oldsize = tbl->tbl_max + 1; + UV newsize = oldsize * 2; + UV i; + + Renew(ary, newsize, PTR_TBL_ENT_t*); + Zero(&ary[oldsize], newsize-oldsize, PTR_TBL_ENT_t*); + tbl->tbl_max = --newsize; + tbl->tbl_ary = ary; + for (i=0; i < oldsize; i++, ary++) { + PTR_TBL_ENT_t **curentp, **entp, *ent; + if (!*ary) + continue; + curentp = ary + oldsize; + for (entp = ary, ent = *ary; ent; ent = *entp) { + if ((newsize & PTR2UV(ent->oldval)) != i) { + *entp = ent->next; + ent->next = *curentp; + *curentp = ent; + continue; + } + else + entp = &ent->next; + } + } +} + +/* remove all the entries from a ptr table */ + +void +modperl_svptr_table_clear(pTHX_ PTR_TBL_t *tbl) +{ + register PTR_TBL_ENT_t **array; + register PTR_TBL_ENT_t *entry; + register PTR_TBL_ENT_t *oentry = (PTR_TBL_ENT_t *)NULL; + UV riter = 0; + UV max; + + if (!tbl || !tbl->tbl_items) { + return; + } + + array = tbl->tbl_ary; + entry = array[0]; + max = tbl->tbl_max; + + for (;;) { + if (entry) { + oentry = entry; + entry = entry->next; + Safefree(oentry); + } + if (!entry) { + if (++riter > max) { + break; + } + entry = array[riter]; + } + } + + tbl->tbl_items = 0; +} + +/* clear and free a ptr table */ + +void +modperl_svptr_table_free(pTHX_ PTR_TBL_t *tbl) +{ + if (!tbl) { + return; + } + modperl_svptr_table_clear(aTHX_ tbl); + Safefree(tbl->tbl_ary); + Safefree(tbl); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_svptr_table.h b/2_0_13/src/modules/perl/modperl_svptr_table.h new file mode 100644 index 0000000..673f643 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_svptr_table.h
@@ -0,0 +1,64 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_SVPTR_TABLE_H +#define MODPERL_SVPTR_TABLE_H + +#ifdef USE_ITHREADS + +PTR_TBL_t *modperl_svptr_table_clone(pTHX_ PerlInterpreter *proto_perl, + PTR_TBL_t *source); + +#endif + +void modperl_svptr_table_destroy(pTHX_ PTR_TBL_t *tbl); + +void modperl_svptr_table_delete(pTHX_ PTR_TBL_t *tbl, void *key); + +/* + * XXX: the following are a copy of the Perl 5.8.0 Perl_ptr_table api + * renamed s/Perl_ptr/modperl_svptr/g; + * two reasons: + * these functions do not exist without -DUSE_ITHREADS + * the clear/free functions do not exist in 5.6.x + */ + +PTR_TBL_t * +modperl_svptr_table_new(pTHX); + +void * +modperl_svptr_table_fetch(pTHX_ PTR_TBL_t *tbl, void *sv); + +void +modperl_svptr_table_store(pTHX_ PTR_TBL_t *tbl, void *oldv, void *newv); + +void +modperl_svptr_table_split(pTHX_ PTR_TBL_t *tbl); + +void +modperl_svptr_table_clear(pTHX_ PTR_TBL_t *tbl); + +void +modperl_svptr_table_free(pTHX_ PTR_TBL_t *tbl); + +#endif /* MODPERL_SVPTR_TABLE_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_sys.c b/2_0_13/src/modules/perl/modperl_sys.c new file mode 100644 index 0000000..3ce3cbc --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_sys.c
@@ -0,0 +1,76 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modperl_largefiles.h" +#include "mod_perl.h" + +/* + * Stat_t needs flags in modperl_largefiles.h + */ +int modperl_sys_is_dir(pTHX_ SV *sv) +{ + Stat_t statbuf; + STRLEN n_a; + char *name = SvPV(sv, n_a); + + if (PerlLIO_stat(name, &statbuf) < 0) { + return 0; + } + + return S_ISDIR(statbuf.st_mode); +} + +/* + * Perl does not provide this abstraction. + * APR does, but requires a pool. efforts to expose this area of apr + * failed. so we roll our own. *sigh* + */ +int modperl_sys_dlclose(void *handle) +{ +#if defined(MP_SYS_DL_DLOPEN) +#ifdef I_DLFCN +#include <dlfcn.h> +#else +#include <nlist.h> +#include <link.h> +#endif + return dlclose(handle) == 0; +#elif defined(MP_SYS_DL_DYLD) + return NSUnLinkModule(handle, FALSE); +#elif defined(MP_SYS_DL_HPUX) +#include <dl.h> + shl_unload((shl_t)handle); + return 1; +#elif defined(MP_SYS_DL_WIN32) + return FreeLibrary(handle); +#elif defined(MP_SYS_DL_BEOS) + return unload_add_on(handle) < B_NO_ERROR; +#elif defined(MP_SYS_DL_DLLLOAD) + return dllfree(handle) == 0; +#elif defined(MP_SYS_DL_AIX) + return dlclose(handle) == 0; +#else +#error "modperl_sys_dlclose not defined on this platform" + return 0; +#endif +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_sys.h b/2_0_13/src/modules/perl/modperl_sys.h new file mode 100644 index 0000000..a52763a --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_sys.h
@@ -0,0 +1,37 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_SYS_H +#define MODPERL_SYS_H + +/* + * system specific type stuff. + * hopefully won't be much here since Perl/APR/Apache + * take care of most portablity issues. + */ + +int modperl_sys_is_dir(pTHX_ SV *sv); + +int modperl_sys_dlclose(void *handle); + +#endif /* MODPERL_SYS_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_time.h b/2_0_13/src/modules/perl/modperl_time.h new file mode 100644 index 0000000..bc7cbf8 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_time.h
@@ -0,0 +1,59 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_TIME_H +#define MODPERL_TIME_H + +#ifdef HZ +# define MP_HZ HZ +#else +# define MP_HZ 100 +#endif + +#ifdef MP_TRACE +#define dMP_TIMES \ + struct tms start_time; \ + struct tms end_time +#else +#define dMP_TIMES dNOOP +#endif + +#define MP_START_TIMES() \ + MP_TRACE_t_do((void)PerlProc_times(&start_time)) + +#define MP_END_TIMES() \ + MP_TRACE_t_do((void)PerlProc_times(&end_time)) + +#define MP_PRINT_TIMES(label) \ + MP_TRACE_t_do({ \ + double utime = \ + (double)(end_time.tms_utime - start_time.tms_utime)/MP_HZ; \ + double stime = \ + (double)(end_time.tms_stime - start_time.tms_stime)/MP_HZ; \ + if (utime || stime) { \ + MP_TRACE_t(MP_FUNC, "%s %5.2f user %5.2f sys", \ + label, utime, stime); \ + } \ + }) + +#endif /* MODPERL_TIME_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_tipool.c b/2_0_13/src/modules/perl/modperl_tipool.c new file mode 100644 index 0000000..9cb0ad0 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_tipool.c
@@ -0,0 +1,410 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +#ifdef USE_ITHREADS + +/* + * tipool == "thread item pool" + * this module is intended to provide generic stuctures/functions + * for managing a "pool" of a given items (data structures) within a threaded + * process. at the moment, mod_perl uses this module to manage a pool + * of PerlInterpreter objects. it should be quite easy to reuse for + * other data, such as database connection handles and the like. + * while it is "generic" it is also tuned for Apache, making use of + * apr_pool_t and the like, and implementing start/max/{min,max}_spare/ + * max_requests configuration. + * this is another "proof-of-concept", plenty of room for improvement here + */ + +modperl_list_t *modperl_list_new() +{ + modperl_list_t *listp = + (modperl_list_t *)malloc(sizeof(*listp)); + memset(listp, '\0', sizeof(*listp)); + return listp; +} + +modperl_list_t *modperl_list_last(modperl_list_t *list) +{ + while (list->next) { + list = list->next; + } + + return list; +} + +modperl_list_t *modperl_list_first(modperl_list_t *list) +{ + while (list->prev) { + list = list->prev; + } + + return list; +} + +modperl_list_t *modperl_list_append(modperl_list_t *list, + modperl_list_t *new_list) +{ + modperl_list_t *last; + + new_list->prev = new_list->next = NULL; + + if (!list) { + return new_list; + } + + last = modperl_list_last(list); + + last->next = new_list; + new_list->prev = last; + + return list; +} + +modperl_list_t *modperl_list_prepend(modperl_list_t *list, + modperl_list_t *new_list) +{ + new_list->prev = new_list->next = NULL; + + if (!list) { + return new_list; + } + + if (list->prev) { + list->prev->next = new_list; + new_list->prev = list->prev; + } + + list->prev = new_list; + new_list->next = list; + + return new_list; +} + +modperl_list_t *modperl_list_remove(modperl_list_t *list, + modperl_list_t *rlist) +{ + modperl_list_t *tmp = list; + + while (tmp) { + if (tmp != rlist) { + tmp = tmp->next; + } + else { + if (tmp->prev) { + tmp->prev->next = tmp->next; + } + if (tmp->next) { + tmp->next->prev = tmp->prev; + } + if (list == tmp) { + list = list->next; + } + + break; + } + } + +#ifdef MP_TRACE + if (!tmp) { + /* should never happen */ + MP_TRACE_i(MP_FUNC, "failed to find 0x%lx in list 0x%lx", + (unsigned long)rlist, (unsigned long)list); + } +#endif + + return list; +} + +modperl_list_t *modperl_list_remove_data(modperl_list_t *list, + void *data, + modperl_list_t **listp) +{ + modperl_list_t *tmp = list; + + while (tmp) { + if (tmp->data != data) { + tmp = tmp->next; + } + else { + *listp = tmp; + if (tmp->prev) { + tmp->prev->next = tmp->next; + } + if (tmp->next) { + tmp->next->prev = tmp->prev; + } + if (list == tmp) { + list = list->next; + } + + break; + } + } + + return list; +} + +modperl_tipool_t *modperl_tipool_new(apr_pool_t *p, + modperl_tipool_config_t *cfg, + modperl_tipool_vtbl_t *func, + void *data) +{ + modperl_tipool_t *tipool = + (modperl_tipool_t *)apr_pcalloc(p, sizeof(*tipool)); + + tipool->cfg = cfg; + tipool->func = func; + tipool->data = data; + + MUTEX_INIT(&tipool->tiplock); + COND_INIT(&tipool->available); + + return tipool; +} + +void modperl_tipool_init(modperl_tipool_t *tipool) +{ + int i; + + for (i=0; i<tipool->cfg->start; i++) { + void *item = + (*tipool->func->tipool_sgrow)(tipool, tipool->data); + + modperl_tipool_add(tipool, item); + } + + MP_TRACE_i(MP_FUNC, "start=%d, max=%d, min_spare=%d, max_spare=%d", + tipool->cfg->start, tipool->cfg->max, + tipool->cfg->min_spare, tipool->cfg->max_spare); + +} + +void modperl_tipool_destroy(modperl_tipool_t *tipool) +{ + while (tipool->idle) { + modperl_list_t *listp; + + if (tipool->func->tipool_destroy) { + (*tipool->func->tipool_destroy)(tipool, tipool->data, + tipool->idle->data); + } + tipool->size--; + listp = tipool->idle->next; + free(tipool->idle); + tipool->idle = listp; + } + + if (tipool->busy) { + MP_TRACE_i(MP_FUNC, "ERROR: %d items still in use", + tipool->in_use); + } + + MUTEX_DESTROY(&tipool->tiplock); + COND_DESTROY(&tipool->available); +} + +void modperl_tipool_add(modperl_tipool_t *tipool, void *data) +{ + modperl_list_t *listp = modperl_list_new(); + + listp->data = data; + + /* assuming tipool->tiplock has already been acquired */ + + tipool->idle = modperl_list_append(tipool->idle, listp); + + tipool->size++; + + MP_TRACE_i(MP_FUNC, "added 0x%lx (size=%d)", + (unsigned long)listp, tipool->size); +} + +void modperl_tipool_remove(modperl_tipool_t *tipool, modperl_list_t *listp) +{ + /* assuming tipool->tiplock has already been acquired */ + + tipool->idle = modperl_list_remove(tipool->idle, listp); + + tipool->size--; + MP_TRACE_i(MP_FUNC, "removed 0x%lx (size=%d)", + (unsigned long)listp, tipool->size); +} + +modperl_list_t *modperl_tipool_pop(modperl_tipool_t *tipool) +{ + modperl_list_t *head; + + modperl_tipool_lock(tipool); + + if (tipool->size == tipool->in_use) { + if (tipool->size < tipool->cfg->max) { + MP_TRACE_i(MP_FUNC, + "no idle items, size %d < %d max", + tipool->size, tipool->cfg->max); + if (tipool->func->tipool_rgrow) { + void * item = + (*tipool->func->tipool_rgrow)(tipool, tipool->data); + + modperl_tipool_add(tipool, item); + } + } + /* block until an item becomes available */ + modperl_tipool_wait(tipool); + } + + head = tipool->idle; + + tipool->idle = modperl_list_remove(tipool->idle, head); + tipool->busy = modperl_list_append(tipool->busy, head); + + tipool->in_use++; + + /* XXX: this should never happen */ + if (!head) { + MP_TRACE_i(MP_FUNC, "PANIC: no items available, %d of %d in use", + tipool->in_use, tipool->size); + abort(); + } + + modperl_tipool_unlock(tipool); + + return head; +} + +static void modperl_tipool_putback_base(modperl_tipool_t *tipool, + modperl_list_t *listp, + void *data, + int num_requests) +{ + int max_spare, max_requests; + + modperl_tipool_lock(tipool); + + /* remove from busy list, add back to idle */ + /* XXX: option to sort list, e.g. on num_requests */ + + if (listp) { + tipool->busy = modperl_list_remove(tipool->busy, listp); + } + else { + tipool->busy = modperl_list_remove_data(tipool->busy, data, &listp); + } + + if (!listp) { + /* XXX: Attempt to putback something that was never there */ + modperl_tipool_unlock(tipool); + return; + } + + tipool->idle = modperl_list_prepend(tipool->idle, listp); + + tipool->in_use--; + +#ifdef MP_TRACE + if (!tipool->busy && tipool->func->tipool_dump) { + MP_TRACE_i(MP_FUNC, "all items idle:"); + MP_TRACE_i_do((*tipool->func->tipool_dump)(tipool, + tipool->data, + tipool->idle)); + } +#endif + + MP_TRACE_i(MP_FUNC, "0x%lx now available (%d in use, %d running)", + (unsigned long)listp->data, tipool->in_use, tipool->size); + + modperl_tipool_broadcast(tipool); + if (tipool->in_use == (tipool->cfg->max - 1)) { + /* hurry up, another thread may be blocking */ + modperl_tipool_unlock(tipool); + return; + } + + max_spare = ((tipool->size - tipool->in_use) > tipool->cfg->max_spare); + max_requests = ((num_requests > 0) && + (num_requests > tipool->cfg->max_requests)); + + if (max_spare) { + MP_TRACE_i(MP_FUNC, + "shrinking pool: max_spare=%d, only %d of %d in use", + tipool->cfg->max_spare, tipool->in_use, tipool->size); + } + else if (max_requests) { + MP_TRACE_i(MP_FUNC, "shrinking pool: max requests %d reached", + tipool->cfg->max_requests); + } + + /* XXX: this management should probably be happening elsewhere + * like in a thread spawned at startup + */ + if (max_spare || max_requests) { + modperl_tipool_remove(tipool, listp); + + if (tipool->func->tipool_destroy) { + (*tipool->func->tipool_destroy)(tipool, tipool->data, + listp->data); + } + + free(listp); /* gone for good */ + + if (max_requests && ((tipool->size - tipool->in_use) < + tipool->cfg->min_spare)) { + if (tipool->func->tipool_rgrow) { + void *item = + (*tipool->func->tipool_rgrow)(tipool, + tipool->data); + + MP_TRACE_i(MP_FUNC, + "growing pool: min_spare=%d, %d of %d in use", + tipool->cfg->min_spare, tipool->in_use, + tipool->size); + + modperl_tipool_add(tipool, item); + } + } + } + + modperl_tipool_unlock(tipool); +} + +/* _data functions are so structures (e.g. modperl_interp_t) don't + * need to maintain a pointer back to the modperl_list_t + */ + +void modperl_tipool_putback_data(modperl_tipool_t *tipool, + void *data, + int num_requests) +{ + modperl_tipool_putback_base(tipool, NULL, data, num_requests); +} + +void modperl_tipool_putback(modperl_tipool_t *tipool, + modperl_list_t *listp, + int num_requests) +{ + modperl_tipool_putback_base(tipool, listp, NULL, num_requests); +} + +#endif /* USE_ITHREADS */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_tipool.h b/2_0_13/src/modules/perl/modperl_tipool.h new file mode 100644 index 0000000..c2d15b8 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_tipool.h
@@ -0,0 +1,96 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_TIPOOL_H +#define MODPERL_TIPOOL_H + +#ifdef USE_ITHREADS + +modperl_list_t *modperl_list_new(void); + +modperl_list_t *modperl_list_last(modperl_list_t *list); + +modperl_list_t *modperl_list_first(modperl_list_t *list); + +modperl_list_t *modperl_list_append(modperl_list_t *list, + modperl_list_t *new_list); + +modperl_list_t *modperl_list_prepend(modperl_list_t *list, + modperl_list_t *new_list); + +modperl_list_t *modperl_list_remove(modperl_list_t *list, + modperl_list_t *rlist); + +modperl_tipool_t *modperl_tipool_new(apr_pool_t *p, + modperl_tipool_config_t *cfg, + modperl_tipool_vtbl_t *func, + void *data); + +void modperl_tipool_init(modperl_tipool_t *tipool); + +void modperl_tipool_destroy(modperl_tipool_t *tipool); + +void modperl_tipool_add(modperl_tipool_t *tipool, void *data); + +void modperl_tipool_remove(modperl_tipool_t *tipool, modperl_list_t *listp); + +modperl_list_t *modperl_list_remove_data(modperl_list_t *list, + void *data, + modperl_list_t **listp); + +modperl_list_t *modperl_tipool_pop(modperl_tipool_t *tipool); + +void modperl_tipool_putback(modperl_tipool_t *tipool, + modperl_list_t *listp, + int num_requests); + +void modperl_tipool_putback_data(modperl_tipool_t *tipool, void *data, + int num_requests); + +#define modperl_tipool_wait(tipool) \ + while (tipool->size == tipool->in_use) { \ + MP_TRACE_i(MP_FUNC, \ + "waiting for available tipool item in thread 0x%lx", \ + MP_TIDF); \ + MP_TRACE_i(MP_FUNC, "(%d items in use, %d alive)", \ + tipool->in_use, tipool->size); \ + COND_WAIT(&tipool->available, &tipool->tiplock); \ + } + +#define modperl_tipool_broadcast(tipool) \ + MP_TRACE_i(MP_FUNC, "broadcast available tipool item"); \ + COND_SIGNAL(&tipool->available) + +#define modperl_tipool_lock(tipool) \ + MP_TRACE_i(MP_FUNC, "about to lock tipool in thread 0x%lx", MP_TIDF); \ + MUTEX_LOCK(&tipool->tiplock); \ + MP_TRACE_i(MP_FUNC, "acquired tipool lock") + +#define modperl_tipool_unlock(tipool) \ + MP_TRACE_i(MP_FUNC, "about to unlock tipool in thread 0x%lx", MP_TIDF); \ + MUTEX_UNLOCK(&tipool->tiplock); \ + MP_TRACE_i(MP_FUNC, "released tipool lock") + +#endif /* USE_ITHREADS */ + +#endif /* MODPERL_TIPOOL_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_types.h b/2_0_13/src/modules/perl/modperl_types.h new file mode 100644 index 0000000..8438f35 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_types.h
@@ -0,0 +1,289 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_TYPES_H +#define MODPERL_TYPES_H + +#ifndef MP_IOBUFSIZE +# ifdef AP_IOBUFSIZE +# define MP_IOBUFSIZE AP_IOBUFSIZE +# else +# define MP_IOBUFSIZE 8192 +# endif +#endif + +/* aliases */ + +typedef request_rec subrequest_rec; +typedef apr_array_header_t MpAV; +typedef apr_table_t MpHV; +typedef char char_len; /* see xs/typemap */ + +/* mod_perl structures */ + +typedef struct { + request_rec *r; + conn_rec *c; + server_rec *s; +} modperl_rcs_t; + +typedef struct modperl_config_con_t modperl_config_con_t; + +#ifdef USE_ITHREADS + +typedef struct modperl_list_t modperl_list_t; + +struct modperl_list_t { + modperl_list_t *prev, *next; + void *data; +}; + +typedef struct modperl_interp_t modperl_interp_t; +typedef struct modperl_interp_pool_t modperl_interp_pool_t; +typedef struct modperl_tipool_t modperl_tipool_t; +typedef struct modperl_tipool_config_t modperl_tipool_config_t; + +struct modperl_interp_t { + modperl_interp_pool_t *mip; + PerlInterpreter *perl; + int num_requests; + U8 flags; + modperl_config_con_t *ccfg; + int refcnt; +#ifdef MP_TRACE + unsigned long tid; +#endif +}; + +typedef struct { + /* s == startup grow + * r == runtime grow + */ + void * (*tipool_sgrow)(modperl_tipool_t *tipool, void *data); + void * (*tipool_rgrow)(modperl_tipool_t *tipool, void *data); + void (*tipool_shrink)(modperl_tipool_t *tipool, void *data, + void *item); + void (*tipool_destroy)(modperl_tipool_t *tipool, void *data, + void *item); + void (*tipool_dump)(modperl_tipool_t *tipool, void *data, + modperl_list_t *listp); +} modperl_tipool_vtbl_t; + +struct modperl_tipool_config_t { + int start; /* number of items to create at startup */ + int min_spare; /* minimum number of spare items */ + int max_spare; /* maximum number of spare items */ + int max; /* maximum number of items */ + int max_requests; /* maximum number of requests per item */ +}; + +struct modperl_tipool_t { + perl_mutex tiplock; + perl_cond available; + modperl_list_t *idle, *busy; + int in_use; /* number of items currrently in use */ + int size; /* current number of items */ + void *data; /* user data */ + modperl_tipool_config_t *cfg; + modperl_tipool_vtbl_t *func; +}; + +struct modperl_interp_pool_t { + server_rec *server; + modperl_tipool_t *tipool; + modperl_interp_t *parent; /* from which to perl_clone() */ +}; + +#endif /* USE_ITHREADS */ + +typedef U32 modperl_opts_t; + +typedef struct { + modperl_opts_t opts; + modperl_opts_t opts_add; + modperl_opts_t opts_remove; + modperl_opts_t opts_override; + modperl_opts_t opts_seen; + int unset; +} modperl_options_t; + +typedef struct { + MpHV *setvars; + MpHV *configvars; + MpHV *SetEnv; + MpHV *PassEnv; + MpAV *PerlRequire, *PerlModule, *PerlPostConfigRequire; + MpAV *handlers_per_srv[MP_HANDLER_NUM_PER_SRV]; + MpAV *handlers_files[MP_HANDLER_NUM_FILES]; + MpAV *handlers_process[MP_HANDLER_NUM_PROCESS]; + MpAV *handlers_pre_connection[MP_HANDLER_NUM_PRE_CONNECTION]; + MpAV *handlers_connection[MP_HANDLER_NUM_CONNECTION]; +#ifdef USE_ITHREADS + modperl_interp_pool_t *mip; + modperl_tipool_config_t *interp_pool_cfg; +#else + PerlInterpreter *perl; +#endif +#ifdef MP_USE_GTOP + modperl_gtop_t *gtop; +#endif + MpAV *argv; + modperl_options_t *flags; + apr_hash_t *modules; + server_rec *server; +} modperl_config_srv_t; + +typedef struct { + char *location; + char *PerlDispatchHandler; + MpAV *handlers_per_dir[MP_HANDLER_NUM_PER_DIR]; + MpHV *SetEnv; + MpHV *setvars; + MpHV *configvars; + modperl_options_t *flags; +} modperl_config_dir_t; + +typedef struct { + const char *file; + modperl_config_dir_t *dcfg; +} modperl_require_file_t; + +typedef struct modperl_mgv_t modperl_mgv_t; + +struct modperl_mgv_t { + char *name; + int len; + UV hash; + modperl_mgv_t *next; +}; + +typedef struct modperl_handler_t modperl_handler_t; + +struct modperl_handler_t { + /* could be: + * - the lightweight gv for named subs + * - the lookup data in $PL_modperl{ANONSUB} + */ + modperl_mgv_t *mgv_obj; + modperl_mgv_t *mgv_cv; + /* could be: + * - a subroutine name for named subs + * - NULL for anon subs + */ + const char *name; + CV *cv; + U8 flags; + U16 attrs; + modperl_handler_t *next; +}; + +#define MP_HANDLER_TYPE_CHAR 1 +#define MP_HANDLER_TYPE_SV 2 + +typedef struct { + int outcnt; + char outbuf[MP_IOBUFSIZE]; + apr_pool_t *pool; + ap_filter_t **filters; + int header_parse; + request_rec *r; +} modperl_wbucket_t; + +typedef enum { + MP_INPUT_FILTER_MODE, + MP_OUTPUT_FILTER_MODE +} modperl_filter_mode_e; + +typedef struct { + int seen_eos; + int eos; + int flush; + ap_filter_t *f; + char *leftover; + apr_ssize_t remaining; + modperl_wbucket_t *wbucket; + apr_bucket *bucket; + apr_bucket_brigade *bb_in; + apr_bucket_brigade *bb_out; + ap_input_mode_t input_mode; + apr_read_type_e block; + apr_off_t readbytes; + apr_status_t rc; + modperl_filter_mode_e mode; + apr_pool_t *pool; + apr_pool_t *temp_pool; +} modperl_filter_t; + +typedef struct { + int sent_eos; + SV *data; + modperl_handler_t *handler; +#ifdef USE_ITHREADS + modperl_interp_t *interp; +#endif +} modperl_filter_ctx_t; + +typedef struct { + HV *pnotes; + apr_pool_t *pool; +#ifdef USE_ITHREADS + modperl_interp_t *interp; +#endif +} modperl_pnotes_t; + +typedef struct { + modperl_pnotes_t pnotes; + SV *global_request_obj; + U8 flags; + int status; + modperl_wbucket_t *wbucket; + MpAV *handlers_per_dir[MP_HANDLER_NUM_PER_DIR]; + MpAV *handlers_per_srv[MP_HANDLER_NUM_PER_SRV]; + modperl_perl_globals_t perl_globals; +} modperl_config_req_t; + +struct modperl_config_con_t { + modperl_pnotes_t pnotes; +#ifdef USE_ITHREADS + modperl_interp_t *interp; +#endif +}; + +typedef struct { + apr_pool_t *pool; + void *data; +} modperl_cleanup_data_t; + +typedef struct { + module *modp; + const char *cmd_data; + const char *func_name; +} modperl_module_cmd_data_t; + +typedef enum { + MP_HOOK_RUN_ALL, + MP_HOOK_RUN_FIRST, + MP_HOOK_VOID +} modperl_hook_run_mode_e; + +#endif /* MODPERL_TYPES_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_util.c b/2_0_13/src/modules/perl/modperl_util.c new file mode 100644 index 0000000..dc06cde --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_util.c
@@ -0,0 +1,1268 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +int modperl_require_module(pTHX_ const char *pv, int logfailure) +{ + SV *sv; + + dSP; + PUSHSTACKi(PERLSI_REQUIRE); + ENTER;SAVETMPS; + PUTBACK; + sv = sv_newmortal(); + sv_setpv(sv, "require "); + sv_catpv(sv, pv); + eval_sv(sv, G_DISCARD); + SPAGAIN; + POPSTACK; + FREETMPS;LEAVE; + + if (SvTRUE(ERRSV)) { + if (logfailure) { + (void)modperl_errsv(aTHX_ HTTP_INTERNAL_SERVER_ERROR, + NULL, NULL); + } + return FALSE; + } + + return TRUE; +} + +int modperl_require_file(pTHX_ const char *pv, int logfailure) +{ + require_pv(pv); + + if (SvTRUE(ERRSV)) { + if (logfailure) { + (void)modperl_errsv(aTHX_ HTTP_INTERNAL_SERVER_ERROR, + NULL, NULL); + } + return FALSE; + } + + return TRUE; +} + +static SV *modperl_hv_request_find(pTHX_ SV *in, char *classname, CV *cv) +{ + static char *r_keys[] = { "r", "_r", NULL }; + HV *hv = (HV *)SvRV(in); + SV *sv = (SV *)NULL; + int i; + + for (i=0; r_keys[i]; i++) { + int klen = i + 1; /* assumes r_keys[] will never change */ + SV **svp; + + if ((svp = hv_fetch(hv, r_keys[i], klen, FALSE)) && (sv = *svp)) { + if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVHV)) { + /* dig deeper */ + return modperl_hv_request_find(aTHX_ sv, classname, cv); + } + break; + } + } + + if (!sv) { + Perl_croak(aTHX_ + "method `%s' invoked by a `%s' object with no `r' key!", + cv ? GvNAME(CvGV(cv)) : "unknown", + (SvRV(in) && SvSTASH(SvRV(in))) + ? HvNAME(SvSTASH(SvRV(in))) + : "unknown"); + } + + return SvROK(sv) ? SvRV(sv) : sv; +} + + +/* notice that if sv is not an Apache2::ServerRec object and + * Apache2->request is not available, the returned global object might + * be not thread-safe under threaded mpms, so use with care + */ + +MP_INLINE server_rec *modperl_sv2server_rec(pTHX_ SV *sv) +{ + if (SvOBJECT(sv) || (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG))) { + return INT2PTR(server_rec *, SvObjIV(sv)); + } + + /* next see if we have Apache2->request available */ + { + request_rec *r = NULL; + (void)modperl_tls_get_request_rec(&r); + if (r) { + return r->server; + } + } + + /* modperl_global_get_server_rec is not thread safe w/o locking */ + return modperl_global_get_server_rec(); +} + +MP_INLINE request_rec *modperl_sv2request_rec(pTHX_ SV *sv) +{ + return modperl_xs_sv2request_rec(aTHX_ sv, NULL, (CV *)NULL); +} + +request_rec *modperl_xs_sv2request_rec(pTHX_ SV *in, char *classname, CV *cv) +{ + SV *sv = (SV *)NULL; + MAGIC *mg; + + if (SvROK(in)) { + SV *rv = (SV*)SvRV(in); + + switch (SvTYPE(rv)) { + case SVt_PVMG: + sv = rv; + break; + case SVt_PVHV: + sv = modperl_hv_request_find(aTHX_ in, classname, cv); + break; + default: + Perl_croak(aTHX_ "panic: unsupported request_rec type %d", + (int)SvTYPE(rv)); + } + } + + /* might be Apache2::ServerRec::warn method */ + if (!sv && !(classname && SvPOK(in) && !strEQ(classname, SvPVX(in)))) { + request_rec *r = NULL; + (void)modperl_tls_get_request_rec(&r); + + if (!r) { + Perl_croak(aTHX_ + "Apache2->%s called without setting Apache2->request!", + cv ? GvNAME(CvGV(cv)) : "unknown"); + } + + return r; + } + + /* there could be pool magic attached to custom $r object, so make + * sure that mg->mg_ptr is set */ + if ((mg = mg_find(sv, PERL_MAGIC_ext)) && mg->mg_ptr) { + return (request_rec *)mg->mg_ptr; + } + else { + if (classname && !sv_derived_from(in, classname)) { + /* XXX: find something faster than sv_derived_from */ + return NULL; + } + return INT2PTR(request_rec *, SvIV(sv)); + } + + return NULL; +} + +MP_INLINE SV *modperl_newSVsv_obj(pTHX_ SV *stashsv, SV *obj) +{ + SV *newobj; + + if (!obj) { + obj = stashsv; + stashsv = (SV *)NULL; + } + + newobj = newSVsv(obj); + + if (stashsv) { + HV *stash = gv_stashsv(stashsv, TRUE); + return sv_bless(newobj, stash); + } + + return newobj; +} + +MP_INLINE SV *modperl_ptr2obj(pTHX_ char *classname, void *ptr) +{ + SV *sv = newSV(0); + + MP_TRACE_h(MP_FUNC, "sv_setref_pv(%s, 0x%lx)", + classname, (unsigned long)ptr); + sv_setref_pv(sv, classname, ptr); + + return sv; +} + +int modperl_errsv(pTHX_ int status, request_rec *r, server_rec *s) +{ + SV *sv = ERRSV; + STRLEN n_a; + + if (SvTRUE(sv)) { + if (sv_derived_from(sv, "APR::Error") && + SvIVx(sv) == MODPERL_RC_EXIT) { + /* ModPerl::Util::exit was called */ + return OK; + } +#if 0 + if (modperl_sv_is_http_code(ERRSV, &status)) { + return status; + } +#endif + if (r) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "%s", SvPV(sv, n_a)); + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "%s", SvPV(sv, n_a)); + } + + return status; + } + + return status; +} + +/* prepends the passed sprintf-like arguments to ERRSV, which also + * gets stringified on the way */ +void modperl_errsv_prepend(pTHX_ const char *pat, ...) +{ + SV *sv; + va_list args; + + va_start(args, pat); + sv = vnewSVpvf(pat, &args); + va_end(args); + + sv_catsv(sv, ERRSV); + sv_copypv(ERRSV, sv); + sv_free(sv); +} + +#define dl_librefs "DynaLoader::dl_librefs" +#define dl_modules "DynaLoader::dl_modules" + +void modperl_xs_dl_handles_clear(pTHX) +{ + AV *librefs = get_av(dl_librefs, FALSE); + if (librefs) { + av_clear(librefs); + } +} + +void **modperl_xs_dl_handles_get(pTHX) +{ + I32 i; + AV *librefs = get_av(dl_librefs, FALSE); + AV *modules = get_av(dl_modules, FALSE); + void **handles; + + if (!librefs) { + MP_TRACE_r(MP_FUNC, + "Could not get @%s for unloading.", + dl_librefs); + return NULL; + } + + if (!(AvFILL(librefs) >= 0)) { + /* dl_librefs and dl_modules are empty */ + return NULL; + } + + handles = (void **)malloc(sizeof(void *) * (AvFILL(librefs)+2)); + + for (i=0; i<=AvFILL(librefs); i++) { + void *handle; + SV *handle_sv = *av_fetch(librefs, i, FALSE); + SV *module_sv = *av_fetch(modules, i, FALSE); + + if(!handle_sv) { + MP_TRACE_r(MP_FUNC, + "Could not fetch $%s[%d]!", + dl_librefs, (int)i); + continue; + } + handle = INT2PTR(void *, SvIV(handle_sv)); + + MP_TRACE_r(MP_FUNC, "%s dl handle == 0x%lx", + SvPVX(module_sv), (unsigned long)handle); + if (handle) { + handles[i] = handle; + } + } + + av_clear(modules); + av_clear(librefs); + + handles[i] = (void *)0; + + return handles; +} + +void modperl_xs_dl_handles_close(void **handles) +{ + int i; + + if (!handles) { + return; + } + + for (i=0; handles[i]; i++) { + MP_TRACE_r(MP_FUNC, "close 0x%lx", (unsigned long)handles[i]); + modperl_sys_dlclose(handles[i]); + } + + free(handles); +} + +/* XXX: There is no XS accessible splice() */ +static void modperl_av_remove_entry(pTHX_ AV *av, I32 index) +{ + I32 i; + AV *tmpav = newAV(); + + /* stash the entries _before_ the item to delete */ + for (i=0; i<=index; i++) { + av_store(tmpav, i, SvREFCNT_inc(av_shift(av))); + } + + /* make size at the beginning of the array */ + av_unshift(av, index-1); + + /* add stashed entries back */ + for (i=0; i<index; i++) { + av_store(av, i, *av_fetch(tmpav, i, 0)); + } + + sv_free((SV *)tmpav); +} + +static void modperl_package_unload_dynamic(pTHX_ const char *package, + I32 dl_index) +{ + AV *librefs = get_av(dl_librefs, 0); + SV *libref = *av_fetch(librefs, dl_index, 0); + + modperl_sys_dlclose(INT2PTR(void *, SvIV(libref))); + + /* remove package from @dl_librefs and @dl_modules */ + modperl_av_remove_entry(aTHX_ get_av(dl_librefs, 0), dl_index); + modperl_av_remove_entry(aTHX_ get_av(dl_modules, 0), dl_index); + + return; +} + +static int modperl_package_is_dynamic(pTHX_ const char *package, + I32 *dl_index) +{ + I32 i; + AV *modules = get_av(dl_modules, FALSE); + + for (i=0; i<av_len(modules); i++) { + SV *module = *av_fetch(modules, i, 0); + if (strEQ(package, SvPVX(module))) { + *dl_index = i; + return TRUE; + } + } + return FALSE; +} + +modperl_cleanup_data_t *modperl_cleanup_data_new(apr_pool_t *p, void *data) +{ + modperl_cleanup_data_t *cdata = + (modperl_cleanup_data_t *)apr_pcalloc(p, sizeof(*cdata)); + cdata->pool = p; + cdata->data = data; + return cdata; +} + +MP_INLINE void modperl_perl_av_push_elts_ref(pTHX_ AV *dst, AV *src) +{ + I32 i, j, src_fill = AvFILLp(src), dst_fill = AvFILLp(dst); + + av_extend(dst, src_fill); + AvFILLp(dst) += src_fill+1; + + for (i=dst_fill+1, j=0; j<=AvFILLp(src); i++, j++) { + AvARRAY(dst)[i] = SvREFCNT_inc(AvARRAY(src)[j]); + } +} + +/* + * similar to hv_fetch_ent, but takes string key and key len rather than SV + * also skips magic and utf8 fu, since we are only dealing with internal tables + */ +HE *modperl_perl_hv_fetch_he(pTHX_ HV *hv, + register char *key, + register I32 klen, + register U32 hash) +{ + register XPVHV *xhv; + register HE *entry; + + xhv = (XPVHV *)SvANY(hv); + if (!HvARRAY(hv)) { + return 0; + } + +#ifdef HvREHASH + if (HvREHASH(hv)) { + PERL_HASH_INTERNAL(hash, key, klen); + } + else +#endif + if (!hash) { + PERL_HASH(hash, key, klen); + } + + entry = ((HE**)HvARRAY(hv))[hash & (I32)xhv->xhv_max]; + + for (; entry; entry = HeNEXT(entry)) { + if (HeHASH(entry) != hash) { + continue; + } + if (HeKLEN(entry) != klen) { + continue; + } + if (HeKEY(entry) != key && memNE(HeKEY(entry), key, klen)) { + continue; + } + return entry; + } + + return 0; +} + +void modperl_str_toupper(char *str) +{ + while (*str) { + *str = apr_toupper(*str); + ++str; + } +} + +/* XXX: same as Perl_do_sprintf(); + * but Perl_do_sprintf() is not part of the "public" api + */ +void modperl_perl_do_sprintf(pTHX_ SV *sv, I32 len, SV **sarg) +{ + STRLEN patlen; + char *pat = SvPV(*sarg, patlen); + bool do_taint = FALSE; + + sv_vsetpvfn(sv, pat, patlen, (va_list *)NULL, sarg + 1, len - 1, &do_taint); + SvSETMAGIC(sv); + if (do_taint) { + SvTAINTED_on(sv); + } +} + +void modperl_perl_call_list(pTHX_ AV *subs, const char *name) +{ + I32 i, oldscope = PL_scopestack_ix; + SV **ary = AvARRAY(subs); + + MP_TRACE_g(MP_FUNC, MP_TRACEf_PERLID + " running %d %s subs", MP_TRACEv_PERLID_ + AvFILLp(subs)+1, name); + + for (i=0; i<=AvFILLp(subs); i++) { + CV *cv = (CV*)ary[i]; + SV *atsv = ERRSV; + + PUSHMARK(PL_stack_sp); + call_sv((SV*)cv, G_EVAL|G_DISCARD); + + if (SvCUR(atsv)) { + Perl_sv_catpvf(aTHX_ atsv, "%s failed--call queue aborted", + name); + while (PL_scopestack_ix > oldscope) { + LEAVE; + } + Perl_croak(aTHX_ "%s", SvPVX(atsv)); + } + } +} + +void modperl_perl_exit(pTHX_ int status) +{ + ENTER; + SAVESPTR(PL_diehook); + PL_diehook = (SV *)NULL; + modperl_croak(aTHX_ MODPERL_RC_EXIT, "ModPerl::Util::exit"); +} + +MP_INLINE SV *modperl_dir_config(pTHX_ request_rec *r, server_rec *s, + char *key, SV *sv_val) +{ + SV *retval = &PL_sv_undef; + + if (r && r->per_dir_config) { + MP_dDCFG; + retval = modperl_table_get_set(aTHX_ dcfg->configvars, + key, sv_val, FALSE); + } + + if (!SvOK(retval)) { + if (s && s->module_config) { + MP_dSCFG(s); + SvREFCNT_dec(retval); /* in case above did newSV(0) */ + retval = modperl_table_get_set(aTHX_ scfg->configvars, + key, sv_val, FALSE); + } + else { + retval = &PL_sv_undef; + } + } + + return retval; +} + +SV *modperl_table_get_set(pTHX_ apr_table_t *table, char *key, + SV *sv_val, int do_taint) +{ + SV *retval = &PL_sv_undef; + + if (table == NULL) { + /* do nothing */ + } + else if (key == NULL) { + retval = modperl_hash_tie(aTHX_ "APR::Table", + (SV *)NULL, (void*)table); + } + else if (!sv_val) { /* no val was passed */ + char *val; + if ((val = (char *)apr_table_get(table, key))) { + retval = newSVpv(val, 0); + } + else { + retval = newSV(0); + } + if (do_taint) { + SvTAINTED_on(retval); + } + } + else if (!SvOK(sv_val)) { /* val was passed in as undef */ + apr_table_unset(table, key); + } + else { + apr_table_set(table, key, SvPV_nolen(sv_val)); + } + + return retval; +} + +static char *package2filename(const char *package, int *len) +{ + const char *s; + char *d; + char *filename; + + filename = malloc((strlen(package)+4)*sizeof(char)); + + for (s = package, d = filename; *s; s++, d++) { + if (*s == ':' && s[1] == ':') { + *d = '/'; + s++; + } + else { + *d = *s; + } + } + *d++ = '.'; + *d++ = 'p'; + *d++ = 'm'; + *d = '\0'; + + *len = d - filename; + return filename; +} + +MP_INLINE int modperl_perl_module_loaded(pTHX_ const char *name) +{ + SV **svp; + int len; + char *filename = package2filename(name, &len); + svp = hv_fetch(GvHVn(PL_incgv), filename, len, 0); + free(filename); + + return (svp && *svp != &PL_sv_undef) ? 1 : 0; +} + +#define SLURP_SUCCESS(action) \ + if (rc != APR_SUCCESS) { \ + SvREFCNT_dec(sv); \ + modperl_croak(aTHX_ rc, \ + apr_psprintf(r->pool, \ + "slurp_filename('%s') / " action, \ + r->filename)); \ + } + +MP_INLINE SV *modperl_slurp_filename(pTHX_ request_rec *r, int tainted) +{ + SV *sv; + apr_status_t rc; + apr_size_t size; + apr_file_t *file; + + size = r->finfo.size; + sv = newSV(size); + + /* XXX: could have checked whether r->finfo.filehand is valid and + * save the apr_file_open call, but apache gives us no API to + * check whether filehand is valid. we can't test whether it's + * NULL or not, as it may contain garbagea + */ + rc = apr_file_open(&file, r->filename, APR_READ|APR_BINARY, + APR_OS_DEFAULT, r->pool); + SLURP_SUCCESS("opening"); + + rc = apr_file_read(file, SvPVX(sv), &size); + SLURP_SUCCESS("reading"); + + MP_TRACE_o(MP_FUNC, "read %d bytes from '%s'", size, r->filename); + + if (r->finfo.size != size) { + SvREFCNT_dec(sv); + Perl_croak(aTHX_ "Error: read %d bytes, expected %d ('%s')", + size, (apr_size_t)r->finfo.size, r->filename); + } + + rc = apr_file_close(file); + SLURP_SUCCESS("closing"); + + SvPVX(sv)[size] = '\0'; + SvCUR_set(sv, size); + SvPOK_on(sv); + + if (tainted) { + SvTAINTED_on(sv); + } + else { + SvTAINTED_off(sv); + } + + return newRV_noinc(sv); +} + +#define MP_VALID_PKG_CHAR(c) (isalnum(c) ||(c) == '_') +#define MP_VALID_PATH_DELIM(c) ((c) == '/' || (c) =='\\') +char *modperl_file2package(apr_pool_t *p, const char *file) +{ + char *package; + char *c; + const char *f; + int len = strlen(file)+1; + + /* First, skip invalid prefix characters */ + while (!MP_VALID_PKG_CHAR(*file)) { + file++; + len--; + } + + /* Then figure out how big the package name will be like */ + for (f = file; *f; f++) { + if (MP_VALID_PATH_DELIM(*f)) { + len++; + } + } + + package = apr_pcalloc(p, len); + + /* Then, replace bad characters with '_' */ + for (c = package; *file; c++, file++) { + if (MP_VALID_PKG_CHAR(*file)) { + *c = *file; + } + else if (MP_VALID_PATH_DELIM(*file)) { + + /* Eliminate subsequent duplicate path delim */ + while (*(file+1) && MP_VALID_PATH_DELIM(*(file+1))) { + file++; + } + + /* path delim not until end of line */ + if (*(file+1)) { + *c = *(c+1) = ':'; + c++; + } + } + else { + *c = '_'; + } + } + + return package; +} + +SV *modperl_apr_array_header2avrv(pTHX_ apr_array_header_t *array) +{ + AV *av = newAV(); + + if (array) { + int i; + for (i = 0; i < array->nelts; i++) { + av_push(av, newSVpv(((char **)array->elts)[i], 0)); + } + } + return newRV_noinc((SV*)av); +} + +apr_array_header_t *modperl_avrv2apr_array_header(pTHX_ apr_pool_t *p, + SV *avrv) +{ + AV *av; + apr_array_header_t *array; + int i, av_size; + + if (!(SvROK(avrv) && (SvTYPE(SvRV(avrv)) == SVt_PVAV))) { + Perl_croak(aTHX_ "Not an array reference"); + } + + av = (AV*)SvRV(avrv); + av_size = av_len(av); + array = apr_array_make(p, av_size+1, sizeof(char *)); + + for (i = 0; i <= av_size; i++) { + SV *sv = *av_fetch(av, i, FALSE); + char **entry = (char **)apr_array_push(array); + *entry = apr_pstrdup(p, SvPV_nolen(sv)); + } + + return array; +} + +/* Remove a package from %INC */ +static void modperl_package_delete_from_inc(pTHX_ const char *package) +{ + int len; + char *filename = package2filename(package, &len); + (void)hv_delete(GvHVn(PL_incgv), filename, len, G_DISCARD); + free(filename); +} + +/* Destroy a package's stash */ +#define MP_STASH_SUBSTASH(key, len) ((len >= 2) && \ + (key[len-1] == ':') && \ + (key[len-2] == ':')) +#define MP_STASH_DEBUGGER(key, len) ((len >= 2) && \ + (key[0] == '_') && \ + (key[1] == '<')) +#define MP_SAFE_STASH(key, len) (!(MP_STASH_SUBSTASH(key,len)|| \ + (MP_STASH_DEBUGGER(key, len)))) +static void modperl_package_clear_stash(pTHX_ const char *package) +{ + HV *stash; + if ((stash = gv_stashpv(package, FALSE))) { + HE *he; + I32 len; + char *key; + hv_iterinit(stash); + while ((he = hv_iternext(stash))) { + key = hv_iterkey(he, &len); + if (MP_SAFE_STASH(key, len)) { + SV *val = hv_iterval(stash, he); + /* The safe thing to do is to skip over stash entries + * that don't come from the package we are trying to + * unload + */ + if (GvSTASH(val) == stash) { + (void)hv_delete(stash, key, len, G_DISCARD); + } + } + } + } +} + +/* Unload a module as completely and cleanly as possible */ +void modperl_package_unload(pTHX_ const char *package) +{ + I32 dl_index; + + modperl_package_clear_stash(aTHX_ package); + modperl_package_delete_from_inc(aTHX_ package); + + if (modperl_package_is_dynamic(aTHX_ package, &dl_index)) { + modperl_package_unload_dynamic(aTHX_ package, dl_index); + } + +} + +#define MP_RESTART_COUNT_KEY "mod_perl_restart_count" + +/* passing the main server object here, just because we don't have the + * modperl_server_pool available yet, later on we can access it + * through the modperl_server_pool() call. + */ +void modperl_restart_count_inc(server_rec *base_server) +{ + void *data; + int *counter; + apr_pool_t *p = base_server->process->pool; + + apr_pool_userdata_get(&data, MP_RESTART_COUNT_KEY, p); + if (data) { + counter = data; + (*counter)++; + } + else { + counter = apr_palloc(p, sizeof *counter); + *counter = 1; + apr_pool_userdata_set(counter, MP_RESTART_COUNT_KEY, + apr_pool_cleanup_null, p); + } +} + +int modperl_restart_count(void) +{ + void *data; + apr_pool_userdata_get(&data, MP_RESTART_COUNT_KEY, + modperl_global_get_server_rec()->process->pool); + return data ? *(int *)data : 0; + } + +static MP_INLINE +apr_status_t modperl_cleanup_pnotes(void *data) { + modperl_pnotes_t *pnotes = data; + + dTHXa(pnotes->interp->perl); + MP_ASSERT_CONTEXT(aTHX); + + SvREFCNT_dec(pnotes->pnotes); + pnotes->pnotes = NULL; + pnotes->pool = NULL; + + MP_INTERP_PUTBACK(pnotes->interp, aTHX); + return APR_SUCCESS; +} + +void modperl_pnotes_kill(void *data) { + modperl_pnotes_t *pnotes = data; + + if( !pnotes->pnotes ) return; + + apr_pool_cleanup_kill(pnotes->pool, pnotes, modperl_cleanup_pnotes); + modperl_cleanup_pnotes(pnotes); +} + +SV *modperl_pnotes(pTHX_ modperl_pnotes_t *pnotes, SV *key, SV *val, + apr_pool_t *pool) { + SV *retval = (SV *)NULL; + + if (!pnotes->pnotes) { + pnotes->pool = pool; +#ifdef USE_ITHREADS + pnotes->interp = modperl_thx_interp_get(aTHX); + pnotes->interp->refcnt++; + MP_TRACE_i(MP_FUNC, "TO: (0x%lx)->refcnt incremented to %ld", + pnotes->interp, pnotes->interp->refcnt); +#endif + pnotes->pnotes = newHV(); + apr_pool_cleanup_register(pool, pnotes, + modperl_cleanup_pnotes, + apr_pool_cleanup_null); + } + + if (key) { + STRLEN len; + char *k = SvPV(key, len); + + if (val) { + retval = *hv_store(pnotes->pnotes, k, len, SvREFCNT_inc(val), 0); + } + else if (hv_exists(pnotes->pnotes, k, len)) { + retval = *hv_fetch(pnotes->pnotes, k, len, FALSE); + } + + return retval ? SvREFCNT_inc(retval) : &PL_sv_undef; + } + return newRV_inc((SV *)pnotes->pnotes); +} + +U16 *modperl_code_attrs(pTHX_ CV *cv) { + MAGIC *mg; + + if (!(SvMAGICAL(cv) && (mg = mg_find((SV*)cv, PERL_MAGIC_ext)))) { + sv_magic((SV*)cv, (SV *)NULL, PERL_MAGIC_ext, NULL, -1); + } + + mg = mg_find((SV*)cv, PERL_MAGIC_ext); + return &(mg->mg_private); +} + +#if AP_SERVER_MAJORVERSION_NUMBER>2 || \ + (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3) + +static apr_hash_t *global_authz_providers = NULL; +static apr_hash_t *global_authn_providers = NULL; + +typedef struct { + SV *cb1; + SV *cb2; + modperl_handler_t *cb1_handler; + modperl_handler_t *cb2_handler; +} auth_callback; + +static apr_status_t cleanup_perl_global_providers(void *ctx) +{ + global_authz_providers = NULL; + global_authn_providers = NULL; + return APR_SUCCESS; +} + +static authz_status perl_check_authorization(request_rec *r, + const char *require_args, + const void *parsed_require_args) +{ + authz_status ret = AUTHZ_DENIED; + int count; + AV *args = (AV *)NULL; + const char *key; + auth_callback *ab; + MP_dINTERPa(r, NULL, NULL); + + if (global_authz_providers == NULL) { + MP_INTERP_PUTBACK(interp, aTHX); + return ret; + } + + key = apr_table_get(r->notes, AUTHZ_PROVIDER_NAME_NOTE); + ab = apr_hash_get(global_authz_providers, key, APR_HASH_KEY_STRING); + if (ab == NULL) { + MP_INTERP_PUTBACK(interp, aTHX); + return ret; + } + + if (ab->cb1 == NULL) { + if (ab->cb1_handler == NULL) { + MP_INTERP_PUTBACK(interp, aTHX); + return ret; + } + + modperl_handler_make_args(aTHX_ &args, "Apache2::RequestRec", r, + "PV", require_args, NULL); + ret = modperl_callback(aTHX_ ab->cb1_handler, r->pool, r, r->server, + args); + SvREFCNT_dec((SV*)args); + MP_INTERP_PUTBACK(interp, aTHX); + return ret; + } + + { + dSP; + ENTER; + SAVETMPS; + PUSHMARK(SP); + XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::RequestRec", r))); + XPUSHs(sv_2mortal(newSVpv(require_args, 0))); + PUTBACK; + count = call_sv(ab->cb1, G_SCALAR); + SPAGAIN; + + if (count == 1) { + ret = (authz_status) POPi; + } + + PUTBACK; + FREETMPS; + LEAVE; + } + + MP_INTERP_PUTBACK(interp, aTHX); + return ret; +} + +static const char *perl_parse_require_line(cmd_parms *cmd, + const char *require_line, + const void **parsed_require_line) +{ + char *ret = NULL; + void *key; + auth_callback *ab; + + if (global_authz_providers == NULL || + apr_hash_count(global_authz_providers) == 0) + { + return NULL; + } + + apr_pool_userdata_get(&key, AUTHZ_PROVIDER_NAME_NOTE, cmd->temp_pool); + ab = apr_hash_get(global_authz_providers, (char *) key, APR_HASH_KEY_STRING); + if (ab == NULL || ab->cb2 == NULL) { + return NULL; + } + + { + /* PerlAddAuthzProvider currently does not support an optional second + * handler, so ab->cb2 should always be NULL above and we will never get + * here. If such support is added in the future then this code will be + * reached, but cannot succeed in the absence of an interpreter. The + * second handler would be called at init to check a Require line for + * errors, but in the current design there is no interpreter available + * at that time. + */ + MP_dINTERP_POOLa(cmd->pool, cmd->server); + if (!MP_HAS_INTERP(interp)) { + return "Require handler is not currently supported in this context"; + } + + { + SV *ret_sv; + int count; + dSP; + + ENTER; + SAVETMPS; + PUSHMARK(SP); + XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::CmdParms", cmd))); + XPUSHs(sv_2mortal(newSVpv(require_line, 0))); + PUTBACK; + count = call_sv(ab->cb2, G_SCALAR); + SPAGAIN; + + if (count == 1) { + ret_sv = POPs; + if (SvOK(ret_sv)) { + char *tmp = SvPV_nolen(ret_sv); + if (*tmp != '\0') { + ret = apr_pstrdup(cmd->pool, tmp); + } + } + } + + PUTBACK; + FREETMPS; + LEAVE; + } + + MP_INTERP_PUTBACK(interp, aTHX); + } + return ret; +} + +static authn_status perl_check_password(request_rec *r, const char *user, + const char *password) +{ + authn_status ret = AUTH_DENIED; + int count; + AV *args = (AV *)NULL; + const char *key; + auth_callback *ab; + MP_dINTERPa(r, NULL, NULL); + + if (global_authn_providers == NULL) { + MP_INTERP_PUTBACK(interp, aTHX); + return ret; + } + + key = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE); + ab = apr_hash_get(global_authn_providers, key, + APR_HASH_KEY_STRING); + if (ab == NULL || ab->cb1) { + MP_INTERP_PUTBACK(interp, aTHX); + return ret; + } + + if (ab->cb1 == NULL) { + if (ab->cb1_handler == NULL) { + MP_INTERP_PUTBACK(interp, aTHX); + return ret; + } + + modperl_handler_make_args(aTHX_ &args, "Apache2::RequestRec", r, + "PV", user, + "PV", password, NULL); + ret = modperl_callback(aTHX_ ab->cb1_handler, r->pool, r, r->server, + args); + SvREFCNT_dec((SV*)args); + MP_INTERP_PUTBACK(interp, aTHX); + return ret; + } + + { + dSP; + ENTER; + SAVETMPS; + PUSHMARK(SP); + XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::RequestRec", r))); + XPUSHs(sv_2mortal(newSVpv(user, 0))); + XPUSHs(sv_2mortal(newSVpv(password, 0))); + PUTBACK; + count = call_sv(ab->cb1, G_SCALAR); + SPAGAIN; + + if (count == 1) { + ret = (authn_status) POPi; + } + + PUTBACK; + FREETMPS; + LEAVE; + } + + MP_INTERP_PUTBACK(interp, aTHX); + return ret; +} + +static authn_status perl_get_realm_hash(request_rec *r, const char *user, + const char *realm, char **rethash) +{ + authn_status ret = AUTH_USER_NOT_FOUND; + const char *key; + auth_callback *ab; + + if (global_authn_providers == NULL || + apr_hash_count(global_authn_providers) == 0) + { + return AUTH_GENERAL_ERROR; + } + + key = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE); + ab = apr_hash_get(global_authn_providers, key, APR_HASH_KEY_STRING); + if (ab == NULL || ab->cb2 == NULL) { + return AUTH_GENERAL_ERROR; + } + + { + /* PerlAddAuthnProvider currently does not support an optional second + * handler, so ab->cb2 should always be NULL above and we will never get + * here. If such support is added in the future then this code will be + * reached. Unlike the PerlAddAuthzProvider case, the second handler here + * would be called during request_rec processing to obtain a password hash + * for the realm so there should be no problem grabbing an interpreter. + */ + MP_dINTERPa(r, NULL, NULL); + + { + SV* rh = sv_2mortal(newSVpv("", 0)); + int count; + dSP; + + ENTER; + SAVETMPS; + PUSHMARK(SP); + XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::RequestRec", r))); + XPUSHs(sv_2mortal(newSVpv(user, 0))); + XPUSHs(sv_2mortal(newSVpv(realm, 0))); + XPUSHs(newRV_noinc(rh)); + PUTBACK; + count = call_sv(ab->cb2, G_SCALAR); + SPAGAIN; + + if (count == 1) { + const char *tmp = SvPV_nolen(rh); + ret = (authn_status) POPi; + if (*tmp != '\0') { + *rethash = apr_pstrdup(r->pool, tmp); + } + } + + PUTBACK; + FREETMPS; + LEAVE; + } + + MP_INTERP_PUTBACK(interp, aTHX); + } + + return ret; +} + +static const authz_provider authz_perl_provider = { perl_check_authorization, + perl_parse_require_line }; + +static const authn_provider authn_perl_provider = { perl_check_password, + perl_get_realm_hash }; + +static apr_status_t register_auth_provider(apr_pool_t *pool, + const char *provider_group, + const char *provider_name, + const char *provider_version, + auth_callback *ab, int type) +{ + void *provider_ = NULL; + + if (global_authz_providers == NULL) { + global_authz_providers = apr_hash_make(pool); + global_authn_providers = apr_hash_make(pool); + /* We have to use pre_cleanup here, otherwise this cleanup method + * would be called after another cleanup method which unloads + * mod_perl module. + */ + apr_pool_pre_cleanup_register(pool, NULL, + cleanup_perl_global_providers); + } + + if (strcmp(provider_group, AUTHZ_PROVIDER_GROUP) == 0) { + provider_ = (void *) &authz_perl_provider; + apr_hash_set(global_authz_providers, provider_name, + APR_HASH_KEY_STRING, ab); + } + else { + provider_ = (void *) &authn_perl_provider; + apr_hash_set(global_authn_providers, provider_name, + APR_HASH_KEY_STRING, ab); + } + + return ap_register_auth_provider(pool, provider_group, provider_name, + provider_version, provider_, type); + +} + +apr_status_t modperl_register_auth_provider(apr_pool_t *pool, + const char *provider_group, + const char *provider_name, + const char *provider_version, + SV *callback1, SV *callback2, + int type) +{ + char *provider_name_dup; + auth_callback *ab = NULL; + + provider_name_dup = apr_pstrdup(pool, provider_name); + ab = apr_pcalloc(pool, sizeof(auth_callback)); + ab->cb1 = callback1; + ab->cb2 = callback2; + + return register_auth_provider(pool, provider_group, provider_name_dup, + provider_version, ab, type); +} + +apr_status_t modperl_register_auth_provider_name(apr_pool_t *pool, + const char *provider_group, + const char *provider_name, + const char *provider_version, + const char *callback1, + const char *callback2, + int type) +{ + char *provider_name_dup; + auth_callback *ab = NULL; + + provider_name_dup = apr_pstrdup(pool, provider_name); + ab = apr_pcalloc(pool, sizeof(auth_callback)); + ab->cb1_handler = modperl_handler_new(pool, callback1); + if (callback2) { + ab->cb2_handler = modperl_handler_new(pool, callback2); + } + + return register_auth_provider(pool, provider_group, provider_name_dup, + provider_version, ab, type); +} + +#endif /* httpd-2.4 */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/src/modules/perl/modperl_util.h b/2_0_13/src/modules/perl/modperl_util.h new file mode 100644 index 0000000..83e51d4 --- /dev/null +++ b/2_0_13/src/modules/perl/modperl_util.h
@@ -0,0 +1,168 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_UTIL_H +#define MODPERL_UTIL_H + +#include "modperl_common_util.h" + +/* check whether the response phase has been initialized already */ +#define MP_CHECK_WBUCKET_INIT(func) \ + if (!rcfg->wbucket) { \ + Perl_croak(aTHX_ "%s: " func " can't be called " \ + "before the response phase", MP_FUNC); \ + } + +/* turn off cgi header parsing. in case we are already inside + * modperl_callback_per_dir(MP_RESPONSE_HANDLER, r, MP_HOOK_RUN_FIRST); + * but haven't sent any data yet, it's too late to change + * MpReqPARSE_HEADERS, so change the wbucket's private flag directly + */ +#define MP_CGI_HEADER_PARSER_OFF(rcfg) \ + MpReqPARSE_HEADERS_Off(rcfg); \ + if (rcfg->wbucket) { \ + rcfg->wbucket->header_parse = 0; \ + } + +MP_INLINE server_rec *modperl_sv2server_rec(pTHX_ SV *sv); +MP_INLINE request_rec *modperl_sv2request_rec(pTHX_ SV *sv); + +request_rec *modperl_xs_sv2request_rec(pTHX_ SV *sv, char *classname, CV *cv); + +MP_INLINE SV *modperl_newSVsv_obj(pTHX_ SV *stashsv, SV *obj); + +MP_INLINE SV *modperl_ptr2obj(pTHX_ char *classname, void *ptr); + +int modperl_errsv(pTHX_ int status, request_rec *r, server_rec *s); + +void modperl_errsv_prepend(pTHX_ const char *pat, ...); + +int modperl_require_module(pTHX_ const char *pv, int logfailure); +int modperl_require_file(pTHX_ const char *pv, int logfailure); + +void modperl_xs_dl_handles_clear(pTHX); + +void **modperl_xs_dl_handles_get(pTHX); + +void modperl_xs_dl_handles_close(void **handles); + +modperl_cleanup_data_t *modperl_cleanup_data_new(apr_pool_t *p, void *data); + +MP_INLINE void modperl_perl_av_push_elts_ref(pTHX_ AV *dst, AV *src); + +HE *modperl_perl_hv_fetch_he(pTHX_ HV *hv, + register char *key, + register I32 klen, + register U32 hash); + +#define hv_fetch_he(hv,k,l,h) \ + modperl_perl_hv_fetch_he(aTHX_ hv, k, l, h) + +void modperl_str_toupper(char *str); + +void modperl_perl_do_sprintf(pTHX_ SV *sv, I32 len, SV **sarg); + +void modperl_perl_call_list(pTHX_ AV *subs, const char *name); + +void modperl_perl_exit(pTHX_ int status); + +MP_INLINE SV *modperl_dir_config(pTHX_ request_rec *r, server_rec *s, + char *key, SV *sv_val); + +SV *modperl_table_get_set(pTHX_ apr_table_t *table, char *key, + SV *sv_val, int do_taint); + +MP_INLINE int modperl_perl_module_loaded(pTHX_ const char *name); + +/** + * slurp the contents of r->filename and return them as a scalar + * @param r request record + * @param tainted whether the SV should be marked tainted or not + * @return a PV scalar with the contents of the file + */ +SV *modperl_slurp_filename(pTHX_ request_rec *r, int tainted); + +char *modperl_file2package(apr_pool_t *p, const char *file); + +SV *modperl_apr_array_header2avrv(pTHX_ apr_array_header_t *array); +apr_array_header_t *modperl_avrv2apr_array_header(pTHX_ apr_pool_t *p, + SV *avrv); +void modperl_package_unload(pTHX_ const char *package); +#if defined(MP_TRACE) && defined(USE_ITHREADS) +#define MP_TRACEf_PERLID "perl id 0x%lx" +#define MP_TRACEv_PERLID (unsigned long)my_perl +#define MP_TRACEv_PERLID_ MP_TRACEv_PERLID, +#define MP_TRACEv__PERLID ,MP_TRACEv_PERLID +#else +#define MP_TRACEf_PERLID +#define MP_TRACEv_PERLID +#define MP_TRACEv_PERLID_ +#define MP_TRACEv__PERLID +#endif /* USE_ITHREADS */ + +/* dumping hundreds of lines in the trace, makes it less useful. Get a + * string chunk of MP_TRACE_STR_LEN bytes or less. Not too long so it + * won't wrap when posted in email. Notice that we copy 'count' bytes + * of the string even if count < MP_TRACE_STR_LEN, because the 'str' + * buffer doesn't necessarily have \0 terminator at 'count'. As this + * is for debug tracing, not to be used in production, it doesn't make + * any difference if it's not efficient. + */ +#define MP_TRACE_STR_LEN 35 +#define MP_TRACE_STR_TRUNC(p, str, count) \ + count < MP_TRACE_STR_LEN \ + ? (char *)apr_pstrmemdup(p, str, count) \ + : (char *)apr_psprintf(p, "%s...", \ + apr_pstrmemdup(p, str, MP_TRACE_STR_LEN)) + +/* functions maintaining the amount of times mod_perl was restarted, + * e.g. on Apache start, it restarts itself, so the count will be + * first 1, and on on restart 2 */ +void modperl_restart_count_inc(server_rec *base_server); +int modperl_restart_count(void); + +void modperl_pnotes_kill(void *data); + +SV *modperl_pnotes(pTHX_ modperl_pnotes_t *pnotes, SV *key, SV *val, + apr_pool_t *pool ); + +U16 *modperl_code_attrs(pTHX_ CV *cv); + +#if AP_SERVER_MAJORVERSION_NUMBER>2 || \ + (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3) +apr_status_t +modperl_register_auth_provider(apr_pool_t *pool, const char *provider_group, + const char *provider_name, + const char *provider_version, SV *callback1, + SV *callback2, int type); + +apr_status_t +modperl_register_auth_provider_name(apr_pool_t *pool, + const char *provider_group, + const char *provider_name, + const char *provider_version, + const char *callback1, + const char *callback2, int type); +#endif + +#endif /* MODPERL_UTIL_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/t/apache/add_config.t b/2_0_13/t/apache/add_config.t new file mode 100644 index 0000000..90edaec --- /dev/null +++ b/2_0_13/t/apache/add_config.t
@@ -0,0 +1,6 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# the handler is configured in modperl_extra.pl via +# Apache2::ServerUtil->server->add_config +use Apache::TestRequest 'GET_BODY_ASSERT'; + +print GET_BODY_ASSERT "/apache/add_config";
diff --git a/2_0_13/t/apache/cgihandler.t b/2_0_13/t/apache/cgihandler.t new file mode 100644 index 0000000..ace671c --- /dev/null +++ b/2_0_13/t/apache/cgihandler.t
@@ -0,0 +1,21 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2; + +my $location = "/TestApache__cgihandler"; + +my $expected = "1..3\nok 1\nok 2\nok 3\n"; + +my $received = POST_BODY $location, content => $expected; + +ok t_cmp $received, $expected, "POST cgihandler"; + +$received = GET_BODY $location; + +ok t_cmp $received, $expected, "GET cgihandler";
diff --git a/2_0_13/t/apache/constants.t b/2_0_13/t/apache/constants.t new file mode 100644 index 0000000..81fe6aa --- /dev/null +++ b/2_0_13/t/apache/constants.t
@@ -0,0 +1,84 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use ExtUtils::testlib; +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +# -compile puts constants into the Apache2:: namespace +use Apache2::Const -compile => qw(:http :common :mpmq :proxy + TAKE23 &OPT_EXECCGI + DECLINE_CMD DIR_MAGIC_TYPE + CRLF); + +# without -compile, constants are in the +# caller namespace. also defaults to :common +use Apache2::Const; + +plan tests => 18; + +ok t_cmp(REDIRECT, 302, 'REDIRECT'); + +ok t_cmp(AUTH_REQUIRED, 401, 'AUTH_REQUIRED'); + +ok t_cmp(OK, 0, 'OK'); + +ok t_cmp(Apache2::Const::OK, 0, 'Apache2::Const::OK'); + +ok t_cmp(Apache2::Const::DECLINED, -1, 'Apache2::Const::DECLINED'); + +ok t_cmp(Apache2::Const::HTTP_GONE, 410, 'Apache2::Const::HTTP_GONE'); + +ok t_cmp(Apache2::Const::DIR_MAGIC_TYPE, + 'httpd/unix-directory', + 'Apache2::Const::DIR_MAGIC_TYPE'); + +ok t_cmp(Apache2::Const::MPMQ_MAX_SPARE_DAEMONS, + 9, + 'Apache2::Const::MPMQ_MAX_SPARE_DAEMONS'); + +ok t_cmp(Apache2::Const::PROXYREQ_REVERSE, + 2, + 'Apache2::Const::PROXYREQ_REVERSE'); + +# the rest of the tests don't fit into the t_cmp() meme +# for one reason or anothre... + +print "testing Apache2::Const::OPT_EXECCGI is defined\n"; +ok defined Apache2::Const::OPT_EXECCGI; + +print "testing Apache2::Const::DECLINE_CMD\n"; +ok Apache2::Const::DECLINE_CMD eq "\x07\x08"; + +# try and weed out EBCDIC - this is the test httpd uses +if (chr(0xC1) eq 'A') { + print "testing Apache2::Const::CRLF (EBCDIC)\n"; + ok Apache2::Const::CRLF eq "\r\n"; +} +else { + print "testing Apache2::Const::CRLF (ASCII)\n"; + ok Apache2::Const::CRLF eq "\015\012"; + +} + +print "testing M_GET not yet defined\n"; +ok ! defined &M_GET; + +Apache2::Const->import('M_GET'); + +print "testing M_GET now defined\n"; +ok defined &M_GET; + +for (qw(BOGUS :bogus -foobar)) { + + eval { Apache2::Const->import($_) }; + + print "testing bogus import $_\n"; + ok $@; +} + +print "testing explicit call to compile()\n"; +eval { Apache2::Const::compile() }; + +ok $@;
diff --git a/2_0_13/t/apache/content_length_header.t b/2_0_13/t/apache/content_length_header.t new file mode 100644 index 0000000..2b414e4 --- /dev/null +++ b/2_0_13/t/apache/content_length_header.t
@@ -0,0 +1,158 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 12 * 2 + 3; + +my $location = "/TestApache__content_length_header"; + +# 1. because Apache proclaims itself governor of the C-L header via +# the C-L filter (ap_content_length_filter at +# httpd-2.0/server/protocol.c), test whether GET and HEAD behave the +# same wrt C-L under varying circumstances. for the most part GET +# and HEAD should behave exactly the same. however, when Apache +# sees a HEAD request with a C-L header of zero it takes special +# action and removes the C-L header. this is done to protect against +# handlers that called r->header_only (which was ok in 1.3 but is +# not in 2.0). So, GET and HEAD behave the same except when the +# content handler (plus filters) end up sending no content. see +# the lengthy comments in ap_http_header_filter in http_protocol.c. +# +# for more discussion on +# why it is important to get HEAD requests right, see these threads +# from the mod_perl list +# http://marc.theaimsgroup.com/?l=apache-modperl&m=108647669726915&w=2 +# http://marc.theaimsgroup.com/?t=109122984600001&r=1&w=2 +# as well as this bug report from mozilla, which shows how they +# are using HEAD requests in the wild +# http://bugzilla.mozilla.org/show_bug.cgi?id=245447 + +foreach my $method (qw(GET HEAD)) { + + no strict qw(refs); + + { + # if the response handler sends no data, and sets no C-L header, + # the client doesn't get C-L header at all. + # + # in 2.0 GET requests get a C-L of zero, while HEAD requests do + # not due to special processing. + my $uri = $location; + my $res = $method->($uri); + + my $cl = 0; + my $head_cl = undef; + + ok t_cmp $res->code, 200, "$method $uri code"; + ok t_cmp ($res->header('Content-Length'), + $method eq 'GET' ? $cl : $head_cl, + "$method $uri C-L header"); + ok t_cmp $res->content, "", "$method $uri content"; + } + + { + # if the response handler sends no data and sets C-L header, + # the client should receive the set content length. in 2.1 + # this is the way it happens. see protocol.c -r1.150 -r1.151 + # + # in 2.0 the client doesn't get C-L header for HEAD requests + # due to special processing, and GET requests get a calculated + # C-L of zero. + my $uri = "$location?set_content_length"; + my $res = $method->($uri); + + my $cl = 0; + my $head_cl; + + ## 2.2.1, 2.0.56, 2.0.57 were not released + ## but we use the versions the changes went into + ## to protect against wierd SVN checkout building. + ## XXX: I'm starting to think this test is more + ## trouble then its worth. + if (have_min_apache_version("2.2.1")) { + $head_cl = 25; + } + elsif (have_min_apache_version("2.2.0")) { + # $head_cl = undef; # avoid warnings + } + elsif (have_min_apache_version("2.0.56")) { + $head_cl = 25; + } + else { + # $head_cl = undef; # avoid warnings + } + + ok t_cmp $res->code, 200, "$method $uri code"; + ok t_cmp ($res->header('Content-Length'), + $method eq 'GET' ? $cl : $head_cl, + "$method $uri C-L header"); + ok t_cmp $res->content, "", "$method $uri content"; + } + + { + # if the response handler sends data, and sets no C-L header, + # the client doesn't get C-L header. + my $uri = "$location?send_body"; + my $res = $method->($uri); + ok t_cmp $res->code, 200, "$method $uri code"; + ok t_cmp $res->header('Content-Length'), undef, + "$method $uri C-L header"; + + my $content = $method eq 'GET' ? 'This is a response string' : ''; + ok t_cmp $res->content, $content, "$method $uri content"; + } + + { + # if the response handler sends data (e.g. one char string), and + # sets C-L header, the client gets the C-L header + my $uri = "$location?send_body+set_content_length"; + my $res = $method->($uri); + ok t_cmp $res->code, 200, "$method $uri code"; + ok t_cmp $res->header('Content-Length'), 25, + "$method $uri C-L header"; + + my $content = $method eq 'GET' ? 'This is a response string' : ''; + ok t_cmp $res->content, $content, "$method $uri content"; + } +} + +# 2. even though the spec says that content handlers should send an +# identical response for GET and HEAD requests, some folks try to +# avoid the overhead of generating the response body, which Apache is +# going to discard anyway for HEAD requests. The following discussion +# assumes that we deal with a HEAD request. +# +# When Apache sees EOS and no headers and no response body were sent, +# ap_content_length_filter (httpd-2.0/server/protocol.c) sets C-L to +# 0. Later on ap_http_header_filter +# (httpd-2.0/modules/http/http_protocol.c) removes the C-L header for +# the HEAD requests +# +# the workaround is to force the sending of the response headers, +# before EOS was sent. The simplest solution is to use rflush(): +# +# if ($r->header_only) { # HEAD +# $body_len = calculate_body_len(); +# $r->set_content_length($body_len); +# $r->rflush; +# } +# else { # GET +# # generate and send the body +# } +# +# now if the handler sets the C-L header it'll be delivered to the +# client unmodified. + +{ + # if the response handler sends data (e.g. one char string), and + # sets C-L header, the client gets the C-L header + my $uri = "$location?head_no_body+set_content_length"; + my $res = HEAD $uri; + ok t_cmp $res->code, 200, "HEAD $uri code"; + ok t_cmp $res->header('Content-Length'), 25, "HEAD $uri C-L header"; + ok t_cmp $res->content, '', "HEAD $uri content"; +}
diff --git a/2_0_13/t/apache/discard_rbody.t b/2_0_13/t/apache/discard_rbody.t new file mode 100644 index 0000000..49caab0 --- /dev/null +++ b/2_0_13/t/apache/discard_rbody.t
@@ -0,0 +1,18 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; +use Apache::TestRequest; + +my $location = "/TestApache__discard_rbody"; +my $content = "Y" x 100000; # more than one bucket + +plan tests => 3; + +for my $test (qw(none partial all)) { + my $received = POST_BODY "$location?$test", content => $content; + ok t_cmp($received, $test, "data consumption: $test"); +} +
diff --git a/2_0_13/t/apache/post.t b/2_0_13/t/apache/post.t new file mode 100644 index 0000000..ba0f573 --- /dev/null +++ b/2_0_13/t/apache/post.t
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2; + +my $location = "/TestApache__post"; +my $str; + +my @data = (arizona => 'wildcats'); +my %data = @data; + +$str = POST_BODY $location, content => "@data"; + +ok $str; + +my $data = join '&', map { "$_=$data{$_}" } keys %data; + +$str = POST_BODY $location, content => $data; +ok t_cmp($str, + join(':', length($data), $data), + "POST");
diff --git a/2_0_13/t/apache/read.t b/2_0_13/t/apache/read.t new file mode 100644 index 0000000..9f7f504 --- /dev/null +++ b/2_0_13/t/apache/read.t
@@ -0,0 +1,52 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +use File::Spec::Functions qw(catfile); + +plan tests => 1; + +#force test to go over http, since this doesn't work with t/TEST -ssl +Apache::TestRequest::scheme('http'); + +my $location = "/TestApache__read"; + +my $socket = Apache::TestRequest::vhost_socket('default'); + +my $file = catfile Apache::Test::vars('serverroot'), "..", 'Makefile'; + +open my $fh, $file or die "open $file: $!"; +my $data = join '', <$fh>; +close $fh; + +my $size = length $data; + +for my $string ("POST $location HTTP/1.0", + "Content-length: $size", + "") { + my $line = "$string\r\n"; + syswrite $socket, $line, length($line); +} + +my $written = 0; +my $bufsiz = 240; + +my $sleeps = 2; + +while ($written < length($data)) { + my $remain = length($data) - $written; + my $len = $remain > $bufsiz ? $bufsiz : $remain; + $written += syswrite $socket, $data, $len, $written; + sleep 1 if $sleeps-- > 0; +} + +while (<$socket>) { + last if /^\015?\012$/; #skip over headers +} + +my $return = join '', <$socket>; + +ok $data eq $return;
diff --git a/2_0_13/t/apache/read2.t b/2_0_13/t/apache/read2.t new file mode 100644 index 0000000..fc585d7 --- /dev/null +++ b/2_0_13/t/apache/read2.t
@@ -0,0 +1,4 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache::TestRequest 'POST_BODY_ASSERT'; +print POST_BODY_ASSERT "/TestApache__read2", + content => "foobar";
diff --git a/2_0_13/t/apache/read3.t b/2_0_13/t/apache/read3.t new file mode 100644 index 0000000..e4fbee4 --- /dev/null +++ b/2_0_13/t/apache/read3.t
@@ -0,0 +1,4 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache::TestRequest 'POST_BODY_ASSERT'; +print POST_BODY_ASSERT "/TestApache__read3", + content => "foobar"x2000;
diff --git a/2_0_13/t/apache/read4.t b/2_0_13/t/apache/read4.t new file mode 100644 index 0000000..eeb7341 --- /dev/null +++ b/2_0_13/t/apache/read4.t
@@ -0,0 +1,4 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache::TestRequest 'POST_BODY_ASSERT'; +print POST_BODY_ASSERT "/TestApache__read4", + content => "foobar"x2;
diff --git a/2_0_13/t/apache/scanhdrs.t b/2_0_13/t/apache/scanhdrs.t new file mode 100644 index 0000000..da305c5 --- /dev/null +++ b/2_0_13/t/apache/scanhdrs.t
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 4; + +my $module = 'TestApache::scanhdrs'; +my $location = "/" . Apache::TestRequest::module2path($module); + +my $res = GET $location; + +t_debug $res->as_string; + +ok t_cmp($res->content, qr/^ok 1$/m); + +ok t_cmp($res->header('Content-Type'), + 'text/test-output', + "standard header"); + +ok t_cmp($res->header('X-Perl-Module'), + $module, + "custom header"); + +ok t_cmp($res->message, qr/beer/);
diff --git a/2_0_13/t/apache/scanhdrs2.t b/2_0_13/t/apache/scanhdrs2.t new file mode 100644 index 0000000..7956b84 --- /dev/null +++ b/2_0_13/t/apache/scanhdrs2.t
@@ -0,0 +1,35 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 5, need 'HTML::HeadParser'; + +my $module = 'TestApache__scanhdrs2'; +my $location = "/$module"; + +my $redirect = 'http://perl.apache.org/'; + +my $res = GET "$location?$redirect", redirect_ok => 0; + +ok t_cmp($res->header('Location')||'', $redirect, + "Location header"); + +ok t_cmp($res->code, 302, + "status == 302"); + +$redirect = '/index.html'; + +$res = GET "$location?$redirect", redirect_ok => 0; + +ok t_cmp(!$res->header('Location'), 1, + "no Location header"); + +ok t_cmp($res->code, 200, + "status == 200"); + +ok t_cmp($res->content, qr{welcome to}, + "content is index.html");
diff --git a/2_0_13/t/apache/send_cgi_header.t b/2_0_13/t/apache/send_cgi_header.t new file mode 100644 index 0000000..6a2bd53 --- /dev/null +++ b/2_0_13/t/apache/send_cgi_header.t
@@ -0,0 +1,32 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 4; + +my $location = "/TestApache__send_cgi_header"; +my $res = GET $location; + +ok t_cmp($res->header('X-Foo'), + 'X-Bar', + "header test"); + +ok t_cmp($res->header('Set-Cookie'), + 'Bad Programmer, No cookie!', + "header test2"); + +my $expected = "\0\0This not the end of the world\0\0\n"; +my $received = $res->content; + +ok t_cmp(length($received), + length($expected), + "body length test"); + +# \000 aren't seen when printed +ok t_cmp($received, + $expected, + "body content test");
diff --git a/2_0_13/t/api/access2.t b/2_0_13/t/api/access2.t new file mode 100644 index 0000000..f106dcd --- /dev/null +++ b/2_0_13/t/api/access2.t
@@ -0,0 +1,39 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +if (!have_min_apache_version("2.4.0")) { + +plan tests => 6, need need_lwp, need_auth, need_access, 'mod_version.c', + 'HTML::HeadParser'; + +my $location = "/TestAPI__access2"; + +ok !GET_OK $location; + +my $rc = GET_RC $location; +ok t_cmp $rc, 401, "no credentials passed"; + +# bad user +ok !GET_OK $location, username => 'root', password => '1234'; + +# good user/bad pass +ok !GET_OK $location, username => 'goo', password => 'foo'; + +# good user/good pass +ok GET_OK $location, username => 'goo', password => 'goopass'; + +# any user/any pass POST works +ok POST_OK $location, username => 'bar', password => 'goopass1', + content => "a"; + +} +else { + +plan tests => 1, need {"mod_perl is not compiled with httpd-2.2" => 0}; + +}
diff --git a/2_0_13/t/api/access2_24.t b/2_0_13/t/api/access2_24.t new file mode 100644 index 0000000..3852c04 --- /dev/null +++ b/2_0_13/t/api/access2_24.t
@@ -0,0 +1,38 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +if (have_min_apache_version("2.4.0")) { + +plan tests => 6, need need_lwp, need_auth, need_access, 'mod_access_compat.c', + 'mod_version.c', 'HTML::HeadParser'; + +my $location = "/TestAPI__access2"; + +ok !GET_OK $location; + +my $rc = GET_RC $location; +ok t_cmp $rc, 401, "no credentials passed"; + +# bad user +ok !GET_OK $location, username => 'root', password => '1234'; + +# good user/bad pass +ok !GET_OK $location, username => 'goo', password => 'foo'; + +# good user/good pass +ok GET_OK $location, username => 'goo', password => 'goopass'; + +# any user/any pass POST works +ok POST_OK $location, username => 'bar', password => 'goopass1', + content => "a"; + +} +else { + +plan tests => 1, need {"mod_perl is not compiled with httpd-2.4" => 0}; + +}
diff --git a/2_0_13/t/api/add_config.t b/2_0_13/t/api/add_config.t new file mode 100644 index 0000000..20a1b7a --- /dev/null +++ b/2_0_13/t/api/add_config.t
@@ -0,0 +1,14 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY_ASSERT); +use Apache::Test; +use Apache::TestUtil; + +my $module = 'TestAPI::add_config'; +my $url = Apache::TestRequest::module2url($module) . "/"; + +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url; +
diff --git a/2_0_13/t/api/content_encoding.t b/2_0_13/t/api/content_encoding.t new file mode 100644 index 0000000..d030f00 --- /dev/null +++ b/2_0_13/t/api/content_encoding.t
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, need_min_module_version("Compress::Zlib", "1.09"); + +my $location = '/TestAPI__content_encoding'; + +my $expected = 'This is a clear text'; + +my $res = POST $location, content => $expected; + +my $received = $res->content; +#t_debug($received); + +if ($res->header('Content-Encoding') =~ /gzip/) { + require Compress::Zlib; + + # gzip already produces data in a network order, so no extra + # transformation seem to be necessary + $received = Compress::Zlib::memGunzip($received); +} + +ok t_cmp $received, $expected, "Content-Encoding: gzip test"; +
diff --git a/2_0_13/t/api/custom_response.t b/2_0_13/t/api/custom_response.t new file mode 100644 index 0000000..3986008 --- /dev/null +++ b/2_0_13/t/api/custom_response.t
@@ -0,0 +1,49 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use File::Spec::Functions qw(catfile); + +use Apache2::Const -compile => qw(FORBIDDEN); + +my $module = 'TestAPI::custom_response'; +my $location = '/' . Apache::TestRequest::module2path($module); + +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport($config); +t_debug("connecting to $hostport"); + +my $file = catfile Apache::Test::vars('documentroot'), + qw(api custom_response.txt); + +open my $fh, $file or die "Can't open $file: $!"; +my $data = do { binmode $fh; local $/; <$fh> }; +close $fh; + +plan tests => 4, need need_lwp, 'HTML::HeadParser'; + +{ + # custom text response + my $expected = "This_is_a_custom_text_response"; + my $res = GET "$location?$expected"; + ok t_cmp $res->code, Apache2::Const::FORBIDDEN, "custom text response (code)"; + ok t_cmp $res->content, $expected, "custom text response (body)"; +} + +{ + # custom relative url response + my $url = "/api/custom_response.txt"; + my $res = GET "$location?$url"; + ok t_cmp $res->content, $data, "custom file response (body)"; +} +{ + my $url = "http://$hostport/api/custom_response.txt"; + # custom full url response + my $res = GET "$location?$url"; + ok t_cmp $res->content, $data, "custom file response (body)"; +} +
diff --git a/2_0_13/t/api/err_headers_out.t b/2_0_13/t/api/err_headers_out.t new file mode 100644 index 0000000..a1eb446 --- /dev/null +++ b/2_0_13/t/api/err_headers_out.t
@@ -0,0 +1,61 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 6, need 'HTML::HeadParser'; + +my $location = '/TestAPI__err_headers_out'; + +{ + # with 2xx responses any of the err_headers_out and headers_out + # headers make it through + + my $res = GET "$location?200"; + + #t_debug $res->as_string; + + ok t_cmp $res->code, 200, "OK"; + + # HTTP::Headers 6.00 makes the next 2 tests fail. When the response comes + # in the header name is stored as "x-err_headers_out". But when it is to + # be read below it is referred as "x-err-headers-out" and hence not found. + local $HTTP::Headers::TRANSLATE_UNDERSCORE= + $HTTP::Headers::TRANSLATE_UNDERSCORE; + undef $HTTP::Headers::TRANSLATE_UNDERSCORE + if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION >= 6.00; + + ok t_cmp $res->header('X-err_headers_out'), "err_headers_out", + "X-err_headers_out: made it"; + + ok t_cmp $res->header('X-headers_out'), "headers_out", + "X-headers_out: made it"; +} + +{ + # with non-2xx responses only the err_headers_out headers make it + # through. the headers_out do not make it. + + my $res = GET "$location?404"; + + #t_debug $res->as_string; + + ok t_cmp $res->code, 404, "not found"; + + # HTTP::Headers 6.00 makes this test fail. When the response comes in + # the header name is stored as "x-err_headers_out". But when it is to + # be read below it is referred as "x-err-headers-out" and hence not found. + local $HTTP::Headers::TRANSLATE_UNDERSCORE= + $HTTP::Headers::TRANSLATE_UNDERSCORE; + undef $HTTP::Headers::TRANSLATE_UNDERSCORE + if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION >= 6.00; + + ok t_cmp $res->header('X-err_headers_out'), "err_headers_out", + "X-err_headers_out: made it"; + + ok !$res->header('X-headers_out'); +} +
diff --git a/2_0_13/t/api/in_out_filters.t b/2_0_13/t/api/in_out_filters.t new file mode 100644 index 0000000..f9aa7a1 --- /dev/null +++ b/2_0_13/t/api/in_out_filters.t
@@ -0,0 +1,22 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $location = '/TestAPI__in_out_filters'; + +my $content = join '', 'AA'..'ZZ', 1..99999; + +my $expected = lc $content; +my $received = POST_BODY $location, content => $content; + +# don't use t_cmp in this test, because the data length is 500K. +# You don't want to see 500K * 2 when you run t/TEST -verbose + +ok $received eq $expected; +
diff --git a/2_0_13/t/api/internal_redirect.t b/2_0_13/t/api/internal_redirect.t new file mode 100644 index 0000000..ecdd9bd --- /dev/null +++ b/2_0_13/t/api/internal_redirect.t
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# test internal redirects originating from 'SetHandler modperl' and +# 'SetHandler perl-script' main handlers, and sub-requests handled by +# the handlers of the same and the opposite kind + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $uri = "/TestAPI__internal_redirect"; + +my %map = ( + "modperl => modperl" => "${uri}_modperl?uri=${uri}_modperl", + "perl-script => modperl" => "${uri}_perl_script?uri=${uri}_modperl", + "perl-script => perl-script" => "${uri}_perl_script?uri=${uri}_perl_script", + "modperl => perl-script" => "${uri}_modperl?uri=${uri}_perl_script", +); + +plan tests => scalar keys %map; + +while (my ($key, $val) = each %map) { + my $expected = "internal redirect: $key"; + my $received = GET_BODY_ASSERT $val; + ok t_cmp($received, $expected); +}
diff --git a/2_0_13/t/api/internal_redirect_handler.t b/2_0_13/t/api/internal_redirect_handler.t new file mode 100644 index 0000000..26237d1 --- /dev/null +++ b/2_0_13/t/api/internal_redirect_handler.t
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $uri = "/TestAPI__internal_redirect_handler"; + +my @ct_types = qw(text/plain text/html); + +plan tests => scalar @ct_types; + +for my $type (@ct_types) { + my $expected = $type; + my $received = GET_BODY_ASSERT "$uri?ct=$type"; + ok t_cmp $received, $expected, "Content-type: $type"; +}
diff --git a/2_0_13/t/api/lookup_misc.t b/2_0_13/t/api/lookup_misc.t new file mode 100644 index 0000000..e73079b --- /dev/null +++ b/2_0_13/t/api/lookup_misc.t
@@ -0,0 +1,35 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use File::Spec; + +my $uri = "/TestAPI__lookup_misc"; + +my $file = File::Spec->rel2abs(__FILE__); +open my $fh, $file or die "Can't open $file: $!"; +my $data = do { binmode $fh; local $/; <$fh> }; +close $fh; + +plan tests => 2; + +# lookup_file +{ + my $args = "subreq=lookup_file;file=$file"; + my $expected = $data; + my $received = GET_BODY_ASSERT "$uri?$args"; + t_debug "lookup_file"; + ok $received eq $expected; +} + +# lookup_method_uri +{ + my $args = "subreq=lookup_method_uri;uri=/lookup_method_uri"; + my $expected = "ok"; + my $received = GET_BODY_ASSERT "$uri?$args"; + ok t_cmp $received, $expected, "lookup_method_uri"; +}
diff --git a/2_0_13/t/api/lookup_uri.t b/2_0_13/t/api/lookup_uri.t new file mode 100644 index 0000000..7864a01 --- /dev/null +++ b/2_0_13/t/api/lookup_uri.t
@@ -0,0 +1,30 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $uri = "/TestAPI__lookup_uri"; + +use constant PREFIX => 0; +use constant SUFFIX => 1; + +my %opts = ( + first => [2, 2], # all filters run twice + second => [1, 2], # the top level req filter skipped for the subreq + none => [1, 1], # no request filters run by subreq + default => [1, 1], # same as none +); + +plan tests => scalar keys %opts; + +while (my ($filter, $runs) = each %opts) { + my $args = "subreq=lookup_uri;filter=$filter"; + my $prefix = "pre+" x $runs->[PREFIX]; + my $suffix = "+suf" x $runs->[SUFFIX]; + my $expected = "$prefix$args$suffix"; + my $received = GET_BODY_ASSERT "$uri?$args"; + ok t_cmp $received, $expected, "$args"; +}
diff --git a/2_0_13/t/api/request_rec.t b/2_0_13/t/api/request_rec.t new file mode 100644 index 0000000..f9163ab --- /dev/null +++ b/2_0_13/t/api/request_rec.t
@@ -0,0 +1,6 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest 'GET_BODY_ASSERT'; +print GET_BODY_ASSERT "/TestAPI__request_rec/my_path_info?my_args=3";
diff --git a/2_0_13/t/api/rflush.t b/2_0_13/t/api/rflush.t new file mode 100644 index 0000000..8f4fca0 --- /dev/null +++ b/2_0_13/t/api/rflush.t
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $location = '/TestAPI__rflush'; + +plan tests => 2; + +{ + my $response = GET_BODY "$location?nontied"; + ok t_cmp($response, "[1][2][3][4][56]", + "non-tied rflush creates bucket brigades"); +} + +{ + my $response = GET_BODY "$location?tied"; + ok t_cmp($response, "[1][2][3456]", + "tied STDOUT internal rflush creates bucket brigades"); +} +
diff --git a/2_0_13/t/api/sendfile.t b/2_0_13/t/api/sendfile.t new file mode 100644 index 0000000..6c3d5e5 --- /dev/null +++ b/2_0_13/t/api/sendfile.t
@@ -0,0 +1,64 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use File::Spec::Functions qw(catfile); + +my $url = '/TestAPI__sendfile'; + +my $file = catfile Apache::Test::vars('serverroot'), + 'response/TestAPI/sendfile.pm'; + +my $contents; +open my $fh, $file or die "can't open $file: $!"; +# need binmode on Win32 so as not to strip \r, which +# are included when sending with sendfile(). +binmode $fh; +{ local $/; $contents = <$fh>; } +close $fh; + +plan tests => 7, need 'HTML::HeadParser'; + +{ + my $header = "This is a header\n"; + my $footer = "This is a footer\n"; + + my $received = GET_BODY "$url?withwrapper"; + my $expected = join '', $header, $contents, $footer; + #t_debug($received); + ok $received && $received eq $expected; +} + +{ + my $received = GET_BODY "$url?offset"; + my $expected = substr $contents, 3; + #t_debug($received); + ok $received && $received eq $expected; +} + +{ + my $received = GET_BODY "$url?len"; + my $expected = substr $contents, 3, 50; + #t_debug($received); + ok $received && $received eq $expected; +} + +{ + # rc is checked and handled by the code + my $res = GET "$url?noexist.txt"; + ok t_cmp($res->code, 500, "failed sendfile"); + #t_debug($res->content); + ok $res->content =~ /an internal error/; +} + +{ + # rc is not checked in this one, testing the exception throwing + my $res = GET "$url?noexist-n-nocheck.txt"; + ok t_cmp($res->code, 500, "failed sendfile"); + #t_debug($res->content); + ok $res->content =~ /an internal error/; +}
diff --git a/2_0_13/t/api/slurp_filename.t b/2_0_13/t/api/slurp_filename.t new file mode 100644 index 0000000..b75da7e --- /dev/null +++ b/2_0_13/t/api/slurp_filename.t
@@ -0,0 +1,7 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache::TestRequest 'GET_BODY_ASSERT'; + +# we want r->filename to be "/slurp/slurp.pl", even though the +# response handler is TestAPI::slurp_filename + +print GET_BODY_ASSERT "/slurp/slurp.pl";
diff --git a/2_0_13/t/api/status.t b/2_0_13/t/api/status.t new file mode 100644 index 0000000..534da3b --- /dev/null +++ b/2_0_13/t/api/status.t
@@ -0,0 +1,44 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# testing $r->status/status_line + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 6; + +my $location = "/TestAPI__status"; + +{ + # test a valid HTTP/1.1 status code (303). In this test + # the handler returns OK, but sets a custom status. Apache will + # lookup the message "See Other" on its own + my $code = 303; # Apache2::Const::HTTP_SEE_OTHER + my $message = "See Other"; + my $res = GET "$location?$code="; + ok t_cmp $res->code, $code, "code"; + ok t_cmp $res->message, $message, "code message"; + ok t_cmp $res->content, "", "content"; +} + +{ + # test a non-existing HTTP/1.1 status code (499). In this test + # the handler returns OK, but sets a custom status_line. + # it also tries to set status (to a different value), but it + # should be ignored by Apache, since status_line is supposed to + # override status. the handler also sets a custom code message + # modules/http/http_filters.c r372958 + # httpd 'zaps' the status_line if it doesn't match the status + # as of 2.2.1 (not released) so 2.2.2 (released) + + my $code = 499; # not in HTTP/1.1 + my $message = "FooBared"; + my $res = GET "$location?$code=$message"; + ok t_cmp $res->code, $code, "code"; + ok t_cmp $res->message, $message, "code message"; + ok t_cmp $res->content, "", "content"; +} +
diff --git a/2_0_13/t/apr-ext/base64.t b/2_0_13/t/apr-ext/base64.t new file mode 100644 index 0000000..0a6926c --- /dev/null +++ b/2_0_13/t/apr-ext/base64.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::base64; + +plan tests => TestAPRlib::base64::num_of_tests(); + +TestAPRlib::base64::test();
diff --git a/2_0_13/t/apr-ext/brigade.t b/2_0_13/t/apr-ext/brigade.t new file mode 100644 index 0000000..ce65cda --- /dev/null +++ b/2_0_13/t/apr-ext/brigade.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::brigade; + +plan tests => TestAPRlib::brigade::num_of_tests(); + +TestAPRlib::brigade::test();
diff --git a/2_0_13/t/apr-ext/bucket.t b/2_0_13/t/apr-ext/bucket.t new file mode 100644 index 0000000..5f7937f --- /dev/null +++ b/2_0_13/t/apr-ext/bucket.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::bucket; + +plan tests => TestAPRlib::bucket::num_of_tests(); + +TestAPRlib::bucket::test();
diff --git a/2_0_13/t/apr-ext/date.t b/2_0_13/t/apr-ext/date.t new file mode 100644 index 0000000..675d5c0 --- /dev/null +++ b/2_0_13/t/apr-ext/date.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::date; + +plan tests => TestAPRlib::date::num_of_tests(); + +TestAPRlib::date::test();
diff --git a/2_0_13/t/apr-ext/error.t b/2_0_13/t/apr-ext/error.t new file mode 100644 index 0000000..297637a --- /dev/null +++ b/2_0_13/t/apr-ext/error.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::error; + +plan tests => TestAPRlib::error::num_of_tests(); + +TestAPRlib::error::test();
diff --git a/2_0_13/t/apr-ext/finfo.t b/2_0_13/t/apr-ext/finfo.t new file mode 100644 index 0000000..828edee --- /dev/null +++ b/2_0_13/t/apr-ext/finfo.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::finfo; + +plan tests => TestAPRlib::finfo::num_of_tests(); + +TestAPRlib::finfo::test();
diff --git a/2_0_13/t/apr-ext/os.t b/2_0_13/t/apr-ext/os.t new file mode 100644 index 0000000..bc3ca57 --- /dev/null +++ b/2_0_13/t/apr-ext/os.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::os; + +plan tests => TestAPRlib::os::num_of_tests(); + +TestAPRlib::os::test();
diff --git a/2_0_13/t/apr-ext/perlio.t b/2_0_13/t/apr-ext/perlio.t new file mode 100644 index 0000000..543e57d --- /dev/null +++ b/2_0_13/t/apr-ext/perlio.t
@@ -0,0 +1,242 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; + +# XXX: this is pretty much the same test as +# t/response/TestAPR/perlio.pm, but used outside mod_perl +# consider avoiding the code duplication. + +use Apache::Test; +use Apache::TestUtil; +use Apache2::Build (); + +use Fcntl (); +use File::Spec::Functions qw(catfile); + +#XXX: APR::LARGE_FILES_CONFLICT constant? +#XXX: you can set to zero if largefile support is not enabled in Perl +use constant LARGE_FILES_CONFLICT => 1; + +my $build = Apache2::Build->build_config; + +# XXX: only when apr-config is found APR will be linked against +# libapr/libaprutil, probably need a more intuitive method for this +# prerequisite +# also need to check whether we build against the source tree, in +# which case we APR.so won't be linked against libapr/libaprutil +my $has_apr_config = $build->{apr_config_path} && + !$build->httpd_is_source_tree; + +my $has_perlio_layers = 0; +if ($has_apr_config) { + require APR; + require APR::PerlIO; + $has_perlio_layers = 1 if APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED(); +} + +my $tests = 12; +my $lfs_tests = 3; + +$tests += $lfs_tests unless LARGE_FILES_CONFLICT; +require APR; require APR::PerlIO; +plan tests => $tests, + need {"this build couldn't find apr-config" => $has_apr_config, + "this build doesn't support PerlIO layers" => $has_perlio_layers, + }; + +require APR::Pool; + +my $pool = APR::Pool->new(); + +my $vars = Apache::Test::config()->{vars}; +my $dir = catfile $vars->{documentroot}, "perlio-ext"; + +t_mkdir($dir); + +my $sep = "-- sep --\n"; +my @lines = ("This is a test: $$\n", "test line --sep two\n"); + +my $expected = $lines[0]; +my $expected_all = join $sep, @lines; + +# write file +my $file = catfile $dir, "test"; +t_debug "open file $file for writing"; +my $foo = "bar"; +open my $fh, ">:APR", $file, $pool + or die "Cannot open $file for writing: $!"; +ok ref($fh) eq 'GLOB'; + +t_debug "write to a file:\n$expected\n"; +print $fh $expected_all; +close $fh; + +# open() failure test +{ + # workaround for locale setups where the error message may be + # in a different language + open my $fh, "perlio_this_file_cannot_exist"; + my $errno_string = "$!"; + + # non-existent file + my $file = "/this/file/does/not/exist"; + if (open my $fh, "<:APR", $file, $pool) { + t_debug "must not be able to open $file!"; + ok 0; + close $fh; + } else { + ok t_cmp("$!", + $errno_string, + "expected failure"); + } +} + +# seek/tell() tests +unless (LARGE_FILES_CONFLICT) { + open my $fh, "<:APR", $file, $pool + or die "Cannot open $file for reading: $!"; + + # read the whole file so we can test the buffer flushed + # correctly on seek. + my $dummy = join '', <$fh>; + + # Fcntl::SEEK_SET() + my $pos = 3; # rewinds after reading 6 chars above + seek $fh, $pos, Fcntl::SEEK_SET(); + my $got = tell($fh); + ok t_cmp($got, + $pos, + "seek/tell the file Fcntl::SEEK_SET"); + + # Fcntl::SEEK_CUR() + my $step = 10; + $pos = tell($fh) + $step; + seek $fh, $step, Fcntl::SEEK_CUR(); + $got = tell($fh); + ok t_cmp($got, + $pos, + "seek/tell the file Fcntl::SEEK_CUR"); + + # Fcntl::SEEK_END() + $pos = -s $file; + seek $fh, 0, Fcntl::SEEK_END(); + $got = tell($fh); + ok t_cmp($got, + $pos, + "seek/tell the file Fcntl::SEEK_END"); + + close $fh; +} + +# read() tests +{ + open my $fh, "<:APR", $file, $pool + or die "Cannot open $file for reading: $!"; + + # basic open test + ok ref($fh) eq 'GLOB'; + + # basic single line read + ok t_cmp(scalar(<$fh>), + $expected, + "single line read"); + + # slurp mode + seek $fh, 0, Fcntl::SEEK_SET(); # rewind to the start + local $/; + ok t_cmp(scalar(<$fh>), + $expected_all, + "slurp file"); + + # test ungetc (a long sep requires read ahead) + seek $fh, 0, Fcntl::SEEK_SET(); # rewind to the start + local $/ = $sep; + my @got_lines = <$fh>; + my @expect = ($lines[0] . $sep, $lines[1]); + ok t_cmp(\@got_lines, + \@expect, + "custom complex input record sep read"); + + close $fh; +} + + +# eof() tests +{ + open my $fh, "<:APR", $file, $pool + or die "Cannot open $file for reading: $!"; + + ok t_cmp(0, + int eof($fh), # returns false, not 0 + "not end of file"); + # go to the end and read so eof will return 1 + seek $fh, 0, Fcntl::SEEK_END(); + my $received = <$fh>; + + t_debug($received); + + ok t_cmp(eof($fh), + 1, + "end of file"); + close $fh; +} + +# dup() test +{ + open my $fh, "<:APR", $file, $pool + or die "Cannot open $file for reading: $!"; + + open my $dup_fh, "<&:APR", $fh + or die "Cannot dup $file for reading: $!"; + close $fh; + ok ref($dup_fh) eq 'GLOB'; + + my $received = <$dup_fh>; + + close $dup_fh; + ok t_cmp($received, + $expected, + "read/write a dupped file"); +} + +# unbuffered write +{ + open my $wfh, ">:APR", $file, $pool + or die "Cannot open $file for writing: $!"; + open my $rfh, "<:APR", $file, $pool + or die "Cannot open $file for reading: $!"; + + my $expected = "This is an un buffering write test"; + # unbuffer + my $oldfh = select($wfh); $| = 1; select($oldfh); + print $wfh $expected; # must be flushed to disk immediately + + ok t_cmp(scalar(<$rfh>), + $expected, + "file unbuffered write"); + + # buffer up + $oldfh = select($wfh); $| = 0; select($oldfh); + print $wfh $expected; # should be buffered up and not flushed + + ok t_cmp(scalar(<$rfh>), + undef, + "file buffered write"); + + close $wfh; + close $rfh; + +} + + +# XXX: need tests +# - for stdin/out/err as they are handled specially + +# XXX: tmpfile is missing: +# consider to use 5.8's syntax: +# open $fh, "+>", undef; + +# cleanup: t_mkdir will remove the whole tree including the file +
diff --git a/2_0_13/t/apr-ext/pool.t b/2_0_13/t/apr-ext/pool.t new file mode 100644 index 0000000..a2f9f15 --- /dev/null +++ b/2_0_13/t/apr-ext/pool.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::pool; + +plan tests => TestAPRlib::pool::num_of_tests(); + +TestAPRlib::pool::test();
diff --git a/2_0_13/t/apr-ext/status.t b/2_0_13/t/apr-ext/status.t new file mode 100644 index 0000000..e5232cf --- /dev/null +++ b/2_0_13/t/apr-ext/status.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::status; + +plan tests => TestAPRlib::status::num_of_tests(); + +TestAPRlib::status::test();
diff --git a/2_0_13/t/apr-ext/string.t b/2_0_13/t/apr-ext/string.t new file mode 100644 index 0000000..ec2389f --- /dev/null +++ b/2_0_13/t/apr-ext/string.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::string; + +plan tests => TestAPRlib::string::num_of_tests(); + +TestAPRlib::string::test();
diff --git a/2_0_13/t/apr-ext/table.t b/2_0_13/t/apr-ext/table.t new file mode 100644 index 0000000..2e6f599 --- /dev/null +++ b/2_0_13/t/apr-ext/table.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::table; + +plan tests => TestAPRlib::table::num_of_tests(); + +TestAPRlib::table::test();
diff --git a/2_0_13/t/apr-ext/threadmutex.t b/2_0_13/t/apr-ext/threadmutex.t new file mode 100644 index 0000000..64d9d02 --- /dev/null +++ b/2_0_13/t/apr-ext/threadmutex.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::threadmutex; + +plan tests => TestAPRlib::threadmutex::num_of_tests(), need_threads; + +TestAPRlib::threadmutex::test();
diff --git a/2_0_13/t/apr-ext/threadrwlock.t b/2_0_13/t/apr-ext/threadrwlock.t new file mode 100644 index 0000000..ba4a5db --- /dev/null +++ b/2_0_13/t/apr-ext/threadrwlock.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::threadrwlock; + +plan tests => TestAPRlib::threadrwlock::num_of_tests(), need_threads; + +TestAPRlib::threadrwlock::test();
diff --git a/2_0_13/t/apr-ext/uri.t b/2_0_13/t/apr-ext/uri.t new file mode 100644 index 0000000..88d601d --- /dev/null +++ b/2_0_13/t/apr-ext/uri.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::uri; + +plan tests => TestAPRlib::uri::num_of_tests(); + +TestAPRlib::uri::test();
diff --git a/2_0_13/t/apr-ext/util.t b/2_0_13/t/apr-ext/util.t new file mode 100644 index 0000000..dd36331 --- /dev/null +++ b/2_0_13/t/apr-ext/util.t
@@ -0,0 +1,12 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; +use Apache::Test; + +use TestAPRlib::util; + +plan tests => TestAPRlib::util::num_of_tests(); + +TestAPRlib::util::test();
diff --git a/2_0_13/t/apr-ext/uuid.t b/2_0_13/t/apr-ext/uuid.t new file mode 100644 index 0000000..973bb65 --- /dev/null +++ b/2_0_13/t/apr-ext/uuid.t
@@ -0,0 +1,31 @@ +#!perl -T +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache2::Build (); + +# XXX: only when apr-config is found APR will be linked against +# libapr/libaprutil, probably need a more intuitive method for this +# prerequisite +# also need to check whether we build against the source tree, in +# which case we APR.so won't be linked against libapr/libaprutil +# In order to do this for all the apr-ext tests, could have +# a wrapper around plan() that does a check like +####### +# my $build = Apache2::Build->build_config; +# +# my $has_apr_config = $build->{apr_config_path} && +# !$build->httpd_is_source_tree; +# plan tests => TestAPRlib::uuid::num_of_tests(), +# need {"the build couldn't find apr-config" => $has_apr_config}; +###### +# that is called from some TestAPRlib::common. + +use TestAPRlib::uuid; + +plan tests => TestAPRlib::uuid::num_of_tests(); + +TestAPRlib::uuid::test();
diff --git a/2_0_13/t/apr/constants.t b/2_0_13/t/apr/constants.t new file mode 100644 index 0000000..b9921e4 --- /dev/null +++ b/2_0_13/t/apr/constants.t
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use ExtUtils::testlib; +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache::TestUtil; + +use APR::Const -compile => qw(:common POLLIN :filetype); +use APR::Const qw(:hook); + +plan tests => 5; + +ok ! defined &POLLIN; +ok t_cmp (APR::Const::SUCCESS, 0, 'APR::Const::SUCCESS'); +ok t_cmp (APR::Const::POLLIN, 0x001, 'APR::Const::POLLIN'); +ok t_cmp (HOOK_LAST, 20, 'HOOK_LAST'); +ok t_cmp (APR::Const::FILETYPE_UNKFILE, 127, 'APR::UNKFILE');
diff --git a/2_0_13/t/apr/pool_lifetime.t b/2_0_13/t/apr/pool_lifetime.t new file mode 100644 index 0000000..4955c6f --- /dev/null +++ b/2_0_13/t/apr/pool_lifetime.t
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +Apache::TestRequest::user_agent(keep_alive => 1); + +plan tests => 2, need 'HTML::HeadParser'; + +my $module = 'TestAPR::pool_lifetime'; +my $location = '/' . Apache::TestRequest::module2path($module); + +for (1..2) { + my $expected = "Pong"; + my $received = GET $location; + + ok t_cmp( + $received->content, + $expected, + "Pong", + ); +}
diff --git a/2_0_13/t/compat/conn_authen.t b/2_0_13/t/compat/conn_authen.t new file mode 100644 index 0000000..880862f --- /dev/null +++ b/2_0_13/t/compat/conn_authen.t
@@ -0,0 +1,13 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need need_lwp, need_auth, 'HTML::HeadParser'; + +my $location = "/TestCompat__conn_authen"; + +ok GET_OK $location, username => 'dougm', password => 'foo'; +
diff --git a/2_0_13/t/compat/request_body.t b/2_0_13/t/compat/request_body.t new file mode 100644 index 0000000..fc02b9b --- /dev/null +++ b/2_0_13/t/compat/request_body.t
@@ -0,0 +1,80 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 5; + +my $location = "/TestCompat__request_body"; + +# $r->send_http_header('text/plain'); +{ + my @data = (test => 'content-type'); + ok t_cmp( + HEAD(query(@data))->content_type(), + "text/plain", + q{$r->send_http_header('text/plain')} + ); +} + +# $r->content +{ + my @data = (test => 'content'); + my $content = join '=', @data; + ok t_cmp( + POST_BODY($location, content => $content), + "@data", + q{$r->content via POST} + ); +} + +# $r->Apache2::args +{ + my @data = (test => 'args'); + ok t_cmp( + GET_BODY(query(@data)), + "@data", + q{$r->Apache2::args} + ); +} + +# encoding/decoding +{ + my %data = ( + test => 'decoding', + body => '%DC%DC+%EC%2E+%D6%D6+%D6%2F', + ); + ok t_cmp( + GET_BODY(query(%data)), + $data{body}, + q{decoding} + ); +} + + +# big POST +{ + my %data = ( + test => 'big_input', + body => ('x' x 819_235), + ); + my $content = join '=', %data; + ok t_cmp( + POST_BODY($location, content => $content), + length($data{body}), + q{big POST} + ); +} + + + +### helper subs ### +sub query { + my (%args) = (@_ % 2) ? %{+shift} : @_; + "$location?" . join '&', map { "$_=$args{$_}" } keys %args; +} +
diff --git a/2_0_13/t/compat/send_fd.t b/2_0_13/t/compat/send_fd.t new file mode 100644 index 0000000..a2e6d97 --- /dev/null +++ b/2_0_13/t/compat/send_fd.t
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +use File::Spec::Functions qw(catfile); + +plan tests => 3, need 'HTML::HeadParser'; + +my $config = Apache::Test::config(); + +my $url = '/TestCompat__send_fd'; + +my $data = GET_BODY($url); + +ok $data; + +my $module = catfile Apache::Test::vars('serverroot'), + 'response/TestCompat/send_fd.pm'; + +ok length($data) == -s $module; + +$data = GET_BODY("$url?noexist.txt"); + +ok $data =~ /Not Found/;
diff --git a/2_0_13/t/conf/extra.conf.in b/2_0_13/t/conf/extra.conf.in new file mode 100644 index 0000000..67c2e23 --- /dev/null +++ b/2_0_13/t/conf/extra.conf.in
@@ -0,0 +1,114 @@ +# needed to test $r->psignature +ServerSignature On + +# The following tests require more than one interpreter during the +# same request: +# +# perls Test +# ----------- +# 2 t/modules/apache_status +# 2 t/filter/both_str_req_proxy +# 2 t/modules/proxy +# +# the following tests will clone a new perl interpreter via +# ithreads.pm regardless of how many interpreters mod_perl has: +# +# t/perl/ithreads +# t/perl/ithreads2 +# +# therefore we need at most 2 interpreters, the missing one loading on +# demand, but we start only with 1, so the startup is quick, +# especially since we immediately restart. We also want MaxSpare to be +# the same as Max, since we have more than one test that requires more +# than one interpreter, so don't waste time to kill and start a new +# one later -- keep it around once spawned +# +# Adjust PerlInterpMax and PerlInterpMaxSpare if the requirements change +<IfDefine PERL_USEITHREADS> + PerlInterpStart 1 + PerlInterpMax 2 + PerlInterpMinSpare 1 + PerlInterpMaxSpare 2 +</IfDefine> + +# make sure that we test under Taint and warnings mode enabled +PerlSwitches -wT + +PerlChildExitHandler ModPerl::Test::exit_handler +PerlModule TestExit::FromPerlModule + +#for t/modules/include.t +<Directory @ServerRoot@/htdocs/includes> + <IfModule mod_mime.c> + AddOutputFilter INCLUDES .shtml + </IfModule> + # #virtual include of a script that sets content type is + # considered the same as #cmd by mod_include, + # therefore can't use IncludesNOEXEC here + Options Indexes FollowSymLinks Includes +</Directory> + +<Directory @ServerRoot@/htdocs/includes-registry> + SetHandler perl-script + Options +ExecCGI +IncludesNoExec + PerlResponseHandler ModPerl::Registry + PerlOptions +ParseHeaders +GlobalRequest + <IfModule mod_mime.c> + AddOutputFilter INCLUDES .spl + </IfModule> +</Directory> + +<IfModule mod_perl.c> + <IfDefine !MODPERL2> + # This should not be touched, since we're running with mod_perl 2 + PerlModule Doesnt::Exist + </IfDefine> +</IfModule> + +# <sandbox-friendly> +# keep everything self-contained, to avoid problems with sandboxes +# which break when things try to run off /tmp +<IfModule mod_cgid.c> + ScriptSock logs/cgisock +</IfModule> +<IfModule mod_env.c> + SetEnv TMPDIR @t_logs@ + + # pass ld_library_path for non standard lib locations + # [rt.cpan.org #66085] + PassEnv LD_LIBRARY_PATH +</IfModule> +# </sandbox-friendly> + +<Location /status/perl> +# PerlSetVar StatusOptionsAll On +# PerlSetVar StatusDumper On +# PerlSetVar StatusPeek On +# PerlSetVar StatusLexInfo On +# PerlSetVar StatusDeparse On +# PerlSetVar StatusDeparseOptions "-p -sC" + PerlSetVar StatusTerse On +# PerlSetVar StatusTerseSize On +# PerlSetVar StatusTerseSizeMainSummary On + SetHandler modperl + PerlResponseHandler Apache2::Status +</Location> + +# for TestApache::util +PerlPassEnv LC_CTYPE +PerlPassEnv LC_TIME + +# for TestCompat::apache_file +PerlPassEnv TMPDIR +PerlPassEnv TEMP + +# see t/filter/out_apache.t +<VirtualHost filter_out_apache> + <IfModule mod_include.c> + # this filter is on purpose configured outside the Location + PerlSetOutputFilter INCLUDES + <Location /> + Options +Includes + </Location> + </IfModule> +</VirtualHost>
diff --git a/2_0_13/t/conf/extra.last.conf.in b/2_0_13/t/conf/extra.last.conf.in new file mode 100644 index 0000000..c9e10ad --- /dev/null +++ b/2_0_13/t/conf/extra.last.conf.in
@@ -0,0 +1,139 @@ +PerlModule Apache2::Module + +PerlPostConfigRequire @ServerRoot@/conf/post_config_startup.pl + +### --------------------------------- ### +<Perl > +use Apache::Test (); +if (Apache::Test::have_module('mod_alias.c')) { + push @Alias, ['/perl_sections', '@DocumentRoot@']; + $Location{'/perl_sections'} = { + 'PerlInitHandler' => 'ModPerl::Test::add_config', + 'AuthType' => 'Basic', + 'AuthName' => 'PerlSection', + 'PerlAuthenHandler' => 'TestHooks::authen_basic', + }; +} +</Perl> + +<Perl > +#Test tied %Location +use TestCommon::TiePerlSection (); +tie %Location, 'TestCommon::TiePerlSection'; +$Location{'/tied'} = 'test_tied'; + +$Apache2::PerlSections::Save = 1; +$Location{'/perl_sections_saved'} = { + 'AuthName' => 'PerlSection', + }; +#This is a comment +$TestDirective::perl::comments="yes"; +$TestDirective::perl::PACKAGE = __PACKAGE__; +</Perl> + +<Perl > +$Apache2::PerlSections::Save = 1; +$TestDirective::perl::filename = __FILE__; +$TestDirective::perl::dollar_zero = $0; +$TestDirective::perl::line = __LINE__; +</Perl> + +#Handle re-entrant <Perl> sections +<Perl > + use File::Spec; + my $file = File::Spec->catfile('@ServerRoot@', 'conf', 'perlsection.conf'); + open my $fh, ">$file" or die "Can't open $file: $!"; + print $fh join "\n", ('<Perl >', '$TestDirective::perl::Included++;', '</Perl>'); + close $fh; + $Include = $file; +</Perl> + +#Deprecated access to Apache2::ReadConfig:: still works +<Perl > +use Apache::Test (); +if (Apache::Test::have_module('mod_alias.c')) { + push @Apache2::ReadConfig::Alias, + ['/perl_sections_readconfig', '@DocumentRoot@']; + $Apache2::ReadConfig::Location{'/perl_sections_readconfig'} = { + 'PerlInitHandler' => 'ModPerl::Test::add_config', + 'AuthType' => 'Basic', + 'AuthName' => 'PerlSection', + 'PerlAuthenHandler' => 'TestHooks::authen_basic', + }; +} +</Perl> + +<Perl > +$TestDirective::perl::base_server = Apache2::PerlSections->server; +</Perl> + +<Perl > +# make sure that these are set at the earliest possible time +die '$ENV{MOD_PERL} not set!' unless $ENV{MOD_PERL}; +die '$ENV{MOD_PERL_API_VERSION} not set!' + unless $ENV{MOD_PERL_API_VERSION} == 2; +</Perl> + +<VirtualHost perlsections> + <Perl > + $TestDirective::perl::vhost_server = Apache2::PerlSections->server; + </Perl> +</VirtualHost> + +### --------------------------------- ### +Perl $TestDirective::perl::worked="yes"; + +### --------------------------------- ### +=pod + +The following line is not seen by Apache + +PerlSetVar TestDirective__pod_hidden whatever + +=over apache + +PerlSetVar TestDirective__pod_over_worked yes + +=back + +This is some more pod + +=cut + +PerlSetVar TestDirective__pod_cut_worked yes + +#This used to trigger a segfault on startup +#See http://thread.gmane.org/gmane.comp.apache.mod-perl/22750 +<IfDefine PERL_USEITHREADS> +<VirtualHost inherit> + PerlSwitches +inherit + PerlOptions +Parent + Perl 1 +</VirtualHost> +</IfDefine> + +#Single-line $PerlConfig +<Perl> +if (Apache::Test::have_module('mod_alias.c')) { + $PerlConfig = "Alias /perl_sections_perlconfig_scalar @DocumentRoot@"; +} +</Perl> + +#Multi-line $PerlConfig +<Perl> +if (Apache::Test::have_module('mod_alias.c')) { + $PerlConfig = "Alias /perl_sections_perlconfig_scalar1 @DocumentRoot@ + Alias /perl_sections_perlconfig_scalar2 @DocumentRoot@ + "; +} +</Perl> + +#@PerlConfig +<Perl> +if (Apache::Test::have_module('mod_alias.c')) { + @PerlConfig = ("Alias /perl_sections_perlconfig_array1 @DocumentRoot@", + "Alias /perl_sections_perlconfig_array2 @DocumentRoot@", + ); +} +</Perl> +
diff --git a/2_0_13/t/conf/modperl_extra.pl b/2_0_13/t/conf/modperl_extra.pl new file mode 100644 index 0000000..f80e416 --- /dev/null +++ b/2_0_13/t/conf/modperl_extra.pl
@@ -0,0 +1,142 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +########################################################## +### IMPORTANT: only things that must be run absolutely ### +### during the config phase should be in this file ### +########################################################## +# +# On the 2nd pass, during server-internal restart, none of the code +# running from this file (config phase) will be able to log any STDERR +# messages. This is because Apache redirects STDERR to /dev/null until +# the open_logs phase. That means that any of the code fails, the +# error message will be lost (but it should have failed on the 1st +# pass, when STDERR goes to the console and any error messages are +# properly logged). Therefore avoid putting any code here (unless +# there is no other way) and instead put all the code to be run at the +# server startup into post_config_startup.pl. when the latter is run, +# STDERR is sent to $ErrorLog. +# + +use strict; +use warnings FATAL => 'all'; + +die '$ENV{MOD_PERL} not set!' unless $ENV{MOD_PERL}; +die '$ENV{MOD_PERL_API_VERSION} not set!' + unless $ENV{MOD_PERL_API_VERSION} == 2; + +use File::Spec::Functions qw(canonpath catdir); + +use Apache2::ServerUtil (); +use Apache2::ServerRec (); +use Apache2::Process (); +use Apache2::Log (); + +use Apache2::Const -compile => ':common'; + +reorg_INC(); + +startup_info(); + +test_add_config(); + +test_add_version_component(); + +test_hooks_startup(); + +test_modperl_env(); + + + +### only subs below this line ### + +# need to run from config phase, since we want to adjust @INC as early +# as possible +sub reorg_INC { + # after Apache2 has pushed blib and core dirs including Apache2 on + # top reorg @INC to have first devel libs, then blib libs, and + # only then perl core libs + my $pool = Apache2::ServerUtil->server->process->pool; + my $project_root = canonpath + Apache2::ServerUtil::server_root_relative($pool, ".."); + my (@a, @b, @c); + for (@INC) { + if (m|^\Q$project_root\E|) { + m|blib| ? push @b, $_ : push @a, $_; + } + else { + push @c, $_; + } + } + @INC = (@a, @b, @c); +} + +# this can be run from post_config_startup.pl, but then it'll do the +# logging twice, so in this case it's actually good to have this code +# run during config phase, so it's logged only once (even though it's +# run the second time, but STDERR == /dev/null) +sub startup_info { + my $ap_mods = scalar grep { /^Apache2/ } keys %INC; + my $apr_mods = scalar grep { /^APR/ } keys %INC; + + Apache2::Log->info("$ap_mods Apache2:: modules loaded"); + Apache2::ServerRec->log->info("$apr_mods APR:: modules loaded"); + + my $server = Apache2::ServerUtil->server; + my $vhosts = 0; + for (my $s = $server->next; $s; $s = $s->next) { + $vhosts++; + } + + $server->log->info("base server + $vhosts vhosts ready to run tests"); +} + +# need to run from config phase, since it changes server config +sub test_add_config { + # testing $s->add_config() + my $conf = <<'EOC'; +# must use PerlModule here to check for segfaults +PerlModule Apache::TestHandler +<Location /apache/add_config> + SetHandler perl-script + PerlResponseHandler Apache::TestHandler::ok1 +</Location> +EOC + Apache2::ServerUtil->server->add_config([split /\n/, $conf]); + + # test a directive that triggers an early startup, so we get an + # attempt to use perl's mip early + Apache2::ServerUtil->server->add_config(['<Perl >', '1;', '</Perl>']); +} + +# need to run from config phase, since it registers PerlPostConfigHandler +sub test_add_version_component { + Apache2::ServerUtil->server->push_handlers( + PerlPostConfigHandler => \&add_my_version); + + sub add_my_version { + my ($conf_pool, $log_pool, $temp_pool, $s) = @_; + $s->add_version_component("world domination series/2.0"); + return Apache2::Const::OK; + } +} + +# cleanup files for TestHooks::startup which can't be done from the +# test itself because the files are created at the server startup and +# the test needing these files may run more than once (t/SMOKE) +# +# we need to run it at config phase since we need to cleanup before +# the open_logs phase +sub test_hooks_startup { + require Apache::Test; + my $dir = catdir Apache::Test::vars('documentroot'), qw(hooks startup); + for (<$dir/*>) { + my $file = ($_ =~ /(.*(?:open_logs|post_config)-\d+)/); + unlink $file; + } +} + +sub test_modperl_env { + # see t/response/TestModperl/env.pm + $ENV{MODPERL_EXTRA_PL} = __FILE__; +} + +1;
diff --git a/2_0_13/t/conf/post_config_startup.pl b/2_0_13/t/conf/post_config_startup.pl new file mode 100644 index 0000000..f8a09fb --- /dev/null +++ b/2_0_13/t/conf/post_config_startup.pl
@@ -0,0 +1,151 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +########################################################## +### this file contains code that should be run on the ### +### server startup but not during the config phase ### +########################################################## +use strict; +use warnings FATAL => 'all'; + +use Socket (); # test DynaLoader vs. XSLoader workaround for 5.6.x + +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Process (); +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use Apache2::Connection (); +use Apache2::Log (); + +use APR::Table (); +use APR::Pool (); + +use ModPerl::Util (); #for CORE::GLOBAL::exit + +use Apache2::Const -compile => ':common'; + +END { + warn "END in modperl_extra.pl, pid=$$\n"; +} + +test_apache_resource(); + +test_apache_status(); + +test_loglevel(); + +test_perl_ithreads(); + +test_server_shutdown_cleanup_register(); + +test_method_obj(); + + + +### only subs below this line ### + +sub test_apache_resource { + ### Apache2::Resource tests + + # load first for the menu + require Apache2::Status; + + # uncomment for local tests + #$ENV{PERL_RLIMIT_DEFAULTS} = 1; + #$Apache2::Resource::Debug = 1; + + # requires optional BSD::Resource + return unless eval { require BSD::Resource }; + + require Apache2::Resource; +} + +sub test_apache_status { + ### Apache2::Status tests + require Apache2::Status; + require Apache2::Module; + Apache2::Status->menu_item( + 'test_menu' => "Test Menu Entry", + sub { + my ($r) = @_; + return ["This is just a test entry"]; + } + ) if Apache2::Module::loaded('Apache2::Status'); +} + +# test startup loglevel setting (under threaded mpms loglevel can be +# changed only before threads are started) so here we test whether we +# can still set it after restart +sub test_loglevel { + use Apache2::Const -compile => 'LOG_INFO'; + my $s = Apache2::ServerUtil->server; + my $oldloglevel = $s->loglevel(Apache2::Const::LOG_INFO); + # restore + $s->loglevel($oldloglevel); +} + +sub test_perl_ithreads { + # this is needed for TestPerl::ithreads + # one should be able to boot ithreads at the server startup and + # then access the ithreads setup at run-time when a perl + # interpreter is running on a different native threads (testing + # that perl interpreters and ithreads aren't related to the native + # threads they are running on). This should work starting from + # perl-5.8.1 and higher. + use Config; + if ($] >= 5.008001 && $Config{useithreads}) { + eval { require threads; "threads"->import() }; + } +} + +sub test_server_shutdown_cleanup_register { + Apache2::ServerUtil::server_shutdown_cleanup_register sub { + warn <<'EOF'; +*** done with server_shutdown_cleanup_register *** +******************************************************************************** +EOF + }; + + Apache2::ServerUtil::server_shutdown_cleanup_register sub { + die "testing server_shutdown_cleanup_register\n"; + }; + + Apache2::ServerUtil::server_shutdown_cleanup_register sub { + warn <<'EOF'; +******************************************************************************** +*** This is a test for Apache2::ServerUtil::server_shutdown_cleanup_register *** +*** Following a line consisting only of * characters there should be a line *** +*** containing *** +*** "cleanup died: testing server_shutdown_cleanup_register". *** +*** The next line should then read *** +*** "done with server_shutdown_cleanup_register" *** +******************************************************************************** +EOF + }; +} + +sub ModPerl::Test::exit_handler { + my ($p, $s) = @_; + + $s->log->info("Child process pid=$$ is exiting"); + + Apache2::Const::OK; + +} + +sub test_method_obj { + # see t/modperl/methodobj + require TestModperl::methodobj; + $TestModperl::MethodObj = TestModperl::methodobj->new; +} + +sub ModPerl::Test::add_config { + my $r = shift; + + #test adding config at request time + $r->add_config(['require valid-user']); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/directive/perl.t b/2_0_13/t/directive/perl.t new file mode 100644 index 0000000..1ffe3b2 --- /dev/null +++ b/2_0_13/t/directive/perl.t
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 8, need need_auth, 'mod_alias.c', 'HTML::HeadParser'; + +#so we don't have to require lwp +my @auth = (Authorization => 'Basic ZG91Z206Zm9v'); #dougm:foo + + +foreach my $location ("/perl_sections/index.html", + "/perl_sections_readconfig/index.html") { + + sok { + ! GET_OK $location; + }; + + sok { + my $rc = GET_RC $location; + $rc == 401; + }; + + sok { + GET_OK $location, @auth; + }; + + sok { + ! GET_OK $location, $auth[0], $auth[1] . 'bogus'; + }; +}
diff --git a/2_0_13/t/directive/perlcleanuphandler.t b/2_0_13/t/directive/perlcleanuphandler.t new file mode 100644 index 0000000..47bbc1e --- /dev/null +++ b/2_0_13/t/directive/perlcleanuphandler.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest 'GET_BODY'; + +plan tests => 3, need_lwp; + +my $module = 'TestDirective::perlcleanuphandler'; + +Apache::TestRequest::user_agent(reset => 1, keep_alive=>1); +sub u {Apache::TestRequest::module2url($module, {path=>$_[0]})} + +t_debug("connecting to ".u('')); +ok t_cmp GET_BODY(u('/get?incr')), 'UNDEF', 'before increment'; +ok t_cmp GET_BODY(u('/get')), '1', 'incremented'; +(undef)=GET_BODY(u('/index.html?incr')); +ok t_cmp GET_BODY(u('/get')), '2', 'incremented again';
diff --git a/2_0_13/t/directive/perlloadmodule2.t b/2_0_13/t/directive/perlloadmodule2.t new file mode 100644 index 0000000..6533011 --- /dev/null +++ b/2_0_13/t/directive/perlloadmodule2.t
@@ -0,0 +1,32 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $url = "/TestDirective__perlloadmodule2"; + +plan tests => 3; + +{ + my $location = "$url?srv"; + my $expected = "srv: one two"; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "access server settings"); +} + +{ + my $location = "$url?"; + my $expected = "dir: one two three four"; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "server/dir merge"); +} + +{ + my $location = "$url/subdir"; + my $expected = "dir: one two three four five six"; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "server/dir/subdir merge"); +}
diff --git a/2_0_13/t/directive/perlloadmodule3.t b/2_0_13/t/directive/perlloadmodule3.t new file mode 100644 index 0000000..8ced2a6 --- /dev/null +++ b/2_0_13/t/directive/perlloadmodule3.t
@@ -0,0 +1,99 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $module = "TestDirective::perlloadmodule3"; +my $config = Apache::Test::config(); +my $base_hostport = Apache::TestRequest::hostport($config); +my $path = Apache::TestRequest::module2path($module); + +# XXX: probably a good idea to split into more sub-tests, that test +# smaller portions of information, but requires a more elaborate +# logic. Alternatively could use diff($expected, $received). + +plan tests => 3; + +t_debug("connecting to $base_hostport"); +{ + my $expected = <<EOI; +Processing by main server. + +Section 1: Main Server +MyAppend : MainServer +MyList : ["MainServer"] +MyOverride : MainServer +MyPlus : 5 + +Section 2: Location +MyAppend : MainServer +MyList : ["MainServer"] +MyOverride : MainServer +MyPlus : 5 +EOI + my $location = "http://$base_hostport/$path"; + my $received = GET_BODY $location; + ok t_cmp($expected, $received, "server merge"); +} + +Apache::TestRequest::module($module); +my $hostport = Apache::TestRequest::hostport($config); + +t_debug("connecting to $hostport"); +{ + my $expected = <<EOI; +Processing by virtual host. + +Section 1: Main Server +MyAppend : MainServer +MyList : ["MainServer"] +MyOverride : MainServer +MyPlus : 5 + +Section 2: Virtual Host +MyAppend : MainServer VHost +MyList : ["MainServer", "VHost"] +MyOverride : VHost +MyPlus : 7 + +Section 3: Location +MyAppend : MainServer VHost Dir +MyList : ["MainServer", "VHost", "Dir"] +MyOverride : Dir +MyPlus : 10 +EOI + my $location = "http://$hostport/$path"; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "server/dir merge"); +} + +{ + my $expected = <<EOI; +Processing by virtual host. + +Section 1: Main Server +MyAppend : MainServer +MyList : ["MainServer"] +MyOverride : MainServer +MyPlus : 5 + +Section 2: Virtual Host +MyAppend : MainServer VHost +MyList : ["MainServer", "VHost"] +MyOverride : VHost +MyPlus : 7 + +Section 3: Location +MyAppend : MainServer VHost Dir SubDir +MyList : ["MainServer", "VHost", "Dir", "SubDir"] +MyOverride : SubDir +MyPlus : 11 +EOI + + my $location = "http://$hostport/$path/subdir"; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "server/dir/subdir merge"); +}
diff --git a/2_0_13/t/directive/perlloadmodule4.t b/2_0_13/t/directive/perlloadmodule4.t new file mode 100644 index 0000000..8efff0f --- /dev/null +++ b/2_0_13/t/directive/perlloadmodule4.t
@@ -0,0 +1,14 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest; +use Apache::Test; + +my $module = "TestDirective::perlloadmodule4"; +my $config = Apache::Test::config(); +Apache::TestRequest::module($module); +my $hostport = Apache::TestRequest::hostport($config); +my $path = Apache::TestRequest::module2path($module); + +print GET_BODY_ASSERT "http://$hostport/$path";
diff --git a/2_0_13/t/directive/perlloadmodule5.t b/2_0_13/t/directive/perlloadmodule5.t new file mode 100644 index 0000000..a466dee --- /dev/null +++ b/2_0_13/t/directive/perlloadmodule5.t
@@ -0,0 +1,14 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest; +use Apache::Test; + +my $module = "TestDirective::perlloadmodule5"; +my $config = Apache::Test::config(); +Apache::TestRequest::module($module); +my $hostport = Apache::TestRequest::hostport($config); +my $path = Apache::TestRequest::module2path($module); + +print GET_BODY_ASSERT "http://$hostport/$path";
diff --git a/2_0_13/t/directive/perlloadmodule6.t b/2_0_13/t/directive/perlloadmodule6.t new file mode 100644 index 0000000..038d148 --- /dev/null +++ b/2_0_13/t/directive/perlloadmodule6.t
@@ -0,0 +1,14 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest; +use Apache::Test; + +my $module = "TestDirective::perlloadmodule6"; +my $config = Apache::Test::config(); +Apache::TestRequest::module($module); +my $hostport = Apache::TestRequest::hostport($config); +my $path = Apache::TestRequest::module2path($module); + +print GET_BODY_ASSERT "http://$hostport/$path";
diff --git a/2_0_13/t/directive/perlmodule.t b/2_0_13/t/directive/perlmodule.t new file mode 100644 index 0000000..e1b3b6f --- /dev/null +++ b/2_0_13/t/directive/perlmodule.t
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# this test tests PerlRequire configuration directive +######################################################################## + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $module = 'TestDirective::perlmodule'; + +plan tests => 1; + +Apache::TestRequest::module($module); + +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport($config); +my $path = Apache::TestRequest::module2path($module); +t_debug("connecting to $hostport"); + +ok t_cmp(GET_BODY("/$path"), + $module, + "testing PerlModule in $module"); +
diff --git a/2_0_13/t/directive/perlrequire.t b/2_0_13/t/directive/perlrequire.t new file mode 100644 index 0000000..f2b48b5 --- /dev/null +++ b/2_0_13/t/directive/perlrequire.t
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# this test tests PerlRequire configuration directive +######################################################################## + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $config = Apache::Test::config(); +my $path = Apache::TestRequest::module2path('TestDirective::perlrequire'); + +my %checks = ( + 'default' => 'PerlRequired by Parent', + 'TestDirective::perlrequire' => 'PerlRequired by VirtualHost', +); + +delete $checks{'TestDirective::perlrequire'} unless have_perl 'ithreads'; + +plan tests => scalar keys %checks; + +for my $module (sort keys %checks) { + + Apache::TestRequest::module($module); + my $hostport = Apache::TestRequest::hostport($config); + t_debug("connecting to $hostport"); + + ok t_cmp(GET_BODY("http://$hostport/$path"), + $checks{$module}, + "testing PerlRequire in $module"); +}
diff --git a/2_0_13/t/directive/setupenv.t b/2_0_13/t/directive/setupenv.t new file mode 100644 index 0000000..1778be8 --- /dev/null +++ b/2_0_13/t/directive/setupenv.t
@@ -0,0 +1,46 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 3; + +my $location = '/TestDirective__setupenv'; + +my $env = GET_BODY $location; + +ok $env; + +my %env; + +for my $line (split /\n/, $env) { + next unless $line =~ /=/; + my ($key, $val) = split /=/, $line, 2; + $env{$key} = $val || ''; +} + +ok t_cmp $env{REQUEST_URI}, $location, "testing REQUEST_URI"; + +{ + # on Win32, some user environment variables, like HOME, may be + # passed through (via Apache?) if set, while system environment + # variables are not. so try to find an existing shell variable + # (that is not passed by Apache) and use it in the test to make + # sure mod_perl doesn't see it + + my $var; + for (qw(SHELL USER OS)) { + $var = $_, last if exists $ENV{$_}; + } + + if (defined $var) { + ok t_cmp $env{$var}, undef, "env var $var=$ENV{$var} is ". + "set in shell, but shouldn't be seen inside mod_perl"; + } + else { + skip "couldn't find a suitable env var to test against", 0; + } +}
diff --git a/2_0_13/t/error/runtime.t b/2_0_13/t/error/runtime.t new file mode 100644 index 0000000..dd961a5 --- /dev/null +++ b/2_0_13/t/error/runtime.t
@@ -0,0 +1,38 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $location = "/TestError__runtime"; + +my @untrapped = qw(plain_mp_error plain_non_mp_error + die_hook_confess_mp_error die_hook_confess_non_mp_error + die_hook_custom_mp_error die_hook_custom_non_mp_error); +my @trapped = qw(eval_block_mp_error eval_block_non_mp_error + eval_string_mp_error eval_block_non_error + overload_test); + +plan tests => @untrapped + @trapped; + +for my $type (@untrapped) { + my $res = GET("$location?$type"); + #t_debug($res->content); + ok t_cmp( + $res->code, + 500, + "500 error on $type exception", + ); +} + +for my $type (@trapped) { + my $body = GET_BODY("$location?$type"); + ok t_cmp( + $body, + "ok $type", + "200 on $type exception", + ); +} +
diff --git a/2_0_13/t/error/syntax.t b/2_0_13/t/error/syntax.t new file mode 100644 index 0000000..81eaa04 --- /dev/null +++ b/2_0_13/t/error/syntax.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = "/TestError__syntax"; + +t_client_log_error_is_expected(); +my $res = GET($location); +#t_debug($res->content); +ok t_cmp( + $res->code, + 500, + "500 error on syntax error", + );
diff --git a/2_0_13/t/filter/TestFilter/both_str_con_add.pm b/2_0_13/t/filter/TestFilter/both_str_con_add.pm new file mode 100644 index 0000000..d2bbbe5 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/both_str_con_add.pm
@@ -0,0 +1,92 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::both_str_con_add; + +# insert an input filter which lowers the case of the data +# insert an output filter which adjusts s/modperl/mod_perl/ + +# see also TestFilter::echo_filter + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use APR::Bucket (); +use APR::Brigade (); +use APR::Error (); +use APR::Socket; + +use base qw(Apache2::Filter); + +use APR::Const -compile => qw(SUCCESS EOF SO_NONBLOCK); +use Apache2::Const -compile => qw(OK MODE_GETLINE); + +sub pre_connection { + my Apache2::Connection $c = shift; + + $c->add_input_filter(\&in_filter); + $c->add_output_filter(\&out_filter); + + return Apache2::Const::OK; +} + +sub in_filter : FilterConnectionHandler { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + $filter->print(lc $buffer); + } + + # test that $filter->ctx works here + $filter->ctx(1); + + Apache2::Const::OK; +} + +sub out_filter : FilterConnectionHandler { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + $buffer =~ s/modperl/mod_perl/; + $filter->print($buffer); + } + + Apache2::Const::OK; +} + +sub handler { + my Apache2::Connection $c = shift; + + # starting from Apache 2.0.49 several platforms require you to set + # the socket to a blocking IO mode + $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0); + + my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc); + + for (;;) { + $c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE); + last if $bb->is_empty; + + my $b = APR::Bucket::flush_create($c->bucket_alloc); + $bb->insert_tail($b); + $c->output_filters->pass_brigade($bb); + # fflush is the equivalent of the previous 3 lines of code: + # but it's tested elsewhere, here testing flush_create + # $c->output_filters->fflush($bb); + } + + $bb->destroy; + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> + <VirtualHost TestFilter::both_str_con_add> + PerlModule TestFilter::both_str_con_add + PerlPreConnectionHandler TestFilter::both_str_con_add::pre_connection + PerlProcessConnectionHandler TestFilter::both_str_con_add + </VirtualHost> +</NoAutoConfig> + +
diff --git a/2_0_13/t/filter/TestFilter/both_str_native_remove.pm b/2_0_13/t/filter/TestFilter/both_str_native_remove.pm new file mode 100644 index 0000000..8cb7a3a --- /dev/null +++ b/2_0_13/t/filter/TestFilter/both_str_native_remove.pm
@@ -0,0 +1,142 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::both_str_native_remove; + +# this tests verifies that we can remove input and output native +# (non-mod_perl filters) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Filter (); +use Apache2::FilterRec (); + +use APR::Table (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK DECLINED M_POST); + +# this filter removes the next filter in chain and itself +sub remove_includes { + my $f = shift; + + my $args = $f->r->args || ''; + if ($args eq 'remove') { + my $ff = $f->next; + $ff->remove if $ff && $ff->frec->name eq 'includes'; + } + + $f->remove; + + return Apache2::Const::DECLINED; +} + +# this filter removes the next filter in chain and itself +sub remove_deflate { + my $f = shift; + + my $args = $f->r->args || ''; + if ($args eq 'remove') { + for (my $ff = $f->r->input_filters; $ff; $ff = $ff->next) { + if ($ff->frec->name eq 'deflate') { + $ff->remove; + last; + } + } + } + $f->remove; + + return Apache2::Const::DECLINED; +} + +# this filter appends the output filter list at eos +sub print_out_flist { + my $f = shift; + + unless ($f->ctx) { + $f->ctx(1); + $f->r->headers_out->unset('Content-Length'); + } + + while ($f->read(my $buffer, 1024)) { + $f->print($buffer); + } + + if ($f->seen_eos) { + my $flist = join ',', get_flist($f->r->output_filters); + $f->print("output2: $flist\n"); + } + + return Apache2::Const::OK; +} + +sub store_in_flist { + my $f = shift; + my $r = $f->r; + + unless ($f->ctx) { + my $x = $r->pnotes('INPUT_FILTERS') || []; + push @$x, join ',', get_flist($f->r->input_filters); + $r->pnotes('INPUT_FILTERS' => $x); + } + + return Apache2::Const::DECLINED; +} + + +sub response { + my $r = shift; + + # just to make sure that print() won't flush, or we would get the + # count wrong + local $| = 0; + + $r->content_type('text/plain'); + if ($r->method_number == Apache2::Const::M_POST) { + $r->print("content: " . TestCommon::Utils::read_post($r) ."\n"); + } + + my $i=1; + for (@{ $r->pnotes('INPUT_FILTERS')||[] }) { + $r->print("input$i: $_\n"); + $i++; + } + + $r->subprocess_env(SSI_TEST => 'SSI OK'); + $r->printf("output1: %s\n", join ',', get_flist($r->output_filters)); + + $r->rflush; # this sends the data in the buffer + flush bucket + $r->print('x<!--#echo var='); + $r->rflush; # this sends the data in the buffer + flush bucket + $r->print('"SSI_TEST" -->x'."\n"); + + Apache2::Const::OK; +} + +sub get_flist { + my $f = shift; + + my @flist = (); + for (; $f; $f = $f->next) { + push @flist, $f->frec->name; + } + + return @flist; +} + +1; +__DATA__ +Options +Includes +SetHandler modperl +PerlModule TestFilter::both_str_native_remove +PerlResponseHandler TestFilter::both_str_native_remove::response +PerlOutputFilterHandler TestFilter::both_str_native_remove::remove_includes +PerlSetOutputFilter INCLUDES +PerlOutputFilterHandler TestFilter::both_str_native_remove::print_out_flist +PerlInputFilterHandler TestFilter::both_str_native_remove::store_in_flist +PerlInputFilterHandler TestFilter::both_str_native_remove::remove_deflate +PerlSetInputFilter DEFLATE +PerlInputFilterHandler TestFilter::both_str_native_remove::store_in_flist
diff --git a/2_0_13/t/filter/TestFilter/both_str_req_add.pm b/2_0_13/t/filter/TestFilter/both_str_req_add.pm new file mode 100644 index 0000000..4f76426 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/both_str_req_add.pm
@@ -0,0 +1,89 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::both_str_req_add; + +# insert an input filter which lowers the case of the data +# insert an output filter which strips spaces + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Filter (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +sub header_parser { + my $r = shift; + # test adding by coderef + $r->add_input_filter(\&in_filter); + # test adding by sub's name + $r->add_output_filter("out_filter"); + + # test adding anon sub + $r->add_output_filter(sub { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + $buffer .= "end"; + $filter->print($buffer); + } + + return Apache2::Const::OK; + }); + + return Apache2::Const::DECLINED; +} + +sub in_filter { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + $filter->print(lc $buffer); + } + + Apache2::Const::OK; +} + +sub out_filter { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + $buffer =~ s/\s+//g; + $filter->print($buffer); + } + + Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + $r->print(TestCommon::Utils::read_post($r)); + } + + return Apache2::Const::OK; +} + + + +1; +__DATA__ +<NoAutoConfig> + PerlModule TestFilter::both_str_req_add + <Location /TestFilter__both_str_req_add> + SetHandler modperl + PerlHeaderParserHandler TestFilter::both_str_req_add::header_parser + PerlResponseHandler TestFilter::both_str_req_add + </Location> +</NoAutoConfig> + + + +
diff --git a/2_0_13/t/filter/TestFilter/both_str_req_mix.pm b/2_0_13/t/filter/TestFilter/both_str_req_mix.pm new file mode 100644 index 0000000..0db61d8 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/both_str_req_mix.pm
@@ -0,0 +1,161 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::both_str_req_mix; + +# this is an elaborated test, where we mix several apache and mod_perl +# filters, both input and output and verifying that they can work +# together, preserving the order when the filters are of the same +# priority + +# in this test the client, the client sends a compressed body, +# 'DEFLATE' deflates it, then mod_perl filter 'transparent' filter +# passes data through as-is. The following 'in_adjust' mod_perl filter +# removes the string 'INPUT' from incoming data. The response handler +# simply passes the data through. Next output filters get to work: +# 'out_adjust_before_ssi' fixups the data to a valid SSI directive, by +# removing the string 'OUTPUT' from the outgoing data, then the +# 'INCLUDES' filter fetches the virtual file, and finally +# 'out_adjust_after_ssi' fixes the file contents returned by SSI, by +# removing the string 'REMOVE' +# +# Here is a visual representation of the transformations: +# +# => <network in> +# +# compressed data +# +# => DEFLATE +# +# <!--#include INPUTvirtual="/includes/OUTPUTclear.shtml" --> +# +# => transparent +# +# <!--#include INPUTvirtual="/includes/OUTPUTclear.shtml" --> +# +# => in_adjust +# +# <!--#include virtual="/includes/OUTPUTclear.shtml" --> +# +# <=> response handler +# +# <!--#include virtual="/includes/OUTPUTclear.shtml" --> +# +# <= out_adjust_before_ssi +# +# <!--#include virtual="/includes/clear.shtml" --> +# +# <= out_adjust_before_ssi +# +# <!--#include virtual="/includes/clear.shtml" --> +# +# <= INCLUDES +# +# This is a REMOVEclear text +# +# <= out_adjust_after_ssi +# +# This is a clear text +# +# <= DEFLATE +# +# compressed data +# +# <= <network out> + + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use Apache::TestTrace; + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +use constant DEBUG => 1; + +sub transparent { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)){ + debug "transparent buffer: $buffer"; + $buffer =~ s/foo//; + $filter->print($buffer); + } + + $filter->print(""); + + Apache2::Const::OK; +} + +sub in_adjust { adjust("INPUT", @_)} +sub out_adjust_before_ssi { adjust("OUTPUT", @_)} +sub out_adjust_after_ssi { adjust("REMOVE", @_)} + +sub adjust { + my ($string, $filter) = @_; + my $sig = "adjust($string):"; + + while ($filter->read(my $buffer, 1024)){ + debug "$sig before: $buffer"; + $buffer =~ s/$string//; + debug "$sig after: $buffer"; + $filter->print($buffer); + } + + Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + $r->print(TestCommon::Utils::read_post($r)); + } + + return Apache2::Const::OK; +} + + +1; +__DATA__ +<NoAutoConfig> + PerlModule TestFilter::both_str_req_mix + <Location /TestFilter__both_str_req_mix> + Options +Includes + + # DEFLATE has a higher priority (AP_FTYPE_CONTENT_SET=20) than + # mod_perl request filters (AP_FTYPE_RESOURCE=10), so it's going + # to filter input first no matter how we insert other mod_perl + # filters. (mod_perl connection filter handlers have an even + # higher priority (AP_FTYPE_PROTOCOL = 30), see + # include/util_filter.h for those definitions). + # + # PerlSetInputFilter is only useful for preserving the + # insertion order of filters with the same priority + SetInputFilter DEFLATE + #PerlInputFilterHandler TestCommon::FilterDebug::snoop_request + PerlInputFilterHandler TestFilter::both_str_req_mix::in_adjust + PerlInputFilterHandler TestFilter::both_str_req_mix::transparent + + # here INCLUDES and adjust are both of the same priority + # (AP_FTYPE_RESOURCE), so PerlSetOutputFilter + PerlOutputFilterHandler TestFilter::both_str_req_mix::out_adjust_before_ssi + PerlSetOutputFilter INCLUDES + PerlOutputFilterHandler TestFilter::both_str_req_mix::out_adjust_after_ssi + #PerlOutputFilterHandler TestCommon::FilterDebug::snoop_request + PerlSetOutputFilter DEFLATE + + SetHandler modperl + PerlResponseHandler TestFilter::both_str_req_mix + </Location> +</NoAutoConfig> + + + +
diff --git a/2_0_13/t/filter/TestFilter/both_str_req_proxy.pm b/2_0_13/t/filter/TestFilter/both_str_req_proxy.pm new file mode 100644 index 0000000..ed8ac0e --- /dev/null +++ b/2_0_13/t/filter/TestFilter/both_str_req_proxy.pm
@@ -0,0 +1,104 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::both_str_req_proxy; + +# very similar to TestFilter::both_str_req_add, but the request is +# proxified. we filter the POSTed body before it goes via the proxy and +# we filter the response after it returned from the proxy + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use Apache::TestTrace; + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +sub in_filter { + my $filter = shift; + + debug "input filter"; + + while ($filter->read(my $buffer, 1024)) { + $filter->print(lc $buffer); + } + + Apache2::Const::OK; +} + +sub out_filter { + my $filter = shift; + + debug "output filter"; + + while ($filter->read(my $buffer, 1024)) { + $buffer =~ s/\s+//g; + $filter->print($buffer); + } + + Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + debug "response handler"; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + $r->print(TestCommon::Utils::read_post($r)); + } + + return Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> + <IfModule mod_proxy.c> + <Proxy http://@servername@:@port@/*> + <IfModule mod_version.c> + <IfVersion < 2.3.0> + <IfModule @ACCESS_MODULE@> + Order Deny,Allow + Deny from all + Allow from @servername@ + </IfModule> + </IfVersion> + <IfVersion > 2.4.1> + <IfModule mod_access_compat.c> + Order Deny,Allow + Deny from all + Allow from @servername@ + </IfModule> + </IfVersion> + </IfModule> + </Proxy> + + ProxyRequests Off + + ProxyPass /TestFilter__both_str_req_proxy/ \ + http://@servername@:@port@/TestFilter__both_str_req_proxy_content/ + ProxyPassReverse /TestFilter__both_str_req_proxy/ \ + http://@servername@:@port@/TestFilter__both_str_req_proxy_content/ + </IfModule> + + PerlModule TestFilter::both_str_req_proxy + <Location /TestFilter__both_str_req_proxy> + PerlInputFilterHandler TestFilter::both_str_req_proxy::in_filter + PerlOutputFilterHandler TestFilter::both_str_req_proxy::out_filter + </Location> + <Location /TestFilter__both_str_req_proxy_content> + SetHandler modperl + PerlResponseHandler TestFilter::both_str_req_proxy + </Location> +</NoAutoConfig> + + + +
diff --git a/2_0_13/t/filter/TestFilter/in_autoload.pm b/2_0_13/t/filter/TestFilter/in_autoload.pm new file mode 100644 index 0000000..5595f44 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_autoload.pm
@@ -0,0 +1,41 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_autoload; + +# test that PerlInputFilterHandler autoloads the module containing the +# handler (since it's ::handler and not a custom sub name we don't +# have to explicitly call PerlModule) +# +# no point testing PerlOutputFilterHandler as it does the same + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Filter (); + +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK); + +sub handler { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + debug "filter read: $buffer"; + $filter->print(lc $buffer); + } + + return Apache2::Const::OK; +} + +1; + +__DATA__ +<NoAutoConfig> + PerlModule TestCommon::Handlers + <Location /TestFilter__in_autoload> + SetHandler modperl + PerlResponseHandler TestCommon::Handlers::pass_through_response_handler + # no PerlModule TestFilter::in_load on purpose + PerlInputFilterHandler TestFilter::in_autoload + </Location> +</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_body.pm b/2_0_13/t/filter/TestFilter/in_bbs_body.pm new file mode 100644 index 0000000..3380df1 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_bbs_body.pm
@@ -0,0 +1,60 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_bbs_body; + +use strict; +use warnings FATAL => 'all'; + +use base qw(Apache2::Filter); #so we inherit MODIFY_CODE_ATTRIBUTES + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use APR::Brigade (); +use APR::Bucket (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); +use APR::Const -compile => ':common'; + +sub handler : FilterRequestHandler { + my ($filter, $bb, $mode, $block, $readbytes) = @_; + + $filter->next->get_brigade($bb, $mode, $block, $readbytes); + + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + + last if $b->is_eos; + + if ($b->read(my $data)) { + #warn"[$data]\n"; + my $nb = APR::Bucket->new($bb->bucket_alloc, scalar reverse $data); + $b->insert_before($nb); + $b->delete; + $b = $nb; + } + } + + Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + $r->puts($data); + } + else { + $r->puts("1..3\nok 1\n"); + } + + Apache2::Const::OK; +} + +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_bbs_body +PerlResponseHandler TestFilter::in_bbs_body::response
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_consume.pm b/2_0_13/t/filter/TestFilter/in_bbs_consume.pm new file mode 100644 index 0000000..b83f2f4 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_bbs_consume.pm
@@ -0,0 +1,107 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_bbs_consume; + +# this test consumes a chunk of input, then consumes and throws away +# the rest of the data, finally returns to the caller that initial +# chunk. This all happens during a single filter invocation. Even +# though there about 6-7 incoming data brigades. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); +use Apache2::Connection (); +use APR::Brigade (); +use APR::Bucket (); + +use Apache::TestTrace; + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +use constant READ_SIZE => 26; + +sub handler { + my ($filter, $bb, $mode, $block, $readbytes) = @_; + my $ba = $filter->r->connection->bucket_alloc; + my $seen_eos = 0; + my $satisfied = 0; + my $buffer = ''; + debug_sub "filter called"; + + until ($satisfied) { + my $tbb = APR::Brigade->new($filter->r->pool, $ba); + $filter->next->get_brigade($tbb, $mode, $block, READ_SIZE); + debug "asking for a bb of " . READ_SIZE . " bytes\n"; + my $data; + ($data, $seen_eos) = bb_data_n_eos($tbb); + $tbb->destroy; + $buffer .= $data; + length($buffer) < READ_SIZE ? redo : $satisfied++; + } + + # consume all the remaining input + do { + my $tbb = APR::Brigade->new($filter->r->pool, $ba); + $filter->next->get_brigade($tbb, $mode, $block, $readbytes); + debug "discarding the next bb"; + $seen_eos = bb_data_n_eos($tbb, 1); # only scan + $tbb->destroy; + } while (!$seen_eos); + + if ($seen_eos) { + # flush the remainder + $bb->insert_tail(APR::Bucket->new($ba, $buffer)); + $bb->insert_tail(APR::Bucket::eos_create($ba)); + debug "seen eos, sending: " . length($buffer) . " bytes"; + } + else { + die "Something is wrong, this filter should have been called only once"; + } + + return Apache2::Const::OK; +} + +# if $scan_only is true, don't read the data, just look for eos +sub bb_data_n_eos { + my ($bb, $scan_only) = @_; + + if ($scan_only) { + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + return 1 if $b->is_eos; + } + return 0; + } + + my $seen_eos = 0; + + my @data; + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + $seen_eos++, last if $b->is_eos; + $b->read(my $bdata); + push @data, $bdata; + } + return (join('', @data), $seen_eos); +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + #warn "HANDLER READ: $data\n"; + $r->print($data); + } + + return Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_bbs_consume +PerlResponseHandler TestFilter::in_bbs_consume::response
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_inject_header.pm b/2_0_13/t/filter/TestFilter/in_bbs_inject_header.pm new file mode 100644 index 0000000..5380c65 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_bbs_inject_header.pm
@@ -0,0 +1,260 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_bbs_inject_header; + +# this filter demonstrates two things: +# 1. how to write a filter that will work only on HTTP headers +# 2. how to inject extra HTTP headers +# +# the first task is simple for non-keepalive connections -- as soon as +# a bucket which matches /^[\r\n]+$/ is read we can store that event +# in the filter context and simply 'return Apache2::Const::DECLINED on the +# future invocation, so not to slow things. +# +# it becomes much trickier with keepalive connection, since Apache +# provides no API to tell you whether a new request is coming in. We +# use $c->keepalives to figure out when a new request is coming in, by +# comparing the previously stored keepalives count, which gets +# incremented by Apache when the HTTP response headers are generated. +# +# +# the second task is a bit trickier, as the headers_in core httpd +# filter is picky and it wants each header to arrive in a separate +# bucket, and moreover this bucket needs to be in its own brigade. +# so this test arranges for this to happen. +# +# the test shows how to push headers at the end of all headers +# and in the middle, whichever way you prefer. + +use strict; +use warnings FATAL => 'all'; + +use base qw(Apache2::Filter); + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Connection (); +use APR::Brigade (); +use APR::Bucket (); +use APR::Table (); + +use Apache::TestTrace; + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK DECLINED CONN_KEEPALIVE); +use APR::Const -compile => ':common'; + +my $header1_key = 'X-My-Protocol'; +my $header1_val = 'POST-IT'; + +my %headers = ( + 'X-Extra-Header2' => 'Value 2', + 'X-Extra-Header3' => 'Value 3', +); + +my $request_body = "This body shouldn't be seen by the filter"; + +# returns 1 if a bucket with a header was inserted to the $bb's tail, +# otherwise returns 0 (i.e. if there are no buckets to insert) +sub inject_header_bucket { + my ($bb, $ctx) = @_; + + return 0 unless @{ $ctx->{buckets} }; + + my $b = shift @{ $ctx->{buckets} }; + $bb->insert_tail($b); + + if (1) { + # extra debug, wasting cycles + $b->read(my $data); + debug "injected header: [$data]"; + } + else { + debug "injected header"; + } + + # next filter invocations will bring the request body if any + if ($ctx->{seen_body_separator} && !@{ $ctx->{buckets} }) { + $ctx->{done_with_headers} = 1; + $ctx->{seen_body_separator} = 0; + } + + return 1; +} + +sub context { + my $filter = shift; + + my $ctx = $filter->ctx; + my $c = $filter->c; + unless ($ctx) { + debug "filter context init"; + $ctx = { + buckets => [], + done_with_headers => 0, + seen_body_separator => 0, + keepalives => $c->keepalives, + }; + + # since we are going to manipulate the reference stored in + # ctx, it's enough to store it only once, we will get the same + # reference in the following invocations of that filter + $filter->ctx($ctx); + return $ctx; + } + + if ($c->keepalive == Apache2::Const::CONN_KEEPALIVE && + $ctx->{done_with_headers} && + $c->keepalives > $ctx->{keepalives}) { + + debug "a new request resetting the input filter state"; + + $ctx->{buckets} = []; + $ctx->{done_with_headers} = 0; + $ctx->{seen_body_separator} = 0; + $ctx->{keepalives} = $c->keepalives; + } + + return $ctx; + +} + +sub handler : FilterConnectionHandler { + my ($filter, $bb, $mode, $block, $readbytes) = @_; + + debug join '', "-" x 20 , " input filter called -", "-" x 20; + + my $ctx = context($filter); + my $c = $filter->c; + + # reset the filter state, we start a new request + if ($c->keepalive == Apache2::Const::CONN_KEEPALIVE && + $ctx->{done_with_headers} && $c->notes->get('reset_request')) { + debug "a new request resetting the input filter state"; + $c->notes->set('reset_request' => 0); + $ctx->{buckets} = []; + $ctx->{seen_body_separator} = 0; + $ctx->{done_with_headers} = 0; + } + + # handling the HTTP request body + if ($ctx->{done_with_headers}) { + # XXX: when the bug in httpd filter will be fixed all the + # code in this branch will be replaced with: + # $filter->remove; + # return Apache2::Const::DECLINED; + # at the moment (2.0.48) it doesn't work + # so meanwhile tell the mod_perl filter core to pass-through + # the brigade unmodified + debug "passing the body through unmodified"; + return Apache2::Const::DECLINED; + } + + # any custom HTTP header buckets to inject? + return Apache2::Const::OK if inject_header_bucket($bb, $ctx); + + # normal HTTP headers processing + my $ctx_bb = APR::Brigade->new($c->pool, $c->bucket_alloc); + my $rv = $filter->next->get_brigade($ctx_bb, $mode, $block, $readbytes); + return $rv unless $rv == APR::Const::SUCCESS; + + while (!$ctx_bb->is_empty) { + my $b = $ctx_bb->first; + + if ($b->is_eos) { + debug "EOS!!!"; + $b->remove; + $bb->insert_tail($b); + last; + } + + $b->read(my $data); + # remove must happen after read, since it may cause split and + # some new buckets inserted behind - if remove called too + # early, those buckets will be lost + $b->remove; + debug "filter read:\n[$data]"; + + # check that we really work only on the headers + die "This filter should not ever receive the request body, " . + "but HTTP headers" if ($data||'') eq $request_body; + + if ($data and $data =~ /^POST/) { + # demonstrate how to add a header while processing other headers + my $header = "$header1_key: $header1_val\r\n"; + push @{ $ctx->{buckets} }, APR::Bucket->new($c->bucket_alloc, $header); + debug "queued header [$header]"; + } + elsif ($data =~ /^[\r\n]+$/) { + # normally the body will start coming in the next call to + # get_brigade, so if your filter only wants to work with + # the headers, it can decline all other invocations if that + # flag is set. However since in this test we need to send + # a few extra bucket brigades, we will turn another flag + # 'done_with_headers' when 'seen_body_separator' is on and + # all headers were sent out + debug "END of original HTTP Headers"; + $ctx->{seen_body_separator}++; + + # we hit the headers and body separator, which is a good + # time to add extra headers: + for my $key (keys %headers) { + my $header = "$key: $headers{$key}\r\n"; + push @{ $ctx->{buckets} }, APR::Bucket->new($c->bucket_alloc, $header); + debug "queued header [$header]"; + } + + # but at the same time we must ensure that the + # the separator header will be sent as a last header + # so we send one newly added header and push the separator + # to the end of the queue + # XXX: this is broken: the bucket must be set-aside before + # it can be stashed away (missing $b->setaside wrapper) + push @{ $ctx->{buckets} }, $b; + debug "queued header [$data]"; + inject_header_bucket($bb, $ctx); + next; # inject_header_bucket already called insert_tail + # notice that if we didn't inject any headers, this will + # still work ok, as inject_header_bucket will send the + # separator header which we just pushed to its queue + } + else { + # fall through + } + + $bb->insert_tail($b); + } + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + # propogate the input headers and the input back to the client + # as we need to do the validations on the client side + $r->headers_out->set($header1_key => + $r->headers_in->get($header1_key)||''); + + for my $key (sort keys %headers) { + $r->headers_out->set($key => $r->headers_in->get($key)||''); + } + + my $data = TestCommon::Utils::read_post($r); + $r->print($data); + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +<VirtualHost TestFilter::in_bbs_inject_header> + PerlModule TestFilter::in_bbs_inject_header + PerlInputFilterHandler TestFilter::in_bbs_inject_header + <Location /TestFilter__in_bbs_inject_header> + SetHandler modperl + PerlResponseHandler TestFilter::in_bbs_inject_header::response + </Location> +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_msg.pm b/2_0_13/t/filter/TestFilter/in_bbs_msg.pm new file mode 100644 index 0000000..12e0868 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_bbs_msg.pm
@@ -0,0 +1,75 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_bbs_msg; + +use strict; +use warnings FATAL => 'all'; + +use base qw(Apache2::Filter); + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use APR::Brigade (); +use APR::Bucket (); + +use Apache2::Const -compile => 'OK'; +use APR::Const -compile => ':common'; + +use Apache::TestTrace; + +my $from_url = '/input_filter.html'; +my $to_url = '/TestFilter__in_bbs_msg'; + +sub handler : FilterConnectionHandler { + my ($filter, $bb, $mode, $block, $readbytes) = @_; + + debug "FILTER CALLED"; + + $filter->next->get_brigade($bb, $mode, $block, $readbytes); + + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + + last if $b->is_eos; + + if ($b->read(my $data)) { + next unless $data =~ s|GET $from_url|GET $to_url|; + debug "GET line rewritten to be:\n$data"; + my $nb = APR::Bucket->new($bb->bucket_alloc, $data); + $b->insert_before($nb); + $b->delete; + $b = $nb; + } + + # XXX: currently a bug in httpd doesn't allow to remove + # the first connection filter. once it's fixed adjust the test + # to test that it was invoked only once. + # debug "removing the filter"; + # $filter->remove; # this filter is no longer needed + } + + Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + $r->puts("1..1\nok 1\n"); + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +<VirtualHost TestFilter::in_bbs_msg> + PerlModule TestFilter::in_bbs_msg + PerlInputFilterHandler TestFilter::in_bbs_msg + + <Location /TestFilter__in_bbs_msg> + SetHandler modperl + PerlResponseHandler TestFilter::in_bbs_msg::response + </Location> + +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/in_bbs_underrun.pm b/2_0_13/t/filter/TestFilter/in_bbs_underrun.pm new file mode 100644 index 0000000..f8f33bb --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_bbs_underrun.pm
@@ -0,0 +1,154 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_bbs_underrun; + +# this test exercises the underrun filter concept. Sometimes filters +# need to read at least N bytes before they can apply their +# transformation. It's quite possible that reading one bucket brigade +# is not enough. But two or more are needed. +# +# When the filter realizes that it doesn't have enough data, it can +# stash the read data in the context, and wait for the next +# invocation, meanwhile it must return an empty bb to the filter that +# has called it. This is not efficient. Instead of returning an empty +# bb to a caller, the input filter can initiate the retrieval of extra +# bucket brigades, after one was received. Notice that this is +# absolutely transparent to any filters before or after the current +# filter. +# +# to see the filter at work, run it as: +# t/TEST -trace=debug -v filter/in_bbs_underrun +# +# and look in the error_log. You will see something like: +# +# ==> TestFilter::in_bbs_underrun::handler : filter called +# ==> asking for a bb +# ==> asking for a bb +# ==> asking for a bb +# ==> storing the remainder: 7611 bytes +# ==> TestFilter::in_bbs_underrun::handler : filter called +# ==> asking for a bb +# ==> asking for a bb +# ==> storing the remainder: 7222 bytes +# ==> TestFilter::in_bbs_underrun::handler : filter called +# ==> asking for a bb +# ==> seen eos, flushing the remaining: 8182 bytes +# +# it's clear from the log that the filter was invoked 3 times, however +# it has consumed 6 bucket brigades +# +# finally, we have to note that this is impossible to do with +# streaming filters, since they can only read data from one bucket +# brigade. So you must process bucket brigades. +# + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use Apache::TestTrace; + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +use constant SIZE => 1024*16 + 5; # ~16k + +sub handler { + my ($filter, $bb, $mode, $block, $readbytes) = @_; + my $ba = $filter->r->connection->bucket_alloc; + my $ctx = $filter->ctx; + my $buffer = defined $ctx ? $ctx : ''; + $ctx = ''; # reset + my $seen_eos = 0; + my $data; + debug_sub "filter called"; + + # fetch and consume bucket brigades untill we have at least SIZE + # bytes to work with + do { + my $tbb = APR::Brigade->new($filter->r->pool, $ba); + $filter->next->get_brigade($tbb, $mode, $block, $readbytes); + debug "asking for a bb"; + ($data, $seen_eos) = flatten_bb($tbb); + $tbb->destroy; + $buffer .= $data; + } while (!$seen_eos && length($buffer) < SIZE); + + # now create a bucket per chunk of SIZE size and put the remainder + # in ctx + for (split_buffer($buffer)) { + if (length($_) == SIZE) { + $bb->insert_tail(APR::Bucket->new($bb->bucket_alloc, $_)); + } + else { + $ctx .= $_; + } + } + + if ($seen_eos) { + # flush the remainder + $bb->insert_tail(APR::Bucket->new($bb->bucket_alloc, $ctx)); + $bb->insert_tail(APR::Bucket::eos_create($ba)); + debug "seen eos, flushing the remaining: " . length($ctx) . " bytes"; + } + else { + # will re-use the remainder on the next invocation + $filter->ctx($ctx); + debug "storing the remainder: " . length($ctx) . " bytes"; + } + + return Apache2::Const::OK; +} + +# split in words of SIZE chars and a remainder +sub split_buffer { + my $buffer = shift; + if ($] < 5.007) { + my @words = $buffer =~ /(.{@{[SIZE]}}|.+)/g; + return @words; + } + else { + # available only since 5.7.x+ + return unpack "(A" . SIZE . ")*", $buffer; + } +} + +sub flatten_bb { + my ($bb) = shift; + + my $seen_eos = 0; + + my @data; + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + $seen_eos++, last if $b->is_eos; + $b->read(my $bdata); + push @data, $bdata; + } + return (join('', @data), $seen_eos); +} + + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + #warn "HANDLER READ: $data\n"; + my $length = length $data; + $r->print("read $length chars"); + } + + return Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_bbs_underrun +PerlResponseHandler TestFilter::in_bbs_underrun::response +PerlInputFilterHandler TestFilter::in_bbs_underrun::handler +#PerlInputFilterHandler TestCommon::FilterDebug::snoop_request
diff --git a/2_0_13/t/filter/TestFilter/in_error.pm b/2_0_13/t/filter/TestFilter/in_error.pm new file mode 100644 index 0000000..633b3a3 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_error.pm
@@ -0,0 +1,53 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_error; + +# errors in filters should be properly propogated to httpd + +# XXX: need to test output as well, and separately connection and +# request filters + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); +use APR::Table (); + +use Apache::TestTrace; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +sub handler { + my $filter = shift; + + debug join '', "-" x 20 , " filter called ", "-" x 20; + + die "This filter must die"; + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + # cause taint problems, as there was a bug (panic: POPSTACK) + # caused when APR/Error.pm was attempted to be loaded from + # $r->read() when the latter was trying to croak about the failed + # read, due to the filter returning 500 + eval { system('echo', 'hello') }; + + t_server_log_error_is_expected(2); + my $len = $r->read(my $data, $r->headers_in->{'Content-Length'}); + + $r->content_type('text/plain'); + $r->print("it shouldn't be printed, because the input filter has died"); + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_error +PerlResponseHandler TestFilter::in_error::response
diff --git a/2_0_13/t/filter/TestFilter/in_init_basic.pm b/2_0_13/t/filter/TestFilter/in_init_basic.pm new file mode 100644 index 0000000..630a511 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_init_basic.pm
@@ -0,0 +1,81 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_init_basic; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use base qw(Apache2::Filter); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +use constant READ_SIZE => 1024; + +# this filter is expected to be called once +# it'll set a note, with the count +sub transparent_init : FilterInitHandler { + my $filter = shift; + + my $ctx = $filter->ctx; + $ctx->{init}++; + $filter->r->notes->set(init => $ctx->{init}); + $filter->ctx($ctx); + + return Apache2::Const::OK; +} + +# this filter passes the data through unmodified and sets a note +# counting how many times it was invoked +sub transparent : FilterRequestHandler + FilterHasInitHandler(\&transparent_init) + { + my ($filter, $bb, $mode, $block, $readbytes) = @_; + + my $ctx = $filter->ctx; + $ctx->{run}++; + $filter->r->notes->set(run => $ctx->{run}); + $filter->ctx($ctx); + + $filter->next->get_brigade($bb, $mode, $block, $readbytes); + + return Apache2::Const::OK; +} + + + +# this filter is not supposed to get a chance to run, since its init +# handler immediately removes it +sub suicide_init : FilterInitHandler { shift->remove(); Apache2::Const::OK } +sub suicide : FilterHasInitHandler(\&suicide_init) { + die "this filter is not supposed to have a chance to run"; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + $r->print(TestCommon::Utils::read_post($r)); + } + + my @keys = qw(init run); + my %times = map { $_ => $r->notes->get($_)||0 } @keys; + $r->print("$_ $times{$_}\n") for @keys; + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_init_basic +PerlResponseHandler TestFilter::in_init_basic::response +PerlInputFilterHandler TestFilter::in_init_basic::suicide +PerlInputFilterHandler TestFilter::in_init_basic::transparent
diff --git a/2_0_13/t/filter/TestFilter/in_str_bin_data.pm b/2_0_13/t/filter/TestFilter/in_str_bin_data.pm new file mode 100644 index 0000000..f304f43 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_str_bin_data.pm
@@ -0,0 +1,58 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_str_bin_data; + +# test that $r->print and $f->print handle binary data correctly +# (e.g. doesn't truncate on "\0" if there is more data after it) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); +use Apache2::RequestRec (); +use Apache2::Filter (); + +use Apache::TestTrace; + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +sub pass_through { + my $f = shift; + + while ($f->read(my $buffer, 1024)) { + debug "read: " . length ($buffer) . "b [$buffer]"; + $f->print($buffer); + } + + return Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + my $length = length $data; + debug "pass through $length bytes of $data\n"; + $r->print($data); + } + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +PerlModule TestFilter::in_str_bin_data +<Location /TestFilter__in_str_bin_data_filter> + PerlInputFilterHandler TestFilter::in_str_bin_data::pass_through + SetHandler modperl + PerlResponseHandler TestFilter::in_str_bin_data +</Location> +<Location /TestFilter__in_str_bin_data> + SetHandler modperl + PerlResponseHandler TestFilter::in_str_bin_data +</Location> +</NoAutoConfig> +
diff --git a/2_0_13/t/filter/TestFilter/in_str_consume.pm b/2_0_13/t/filter/TestFilter/in_str_consume.pm new file mode 100644 index 0000000..4bd32ce --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_str_consume.pm
@@ -0,0 +1,149 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_str_consume; + +# this test verifies that streaming filters framework handles +# gracefully the case when a filter doesn't print anything at all to +# the caller. + +# the real problem is that in the streaming filters we can't consume +# more than one bucket brigade during a single filter invocation, +# which we can in non-stream filters., (e.g. see in_bbs_underrun.pm) +# +# it seems that this works just fine (2.0.46+) and older httpds +# had problems when a filter invocation hasn't printed a thing. +# +# currently if the streaming filter doesn't print anything, the +# upstream filter gets an empty brigade brigade (easily verified with +# the snooping debug filter). Of course if the filter returns +# Apache2::Const::DECLINED the unconsumed data will be passed to upstream filter +# +# However this filter has a problem. Since it doesn't consume all the +# data, the client is left with un-read data, and when the response is +# sent a client get the broken pipe on the socket. It seems that LWP +# on linux handles that situation gracefully, but not on win32, where +# it silently dies. Other clients may have similar problems as +# well. The proper solution is to consume all the data till EOS and +# just drop it on the floor if it's unneeded. Unfortunately we waste +# the resources of passing the data through all filters in the chain +# and doing a wasteful work, but currently there is no way to tell the +# in_core network filter to discard all the data without passing it +# upstream. Notice that in this test we solve the problem in a +# different manner, we simply call $r->discard_request_body which does +# the trick. However it's inappropriate for a stand-alone filter, who +# should read all the data in instead. +# +# this test receives about 10 bbs +# it reads only the first 23 bytes of each bb and discards the rest +# since it wants only 105 bytes it partially consumes only the first 5 bbs +# since it doesn't read all the data in, it'll never see EOS +# therefore once it has read all 105 bytes, it manually sets the EOS flag +# and the rest of the bbs are ignored, the filter is invoked only 5 times +# +# to debug this filter run it as: +# +# t/TEST -v -trace=debug filter/in_str_consume +# +# to enable upstream and downstream filter snooping, uncomment the +# snooping filters directives at the end of this file and rerun: +# t/TEST -conf +# +# to see what happens inside the filter, assuming that you built +# mod_perl with MP_TRACE=1, run: +# env MOD_PERL_TRACE=f t/TEST -v -trace=debug filter/in_str_consume +# + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Filter (); +use Apache::TestTrace; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +use constant READ_BYTES_TOTAL => 105; +use constant READ_BYTES_FIRST => 23; + +sub handler { + my $filter = shift; + + my $ctx = $filter->ctx || { data => '', count => '1'}; + debug "FILTER INVOKED: $ctx->{count}"; + + # read untill READ_BYTES read, no matter how many filter + # invocations it'll take + my $wanted_total = READ_BYTES_TOTAL - length $ctx->{data}; + my $wanted_current = READ_BYTES_FIRST; + my $wanted = $wanted_total; + $wanted = $wanted_current if $wanted > $wanted_current; + debug "total wanted: $wanted_total bytes"; + debug "this bb wanted: $wanted bytes"; + while ($wanted) { + my $len = $filter->read(my $buffer, $wanted); + $ctx->{data} .= $buffer; + $wanted_total -= $len; + $wanted -= $len; + debug "FILTER READ: [$buffer]"; + debug "FILTER READ: $len ($wanted_total more to go)"; + last unless $len; # no more data to read in this bb + } + + $ctx->{count}++; + + unless ($wanted_total) { + # we don't want to read the rest if there is anything left + $filter->seen_eos(1); + # but we really should, though we workaround it in the + # response handler, by calling $r->discard_request_body + } + + if ($filter->seen_eos) { + # flush the data if we are done + $filter->print($ctx->{data}); + } + else { + # store the data away + $filter->ctx($ctx); + + # notice that it seems to work even though we don't print + # anything. the upstream filter gets an empty bb. + + # alternatively could print the chunks of data that we read, + # if we don't need to have it as a whole chunk + } + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + + # tell Apache to get rid of the rest of the request body + # if we don't a client will get a broken pipe and may fail to + # handle this situation gracefully + $r->discard_request_body; + + my $len = length $data; + debug "HANDLER READ: $len bytes\n"; + $r->print($len); + } + + return Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_str_consume +PerlResponseHandler TestFilter::in_str_consume::response +#PerlInputFilterHandler TestCommon::FilterDebug::snoop_request +PerlInputFilterHandler TestFilter::in_str_consume::handler +#PerlInputFilterHandler TestCommon::FilterDebug::snoop_request
diff --git a/2_0_13/t/filter/TestFilter/in_str_declined.pm b/2_0_13/t/filter/TestFilter/in_str_declined.pm new file mode 100644 index 0000000..07bd69e --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_str_declined.pm
@@ -0,0 +1,69 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_str_declined; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Filter (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK DECLINED M_POST); + +# make sure that if the input filter returns DECLINED without +# reading/printing data the data flow is not broken +sub handler { + my $filter = shift; + + my $ctx = $filter->ctx; + $ctx->{invoked}++; + $filter->ctx($ctx); + + # can't use $f->seen_eos, since we don't read the data, so + # we have to set the note on each invocation + $filter->r->notes->set(invoked => $ctx->{invoked}); + #warn "filter was invoked $ctx->{invoked} times\n"; + + return Apache2::Const::DECLINED; +} + +sub response { + my $r = shift; + + my $data; + if ($r->method_number == Apache2::Const::M_POST) { + # consume the data so the input filter is invoked + $data = TestCommon::Utils::read_post($r); + } + + plan $r, tests => 2; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + ok t_cmp(length $data, 20000, "the request body received ok"); + } + + # ~20k of input makes it four bucket brigades: + # - 2 full bucket brigades of 8k + # - 1 half full brigade ~4k + # - 1 bucket brigade with EOS bucket + # however different Apache versions may send extra bb or split + # data differently so we can't rely on the exact count + my $invoked = $r->notes->get('invoked') || 0; + ok $invoked > 1; + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_str_declined +PerlResponseHandler TestFilter::in_str_declined::response +
diff --git a/2_0_13/t/filter/TestFilter/in_str_declined_read.pm b/2_0_13/t/filter/TestFilter/in_str_declined_read.pm new file mode 100644 index 0000000..06b9a9d --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_str_declined_read.pm
@@ -0,0 +1,57 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_str_declined_read; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Filter (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK DECLINED M_POST); + +# a filter must not return DECLINED after calling $r->read, since the +# latter already fetches the bucket brigade in which case it's up to +# the user to complete reading it and send it out +# thefore this filter must fail +sub handler { + my $filter = shift; + + # this causes a fetch of bb + $filter->read(my $buffer, 10); + + return Apache2::Const::DECLINED; +} + +sub response { + my $r = shift; + + my $err; + if ($r->method_number == Apache2::Const::M_POST) { + # this should fail, because of the failing filter + eval { TestCommon::Utils::read_post($r) }; + $err = $@; + } + + plan $r, tests => 1; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + ok $err; + } + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_str_declined_read +PerlResponseHandler TestFilter::in_str_declined_read::response +
diff --git a/2_0_13/t/filter/TestFilter/in_str_lc.pm b/2_0_13/t/filter/TestFilter/in_str_lc.pm new file mode 100644 index 0000000..60f5a80 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_str_lc.pm
@@ -0,0 +1,43 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_str_lc; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +sub handler { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + #warn "FILTER READ: $buffer\n"; + $filter->print(lc $buffer); + } + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + #warn "HANDLER READ: $data\n"; + $r->print($data); + } + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_str_lc +PerlResponseHandler TestFilter::in_str_lc::response
diff --git a/2_0_13/t/filter/TestFilter/in_str_msg.pm b/2_0_13/t/filter/TestFilter/in_str_msg.pm new file mode 100644 index 0000000..e4582e2 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_str_msg.pm
@@ -0,0 +1,109 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_str_msg; + +# test: +# - input connection filter rewriting the first HTTP header POST +# - input request filter configured outside the resource container +# should work just fine (via PerlOptions +MergeHandlers) +# - input connection filter configured inside the resource container +# is silently skipped (at the moment we can't complain about such, +# since there could be connection filters from outside the resource +# container that will get merged inside the resource dir_config + +use strict; +use warnings FATAL => 'all'; + +use base qw(Apache2::Filter); + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use APR::Brigade (); +use APR::Bucket (); + +use Apache::Test; +use Apache::TestUtil; + +use TestCommon::Utils (); + +use Apache2::Const -compile => 'OK'; +use APR::Const -compile => ':common'; + +my $from_url = '/input_filter.html'; +my $to_url = '/TestFilter__in_str_msg'; + +sub con : FilterConnectionHandler { + my $filter = shift; + + #warn "FILTER con CALLED\n"; + my $ctx = $filter->ctx; + + while ($filter->read(my $buffer, 1024)) { + #warn "FILTER READ: $buffer\n"; + unless ($ctx) { + $buffer =~ s|POST $from_url|POST $to_url|; + $ctx = 1; # done + } + $filter->print($buffer); + } + $filter->ctx($ctx) if $ctx; + + return Apache2::Const::OK; +} + +sub req : FilterRequestHandler { + my $filter = shift; + + #warn "FILTER req CALLED\n"; + while ($filter->read(my $buffer, 1024)) { + $buffer =~ s/upcase me/UPCASED/; + $filter->print($buffer); + } + + return Apache2::Const::OK; +} + +sub con_skip : FilterConnectionHandler { + my $filter = shift; + + #warn "FILTER con_skip CALLED\n"; + while ($filter->read(my $buffer, 1024)) { + $filter->print("I'm a bogus filter. Don't run me\n"); + } + + return Apache2::Const::OK; +} + +my $expected = "UPCASED"; +sub response { + my $r = shift; + + my $received = TestCommon::Utils::read_post($r); + + plan $r, tests => 1; + + ok t_cmp($received, $expected, + "request filter must have upcased the data"); + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +<VirtualHost TestFilter::in_str_msg> + PerlModule TestFilter::in_str_msg + PerlInputFilterHandler TestFilter::in_str_msg::con + + # this request filter is outside the resource container and it + # should work just fine because of PerlOptions +MergeHandlers + PerlInputFilterHandler TestFilter::in_str_msg::req + + <Location /TestFilter__in_str_msg> + SetHandler modperl + PerlOptions +MergeHandlers + PerlInputFilterHandler TestFilter::in_str_msg::con_skip + PerlResponseHandler TestFilter::in_str_msg::response + </Location> + +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/in_str_sandwich.pm b/2_0_13/t/filter/TestFilter/in_str_sandwich.pm new file mode 100644 index 0000000..a7a9f19 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/in_str_sandwich.pm
@@ -0,0 +1,57 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::in_str_sandwich; + +# this test verifies whether the filter can pre-insert data (using +# context) and post-insert data (using the seen_eos flag) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +sub handler { + my $filter = shift; + + my $ctx = $filter->ctx; + + unless ($ctx) { + $filter->print("HEADER\n"); + $filter->ctx(1); + } + + while ($filter->read(my $buffer, 1024)) { + #warn "FILTER READ: $buffer\n"; + $filter->print($buffer); + } + + if ($filter->seen_eos) { + $filter->print("TAIL\n"); + } + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + #warn "HANDLER READ: $data\n"; + $r->print($data); + } + + return Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::in_str_sandwich +PerlResponseHandler TestFilter::in_str_sandwich::response
diff --git a/2_0_13/t/filter/TestFilter/out_bbs_basic.pm b/2_0_13/t/filter/TestFilter/out_bbs_basic.pm new file mode 100644 index 0000000..8071992 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_bbs_basic.pm
@@ -0,0 +1,73 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_bbs_basic; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); +use APR::Brigade (); +use APR::Bucket (); +use APR::BucketType (); + +use Apache2::Const -compile => 'OK'; + +#XXX: Not implemented yet, required by Test.pm +sub Apache::TestToString::PRINTF {} + +sub handler { + my ($filter, $bb) = @_; + + unless ($filter->ctx) { + + Apache::TestToString->start; + + plan tests => 4; + + my $ba = $filter->r->connection->bucket_alloc; + + #should only have 1 bucket from the response() below + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + ok $b->type->name; + ok $b->length == 2; + $b->read(my $data); + ok (defined $data and $data eq 'ok'); + } + + my $tests = Apache::TestToString->finish; + + my $brigade = APR::Brigade->new($filter->r->pool, $ba); + my $b = APR::Bucket->new($ba, $tests); + + $brigade->insert_tail($b); + + my $ok = $brigade->first->type->name =~ /mod_perl/ ? 4 : 0; + $brigade->insert_tail(APR::Bucket->new($ba, "ok $ok\n")); + + $brigade->insert_tail(APR::Bucket::eos_create($ba)); + + $filter->next->pass_brigade($brigade); + + $filter->ctx(1); # flag that we have run this already + } + + Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + $r->puts("ok"); + + 0; +} + +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_bbs_basic +PerlResponseHandler TestFilter::out_bbs_basic::response
diff --git a/2_0_13/t/filter/TestFilter/out_bbs_ctx.pm b/2_0_13/t/filter/TestFilter/out_bbs_ctx.pm new file mode 100644 index 0000000..b6f2175 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_bbs_ctx.pm
@@ -0,0 +1,119 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_bbs_ctx; + +# this is the same test as TestFilter::context_stream, but uses the +# bucket brigade API + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use APR::Brigade (); +use APR::Bucket (); +use APR::BucketType (); + +use base qw(Apache2::Filter); + +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK M_POST); +use APR::Const -compile => ':common'; + +use constant BLOCK_SIZE => 5003; + +sub handler { + my ($filter, $bb) = @_; + + debug "filter got called"; + + my $c = $filter->c; + my $ba = $c->bucket_alloc; + my $bb_ctx = APR::Brigade->new($c->pool, $ba); + + my $ctx = $filter->ctx; + $ctx->{invoked}++; + + my $data = exists $ctx->{data} ? $ctx->{data} : ''; + + while (my $b = $bb->first) { + + if ($b->is_eos) { + debug "got EOS"; + # flush the remainings and send a stats signature + $bb_ctx->insert_tail(APR::Bucket->new($ba, "$data\n")) if $data; + my $sig = join "\n", "received $ctx->{blocks} complete blocks", + "filter invoked $ctx->{invoked} times\n"; + $bb_ctx->insert_tail(APR::Bucket->new($ba, $sig)); + $b->remove; + $bb_ctx->insert_tail($b); + last; + } + + if ($b->read(my $bdata)) { + debug "got data"; + $b->delete; + $data .= $bdata; + my $len = length $data; + + my $blocks = 0; + if ($len >= BLOCK_SIZE) { + $blocks = int($len / BLOCK_SIZE); + $len = $len % BLOCK_SIZE; + $data = substr $data, $blocks*BLOCK_SIZE, $len; + $ctx->{blocks} += $blocks; + } + if ($blocks) { + my $nb = APR::Bucket->new($ba, "#" x $blocks); + $bb_ctx->insert_tail($nb); + } + } + else { + debug "got bucket with no data: type: " . $b->type->name; + $b->remove; + $bb_ctx->insert_tail($b); + } + + } + + $ctx->{data} = $data; + $filter->ctx($ctx); + + my $rv = $filter->next->pass_brigade($bb_ctx); + return $rv unless $rv == APR::Const::SUCCESS; + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + # just to make sure that print() won't flush, or we would get the + # count wrong + local $| = 0; + + # make sure that: + # - we send big enough data so it won't fit into one buffer + # - use chunk size which doesn't nicely fit into a buffer size, so + # we have something to store in the context between filter calls + + my $blocks = 33; + my $block_size = BLOCK_SIZE + 1; + my $block = "x" x $block_size; + for (1..$blocks) { + $r->print($block); + $r->rflush; # so the filter reads a chunk at a time + } + + return Apache2::Const::OK; +} + +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_bbs_ctx +PerlResponseHandler TestFilter::out_bbs_ctx::response +
diff --git a/2_0_13/t/filter/TestFilter/out_bbs_filebucket.pm b/2_0_13/t/filter/TestFilter/out_bbs_filebucket.pm new file mode 100644 index 0000000..80f56dd --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_bbs_filebucket.pm
@@ -0,0 +1,67 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_bbs_filebucket; + +# testing how the filter handles file buckets + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter; +use Apache2::URI (); + +use APR::Brigade (); +use APR::Bucket (); + +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK); +use APR::Const -compile => qw(SUCCESS); + +use constant BLOCK_SIZE => 5003; + +sub handler { + my ($filter, $bb) = @_; + + debug "FILTER INVOKED"; + + my $cnt = 0; + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + + $cnt++; + debug "reading bucket #$cnt"; + + last if $b->is_eos; + + if (my $len = $b->read(my $data)) { + my $nb = APR::Bucket->new($bb->bucket_alloc, uc $data); + $b->insert_before($nb); + $b->delete; + $b = $nb; + } + } + + return $filter->next->pass_brigade($bb); +} + +sub response { + my $r = shift; + + debug "\n-------- new request ----------"; + + $r->content_type('text/plain'); + + my $file = $r->args; + Apache2::URI::unescape_url($file); + $r->sendfile($file); + + return Apache2::Const::OK; +} + +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_bbs_filebucket +PerlResponseHandler TestFilter::out_bbs_filebucket::response +PerlOutputFilterHandler TestFilter::out_bbs_filebucket::handler
diff --git a/2_0_13/t/filter/TestFilter/out_init_basic.pm b/2_0_13/t/filter/TestFilter/out_init_basic.pm new file mode 100644 index 0000000..ccfa876 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_init_basic.pm
@@ -0,0 +1,87 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_init_basic; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use base qw(Apache2::Filter); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +use constant READ_SIZE => 1024; + +# this filter is expected to be called once +# it'll set a note, with the count +sub init : FilterInitHandler { + my $filter = shift; + + #warn "**** init was invoked\n"; + + my $ctx = $filter->ctx; + $ctx->{init}++; + $filter->r->notes->set(init => $ctx->{init}); + $filter->ctx($ctx); + + #warn "**** init is exiting\n"; + + return Apache2::Const::OK; +} + +# testing whether we can get the pre handler callback in evolved way +sub get_pre_handler { return \&TestFilter::out_init_basic::init } + +# this filter adds a count for each time it is invoked +sub transparent : FilterRequestHandler + FilterHasInitHandler(get_pre_handler()) + { + my ($filter, $bb) = @_; + + #warn "**** filter was invoked\n"; + + my $ctx = $filter->ctx; + + $filter->print('run ', ++$ctx->{run}, "\n"); + + $filter->ctx($ctx); + + my $rv = $filter->next->pass_brigade($bb); + return $rv unless $rv == APR::Const::SUCCESS; + + #warn "**** filter is exiting\n"; + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + #warn "**** content was invoked\n"; + + $r->content_type('text/plain'); + + my $data; + if ($r->method_number == Apache2::Const::M_POST) { + $data = TestCommon::Utils::read_post($r); + } + + $r->print('init ', $r->notes->get('init'), "\n"); + $r->print($data) if $data; + + #warn "**** content is exiting\n"; + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_init_basic +PerlResponseHandler TestFilter::out_init_basic::response +PerlOutputFilterHandler TestFilter::out_init_basic::transparent
diff --git a/2_0_13/t/filter/TestFilter/out_str_api.pm b/2_0_13/t/filter/TestFilter/out_str_api.pm new file mode 100644 index 0000000..b1c6bb7 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_api.pm
@@ -0,0 +1,99 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_api; + +# Test Apache2::FilterRec and Apache2::Filter accessors + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); +use Apache2::FilterRec (); + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use Apache2::Const -compile => 'OK'; + +my $response_data = "blah blah blah"; + +#XXX: else pp_untie complains: +#untie attempted while %d inner references still exist +sub Apache2::Filter::UNTIE {} +sub Apache2::Filter::PRINTF {} + +sub handler { + my $filter = shift; + + my $data = ''; + while ($filter->read(my $buffer, 1024)) { + $data .= $buffer; + } + + tie *STDOUT, $filter; + + plan tests => 8; + + ok t_cmp($data, $response_data, "response data"); + + ok $filter->isa('Apache2::Filter'); + + { + my $frec = $filter->frec; + + ok $frec->isa('Apache2::FilterRec'); + ok t_cmp($frec->name, "modperl_request_output", '$frec->name'); + + my $next = $filter->next; + ok t_cmp($next->frec->name, "modperl_request_output", + '$filter->next->frec->name'); + + $next = $next->next; + # since we can't ensure that the next filter will be the same, + # as it's not under control, just check that we get some name + my $name = $next->frec->name; + t_debug("next->next name: $name"); + ok $name; + } + + my $r = $filter->r; + + ok $r->isa('Apache2::RequestRec'); + + my $path = '/' . Apache::TestRequest::module2path(__PACKAGE__); + ok t_cmp($r->uri, $path, "path"); + + untie *STDOUT; + + # we have done the job + $filter->remove; + + Apache2::Const::OK; +} + +sub pass_through { + return Apache2::Const::DECLINED; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + $r->puts($response_data); + + Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> +PerlModule TestFilter::out_str_api +<Location /TestFilter__out_str_api> + SetHandler modperl + PerlResponseHandler TestFilter::out_str_api::response + PerlOutputFilterHandler TestFilter::out_str_api + PerlOutputFilterHandler TestFilter::out_str_api::pass_through +</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/filter/TestFilter/out_str_buffer.pm b/2_0_13/t/filter/TestFilter/out_str_buffer.pm new file mode 100644 index 0000000..027e10f --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_buffer.pm
@@ -0,0 +1,99 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_buffer; + +# in this test we want to buffer the data, modify the length of the +# response, set the c-l header and make sure that the client sees the +# right thing +# +# notice that a bucket brigades based filter must be used. The streaming +# API lets FLUSH buckets through which causes an early flush of HTTP +# response headers + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use APR::Table (); +use APR::Bucket (); +use APR::Brigade (); + +use TestCommon::Utils (); + +use base qw(Apache2::Filter); + +use Apache2::Const -compile => qw(OK M_POST); +use APR::Const -compile => ':common'; + +sub flatten_bb { + my ($bb) = shift; + + my $seen_eos = 0; + + my @data; + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + $seen_eos++, last if $b->is_eos; + $b->read(my $bdata); + push @data, $bdata; + } + return (join('', @data), $seen_eos); +} + +sub handler { + my ($filter, $bb) = @_; + + my $ctx = $filter->ctx; + + # no need to unset the C-L header, since this filter makes sure to + # correct it before any headers go out. + #unless ($ctx) { + # $filter->r->headers_out->unset('Content-Length'); + #} + + my $data = exists $ctx->{data} ? $ctx->{data} : ''; + $ctx->{invoked}++; + my ($bdata, $seen_eos) = flatten_bb($bb); + $bdata =~ s/-//g; + $data .= $bdata if $bdata; + + if ($seen_eos) { + my $len = length $data; + $filter->r->headers_out->set('Content-Length', $len); + $filter->print($data) if $data; + } + else { + # store context for all but the last invocation + $ctx->{data} = $data; + $filter->ctx($ctx); + } + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + my $data = ''; + if ($r->method_number == Apache2::Const::M_POST) { + $data = TestCommon::Utils::read_post($r); + $r->headers_out->set('Content-Length' => length $data); + } + + for my $chunk (split /0/, $data) { + $r->print($chunk); + $r->rflush; # so the filter reads a chunk at a time + } + + return Apache2::Const::OK; +} + +1; +__DATA__ + +SetHandler modperl +PerlModule TestFilter::out_str_buffer +PerlResponseHandler TestFilter::out_str_buffer::response +
diff --git a/2_0_13/t/filter/TestFilter/out_str_ctx.pm b/2_0_13/t/filter/TestFilter/out_str_ctx.pm new file mode 100644 index 0000000..762c60b --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_ctx.pm
@@ -0,0 +1,92 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_ctx; + +# this is the same test as TestFilter::context, but uses the streaming +# API + +use strict; +use warnings;# FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use base qw(Apache2::Filter); + +use Apache2::Const -compile => qw(OK M_POST); +use APR::Const -compile => ':common'; + +use constant BLOCK_SIZE => 5003; +use constant READ_SIZE => 1024; + +sub handler { + my $filter = shift; + + my $ctx = $filter->ctx; + my $data = exists $ctx->{data} ? $ctx->{data} : ''; + $ctx->{invoked}++; + + while ($filter->read(my $bdata, READ_SIZE)) { + $data .= $bdata; + my $len = length $data; + + my $blocks = 0; + if ($len >= BLOCK_SIZE) { + $blocks = int($len / BLOCK_SIZE); + $len = $len % BLOCK_SIZE; + $data = substr $data, $blocks*BLOCK_SIZE, $len; + $ctx->{blocks} += $blocks; + } + if ($blocks) { + $filter->print("#" x $blocks); + } + } + + if ($filter->seen_eos) { + # flush the remaining data and add a statistics signature + $filter->print("$data\n") if $data; + my $sig = join "\n", "received $ctx->{blocks} complete blocks", + "filter invoked $ctx->{invoked} times\n"; + $filter->print($sig); + } + else { + # store context for all but the last invocation + $ctx->{data} = $data; + $filter->ctx($ctx); + } + + return Apache2::Const::OK; +} + + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + # just to make sure that print() flushes, or we would get the + # count wrong + local $| = 1; + + # make sure that + # - we send big enough data so it won't fit into one buffer + # - use chunk size which doesn't nicely fit into a buffer size, so + # we have something to store in the context between filter calls + + my $blocks = 33; + my $block_size = BLOCK_SIZE + 1; + my $block = "x" x $block_size; + for (1..$blocks) { + $r->print($block); + $r->rflush; # so the filter reads a chunk at a time + } + + return Apache2::Const::OK; +} + +1; +__DATA__ + +SetHandler modperl +PerlModule TestFilter::out_str_ctx +PerlResponseHandler TestFilter::out_str_ctx::response +
diff --git a/2_0_13/t/filter/TestFilter/out_str_declined.pm b/2_0_13/t/filter/TestFilter/out_str_declined.pm new file mode 100644 index 0000000..0f4cbf6 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_declined.pm
@@ -0,0 +1,82 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_declined; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Filter (); + +use Apache2::Const -compile => qw(OK DECLINED); + +use constant READ_SIZE => 1024; + +# make sure that if the input filter returns DECLINED without +# reading/printing data the data flow is not broken +sub decline { + my $filter = shift; + + my $ctx = $filter->ctx; + $ctx->{invoked}++; + $filter->ctx($ctx); + + # can't use $f->seen_eos, since we don't read the data, so + # we have to set the note on each invocation + $filter->r->notes->set(invoked => $ctx->{invoked}); + #warn "decline filter was invoked $ctx->{invoked} times\n"; + + return Apache2::Const::DECLINED; +} + +# this filter ignores all the data that comes through, though on the +# last invocation it prints how many times the filter 'decline' was called +# which it could count by itself, but we want to test that +# 'return Apache2::Const::DECLINED' works properly in output filters +sub black_hole { + my $filter = shift; + + my $ctx = $filter->ctx; + $ctx->{invoked}++; + $filter->ctx($ctx); + #warn "black_hole filter was invoked $ctx->{invoked} times\n"; + + while ($filter->read(my $data, READ_SIZE)) { + #warn "black_hole data: $data\n"; + # let the data fall between the chairs + } + + if ($filter->seen_eos) { + my $invoked = $filter->r->notes->get('invoked') || 0; + $filter->print($invoked); + } + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + # just to make sure that print() won't flush, or we would get the + # count wrong + local $| = 0; + + $r->content_type('text/plain'); + for (1..10) { + $r->print("a"); # this buffers the data + $r->rflush; # this sends the data in the buffer + flush bucket + } + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_str_declined +PerlResponseHandler TestFilter::out_str_declined::response +PerlOutputFilterHandler TestFilter::out_str_declined::decline +PerlOutputFilterHandler TestFilter::out_str_declined::black_hole
diff --git a/2_0_13/t/filter/TestFilter/out_str_eval.pm b/2_0_13/t/filter/TestFilter/out_str_eval.pm new file mode 100644 index 0000000..0201bcd --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_eval.pm
@@ -0,0 +1,45 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_eval; + +# at some point there was a problem when eval {} in a non-filter +# handler wasn't functioning when a filter was involved. the $@ value +# was getting lost when t_cmp was doing print of debug values. and a +# new invocation of a filter handler resets the value of $@. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK DECLINED); + +# dummy pass_through filter was good enough to trigger the problem +sub handler { + return Apache2::Const::DECLINED; +} + +sub response { + my $r = shift; + + plan $r, tests => 1; + # test that filters don't reset $@ + eval { i_do_not_exist_really_i_do_not() }; + # trigger the filter invocation, before using $@ + $r->print("# whatever"); + $r->rflush; + ok t_cmp($@, qr/Undefined subroutine/, "some croak"); + + return Apache2::Const::OK; +} + +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_str_eval +PerlResponseHandler TestFilter::out_str_eval::response +
diff --git a/2_0_13/t/filter/TestFilter/out_str_lc.pm b/2_0_13/t/filter/TestFilter/out_str_lc.pm new file mode 100644 index 0000000..8325b38 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_lc.pm
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_lc; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Filter (); + +use TestCommon::Utils; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + + # test that read() returns tainted data + die "read() has returned untainted data" + unless TestCommon::Utils::is_tainted($buffer); + + $filter->print(lc $buffer); + } + + Apache2::Const::OK; +} + +1; +__DATA__ + +<Location /top_dir> + PerlOutputFilterHandler TestFilter::out_str_lc +</Location> +<IfModule mod_alias.c> + Alias /top_dir @top_dir@ +</IfModule>
diff --git a/2_0_13/t/filter/TestFilter/out_str_remove.pm b/2_0_13/t/filter/TestFilter/out_str_remove.pm new file mode 100644 index 0000000..cc3d14d --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_remove.pm
@@ -0,0 +1,67 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_remove; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Filter (); + +use Apache2::Const -compile => qw(OK); + +use constant READ_SIZE => 1024; + +# this filter reads the first bb, upcases the data in it and removes itself +sub upcase_n_remove { + my $filter = shift; + + #warn "filter upcase_n_remove called\n"; + while ($filter->read(my $buffer, 1024)) { + $filter->print(uc $buffer); + } + + $filter->remove; + + return Apache2::Const::OK; +} + +# this filter inserts underscores after each character it receives +sub insert_underscores { + my $filter = shift; + + #warn "filter insert_underscores called\n"; + while ($filter->read(my $buffer, 1024)) { + $buffer =~ s/(.)/$1_/g; + $filter->print($buffer); + } + + return Apache2::Const::OK; +} + + +sub response { + my $r = shift; + + # just to make sure that print() won't flush, or we would get the + # count wrong + local $| = 0; + + $r->content_type('text/plain'); + $r->print("Foo"); + $r->rflush; # this sends the data in the buffer + flush bucket + $r->print("bar"); + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_str_remove +PerlResponseHandler TestFilter::out_str_remove::response +PerlOutputFilterHandler TestFilter::out_str_remove::insert_underscores +PerlOutputFilterHandler TestFilter::out_str_remove::upcase_n_remove
diff --git a/2_0_13/t/filter/TestFilter/out_str_req_eos.pm b/2_0_13/t/filter/TestFilter/out_str_req_eos.pm new file mode 100644 index 0000000..866c8a1 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_req_eos.pm
@@ -0,0 +1,83 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_req_eos; + +# here we test how EOS is passed from one streaming filter to another, +# making sure that it's not lost + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +my $prefix = 'PREFIX_'; +my $suffix = '_SUFFIX'; + +sub add_prefix { + my $filter = shift; + + #warn "add_prefix called\n"; + + unless ($filter->ctx) { + $filter->print($prefix); + $filter->ctx(1); + } + + while ($filter->read(my $buffer, 1024)){ + #warn "add_prefix read: [$buffer]\n"; + $filter->print($buffer); + } + + Apache2::Const::OK; +} + +sub add_suffix { + my $filter = shift; + + #warn "add_suffix called\n"; + + while ($filter->read(my $buffer, 1024)){ + #warn "add_suffix read: [$buffer]\n"; + $filter->print($buffer); + } + + if ($filter->seen_eos) { + $filter->print($suffix); + $filter->ctx(1); + } + + Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + $r->print(TestCommon::Utils::read_post($r)); + } + + return Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> + PerlModule TestFilter::out_str_req_eos + <Location /TestFilter__out_str_req_eos> + SetHandler modperl + PerlResponseHandler TestFilter::out_str_req_eos + PerlOutputFilterHandler TestFilter::out_str_req_eos::add_prefix + PerlOutputFilterHandler TestFilter::out_str_req_eos::add_suffix + </Location> +</NoAutoConfig> + + + +
diff --git a/2_0_13/t/filter/TestFilter/out_str_req_mix.pm b/2_0_13/t/filter/TestFilter/out_str_req_mix.pm new file mode 100644 index 0000000..771cb09 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_req_mix.pm
@@ -0,0 +1,87 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_req_mix; + +# in this test we verify that we can preserve the mixed order of +# modperl and non-modperl filters using the PerlSetOutputFilter +# directive, instead of SetOutputFilter for non-modperl filters. +# +# response handler prints a mangled SSI directive: +# <!--#include virtual="/includes/REMOVEclear.shtml" --> +# (which it receives via POST from the client) +# +# adjust() filter is configured to be called first and it removes the +# string 'REMOVE' from the response handler's output, so that SSI will +# find the fixed resource specification: +# <!--#include virtual="/includes/clear.shtml" --> +# +# the INCLUDES filter, which is configured to be next on the stack +# (mod_include) processes the directive and returns the contents of +# file "/includes/clear.shtml", which is: +# This is a REMOVEclear text +# +# finally the second mod_perl filter (which happens to be the same +# adjust() filter, but to all purposes it's a separate filter) +# configured to run after the INCLUDES filter fixes the data sent by +# the INCLUDES filter to be: +# This is a clear text +# +# and this is what the client is expecting to receive +# +# WARNING: notice that the adjust() filter assumes that it'll receive +# the word REMOVE in a single bucket, which is good enough for the +# test because we control all the used filters and normally Apache +# core filters won't split short data into several buckets. However +# filter developers shouldn't make any assumptions, since any data can +# be split by any of the upstream filters. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Filter (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +sub adjust { + my $filter = shift; + + #warn "adjust called\n"; + + while ($filter->read(my $buffer, 1024)){ + $buffer =~ s/REMOVE//; + $filter->print($buffer); + } + + Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + if ($r->method_number == Apache2::Const::M_POST) { + $r->print(TestCommon::Utils::read_post($r)); + } + + return Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> + PerlModule TestFilter::out_str_req_mix + <Location /TestFilter__out_str_req_mix> + Options +Includes + PerlOutputFilterHandler TestFilter::out_str_req_mix::adjust + PerlSetOutputFilter INCLUDES + PerlOutputFilterHandler TestFilter::out_str_req_mix::adjust + SetHandler modperl + PerlResponseHandler TestFilter::out_str_req_mix + </Location> +</NoAutoConfig> + + + +
diff --git a/2_0_13/t/filter/TestFilter/out_str_reverse.pm b/2_0_13/t/filter/TestFilter/out_str_reverse.pm new file mode 100644 index 0000000..5237f1f --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_reverse.pm
@@ -0,0 +1,82 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_reverse; + +# this filter tests how the data can be set-aside between filter +# invocations. here we collect a single line (which terminates with a +# new line) before we apply the reversing transformation. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK M_POST); + +use constant BUFF_LEN => 2; +use constant signature => "Reversed by mod_perl 2.0\n"; + +sub handler { + my $f = shift; + #warn "called\n"; + + my $leftover = $f->ctx; + + # We are about to change the length of the response body. Hence, we + # have to adjust the content-length header. + unless (defined $leftover) { # 1st invocation + $f->r->headers_out->{'Content-Length'}+=length signature + if exists $f->r->headers_out->{'Content-Length'}; + } + + while ($f->read(my $buffer, BUFF_LEN)) { + #warn "buffer: [$buffer]\n"; + $buffer = $leftover . $buffer if defined $leftover; + $leftover = undef; + while ($buffer =~ /([^\r\n]*)([\r\n]*)/g) { + $leftover = $1, last unless $2; + $f->print(scalar(reverse $1), $2); + } + } + + if ($f->seen_eos) { + $f->print(scalar reverse $leftover) if defined $leftover; + $f->print(signature); + } + else { + $f->ctx($leftover) if defined $leftover; + } + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + # unbuffer stdout, so we get the data split across several bbs + local $_ = 1; + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + $r->print($_) for grep length $_, split /(.{5})/, $data; + } + + return Apache2::Const::OK; +} + +1; +__DATA__ +<Base> + PerlModule TestFilter::out_str_reverse + <LocationMatch "/filter/reverse.txt"> + PerlOutputFilterHandler TestFilter::out_str_reverse + </LocationMatch> +</Base> + +SetHandler modperl +PerlResponseHandler TestFilter::out_str_reverse::response +
diff --git a/2_0_13/t/filter/TestFilter/out_str_subreq_default.pm b/2_0_13/t/filter/TestFilter/out_str_subreq_default.pm new file mode 100644 index 0000000..2ffcc0f --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_subreq_default.pm
@@ -0,0 +1,82 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_subreq_default; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache2::Filter (); + +use Apache2::Const -compile => qw(OK); + +# include the contents of a subrequest +# in the filter, a la mod_include's +# <!--#include virtual="/subrequest" --> + +sub include { + + my $filter = shift; + + unless ($filter->ctx) { + # don't forget to remove the C-L header + $filter->r->headers_out->unset('Content-Length'); + + $filter->ctx(1); + } + + while ($filter->read(my $buffer, 1024)){ + + if ($buffer eq "<tag>\n") { + my $sub = $filter->r->lookup_uri('/default_subrequest/subrequest.txt'); + my $rc = $sub->run; + } + else { + # send all other data along unaltered + $filter->print($buffer); + } + + } + + # add our own at the end + if ($filter->seen_eos) { + $filter->print("filter\n"); + $filter->ctx(1); + } + + return Apache2::Const::OK; +} + +sub response { + + my $r = shift; + + $r->content_type('text/plain'); + + $r->print("content\n"); + $r->rflush; + $r->print("<tag>\n"); + $r->rflush; + $r->print("more content\n"); + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_str_subreq_default +PerlResponseHandler TestFilter::out_str_subreq_default::response +PerlOutputFilterHandler TestFilter::out_str_subreq_default::include + +<IfModule mod_alias.c> + Alias /default_subrequest @DocumentRoot@/filter +</IfModule> + +<Location /default_subrequest> + SetHandler default-handler +</Location>
diff --git a/2_0_13/t/filter/TestFilter/out_str_subreq_modperl.pm b/2_0_13/t/filter/TestFilter/out_str_subreq_modperl.pm new file mode 100644 index 0000000..ba3b4a4 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/out_str_subreq_modperl.pm
@@ -0,0 +1,89 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestFilter::out_str_subreq_modperl; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache2::Filter (); + +use Apache2::Const -compile => qw(OK); + +# include the contents of a subrequest +# in the filter, a la mod_include's +# <!--#include virtual="/subrequest" --> + +sub include { + + my $filter = shift; + + unless ($filter->ctx) { + # don't forget to remove the C-L header + $filter->r->headers_out->unset('Content-Length'); + + $filter->ctx(1); + } + + while ($filter->read(my $buffer, 1024)){ + + if ($buffer eq "<tag>\n") { + my $sub = $filter->r->lookup_uri('/modperl_subrequest'); + my $rc = $sub->run; + } + else { + # send all other data along unaltered + $filter->print($buffer); + } + + } + + # add our own at the end + if ($filter->seen_eos) { + $filter->print("filter\n"); + $filter->ctx(1); + } + + return Apache2::Const::OK; +} + +sub subrequest { + + my $r = shift; + + $r->content_type('text/plain'); + $r->print("modperl subrequest\n"); + + return Apache2::Const::OK; +} + +sub response { + + my $r = shift; + + $r->content_type('text/plain'); + + $r->print("content\n"); + $r->rflush; + $r->print("<tag>\n"); + $r->rflush; + $r->print("more content\n"); + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler modperl +PerlModule TestFilter::out_str_subreq_modperl +PerlResponseHandler TestFilter::out_str_subreq_modperl::response +PerlOutputFilterHandler TestFilter::out_str_subreq_modperl::include + +<Location /modperl_subrequest> + SetHandler modperl + PerlResponseHandler TestFilter::out_str_subreq_modperl::subrequest +</Location>
diff --git a/2_0_13/t/filter/TestFilter/with_subrequest.pm b/2_0_13/t/filter/TestFilter/with_subrequest.pm new file mode 100644 index 0000000..1448ee4 --- /dev/null +++ b/2_0_13/t/filter/TestFilter/with_subrequest.pm
@@ -0,0 +1,38 @@ +package TestFilter::with_subrequest; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Filter (); +use Apache2::SubRequest (); + +use TestCommon::Utils; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $f = shift; + my $r = $f->r; + + my $subr; + while ($f->read(my $buffer, 1024)) { + $f->print(lc $buffer); + if (!$subr) { + $subr = $r->lookup_uri($r->uri); + my $rc = $subr->run; + } + } + + Apache2::Const::OK; +} + +1; +__DATA__ + +<Location /with_subrequest> + PerlOutputFilterHandler TestFilter::with_subrequest +</Location> + +<IfModule mod_alias.c> + Alias /with_subrequest @top_dir@ +</IfModule>
diff --git a/2_0_13/t/filter/both_str_con_add.t b/2_0_13/t/filter/both_str_con_add.t new file mode 100644 index 0000000..1937406 --- /dev/null +++ b/2_0_13/t/filter/both_str_con_add.t
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = qw(MODPERL 2.0 RULES); + +# blocking socket bug fixed in 2.0.52 +my $ok = $^O !~ /^(Open|Net)BSD$/i || need_min_apache_version('2.0.52'); + +plan tests => 1 + @test_strings, $ok; + +my $module = "TestFilter::both_str_con_add"; +my $socket = Apache::TestRequest::vhost_socket($module); + +ok $socket; + +for my $str (@test_strings) { + print $socket "$str\n"; + chomp(my $reply = <$socket>||''); + $str = lc $str; + $str =~ s/modperl/mod_perl/; + ok t_cmp($reply, $str); +}
diff --git a/2_0_13/t/filter/both_str_native_remove.t b/2_0_13/t/filter/both_str_native_remove.t new file mode 100644 index 0000000..4dbc1c1 --- /dev/null +++ b/2_0_13/t/filter/both_str_native_remove.t
@@ -0,0 +1,60 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 8, need 'deflate', 'include', + need_min_module_version("Compress::Zlib", "1.09"); + +require Compress::Zlib; + +my $base = '/TestFilter__both_str_native_remove'; + +# 1. check if DEFLATE input and INCLUDES output filter work +{ + my $location = $base; + my $received = POST_BODY $location, + content => Compress::Zlib::memGzip('gzipped text'), + 'Content-Encoding' => "gzip"; + + ok t_cmp $received, qr/xSSI OK/, "INCLUDES filter"; + + ok t_cmp $received, qr/content: gzipped text/, "DEFLATE filter"; +} + + +# 2. check if DEFLATE input and INCLUDES output filter can be removed +{ + my $location = "$base?remove"; + my $received = POST_BODY $location, content => 'plain text'; + + ok t_cmp $received, + qr/input1: [\w,]+deflate/, + "DEFLATE filter is present"; + + ok !t_cmp $received, + qr/input2: [\w,]+deflate/, + "DEFLATE filter is removed"; + + ok t_cmp $received, + qr/content: plain text/, + "DEFLATE filter wasn't invoked"; + + ok t_cmp $received, + qr/output1: modperl_request_output,includes,modperl_request_output,/, + "INCLUDES filter is present"; + + ok t_cmp $received, + qr/output2: modperl_request_output,(?!includes)/, + "INCLUDES filter is removed"; + + ok t_cmp $received, + qr/x<!--#echo var="SSI_TEST" -->x/, + "INCLUDES filter wasn't invoked"; + +} + +
diff --git a/2_0_13/t/filter/both_str_req_add.t b/2_0_13/t/filter/both_str_req_add.t new file mode 100644 index 0000000..867ebf8 --- /dev/null +++ b/2_0_13/t/filter/both_str_req_add.t
@@ -0,0 +1,18 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $data = join ' ', 'A'..'Z', 0..9; +my $expected = lc $data; # that's what the input filter does +$expected =~ s/\s+//g; # that's what the output filter does +$expected .= "end"; # that's what the anon output filter does +my $location = '/TestFilter__both_str_req_add'; +my $response = POST_BODY $location, content => $data; +ok t_cmp($response, $expected, "lc input and reverse output filters"); +
diff --git a/2_0_13/t/filter/both_str_req_mix.t b/2_0_13/t/filter/both_str_req_mix.t new file mode 100644 index 0000000..fa44462 --- /dev/null +++ b/2_0_13/t/filter/both_str_req_mix.t
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, need 'deflate', 'include', + need_min_module_version("Compress::Zlib", "1.09"); + +require Compress::Zlib; +my $location = '/TestFilter__both_str_req_mix'; + +my $request_orig = '<!--#include INPUTvirtual="/includes/OUTPUTclear.shtml" -->'; +my $response_orig = 'This is a clear text'; + +# gzip already produces data in a network order, so no extra +# transformation seem to be necessary + +my $content = Compress::Zlib::memGzip($request_orig); +my $response_raw = POST_BODY $location, + content => $content, + 'Accept-Encoding' => "gzip", + 'Content-Encoding' => "gzip"; + +#t_debug($response_raw); +my $response_clear = Compress::Zlib::memGunzip($response_raw); +#t_debug($response_clear); + +my $expected = $response_orig; +(my $received = $response_clear) =~ s{\r?\n$}{}; + +ok t_cmp($received, $expected, + "mixing httpd and mod_perl filters, while preserving order"); +
diff --git a/2_0_13/t/filter/both_str_req_proxy.t b/2_0_13/t/filter/both_str_req_proxy.t new file mode 100644 index 0000000..ae91fc7 --- /dev/null +++ b/2_0_13/t/filter/both_str_req_proxy.t
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my @modules = qw(mod_proxy proxy_http.c); +push @modules, 'mod_access_compat.c' if have_min_apache_version("2.4.0"); +plan tests => 1, need need_module(@modules), need_access; + +my $data = join ' ', 'A'..'Z', 0..9; +my $expected = lc $data; # that's what the input filter does +$expected =~ s/\s+//g; # that's what the output filter does +my $location = '/TestFilter__both_str_req_proxy/foo'; +my $response = POST_BODY $location, content => $data; +ok t_cmp($response, $expected, "lc input and reverse output filters"); +
diff --git a/2_0_13/t/filter/in_autoload.t b/2_0_13/t/filter/in_autoload.t new file mode 100644 index 0000000..d57ae30 --- /dev/null +++ b/2_0_13/t/filter/in_autoload.t
@@ -0,0 +1,18 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = '/TestFilter__in_autoload'; + +my $data = "[Foo BaR] "; +my $expected = lc $data; +my $received = POST_BODY $location, content => $data; + +ok t_cmp($received, $expected, "input stream filter lc autoloaded") +
diff --git a/2_0_13/t/filter/in_bbs_body.t b/2_0_13/t/filter/in_bbs_body.t new file mode 100644 index 0000000..8ca5e5c --- /dev/null +++ b/2_0_13/t/filter/in_bbs_body.t
@@ -0,0 +1,14 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest; + +my $location = '/TestFilter__in_bbs_body'; + +print GET_BODY_ASSERT $location; + +for my $x (2..3) { + my $data = scalar reverse "ok $x\n"; + print POST_BODY_ASSERT $location, content => $data; +}
diff --git a/2_0_13/t/filter/in_bbs_consume.t b/2_0_13/t/filter/in_bbs_consume.t new file mode 100644 index 0000000..3defa2b --- /dev/null +++ b/2_0_13/t/filter/in_bbs_consume.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = '/TestFilter__in_bbs_consume'; + +# send a message bigger than 8k, so to make sure that the input filter +# will get more than one bucket brigade with data. +my $length = 40 * 1024 + 7; # ~40k+ (~6 incoming bucket brigades) +my $expected = join '', 'a'..'z'; +my $data = $expected . "x" x $length; +my $received = POST_BODY $location, content => $data; + +ok t_cmp($received, $expected, "input bbs filter full consume")
diff --git a/2_0_13/t/filter/in_bbs_inject_header.t b/2_0_13/t/filter/in_bbs_inject_header.t new file mode 100644 index 0000000..e45b047 --- /dev/null +++ b/2_0_13/t/filter/in_bbs_inject_header.t
@@ -0,0 +1,67 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache::TestRequest; + +my $module = 'TestFilter::in_bbs_inject_header'; +my $location = "/" . Apache::TestRequest::module2path($module); + +Apache::TestRequest::scheme('http'); #force http for t/TEST -ssl +Apache::TestRequest::module($module); + +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport($config); +t_debug("connecting to $hostport"); + +my $content = "This body shouldn't be seen by the filter"; + +my $header1_key = 'X-My-Protocol'; +my $header1_val = 'POST-IT'; + +my %headers = ( + 'X-Extra-Header2' => 'Value 2', + 'X-Extra-Header3' => 'Value 3', +); + +my $keep_alive_times = 4; +my $non_keep_alive_times = 4; +my $tests = 2 + keys %headers; +my $times = $non_keep_alive_times + $keep_alive_times + 1; + +plan tests => $tests * $times; + +# try non-keepalive conn +validate(POST($location, content => $content)) for 1..$non_keep_alive_times; + +# try keepalive conns +Apache::TestRequest::user_agent(reset => 1, keep_alive => 1); +validate(POST($location, content => $content)) for 1..$keep_alive_times; + +# try non-keepalive conn +Apache::TestRequest::user_agent(reset => 1, keep_alive => 0); +validate(POST($location, content => $content)); + +# 4 sub-tests +sub validate { + my $res = shift; + + die join "\n", + "request has failed (the response code was: " . $res->code . ")", + "see t/logs/error_log for more details\n" unless $res->is_success; + + ok t_cmp($res->content, $content, "body"); + + ok t_cmp($res->header($header1_key), + $header1_val, + "injected header $header1_key"); + + for my $key (sort keys %headers) { + ok t_cmp($res->header($key), + $headers{$key}, + "injected header $key"); + } +}
diff --git a/2_0_13/t/filter/in_bbs_msg.t b/2_0_13/t/filter/in_bbs_msg.t new file mode 100644 index 0000000..02a3027 --- /dev/null +++ b/2_0_13/t/filter/in_bbs_msg.t
@@ -0,0 +1,16 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache::Test (); +use Apache::TestUtil; + +use Apache::TestRequest 'GET_BODY_ASSERT'; + +my $module = 'TestFilter::in_bbs_msg'; + +Apache::TestRequest::scheme('http'); #force http for t/TEST -ssl +Apache::TestRequest::module($module); + +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport($config); +t_debug("connecting to $hostport"); + +print GET_BODY_ASSERT "/input_filter.html";
diff --git a/2_0_13/t/filter/in_bbs_underrun.t b/2_0_13/t/filter/in_bbs_underrun.t new file mode 100644 index 0000000..70e999b --- /dev/null +++ b/2_0_13/t/filter/in_bbs_underrun.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = '/TestFilter__in_bbs_underrun'; + +# send a message of about 40k, so to make sure that the input filter +# will get several bucket brigades with data (about 8k/brigade) +my $length = 40 * 1024 + 7; # ~40k+ (~6 incoming bucket brigades) +my $data = "x" x $length; +my $received = POST_BODY $location, content => $data; +my $expected = "read $length chars"; + +ok t_cmp($received, $expected, "input bbs filter underrun test")
diff --git a/2_0_13/t/filter/in_error.t b/2_0_13/t/filter/in_error.t new file mode 100644 index 0000000..0ac9662 --- /dev/null +++ b/2_0_13/t/filter/in_error.t
@@ -0,0 +1,15 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = '/TestFilter__in_error'; + +my $res = POST $location, content => 'foo'; +ok t_cmp($res->code, 500, "an error in a filter should cause 500"); +
diff --git a/2_0_13/t/filter/in_init_basic.t b/2_0_13/t/filter/in_init_basic.t new file mode 100644 index 0000000..a82ffaa --- /dev/null +++ b/2_0_13/t/filter/in_init_basic.t
@@ -0,0 +1,17 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $content = "content ok\n"; +# older httpds may run the input request filter twice +my $expected = join '', $content, "init 1\n", "run [12]\n"; + +my $location = '/TestFilter__in_init_basic'; +my $response = POST_BODY $location, content => $content; +ok t_cmp($response, qr/$expected/, "test filter init functionality");
diff --git a/2_0_13/t/filter/in_str_bin_data.t b/2_0_13/t/filter/in_str_bin_data.t new file mode 100644 index 0000000..da801bd --- /dev/null +++ b/2_0_13/t/filter/in_str_bin_data.t
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 4; + +my $base = "/TestFilter__in_str_bin_data"; +my @locations = map {$base . $_ } ('', '_filter'); +my $expected = "123\001456\000789"; + +# test the binary data read/print w/ and w/o pass through filter +for my $location (@locations) { + my $received = POST_BODY_ASSERT $location, content => $expected; + + ok t_cmp(length($received), + length($expected), + "$location binary response length"); + + ok t_cmp($received, + $expected, + "$location binary response data"); +} +
diff --git a/2_0_13/t/filter/in_str_consume.t b/2_0_13/t/filter/in_str_consume.t new file mode 100644 index 0000000..7ad619d --- /dev/null +++ b/2_0_13/t/filter/in_str_consume.t
@@ -0,0 +1,22 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# see the explanations in in_str_consume.pm + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = '/TestFilter__in_str_consume'; + +my $data = "*" x 80000; # about 78K => ~10 bbs +my $expected = 105; + +t_debug "sent " . length($data) . "B, expecting ${expected}B to make through"; + +my $received = POST_BODY $location, content => $data; + +ok t_cmp($received, $expected, "input stream filter partial consume")
diff --git a/2_0_13/t/filter/in_str_declined.t b/2_0_13/t/filter/in_str_declined.t new file mode 100644 index 0000000..f22db3b --- /dev/null +++ b/2_0_13/t/filter/in_str_declined.t
@@ -0,0 +1,12 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest 'POST_BODY_ASSERT';; + +my $location = '/TestFilter__in_str_declined'; + +my $chunk = "1234567890"; +my $data = $chunk x 2000; + +print POST_BODY_ASSERT $location, content => $data;
diff --git a/2_0_13/t/filter/in_str_declined_read.t b/2_0_13/t/filter/in_str_declined_read.t new file mode 100644 index 0000000..94b6618 --- /dev/null +++ b/2_0_13/t/filter/in_str_declined_read.t
@@ -0,0 +1,12 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest 'POST_BODY_ASSERT';; + +my $location = '/TestFilter__in_str_declined_read'; + +my $chunk = "1234567890"; +my $data = $chunk x 2000; + +print POST_BODY_ASSERT $location, content => $data;
diff --git a/2_0_13/t/filter/in_str_lc.t b/2_0_13/t/filter/in_str_lc.t new file mode 100644 index 0000000..e2dceaf --- /dev/null +++ b/2_0_13/t/filter/in_str_lc.t
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = '/TestFilter__in_str_lc'; + +my $chunk = "[Foo BaR] "; +my $data = $chunk x 250; +my $expected = lc $data; +my $received = POST_BODY $location, content => $data; + +ok t_cmp($received, $expected, "input stream filter lc") +
diff --git a/2_0_13/t/filter/in_str_msg.t b/2_0_13/t/filter/in_str_msg.t new file mode 100644 index 0000000..74a781f --- /dev/null +++ b/2_0_13/t/filter/in_str_msg.t
@@ -0,0 +1,16 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache::Test (); +use Apache::TestUtil; + +use Apache::TestRequest 'POST_BODY_ASSERT'; + +my $module = 'TestFilter::in_str_msg'; + +Apache::TestRequest::scheme('http'); #force http for t/TEST -ssl +Apache::TestRequest::module($module); + +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport($config); +t_debug("connecting to $hostport"); + +print POST_BODY_ASSERT "/input_filter.html", content => "upcase me";
diff --git a/2_0_13/t/filter/in_str_sandwich.t b/2_0_13/t/filter/in_str_sandwich.t new file mode 100644 index 0000000..a9d7ef6 --- /dev/null +++ b/2_0_13/t/filter/in_str_sandwich.t
@@ -0,0 +1,17 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = '/TestFilter__in_str_sandwich'; + +my $expected = join "\n", qw(HEADER BODY TAIL), ''; +my $received = POST_BODY $location, content => "BODY\n"; + +ok t_cmp($received, $expected, "input stream filter sandwich") +
diff --git a/2_0_13/t/filter/out_apache.t b/2_0_13/t/filter/out_apache.t new file mode 100644 index 0000000..79c1325 --- /dev/null +++ b/2_0_13/t/filter/out_apache.t
@@ -0,0 +1,38 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# test the situation where a native apache response filter is +# configured outside the <Location> block with PerlSet*Filter +# directive. In this case we need to make sure that mod_perl doesn't +# try to add it as connection filter + +# see the server side config in t/conf/extra.conf.in + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest 'GET_BODY_ASSERT'; +use TestCommon::LogDiff; +use File::Spec::Functions qw(catfile); + +my $path = catfile Apache::Test::vars('serverroot'), + qw(logs error_log); + +plan tests => 2, need 'include', 'HTML::HeadParser'; + +my $module = 'filter_out_apache'; +my $config = Apache::Test::config(); + +Apache::TestRequest::module($module); +my $hostport = Apache::TestRequest::hostport($config); +t_debug("connecting to $hostport"); + +my $logdiff = TestCommon::LogDiff->new($path); + +my $expected = qr/welcome to/; +my $response = GET_BODY_ASSERT "http://$hostport/"; +ok t_cmp $response, qr/$expected/, "success"; + +ok !t_cmp $logdiff->diff, + qr/content filter was added without a request: includes/, + "shouldn't [error] complain in error_log";
diff --git a/2_0_13/t/filter/out_bbs_ctx.t b/2_0_13/t/filter/out_bbs_ctx.t new file mode 100644 index 0000000..8e16c98 --- /dev/null +++ b/2_0_13/t/filter/out_bbs_ctx.t
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $blocks = 33; +my $invoked = 34; # 33 bb made of data and 1 flush bucket (unbuffered print) + # 1 bb with EOS bucket +my $sig = join "\n", "received $blocks complete blocks", + "filter invoked $invoked times\n"; +my $data = "#" x $blocks . "x" x $blocks; +my $expected = join "\n", $data, $sig; + +{ + # test the filtering of the mod_perl response handler + my $location = '/TestFilter__out_bbs_ctx'; + my $response = GET_BODY $location; + ok t_cmp($response, $expected, "context filter"); +}
diff --git a/2_0_13/t/filter/out_bbs_filebucket.t b/2_0_13/t/filter/out_bbs_filebucket.t new file mode 100644 index 0000000..53cd409 --- /dev/null +++ b/2_0_13/t/filter/out_bbs_filebucket.t
@@ -0,0 +1,47 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use File::Spec::Functions qw(catdir catfile); + +my $url = '/TestFilter__out_bbs_filebucket'; + +my $dir = catdir Apache::Test::vars('documentroot'), qw(filter); + +my @sizes = qw(1 100 500 1000 5000); + +plan tests => 2 * scalar @sizes; + +for my $size (@sizes) { + my ($file, $data) = write_file($size); + my $received = GET_BODY "$url?$file"; + + my $received_size = length $received; + my $expected_size = $size * 1024; + + ok t_cmp length($received), length($data), "length"; + ok $received && $received eq uc($data); + unlink $file; +} + +sub write_file { + my $size = shift; + + my $data = "abcd" x ($size * 256); + + my $file = catfile $dir, "data_${size}k.txt"; + open my $fh, ">$file" or die "can't open $file: $!"; + # need binmode on Win32 so as not to strip \r, which + # are included when sending with sendfile(). + binmode $fh; + print $fh $data; + close $fh; + + return ($file, $data); +} + +
diff --git a/2_0_13/t/filter/out_init_basic.t b/2_0_13/t/filter/out_init_basic.t new file mode 100644 index 0000000..ac879f7 --- /dev/null +++ b/2_0_13/t/filter/out_init_basic.t
@@ -0,0 +1,18 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $content = "content ok\n"; +my $expected = join '', "init 1\n", "run 1\n", $content, "run 2\n"; +# newer Apache versions may make yet another call, so you will see +# "run 3\n" as well. + +my $location = '/TestFilter__out_init_basic'; +my $response = POST_BODY $location, content => $content; +ok t_cmp($response, qr/^$expected/, "test filter init functionality");
diff --git a/2_0_13/t/filter/out_str_buffer.t b/2_0_13/t/filter/out_str_buffer.t new file mode 100644 index 0000000..1b48c82 --- /dev/null +++ b/2_0_13/t/filter/out_str_buffer.t
@@ -0,0 +1,23 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2; + +my $sep = "-0-"; +my $data = join $sep, "aa" .. "zz"; + +(my $expected = $data) =~ s/$sep//g; +my $expected_len = length $expected; + +my $location = '/TestFilter__out_str_buffer'; +my $res = POST $location, content => $data; +#t_debug $res->as_string; +my $received_len = $res->header('Content-Length') || 0; +ok t_cmp $received_len, $expected_len, "Content-Length header"; +ok t_cmp $res->content, $expected, "filtered data"; +
diff --git a/2_0_13/t/filter/out_str_ctx.t b/2_0_13/t/filter/out_str_ctx.t new file mode 100644 index 0000000..4f1f44b --- /dev/null +++ b/2_0_13/t/filter/out_str_ctx.t
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $blocks = 33; +my $invoked = 67; # 33 bb made of data and 1 flush bucket (unbuffered print) + # 33 bb made of 1 flush bucket (rflush) + # 1 bb with EOS bucket +my $sig = join "\n", "received $blocks complete blocks", + "filter invoked $invoked times\n"; +my $data = "#" x $blocks . "x" x $blocks; +my $expected = join "\n", $data, $sig; + +{ + # test the filtering of the mod_perl response handler + my $location = '/TestFilter__out_str_ctx'; + my $response = GET_BODY $location; + ok t_cmp($response, $expected, "context stream filter"); +}
diff --git a/2_0_13/t/filter/out_str_declined.t b/2_0_13/t/filter/out_str_declined.t new file mode 100644 index 0000000..488cadd --- /dev/null +++ b/2_0_13/t/filter/out_str_declined.t
@@ -0,0 +1,16 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $expected = 11; # 10 flushes and 1 EOS bb + +my $location = '/TestFilter__out_str_declined'; +my $response = GET_BODY $location; +ok t_cmp($response, $expected, "an output filter handler returning DECLINED"); +
diff --git a/2_0_13/t/filter/out_str_lc.t b/2_0_13/t/filter/out_str_lc.t new file mode 100644 index 0000000..710c2e5 --- /dev/null +++ b/2_0_13/t/filter/out_str_lc.t
@@ -0,0 +1,14 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need 'mod_alias'; + +my $location = "/top_dir/Makefile"; + +my $str = GET_BODY $location; + +ok $str !~ /[A-Z]/;
diff --git a/2_0_13/t/filter/out_str_remove.t b/2_0_13/t/filter/out_str_remove.t new file mode 100644 index 0000000..0740136 --- /dev/null +++ b/2_0_13/t/filter/out_str_remove.t
@@ -0,0 +1,15 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $expected = "F_O_O_b_a_r_"; +my $location = '/TestFilter__out_str_remove'; +my $response = GET_BODY $location; +ok t_cmp($response, $expected, "a filter that removes itself"); +
diff --git a/2_0_13/t/filter/out_str_req_eos.t b/2_0_13/t/filter/out_str_req_eos.t new file mode 100644 index 0000000..3e09ee1 --- /dev/null +++ b/2_0_13/t/filter/out_str_req_eos.t
@@ -0,0 +1,21 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, ['include']; + +my $location = '/TestFilter__out_str_req_eos'; + +my $content = 'BODY'; +my $prefix = 'PREFIX_'; +my $suffix = '_SUFFIX'; + +my $expected = join '', $prefix, $content, $suffix; +my $received = POST_BODY $location, content => $content; + +ok t_cmp($received, $expected, + "testing the EOS bucket forwarding through the mp filters chains");
diff --git a/2_0_13/t/filter/out_str_req_mix.t b/2_0_13/t/filter/out_str_req_mix.t new file mode 100644 index 0000000..d7d839d --- /dev/null +++ b/2_0_13/t/filter/out_str_req_mix.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, ['include']; + +my $location = '/TestFilter__out_str_req_mix'; + +my $content = '<!--#include virtual="/includes/REMOVEclear.shtml" -->'; + +my $expected = 'This is a clear text'; +my $received = POST_BODY $location, content => $content; +$received =~ s{\r?\n$}{}; + +ok t_cmp($expected, $received, + "mixing output httpd and mod_perl filters, while preserving order");
diff --git a/2_0_13/t/filter/out_str_reverse.t b/2_0_13/t/filter/out_str_reverse.t new file mode 100644 index 0000000..8513dac --- /dev/null +++ b/2_0_13/t/filter/out_str_reverse.t
@@ -0,0 +1,32 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2; + +my @data = (join('', 'a'..'z'), join('', 0..9)); + +my $reversed_data = join '', map { scalar(reverse $_) . "\n" } @data; +my $normal_data = join '', map { $_ . "\n" } @data; +#t_debug($reversed_data); +my $sig = "Reversed by mod_perl 2.0\n"; +my $expected = $normal_data . $sig; + +{ + # test the filtering of the mod_perl response handler + my $location = '/TestFilter__out_str_reverse'; + my $response = POST_BODY $location, content => $reversed_data; + ok t_cmp($response, $expected, "reverse filter"); +} + +{ + # test the filtering of the non-mod_perl response handler (file) + my $location = '/filter/reverse.txt'; + my $response = GET_BODY $location; + $response =~ s/\r//g; + ok t_cmp($response, $expected, "reverse filter"); +}
diff --git a/2_0_13/t/filter/out_str_subreq_default.t b/2_0_13/t/filter/out_str_subreq_default.t new file mode 100644 index 0000000..1f408e5 --- /dev/null +++ b/2_0_13/t/filter/out_str_subreq_default.t
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +plan tests => 1, need 'mod_alias'; + +my $location = '/TestFilter__out_str_subreq_default'; + +my $content1 = "content\n"; +my $content2 = "more content\n"; +my $filter = "filter\n"; +my $subrequest = "default-handler subrequest\n"; + +my $expected = join '', $content1, $subrequest, $content2, $filter; +my $received = GET_BODY $location; +# Win32 and Cygwin fix for line endings +$received =~ s{\r}{}g if Apache::TestConfig::WIN32 || Apache::TestConfig::CYGWIN; + +ok t_cmp($received, $expected, + "testing filter-originated lookup_uri() call to core served URI");
diff --git a/2_0_13/t/filter/out_str_subreq_modperl.t b/2_0_13/t/filter/out_str_subreq_modperl.t new file mode 100644 index 0000000..9b1a875 --- /dev/null +++ b/2_0_13/t/filter/out_str_subreq_modperl.t
@@ -0,0 +1,22 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1; + +my $location = '/TestFilter__out_str_subreq_modperl'; + +my $content1 = "content\n"; +my $content2 = "more content\n"; +my $filter = "filter\n"; +my $subrequest = "modperl subrequest\n"; + +my $expected = join '', $content1, $subrequest, $content2, $filter; +my $received = GET_BODY $location; + +ok t_cmp($received, $expected, + "testing filter-originated lookup_uri() call to modperl-served URI");
diff --git a/2_0_13/t/filter/with_subrequest.t b/2_0_13/t/filter/with_subrequest.t new file mode 100644 index 0000000..d935316 --- /dev/null +++ b/2_0_13/t/filter/with_subrequest.t
@@ -0,0 +1,13 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need 'mod_alias'; + +my $location = "/with_subrequest/Makefile"; + +my $str = GET_BODY $location; + +ok $str !~ /[A-Z]/;
diff --git a/2_0_13/t/hooks/TestHooks/access.pm b/2_0_13/t/hooks/TestHooks/access.pm new file mode 100644 index 0000000..e78c974 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/access.pm
@@ -0,0 +1,50 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::access; + +# demonstrates the phases execution (sometimes users claim that +# PerlInitHandler is running more than once +# run with: +# t/TEST -trace=debug -v hooks/access + +use strict; +use warnings FATAL => 'all'; + +use APR::Table (); +use Apache2::Access (); +use Apache2::RequestRec (); +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK FORBIDDEN); + +my $allowed_ips = qr{^(10|127)\.}; + +sub handler { + my $r = shift; + + my $fake_ip = $r->headers_in->get('X-Forwarded-For') || ""; + + debug "access: " . ($fake_ip =~ $allowed_ips ? "OK\n" : "FORBIDDEN\n"); + + return Apache2::Const::FORBIDDEN unless $fake_ip =~ $allowed_ips; + + Apache2::Const::OK; +} + +sub fixup { debug "fixup\n"; Apache2::Const::OK } +sub init { debug "init\n"; Apache2::Const::OK } + +1; +__DATA__ +<NoAutoConfig> +PerlModule TestHooks::access +<Location /TestHooks__access> + PerlAccessHandler TestHooks::access + PerlInitHandler TestHooks::access::init + PerlFixupHandler TestHooks::access::fixup + PerlResponseHandler Apache::TestHandler::ok1 + SetHandler modperl +</Location> +#<Location /> +# PerlAccessHandler TestHooks::access +#</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/authen_basic.pm b/2_0_13/t/hooks/TestHooks/authen_basic.pm new file mode 100644 index 0000000..a7ba01e --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/authen_basic.pm
@@ -0,0 +1,51 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::authen_basic; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Access (); + +use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED SERVER_ERROR); +use constant APACHE24 => have_min_apache_version('2.4.0'); + +sub handler { + my $r = shift; + + my ($rc, $sent_pw) = $r->get_basic_auth_pw; + + return $rc if $rc != Apache2::Const::OK; + + my $user = $r->user; + + # We don't have to check for valid-user in 2.4.0+. If there is bug + # in require valid-user handling, it will result in failed test with + # bad username/password. + if (!APACHE24) { + my $requirement = $r->requires->[0]->{requirement}; + return Apache2::Const::SERVER_ERROR unless $requirement eq 'valid-user'; + } + + unless ($user eq 'dougm' and $sent_pw eq 'foo') { + $r->note_basic_auth_failure; + return Apache2::Const::HTTP_UNAUTHORIZED; + } + + Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> +<Location /TestHooks__authen_basic> + require valid-user + AuthType Basic + AuthName simple + PerlAuthenHandler TestHooks::authen_basic + PerlResponseHandler Apache::TestHandler::ok1 + SetHandler modperl +</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/authen_digest.pm b/2_0_13/t/hooks/TestHooks/authen_digest.pm new file mode 100644 index 0000000..9ccc396 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/authen_digest.pm
@@ -0,0 +1,43 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::authen_digest; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Access (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED); + +sub handler { + + my $r = shift; + + # we don't need to do the entire Digest auth round + # trip just to see if note_digest_auth_failure is + # functioning properly - see authen_digest.t for the + # header checks + if ($r->args) { + $r->note_digest_auth_failure; + return Apache2::Const::HTTP_UNAUTHORIZED; + } + + $r->user("user"); + $r->ap_auth_type("Digest"); + + return Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> +<Location /TestHooks__authen_digest> + PerlAuthenHandler TestHooks::authen_digest + PerlResponseHandler Apache::TestHandler::ok + SetHandler modperl + + require valid-user + AuthType Digest + AuthName "Simple Digest" +</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/authz.pm b/2_0_13/t/hooks/TestHooks/authz.pm new file mode 100644 index 0000000..1134eb3 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/authz.pm
@@ -0,0 +1,48 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::authz; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Access (); + +use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED); + +sub auth_any { + my $self = shift; + my $r = shift; + + my ($res, $sent_pw) = $r->get_basic_auth_pw; + return $res if $res != Apache2::Const::OK; + + unless($r->user and $sent_pw) { + # testing $r->note_auth_failure: + # AuthType Basic + note_auth_failure == note_basic_auth_failure; + $r->note_auth_failure; + return Apache2::Const::HTTP_UNAUTHORIZED; + } + + return Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + my $user = $r->user; + + return Apache2::Const::HTTP_UNAUTHORIZED unless $user; + + return Apache2::Const::HTTP_UNAUTHORIZED unless "dougm" eq $user; + + Apache2::Const::OK; +} + +1; +__DATA__ +require user dougm +AuthType Basic +AuthName simple +PerlModule TestHooks::authz +PerlAuthenHandler TestHooks::authz->auth_any +PerlResponseHandler Apache::TestHandler::ok1 +SetHandler modperl
diff --git a/2_0_13/t/hooks/TestHooks/cleanup.pm b/2_0_13/t/hooks/TestHooks/cleanup.pm new file mode 100644 index 0000000..f493e24 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/cleanup.pm
@@ -0,0 +1,67 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::cleanup; + +# test various ways to assign cleanup handlers + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use File::Spec::Functions qw(catfile); + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); + +use Apache2::Const -compile => qw(OK DECLINED); + +sub get_file { + catfile Apache::Test::vars("documentroot"), "hooks", "cleanup"; +} + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + $r->print('ok'); + $r->pnotes(items => ["cleanup"," ok"]); + $r->push_handlers(PerlCleanupHandler => \&cleanup2); + + return Apache2::Const::OK; +} + +sub cleanup1 { + my $r = shift; + + my $items = $r->pnotes('items'); + die "no items" unless $items; + my $item = $items ? $items->[0] : ''; + #warn "cleanup CALLED\n"; + t_write_file(get_file(), $item); + + return Apache2::Const::OK; +} + +sub cleanup2 { + my $r = shift; + + my $items = $r->pnotes('items'); + my $item = $items ? $items->[1] : ''; + #warn "cleanup2 CALLED\n"; + t_append_file(get_file(), $item); + + return Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> + <Location /TestHooks__cleanup> + SetHandler modperl + PerlCleanupHandler TestHooks::cleanup::cleanup1 + PerlResponseHandler TestHooks::cleanup + </Location> +</NoAutoConfig> +
diff --git a/2_0_13/t/hooks/TestHooks/cleanup2.pm b/2_0_13/t/hooks/TestHooks/cleanup2.pm new file mode 100644 index 0000000..1c68dfa --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/cleanup2.pm
@@ -0,0 +1,58 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::cleanup2; + +# test the cleanup handler removing a temp file + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use File::Spec::Functions qw(catfile); + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use APR::Pool (); + +use Apache2::Const -compile => qw(OK DECLINED); +use APR::Const -compile => 'SUCCESS'; + +my $file = catfile Apache::Test::config->{vars}->{documentroot}, + "hooks", "cleanup2"; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + t_write_file($file, "cleanup2 is ok"); + + my $status = $r->sendfile($file); + die "sendfile has failed" unless $status == APR::Const::SUCCESS; + + $r->pool->cleanup_register(\&cleanup, $file); + + return Apache2::Const::OK; +} + +sub cleanup { + my $file_arg = shift; + + debug_sub "called"; + die "Can't find file: $file_arg" unless -e $file_arg; + unlink $file_arg or die "failed to unlink $file_arg"; + + return Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> + <Location /TestHooks__cleanup2> + SetHandler modperl + PerlResponseHandler TestHooks::cleanup2 + </Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/error.pm b/2_0_13/t/hooks/TestHooks/error.pm new file mode 100644 index 0000000..6ce74fd --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/error.pm
@@ -0,0 +1,44 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::error; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Const -compile => 'OK'; + +use APR::Table (); + +sub handler { + my $r = shift; + my $args = $r->args(); + if (defined($args) && $args ne '') { + $r->notes->set('error-notes' => $args); + } + &bomb(); + Apache2::Const::OK; +} + +sub fail { + my $r = shift; + $r->print('Error: '.$r->prev->notes->get('error-notes')); + Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> + <Location /TestHooks__error> + SetHandler modperl + PerlResponseHandler TestHooks::error + ErrorDocument 500 /TestHooks__error__fail + </Location> + <Location /TestHooks__error__fail> + SetHandler modperl + PerlResponseHandler TestHooks::error::fail + </Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/fixup.pm b/2_0_13/t/hooks/TestHooks/fixup.pm new file mode 100644 index 0000000..80d6fff --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/fixup.pm
@@ -0,0 +1,35 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::fixup; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use APR::Table (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->notes->set(ok => 1); + + Apache2::Const::OK; +} + +sub response { + my $r = shift; + + plan $r, tests => 1; + + ok $r->notes->get('ok'); + + Apache2::Const::OK; +} + +1; +__DATA__ +PerlResponseHandler TestHooks::fixup::response +SetHandler modperl
diff --git a/2_0_13/t/hooks/TestHooks/headerparser.pm b/2_0_13/t/hooks/TestHooks/headerparser.pm new file mode 100644 index 0000000..780bf78 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/headerparser.pm
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::headerparser; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use APR::Table (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->notes->set(headerparser => 'set'); + + Apache2::Const::OK; +} + +sub response { + my $r = shift; + + plan $r, tests => 1; + + ok $r->notes->get('headerparser') eq 'set'; + + Apache2::Const::OK; +} + +1; +__DATA__ +PerlOptions +SetupEnv +PerlResponseHandler TestHooks::headerparser::response +SetHandler modperl
diff --git a/2_0_13/t/hooks/TestHooks/hookrun.pm b/2_0_13/t/hooks/TestHooks/hookrun.pm new file mode 100644 index 0000000..c842ee9 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/hookrun.pm
@@ -0,0 +1,156 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::hookrun; + +# this test runs all Apache phases from within the very first http +# phase + +# XXX: may be improve the test to do a full-blown test, where each +# phase does something useful. + +# see also TestProtocol::pseudo_http + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use Apache2::HookRun (); +use APR::Table (); +use ModPerl::Util (); + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK DECLINED DONE SERVER_ERROR); + +my $path = '/' . Apache::TestRequest::module2path(__PACKAGE__); + +my @phases = qw( + PerlPostReadRequestHandler + PerlTransHandler + PerlMapToStorageHandler + PerlHeaderParserHandler + PerlAccessHandler + PerlAuthenHandler + PerlAuthzHandler + PerlTypeHandler + PerlFixupHandler + PerlResponseHandler + PerlLogHandler +); + +sub post_read_request { + my $r = shift; + my $rc; + + $r->push_handlers(PerlTransHandler => \&any); + $r->push_handlers(PerlMapToStorageHandler => \&any); + $r->push_handlers(PerlHeaderParserHandler => \&any); + $r->push_handlers(PerlAccessHandler => \&any); + $r->push_handlers(PerlAuthenHandler => \&any); + $r->push_handlers(PerlAuthzHandler => \&any); + $r->push_handlers(PerlTypeHandler => \&any); + $r->push_handlers(PerlFixupHandler => \&any); + $r->push_handlers(PerlLogHandler => \&any); + + any($r); # indicate that the post_read_request phase was run + + # for the full Apache logic for running phases starting from + # post_read_request and ending with fixup see + # ap_process_request_internal in httpd-2.0/server/request.c + + $rc = $r->run_translate_name; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + $rc = $r->run_map_to_storage; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + # this must be run all a big havoc will happen in the following + # phases + $r->location_merge($path); + + $rc = $r->run_header_parser; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + my $args = $r->args || ''; + if ($args eq 'die') { + $r->die(Apache2::Const::SERVER_ERROR); + return Apache2::Const::DONE; + } + + $rc = $r->run_access_checker; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + $rc = $r->run_auth_checker; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + $rc = $r->run_check_user_id; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + $rc = $r->run_type_checker; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + $rc = $r->run_fixups; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + # $r->run_handler is called internally by $r->invoke_handler, + # invoke_handler sets all kind of filters, and does a few other + # things but it's possible to call $r->run_handler, bypassing + # invoke_handler + $rc = $r->invoke_handler; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + $rc = $r->run_log_transaction; + return $rc unless $rc == Apache2::Const::OK or $rc == Apache2::Const::DECLINED; + + return Apache2::Const::DONE; + + # Apache runs ap_finalize_request_protocol on return of this + # handler +} + +sub any { + my $r = shift; + + my $callback = ModPerl::Util::current_callback(); + + debug "running $callback\n"; + $r->notes->set($callback => 1); + + # unset the callback that was already run + $r->set_handlers($callback => []); + + Apache2::Const::OK; +} + +sub response { + my $r = shift; + + my @pre_response = (@phases)[0..($#phases-2)]; + plan tests => scalar(@pre_response); + + for my $phase (@pre_response) { + my $note = $r->notes->get($phase); + $r->print("$phase:$note\n"); + } + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +<VirtualHost TestHooks::hookrun> + PerlModule TestHooks::hookrun + PerlPostReadRequestHandler TestHooks::hookrun::post_read_request + <Location /TestHooks__hookrun> + SetHandler modperl + PerlResponseHandler TestHooks::hookrun::response + + AuthName modperl + AuthType none + Require valid-user + </Location> +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/init.pm b/2_0_13/t/hooks/TestHooks/init.pm new file mode 100644 index 0000000..dada6a8 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/init.pm
@@ -0,0 +1,69 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::init; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use APR::Table (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => qw(OK DECLINED); + +sub first { + my $r = shift; + + $r->notes->set(ok1 => 1); + + Apache2::Const::OK; +} + +sub second { + my $r = shift; + + my $ok = $r->notes->get('ok1') || 0; + + $r->notes->set(ok2 => $ok + 1); + + Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + my $ok = $r->notes->get('ok2') || 0; + + $r->notes->set(ok3 => $ok + 1); + + Apache2::Const::DECLINED; +} + +sub response { + my $r = shift; + + my $tests = 3; + plan $r, tests => $tests; + + for my $x (1..$tests) { + my $val = $r->notes->get("ok$x") || 0; + ok $val == $x; + } + + Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> + <VirtualHost TestHooks::init> + PerlModule TestHooks::init + PerlInitHandler TestHooks::init::first + <Location /TestHooks__init> + PerlInitHandler TestHooks::init::second + PerlResponseHandler TestHooks::init + PerlResponseHandler TestHooks::init::response + SetHandler modperl + </Location> + </VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/inlined_handlers.pm b/2_0_13/t/hooks/TestHooks/inlined_handlers.pm new file mode 100644 index 0000000..be25837 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/inlined_handlers.pm
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::inlined_handlers; + +# this test exercises httpd.conf inlined one-liner handlers, like: +# PerlFixupHandler 'sub { use Apache2::Const qw(DECLINED); DECLINED }' +# previously there was a bug in non-ithreaded-perl implementation +# where the cached compiled CODE ref didn't have the reference count +# right. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->print('ok'); + + Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> + <Location /TestHooks__inlined_handlers> + SetHandler modperl + PerlFixupHandler 'sub { use Apache2::Const qw(DECLINED); DECLINED }' + PerlResponseHandler TestHooks::inlined_handlers + </Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/push_handlers.pm b/2_0_13/t/hooks/TestHooks/push_handlers.pm new file mode 100644 index 0000000..2d85f6d --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/push_handlers.pm
@@ -0,0 +1,70 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::push_handlers; + +# test various ways to push handlers + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); + +use Apache2::Const -compile => qw(OK DECLINED DONE); + +sub handler { + my $r = shift; + + $r->handler("modperl"); + + $r->push_handlers(PerlResponseHandler => \&coderef); + $r->push_handlers(PerlResponseHandler => + \&TestHooks::push_handlers::full_coderef); + + $r->push_handlers(PerlResponseHandler => + [\&coderef1, __PACKAGE__.'::coderef2', \&coderef3]); + + $r->push_handlers(PerlResponseHandler => + sub { return say(shift, "anonymous") }); + + $r->push_handlers(PerlResponseHandler => + [sub { return say(shift, "anonymous1") }, + \&coderef4, + sub { return say(shift, "anonymous3") }, + ]); + + $r->push_handlers(PerlResponseHandler => \&end); + + return Apache2::Const::DECLINED; +} + +sub end { return Apache2::Const::DONE } +sub say { shift->print(shift,"\n"); return Apache2::Const::DECLINED } + +sub conf { + # this one is configured from httpd.conf + my $r= shift; + $r->content_type('text/plain'); + return say($r, "conf"); +} + +sub conf1 { return say(shift, "conf1") } +sub conf2 { return say(shift, "conf2") } +sub coderef { return say(shift, "coderef") } +sub coderef1 { return say(shift, "coderef1") } +sub coderef2 { return say(shift, "coderef2") } +sub coderef3 { return say(shift, "coderef3") } +sub coderef4 { return say(shift, "coderef4") } +sub full_coderef { return say(shift, "full_coderef") } + +1; +__DATA__ +<NoAutoConfig> + <Location /TestHooks__push_handlers> + SetHandler modperl + PerlHeaderParserHandler TestHooks::push_handlers + PerlResponseHandler TestHooks::push_handlers::conf + PerlResponseHandler TestHooks::push_handlers::conf1 TestHooks::push_handlers::conf2 + </Location> +</NoAutoConfig> +
diff --git a/2_0_13/t/hooks/TestHooks/push_handlers_anon.pm b/2_0_13/t/hooks/TestHooks/push_handlers_anon.pm new file mode 100644 index 0000000..abfd028 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/push_handlers_anon.pm
@@ -0,0 +1,63 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::push_handlers_anon; + +# in addition to other anon sub handler tests in push_handlers*, here +# we test an anon sub added at the server startup. in order not to mess +# with the rest of the test suite, we run it in its own vhost + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::ServerUtil (); +use APR::Pool (); + +use Apache2::Const -compile => qw(OK DECLINED); + +use Apache::Test; +use Apache::TestUtil; + +sub add_note { + my $r = shift; + + my $count = $r->notes->get("add_note") || 0; + $count++; + $r->notes->set("add_note", $count); + Apache2::Const::DECLINED; +} + +# PerlFixupHandlers added at the server startup should add 3 notes +sub handler { + my $r = shift; + + plan $r, tests => 1; + + my $count = $r->notes->get("add_note") || 0; + ok t_cmp $count, 3, "$count callbacks"; + + Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> +# APACHE_TEST_CONFIG_ORDER 1000 +<VirtualHost TestHooks::push_handlers_anon> + PerlModule TestHooks::push_handlers_anon + <Perl > + my $s = Apache2::PerlSections->server; + + $s->push_handlers(PerlFixupHandler => + sub { &TestHooks::push_handlers_anon::add_note }); + $s->push_handlers(PerlFixupHandler => + \&TestHooks::push_handlers_anon::add_note ); + $s->push_handlers(PerlFixupHandler => + "TestHooks::push_handlers_anon::add_note" ); + </Perl> + + <Location /TestHooks__push_handlers_anon> + SetHandler modperl + PerlResponseHandler TestHooks::push_handlers_anon + </Location> +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/push_handlers_blessed.pm b/2_0_13/t/hooks/TestHooks/push_handlers_blessed.pm new file mode 100644 index 0000000..0a5dd53 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/push_handlers_blessed.pm
@@ -0,0 +1,45 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::push_handlers_blessed; + +# test that we +# - can push and execute blessed anon handlers + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK DECLINED); + +sub handler { + my $r = shift; + + plan $r, tests => 1; + + my $sub = sub { + ok 1; + + return Apache2::Const::OK; + }; + + my $handler = bless $sub, __PACKAGE__; + + $r->push_handlers(PerlResponseHandler => $handler); + + return Apache2::Const::DECLINED; +} + +1; +__DATA__ +<NoAutoConfig> +<Location /TestHooks__push_handlers_blessed> + SetHandler modperl + PerlResponseHandler TestHooks::push_handlers_blessed +</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/push_handlers_same_phase.pm b/2_0_13/t/hooks/TestHooks/push_handlers_same_phase.pm new file mode 100644 index 0000000..6584e12 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/push_handlers_same_phase.pm
@@ -0,0 +1,67 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::push_handlers_same_phase; + +# test that we +# - can push handlers into the same phase that is currently running +# - cannot switch 'perl-script' to 'modperl' and vice versa once +# inside the response phase + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK DECLINED); + +sub handler { + my $r = shift; + + my $counter = $r->notes->get('counter') || 0; + $r->notes->set(counter => $counter+1); + + $r->push_handlers(PerlResponseHandler => \&real_response); + + return Apache2::Const::DECLINED; +} + +sub real_response { + my $r = shift; + + plan $r, tests => 3; + + # test that we don't rerun all the handlers again (it should no + # longer happen as we don't allow switching 'perl-script' <=> + # 'modperl' on the go, but test anyway) + my $counter = $r->notes->get('counter') || 0; + ok t_cmp($counter, 1, + __PACKAGE__ . "::handler must have been called only once"); + + my @handlers = @{ $r->get_handlers('PerlResponseHandler') || []}; + ok t_cmp(scalar(@handlers), + 2, + "there should be 2 response handlers"); + + # once running inside the response phase it shouldn't be possible + # to switch from 'perl-script' to 'modperl' and vice versa + eval { $r->handler("perl-script") }; + ok t_cmp($@, qr/Can't switch from/, + "can't switch from 'perl-script' to 'modperl' inside " . + "the response phase"); + + return Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +<Location /TestHooks__push_handlers_same_phase> + SetHandler modperl + PerlResponseHandler TestHooks::push_handlers_same_phase +</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/set_handlers.pm b/2_0_13/t/hooks/TestHooks/set_handlers.pm new file mode 100644 index 0000000..f64dbf1 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/set_handlers.pm
@@ -0,0 +1,46 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::set_handlers; + +# test various ways to reset/unset handlers list + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); + +use Apache2::Const -compile => qw(OK); + +sub handler { + my $r = shift; + + # the first way to reset the handlers list is to pass undef + # access handler phase will be not called for mp + $r->set_handlers(PerlAccessHandler => undef); + + # the second way to reset the handlers list is to pass [] + # fixup must be not executed + $r->set_handlers(PerlFixupHandler => \&fixup); + $r->set_handlers(PerlFixupHandler => []); + + # normal override + $r->set_handlers(PerlResponseHandler => sub { die "not to be called"}); + $r->set_handlers(PerlResponseHandler => [\&Apache::TestHandler::ok1]); + $r->handler("modperl"); + + return Apache2::Const::OK; +} + +sub fixup { + die "fixup must not be executed"; +} + +1; +__DATA__ +<NoAutoConfig> + <Location /TestHooks__set_handlers> + PerlHeaderParserHandler TestHooks::set_handlers + </Location> +</NoAutoConfig> +
diff --git a/2_0_13/t/hooks/TestHooks/stacked_handlers.pm b/2_0_13/t/hooks/TestHooks/stacked_handlers.pm new file mode 100644 index 0000000..e74a974 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/stacked_handlers.pm
@@ -0,0 +1,70 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::stacked_handlers; + +# this test exercises the execution of the stacked handlers and test +# whether the execution breaks when something different than OK or +# DECLINED is returned + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); + +use Apache2::Const -compile => qw(OK DECLINED DONE); + +sub handler { + my $r = shift; + + $r->handler("modperl"); + $r->push_handlers(PerlResponseHandler => [\&one, \&two, \&three, \&four]); + + return Apache2::Const::OK; +} + +sub one { + my $r = shift; + + $r->content_type('text/plain'); + $r->print("one\n"); + + return Apache2::Const::DECLINED; +} + +sub two { + my $r = shift; + + $r->print("two\n"); + + return Apache2::Const::DECLINED; +} + +sub three { + my $r = shift; + + $r->print("three\n"); + + return Apache2::Const::DONE; +} + +# this one shouldn't get called, because the handler 'three' has +# returned DONE +sub four { + my $r = shift; + + $r->print("four\n"); + + return Apache2::Const::OK; +} + + +1; +__DATA__ +<NoAutoConfig> + <Location /TestHooks__stacked_handlers> + SetHandler modperl + PerlHeaderParserHandler TestHooks::stacked_handlers + </Location> +</NoAutoConfig> +
diff --git a/2_0_13/t/hooks/TestHooks/stacked_handlers2.pm b/2_0_13/t/hooks/TestHooks/stacked_handlers2.pm new file mode 100644 index 0000000..25f1ca7 --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/stacked_handlers2.pm
@@ -0,0 +1,209 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::stacked_handlers2; + +# this test exercises the execution of the stacked handlers +# connection, translation, authen, authz, type, and response +# phases should end for the first handler that returns OK + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); + +use ModPerl::Util (); + +use APR::Table; + +use Apache2::Const -compile => qw(OK DECLINED AUTH_REQUIRED SERVER_ERROR); + +sub ok { + + callback(shift); + + return Apache2::Const::OK; +} + +sub ok_authen { + + my $r = shift; + callback($r); + + $r->user("user"); + $r->ap_auth_type("Basic"); + + return Apache2::Const::OK; +} + +sub declined { + + callback(shift); + + return Apache2::Const::DECLINED; +} + +sub auth_required { + + callback(shift); + + return Apache2::Const::AUTH_REQUIRED; +} + +sub server_error { + + callback(shift); + + return Apache2::Const::SERVER_ERROR; +} + +sub push_handlers { + + my $r = shift; + + $r->push_handlers(PerlFixupHandler => \&ok); + + callback($r); + + return Apache2::Const::OK; +} + +sub callback { + + my $obj = shift; + + my ($r, $callback); + + if ($obj->isa('Apache2::Filter')) { + $r = $obj->r; + $callback = 'PerlOutputFilterHandler'; + } + else { + $r = $obj + } + + $callback ||= ModPerl::Util::current_callback; + + my $count = $r->notes->get($callback) || 0; + + $r->notes->set($callback, ++$count); +} + +sub handler { + + my $r = shift; + + $r->content_type('text/plain'); + + callback($r); + + foreach my $callback (qw(PerlPostReadRequestHandler + PerlTransHandler + PerlMapToStorageHandler + PerlHeaderParserHandler + PerlAccessHandler + PerlAuthenHandler + PerlAuthzHandler + PerlTypeHandler + PerlFixupHandler + PerlResponseHandler)) { + + my $count = $r->notes->get($callback) || 0; + + $r->print("ran $count $callback handlers\n"); + } + + return Apache2::Const::OK; +} + +sub passthru { + my $filter = shift; + + unless ($filter->ctx) { + callback($filter); + $filter->ctx({seen => 1}); + } + + while ($filter->read(my $buffer, 1024)) { + $filter->print($buffer); + } + + # this should be ignored? + Apache2::Const::OK; +} + +sub filter { + my $filter = shift; + + unless ($filter->ctx) { + callback($filter); + $filter->ctx({seen => 1}); + } + + while ($filter->read(my $buffer, 1024)) { + $filter->print($buffer); + } + + if ($filter->seen_eos) { + my $count = $filter->r->notes->get('PerlOutputFilterHandler') || 0; + + $filter->print("ran $count PerlOutputFilterHandler handlers\n"); + } + + # this should be ignored? + Apache2::Const::OK; +} + +1; +__DATA__ +# create a new virtual host so we can test (almost all) all the hooks +<NoAutoConfig> +<VirtualHost TestHooks::stacked_handlers2> + + PerlModule TestHooks::stacked_handlers2 + + # all 2 run + PerlPostReadRequestHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::ok + + # 1 run, 1 left behind + PerlTransHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::server_error + + # 1 run, 1 left behind + PerlMapToStorageHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::server_error + + <Location /TestHooks__stacked_handlers2> + # all 4 run + PerlHeaderParserHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::declined + PerlHeaderParserHandler TestHooks::stacked_handlers2::declined TestHooks::stacked_handlers2::ok + + # all 2 run + PerlAccessHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::ok + + # 2 run, 1 left behind + PerlAuthenHandler TestHooks::stacked_handlers2::declined TestHooks::stacked_handlers2::ok_authen + PerlAuthenHandler TestHooks::stacked_handlers2::auth_required + + # 2 run, 1 left behind + PerlAuthzHandler TestHooks::stacked_handlers2::declined TestHooks::stacked_handlers2::ok + PerlAuthzHandler TestHooks::stacked_handlers2::auth_required + + # 1 run, 1 left behind + PerlTypeHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers3::server_error + + # all 4 run + PerlFixupHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::ok + PerlFixupHandler TestHooks::stacked_handlers2::push_handlers + + # 2 run, 2 left behind + PerlResponseHandler TestHooks::stacked_handlers2::declined TestHooks::stacked_handlers2 + PerlResponseHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::server_error + + SetHandler modperl + AuthType Basic + Require valid-user + + PerlOutputFilterHandler TestHooks::stacked_handlers2::passthru TestHooks::stacked_handlers2::filter + </Location> + +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/startup.pm b/2_0_13/t/hooks/TestHooks/startup.pm new file mode 100644 index 0000000..ecceeba --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/startup.pm
@@ -0,0 +1,135 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::startup; + +# test PerlPostConfigHandler and PerlOpenLogsHandler phases +# also test that we can run things on vhost entries from these phases + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; +use Apache::TestTrace; + +use APR::Table; +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use File::Spec::Functions qw(catfile catdir); +use File::Path qw(mkpath); + +use Apache2::Const -compile => 'OK'; + +my $dir = catdir Apache::Test::vars("documentroot"), 'hooks', 'startup'; + +sub open_logs { + my ($conf_pool, $log_pool, $temp_pool, $s) = @_; + + # main server + run("open_logs", $s); + + for (my $vhost_s = $s->next; $vhost_s; $vhost_s = $vhost_s->next) { + my $port = $vhost_s->port; + my $val = $vhost_s->dir_config->{PostConfig}; + # we have one vhost that we want to run open_logs for + next unless $val && $val eq 'VHost'; + run("open_logs", $vhost_s); + } + + Apache2::Const::OK; +} + +sub post_config { + my ($conf_pool, $log_pool, $temp_pool, $s) = @_; + + # main server + run("post_config", $s); + + for (my $vhost_s = $s->next; $vhost_s; $vhost_s = $vhost_s->next) { + my $port = $vhost_s->port; + my $val = $vhost_s->dir_config->{PostConfig}; + # we have one vhost that we want to run post_config for + next unless $val && $val eq 'VHost'; + run("post_config", $vhost_s); + } + + Apache2::Const::OK; +} + +sub run { + my ($phase, $s) = @_; + + my $val = $s->dir_config->{PostConfig} or die "Can't read PostConfig var"; + + # make sure that these are set at the earliest possible time + die '$ENV{MOD_PERL} not set!' unless $ENV{MOD_PERL}; + die '$ENV{MOD_PERL_API_VERSION} not set!' + unless $ENV{MOD_PERL_API_VERSION} == 2; + + my $port = $s->port; + my $file = catfile $dir, "$phase-$port"; + + mkpath $dir, 0, 0755; + open my $fh, ">$file" or die "can't open $file: $!"; + print $fh $val; + close $fh; + + debug "Phase $phase is completed for server at port $port"; +} + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + my $s = $r->server; + my $expected = $s->dir_config->{PostConfig} + or die "Can't read PostConfig var"; + my $port = $s->port; + + for my $phase (qw(open_logs post_config)) { + my $file = catfile $dir, "$phase-$port"; + open my $fh, "$file" or die "can't open $file: $!"; + my $received = <$fh> || ''; + close $fh; + + # can't cleanup the file here, because t/SMOKE may run this + # test more than once, so we cleanup on startup in modperl_extra.pl + # unlink $file; + + if ($expected eq $received) { + $r->print("$phase ok\n"); + } else { + warn "phase: $phase\n"; + warn "port: $port\n"; + warn "expected: $expected\n"; + warn "received: $received\n"; + } + } + Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> +<VirtualHost TestHooks::startup> + PerlSetVar PostConfig VHost + PerlModule TestHooks::startup + PerlPostConfigHandler TestHooks::startup::post_config + PerlOpenLogsHandler TestHooks::startup::open_logs + <Location /TestHooks__startup> + SetHandler modperl + PerlResponseHandler TestHooks::startup + </Location> +</VirtualHost> +PerlSetVar PostConfig Main +PerlModule TestHooks::startup +PerlPostConfigHandler TestHooks::startup::post_config +PerlOpenLogsHandler TestHooks::startup::open_logs +<Location /TestHooks__startup> + SetHandler modperl + PerlResponseHandler TestHooks::startup +</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/TestHooks/trans.pm b/2_0_13/t/hooks/TestHooks/trans.pm new file mode 100644 index 0000000..279fd5c --- /dev/null +++ b/2_0_13/t/hooks/TestHooks/trans.pm
@@ -0,0 +1,49 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestHooks::trans; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestConfig (); + +use Apache2::RequestRec (); + +use Apache2::Const -compile => qw(OK DECLINED); + +my %trans = ( + '/TestHooks/trans.pm' => sub { + my $r = shift; + $r->filename(__FILE__); + Apache2::Const::OK; + }, + '/phooey' => sub { + my $r = shift; + $r->filename(__FILE__); #filename is currently required + $r->uri('/TestHooks::trans'); + Apache2::Const::OK; + }, +); + +sub handler { + my $r = shift; + + my $uri = $r->uri; + + my $handler = $trans{ $uri }; + + return Apache2::Const::DECLINED unless $handler; + + $handler->($r); +} + +1; +__DATA__ +<NoAutoConfig> + <VirtualHost TestHooks::trans> + PerlTransHandler TestHooks::trans + <Location /TestHooks__trans> + PerlResponseHandler Apache::TestHandler::ok1 + SetHandler modperl + </Location> + </VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/hooks/access.t b/2_0_13/t/hooks/access.t new file mode 100644 index 0000000..3266a3c --- /dev/null +++ b/2_0_13/t/hooks/access.t
@@ -0,0 +1,22 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 4, need 'HTML::HeadParser'; + +my $location = "/TestHooks__access"; + +ok ! GET_OK $location; + +my $rc = GET_RC $location; + +ok $rc == 403; + +ok GET_OK $location, 'X-Forwarded-For' => '127.0.0.1'; + +ok ! GET_OK $location, 'X-Forwarded-For' => '666.0.0.1'; + +
diff --git a/2_0_13/t/hooks/authen_basic.t b/2_0_13/t/hooks/authen_basic.t new file mode 100644 index 0000000..759d010 --- /dev/null +++ b/2_0_13/t/hooks/authen_basic.t
@@ -0,0 +1,34 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 4, need need_lwp, need_auth, 'HTML::HeadParser'; + +my $location = "/TestHooks__authen_basic"; + +sok { + ! GET_OK $location; +}; + +sok { + my $rc = GET_RC $location; + $rc == 401; +}; + +sok { + GET_OK $location, username => 'dougm', password => 'foo'; +}; + +# since LWP 5.815, the user agent retains credentials +# tell Apache::TestRequest to reinitialize its global agent +Apache::TestRequest::user_agent(reset => 1); + +sok { + ! GET_OK $location, username => 'dougm', password => 'wrong'; +}; + + +
diff --git a/2_0_13/t/hooks/authen_digest.t b/2_0_13/t/hooks/authen_digest.t new file mode 100644 index 0000000..3bc9c97 --- /dev/null +++ b/2_0_13/t/hooks/authen_digest.t
@@ -0,0 +1,52 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 7, need need_lwp, 'auth_digest', 'HTML::HeadParser'; + +my $location = '/TestHooks__authen_digest'; + +{ + my $response = GET $location; + + ok t_cmp($response->code, + 200, + 'handler returned HTTP_OK'); + + my $wwwauth = $response->header('WWW-Authenticate'); + + t_debug('response had no WWW-Authenticate header'); + ok (!$wwwauth); +} + +{ + my $response = GET "$location?fail"; + + ok t_cmp($response->code, + 401, + 'handler returned HTTP_UNAUTHORIZED'); + + my $wwwauth = $response->header('WWW-Authenticate'); + + t_debug('response had a WWW-Authenticate header'); + ok ($wwwauth); + + ok t_cmp($wwwauth, + qr/^Digest/, + 'response is using Digest authentication scheme'); + + ok t_cmp($wwwauth, + qr/realm="Simple Digest"/, + 'WWW-Authenticate header contains the proper realm'); + + ok t_cmp($wwwauth, + qr/nonce="/, + 'WWW-Authenticate header contains a nonce'); + + # other fields, such as qop, are added only if add additional + # configuration directives, such as AuthDigestQop +}
diff --git a/2_0_13/t/hooks/authz.t b/2_0_13/t/hooks/authz.t new file mode 100644 index 0000000..5ad3b8e --- /dev/null +++ b/2_0_13/t/hooks/authz.t
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 4, need need_lwp, 'HTML::HeadParser'; + +my $location = "/TestHooks__authz"; + +ok ! GET_OK $location; + +my $rc = GET_RC $location; + +ok $rc == 401; + +ok GET_OK $location, username => 'dougm', password => 'foo'; + +# since LWP 5.815, the user agent retains credentials +# tell Apache::TestRequest to reinitialize its global agent +Apache::TestRequest::user_agent(reset => 1); + +ok ! GET_OK $location, username => 'jobbob', password => 'whatever'; + +
diff --git a/2_0_13/t/hooks/cleanup.t b/2_0_13/t/hooks/cleanup.t new file mode 100644 index 0000000..d47554b --- /dev/null +++ b/2_0_13/t/hooks/cleanup.t
@@ -0,0 +1,55 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use File::Spec::Functions qw(catfile catdir); + +use constant SIZE => 10; +use constant TRIES => 20; + +my $file = catfile Apache::Test::vars("documentroot"), "hooks", "cleanup"; + +plan tests => 2; + +{ + # this registers and performs cleanups, but we test whether the + # cleanup was run only in the next sub-test + my $location = "/TestHooks__cleanup"; + my $expected = 'ok'; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "register req cleanup"); +} + +{ + # this sub-tests checks that the cleanup stage was run successfully + + # since Apache destroys the request rec after the logging has been + # finished, we have to give it some time to get there + # and fill in the file. (wait 0.25 .. 5 sec) + my $t = 0; + select undef, undef, undef, 0.25 + until -e $file && -s _ == SIZE || $t++ == TRIES; + + unless (-e $file) { + t_debug("can't find $file"); + ok 0; + } + else { + open my $fh, $file or die "Can't open $file: $!"; + my $received = <$fh> || ''; + close $fh; + my $expected = "cleanup ok"; + ok t_cmp($received, $expected, "verify req cleanup execution"); + + # XXX: while Apache::TestUtil fails to cleanup by itself + unlink $file; + } + +} + + +
diff --git a/2_0_13/t/hooks/cleanup2.t b/2_0_13/t/hooks/cleanup2.t new file mode 100644 index 0000000..fcd9e74 --- /dev/null +++ b/2_0_13/t/hooks/cleanup2.t
@@ -0,0 +1,53 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use File::Spec::Functions qw(catfile catdir); + +use constant TRIES => 20; + +my $vars = Apache::Test::config->{vars}; +my $dir = catdir $vars->{documentroot}, "hooks"; +my $file = catfile $dir, "cleanup2"; + +plan tests => 2; + +{ + # cleanup, just to make sure we start with virgin state + if (-e $file) { + unlink $file or die "Couldn't remove $file"; + } + # this registers and performs cleanups, but we test whether the + # cleanup was run only in the next sub-test + my $location = "/TestHooks__cleanup2"; + my $expected = 'cleanup2 is ok'; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "register req cleanup"); +} + +{ + # this sub-tests checks that the cleanup stage was run successfully + # which is supposed to remove the file that was created + # + # since Apache destroys the request rec after the logging has been + # finished, we have to give it some time to get there + # and remove in the file. (wait 0.25 .. 5 sec) + my $t = 0; + select undef, undef, undef, 0.25 until !-e $file || $t++ == TRIES; + + if (-e $file) { + t_debug("$file wasn't removed by the cleanup phase"); + ok 0; + unlink $file; # cleanup + } + else { + ok 1; + } +} + + +
diff --git a/2_0_13/t/hooks/error.t b/2_0_13/t/hooks/error.t new file mode 100644 index 0000000..160d43a --- /dev/null +++ b/2_0_13/t/hooks/error.t
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2; + +{ + my $location = "/TestHooks__error"; + my $expected = qr/^Error: Undefined subroutine/; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "error-notes set on ErrorDocument"); +} + +{ + my $error_seed_text = 'seed_text'; + my $location = "/TestHooks__error?$error_seed_text"; + my $expected = qr/^Error: \Q$error_seed_text\E, Undefined subroutine/; + my $received = GET_BODY $location; + ok t_cmp($received, $expected, "seeded error-notes set on ErrorDocument"); +}
diff --git a/2_0_13/t/hooks/hookrun.t b/2_0_13/t/hooks/hookrun.t new file mode 100644 index 0000000..d1c44f1 --- /dev/null +++ b/2_0_13/t/hooks/hookrun.t
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $module = 'TestHooks::hookrun'; +my $config = Apache::Test::config(); +my $path = Apache::TestRequest::module2path($module); + +Apache::TestRequest::module($module); +my $hostport = Apache::TestRequest::hostport($config); +t_debug("connecting to $hostport"); + +plan tests => 10; + +my $ret = GET "http://$hostport/$path?die"; +ok t_cmp $ret->code, 500, '$r->die'; + +my $body = GET_BODY_ASSERT "http://$hostport/$path?normal"; +for my $line (split /\n/, $body) { + my ($phase, $value) = split /:/, $line; + ok t_cmp $value, 1, "$phase"; +}
diff --git a/2_0_13/t/hooks/init.t b/2_0_13/t/hooks/init.t new file mode 100644 index 0000000..e7355ae --- /dev/null +++ b/2_0_13/t/hooks/init.t
@@ -0,0 +1,17 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY_ASSERT); +use Apache::Test; +use Apache::TestUtil; + +my $module = 'TestHooks::init'; + +Apache::TestRequest::module($module); +my $path = Apache::TestRequest::module2path($module); +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport($config); +t_debug("connecting to $hostport"); + +print GET_BODY_ASSERT "http://$hostport/$path";
diff --git a/2_0_13/t/hooks/inlined_handlers.t b/2_0_13/t/hooks/inlined_handlers.t new file mode 100644 index 0000000..2aa7f6d --- /dev/null +++ b/2_0_13/t/hooks/inlined_handlers.t
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +use TestCommon::SameInterp; + +plan tests => 2, need 'HTML::HeadParser'; + +my $location = "/TestHooks__inlined_handlers"; + +my $expected = "ok"; +for (1..2) { + my $received = GET $location; + + ok t_cmp( + $received->content, + $expected, + "anonymous handlers in httpd.conf test", + ); +} +
diff --git a/2_0_13/t/hooks/push_handlers.t b/2_0_13/t/hooks/push_handlers.t new file mode 100644 index 0000000..c4656b6 --- /dev/null +++ b/2_0_13/t/hooks/push_handlers.t
@@ -0,0 +1,21 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my @refs = qw(conf conf1 conf2 coderef + full_coderef coderef1 coderef2 coderef3); +my @anon = qw(anonymous anonymous1 coderef4 anonymous3); + +my @strings = (@refs, @anon); + +my $location = "/TestHooks__push_handlers"; +my $expected = join "\n", @strings, ''; +my $received = GET_BODY $location; + +ok t_cmp($received, $expected, "push_handlers ways");
diff --git a/2_0_13/t/hooks/push_handlers_anon.t b/2_0_13/t/hooks/push_handlers_anon.t new file mode 100644 index 0000000..5c39d92 --- /dev/null +++ b/2_0_13/t/hooks/push_handlers_anon.t
@@ -0,0 +1,12 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# the handler is configured in modperl_extra.pl via +# Apache2::ServerUtil->server->add_config + +use Apache::TestUtil; +use Apache::TestRequest 'GET_BODY_ASSERT'; + +my $module = 'TestHooks::push_handlers_anon'; +my $url = Apache::TestRequest::module2url($module); + +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/hooks/stacked_handlers.t b/2_0_13/t/hooks/stacked_handlers.t new file mode 100644 index 0000000..6d6f242 --- /dev/null +++ b/2_0_13/t/hooks/stacked_handlers.t
@@ -0,0 +1,15 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1; + +my $location = "/TestHooks__stacked_handlers"; +my $expected = join "\n", qw(one two three), ''; +my $received = GET_BODY $location; + +ok t_cmp($received, $expected, "stacked_handlers");
diff --git a/2_0_13/t/hooks/stacked_handlers2.t b/2_0_13/t/hooks/stacked_handlers2.t new file mode 100644 index 0000000..9c29d12 --- /dev/null +++ b/2_0_13/t/hooks/stacked_handlers2.t
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest; +use Apache::Test; +use Apache::TestUtil; + +my $module = "TestHooks::stacked_handlers2"; +Apache::TestRequest::module($module); + +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport($config); +my $path = Apache::TestRequest::module2path($module); + +my $location = "http://$hostport/$path"; + +t_debug("connecting to $location"); + +plan tests => 1; + +my $expected = q!ran 2 PerlPostReadRequestHandler handlers +ran 1 PerlTransHandler handlers +ran 1 PerlMapToStorageHandler handlers +ran 4 PerlHeaderParserHandler handlers +ran 2 PerlAccessHandler handlers +ran 2 PerlAuthenHandler handlers +ran 2 PerlAuthzHandler handlers +ran 1 PerlTypeHandler handlers +ran 4 PerlFixupHandler handlers +ran 2 PerlResponseHandler handlers +ran 2 PerlOutputFilterHandler handlers!; + +chomp(my $received = GET_BODY_ASSERT $location); + +ok t_cmp($received, $expected, "stacked_handlers");
diff --git a/2_0_13/t/hooks/startup.t b/2_0_13/t/hooks/startup.t new file mode 100644 index 0000000..7e2c218 --- /dev/null +++ b/2_0_13/t/hooks/startup.t
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $config = Apache::Test::config(); +my $path = Apache::TestRequest::module2path('TestHooks::startup'); + +my @modules = qw(default TestHooks::startup); + +plan tests => scalar @modules; + +my $expected = join '', "open_logs ok\n", "post_config ok\n"; + +for my $module (sort @modules) { + + Apache::TestRequest::module($module); + my $hostport = Apache::TestRequest::hostport($config); + t_debug("connecting to $hostport"); + + ok t_cmp(GET_BODY_ASSERT("http://$hostport/$path"), + $expected, + "testing PostConfig"); +} +
diff --git a/2_0_13/t/hooks/trans.t b/2_0_13/t/hooks/trans.t new file mode 100644 index 0000000..95b21e9 --- /dev/null +++ b/2_0_13/t/hooks/trans.t
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use Apache2::Const ':common'; + +my $module = 'TestHooks::trans'; +Apache::TestRequest::module($module); +my $path = Apache::TestRequest::module2path($module); +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport($config); +t_debug("connecting to $hostport"); + +plan tests => 3, need 'HTML::HeadParser'; + +t_client_log_error_is_expected(); +ok t_cmp GET_RC("http://$hostport/nope"), NOT_FOUND; + +my $body = GET_BODY "http://$hostport/TestHooks/trans.pm"; + +ok $body =~ /package $module/; + +ok GET_OK "http://$hostport/phooey";
diff --git a/2_0_13/t/htdocs/TestAPI__add_config/htaccess b/2_0_13/t/htdocs/TestAPI__add_config/htaccess new file mode 100644 index 0000000..cd9bed1 --- /dev/null +++ b/2_0_13/t/htdocs/TestAPI__add_config/htaccess
@@ -0,0 +1 @@ +TestAddConfig Htaccess
diff --git a/2_0_13/t/htdocs/api/auth-groups b/2_0_13/t/htdocs/api/auth-groups new file mode 100644 index 0000000..90f5994 --- /dev/null +++ b/2_0_13/t/htdocs/api/auth-groups
@@ -0,0 +1,2 @@ +bar: goo bar +tar: mar far
diff --git a/2_0_13/t/htdocs/api/auth-users b/2_0_13/t/htdocs/api/auth-users new file mode 100644 index 0000000..272a21b --- /dev/null +++ b/2_0_13/t/htdocs/api/auth-users
@@ -0,0 +1,2 @@ +goo:$apr1$g.mxW/..$p8ILT9D4345OO6vtYt8mT0 +bar:$apr1$ALRiO/..$GxXWAshiDKPmFGUA7r66e/
diff --git a/2_0_13/t/htdocs/api/custom_response.txt b/2_0_13/t/htdocs/api/custom_response.txt new file mode 100644 index 0000000..f9e84f1 --- /dev/null +++ b/2_0_13/t/htdocs/api/custom_response.txt
@@ -0,0 +1 @@ +This is a custom file/url response
diff --git a/2_0_13/t/htdocs/api/slurp.pl b/2_0_13/t/htdocs/api/slurp.pl new file mode 100644 index 0000000..43adae0 --- /dev/null +++ b/2_0_13/t/htdocs/api/slurp.pl
@@ -0,0 +1,6 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +my $z = <<EOI; +English: Internet +Hebrew : \x{05D0}\x{05D9}\x{05E0}\x{05D8}\x{05E8}\x{05E0}\x{05D8} +EOI +$z;
diff --git a/2_0_13/t/htdocs/filter/reverse.txt b/2_0_13/t/htdocs/filter/reverse.txt new file mode 100644 index 0000000..7ca9d67 --- /dev/null +++ b/2_0_13/t/htdocs/filter/reverse.txt
@@ -0,0 +1,2 @@ +zyxwvutsrqponmlkjihgfedcba +9876543210
diff --git a/2_0_13/t/htdocs/filter/subrequest.txt b/2_0_13/t/htdocs/filter/subrequest.txt new file mode 100644 index 0000000..93dfba3 --- /dev/null +++ b/2_0_13/t/htdocs/filter/subrequest.txt
@@ -0,0 +1 @@ +default-handler subrequest
diff --git a/2_0_13/t/htdocs/includes-registry/cgipm.pl b/2_0_13/t/htdocs/includes-registry/cgipm.pl new file mode 100755 index 0000000..1f2b824 --- /dev/null +++ b/2_0_13/t/htdocs/includes-registry/cgipm.pl
@@ -0,0 +1,11 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache2::compat (); +use CGI (); + +my $cgi = CGI->new; + +print $cgi->header; + +print "cgi.pm\n"; + +__END__
diff --git a/2_0_13/t/htdocs/includes-registry/test.pl b/2_0_13/t/htdocs/includes-registry/test.pl new file mode 100755 index 0000000..87d29cc --- /dev/null +++ b/2_0_13/t/htdocs/includes-registry/test.pl
@@ -0,0 +1,4 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +print "Content-type: text/html\n\n"; + +print "Hello World<br>\n";
diff --git a/2_0_13/t/htdocs/includes-registry/test.spl b/2_0_13/t/htdocs/includes-registry/test.spl new file mode 100755 index 0000000..6ce1195 --- /dev/null +++ b/2_0_13/t/htdocs/includes-registry/test.spl
@@ -0,0 +1,23 @@ +use strict; + +#XXX: this test needs to be more robust. +#various output buffers spread across multiple prints +#more mod_include features mixed and checking that the output +#is *exactly* what we expected, not just matching a few patterns. + +print "Content-type: text/html\n\n"; + +my $r = shift; + +my $test_string = 'Perl-SSI'; + +$r->subprocess_env->set(MY_TEST => $test_string); + +print <<EOF; +Hello World from <!--#echo var="SERVER_ADMIN" --><br> +Local date is <!--#echo var="DATE_LOCAL" --><br> +Brought to you by <!--#echo var="MY_TEST" --> +<!--#echo var="SERVER_SOFTWARE" --> +<br> +EOF +
diff --git a/2_0_13/t/htdocs/includes/clear.shtml b/2_0_13/t/htdocs/includes/clear.shtml new file mode 100644 index 0000000..a636c08 --- /dev/null +++ b/2_0_13/t/htdocs/includes/clear.shtml
@@ -0,0 +1 @@ +This is a REMOVEclear text
diff --git a/2_0_13/t/htdocs/includes/footer.shtml b/2_0_13/t/htdocs/includes/footer.shtml new file mode 100644 index 0000000..cc8ce24 --- /dev/null +++ b/2_0_13/t/htdocs/includes/footer.shtml
@@ -0,0 +1,2 @@ +<hr> +<h5>footer</h5>
diff --git a/2_0_13/t/htdocs/includes/header.shtml b/2_0_13/t/htdocs/includes/header.shtml new file mode 100644 index 0000000..f595ab0 --- /dev/null +++ b/2_0_13/t/htdocs/includes/header.shtml
@@ -0,0 +1,7 @@ +<html> +<head> +<title><!--#echo var="QUERY_STRING" --></title> +<meta http-equiv="Content-Type" content="text/html"> +</head> + +<h1><!--#echo var="QUERY_STRING" --></h1>
diff --git a/2_0_13/t/htdocs/includes/test.shtml b/2_0_13/t/htdocs/includes/test.shtml new file mode 100644 index 0000000..ee62d73 --- /dev/null +++ b/2_0_13/t/htdocs/includes/test.shtml
@@ -0,0 +1,9 @@ +<!--#include virtual="/includes/header.shtml?mod_perl mod_include test" --> + +<!--#include virtual="/includes-registry/test.pl" --> + +<!--#include virtual="/includes-registry/cgipm.pl" --> + +<p align=right>[<a href="../index.html">back</a>]</p> + +<!--#include virtual="/includes/footer.shtml" -->
diff --git a/2_0_13/t/htdocs/merge3/htaccess b/2_0_13/t/htdocs/merge3/htaccess new file mode 100644 index 0000000..3182b66 --- /dev/null +++ b/2_0_13/t/htdocs/merge3/htaccess
@@ -0,0 +1,6 @@ +# htaccess file for t/response/TestModperl/merge.pm + +PerlSetEnv MergeSetEnv3 SetEnv3Merge3Val +PerlSetVar MergeSetVar3 SetVar3Merge3Val +PerlSetVar MergeAddVar3 AddVar3Merge3Val1 +PerlAddVar MergeAddVar3 AddVar3Merge3Val2
diff --git a/2_0_13/t/htdocs/modperl/setupenv2/config_require.pl b/2_0_13/t/htdocs/modperl/setupenv2/config_require.pl new file mode 100644 index 0000000..c1a7709 --- /dev/null +++ b/2_0_13/t/htdocs/modperl/setupenv2/config_require.pl
@@ -0,0 +1,6 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +TestModperl::setupenv2::register_mixed(); +TestModperl::setupenv2::register_perl(); +$ENV{EnvChangeMixedTest} = "config_require"; +$ENV{EnvChangePerlTest} = "config_require"; +1;
diff --git a/2_0_13/t/htdocs/modperl/setupenv2/module.pm b/2_0_13/t/htdocs/modperl/setupenv2/module.pm new file mode 100644 index 0000000..df7c5f2 --- /dev/null +++ b/2_0_13/t/htdocs/modperl/setupenv2/module.pm
@@ -0,0 +1,7 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package htdocs::modperl::setupenv2::module; +TestModperl::setupenv2::register_mixed(); +TestModperl::setupenv2::register_perl(); +$ENV{EnvChangeMixedTest} = "perlmodule"; +$ENV{EnvChangePerlTest} = "perlmodule"; +1;
diff --git a/2_0_13/t/htdocs/modperl/setupenv2/post_config_require.pl b/2_0_13/t/htdocs/modperl/setupenv2/post_config_require.pl new file mode 100644 index 0000000..d75fefb --- /dev/null +++ b/2_0_13/t/htdocs/modperl/setupenv2/post_config_require.pl
@@ -0,0 +1,6 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +TestModperl::setupenv2::register_mixed(); +TestModperl::setupenv2::register_perl(); +$ENV{EnvChangeMixedTest} = "post_config_require"; +$ENV{EnvChangePerlTest} = "post_config_require"; +1;
diff --git a/2_0_13/t/htdocs/modperl/setupenv2/require.pl b/2_0_13/t/htdocs/modperl/setupenv2/require.pl new file mode 100644 index 0000000..417f471 --- /dev/null +++ b/2_0_13/t/htdocs/modperl/setupenv2/require.pl
@@ -0,0 +1,6 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +TestModperl::setupenv2::register_mixed(); +TestModperl::setupenv2::register_perl(); +$ENV{EnvChangeMixedTest} = "require"; +$ENV{EnvChangePerlTest} = "require"; +1;
diff --git a/2_0_13/t/htdocs/perlio/MoonRise.jpeg b/2_0_13/t/htdocs/perlio/MoonRise.jpeg new file mode 100644 index 0000000..5a57b91 --- /dev/null +++ b/2_0_13/t/htdocs/perlio/MoonRise.jpeg Binary files differ
diff --git a/2_0_13/t/htdocs/perlio/redrum.txt b/2_0_13/t/htdocs/perlio/redrum.txt new file mode 100644 index 0000000..e0e634d --- /dev/null +++ b/2_0_13/t/htdocs/perlio/redrum.txt
@@ -0,0 +1,8 @@ +ALL wORk and NO play mAKes Jack A dull BoY. +ALl WORK and no plAy makEs JaCk a dULl boY. +All wORk AND no PLAy mAkes JACk A DULL boy. +AlL WORK and nO play MAKES JacK a dUlL bOy. +ALL wOrK ANd no PLAY makes JACk A dULl Boy. +All woRk and NO play mAKes Jack a Dull BOY. +alL work and no pLaY makeS JaCk a dull boy. +aLL wORK aND nO pLAY mAKES Jack A dULL bOY.
diff --git a/2_0_13/t/htdocs/protocols/basic-auth b/2_0_13/t/htdocs/protocols/basic-auth new file mode 100644 index 0000000..afb4872 --- /dev/null +++ b/2_0_13/t/htdocs/protocols/basic-auth
@@ -0,0 +1 @@ +stas:$apr1$qnKIk...$TRSGo5zlwo3LMc0R/iLWo/
diff --git a/2_0_13/t/htdocs/vhost/post_config.pl b/2_0_13/t/htdocs/vhost/post_config.pl new file mode 100644 index 0000000..472f80f --- /dev/null +++ b/2_0_13/t/htdocs/vhost/post_config.pl
@@ -0,0 +1,9 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache2::ServerUtil (); + +$TestVhost::config::restart_count = Apache2::ServerUtil::restart_count(); + +1;
diff --git a/2_0_13/t/htdocs/vhost/startup.pl b/2_0_13/t/htdocs/vhost/startup.pl new file mode 100644 index 0000000..ae156e6 --- /dev/null +++ b/2_0_13/t/htdocs/vhost/startup.pl
@@ -0,0 +1,34 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use warnings; +use strict; + +use Apache2::ServerUtil (); +use Apache2::ServerRec (); + +use File::Spec::Functions qw(catdir); + +# base server +# XXX: at the moment this is wrong, since it return the base server $s +# and not the vhost's one. needs to be fixed. +my $s = Apache2::ServerUtil->server; + +my $vhost_doc_root = catdir Apache2::ServerUtil::server_root, qw(htdocs vhost); + +# testing $s->add_config() in vhost +my $conf = <<"EOC"; +# must use PerlModule here to check for segfaults +# and that the module is loaded by vhost +PerlModule TestVhost::config +PerlSetVar DocumentRootCheck $vhost_doc_root +<Location /TestVhost__config> + SetHandler modperl + PerlResponseHandler TestVhost::config::my_handler +</Location> +EOC + +$s->add_config([split /\n/, $conf]); + +# this used to have problems on win32 +$s->add_config(['<Perl >', '1;', '</Perl>']); + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/base64.pm b/2_0_13/t/lib/TestAPRlib/base64.pm new file mode 100644 index 0000000..1867a4a --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/base64.pm
@@ -0,0 +1,34 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::base64; + +# testing APR::Base64 API + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Base64; + +sub num_of_tests { + return 3; +} + +sub test { + + my $str = '12345qwert!@#$%'; + my $encoded = APR::Base64::encode($str); + + t_debug("encoded string: $encoded"); + ok t_cmp($encoded, 'MTIzNDVxd2VydCFAIyQl', 'encode'); + + ok t_cmp(APR::Base64::encode_len(length $str), + length $encoded, + "encoded length"); + + ok t_cmp(APR::Base64::decode($encoded), $str, "decode"); + +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/brigade.pm b/2_0_13/t/lib/TestAPRlib/brigade.pm new file mode 100644 index 0000000..5fdcc4c --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/brigade.pm
@@ -0,0 +1,107 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::brigade; + +# testing APR::Brigade in this tests. +# Other tests do that too: +# TestAPR::flatten : flatten() +# TestAPR::bucket : is_empty(), first(), last() + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Pool (); +use APR::Brigade (); +use APR::Bucket (); +use APR::BucketAlloc (); + +use Apache2::Const -compile => 'OK'; + +sub num_of_tests { + return 14; +} + +sub test { + + my $p = APR::Pool->new(); + my $ba = APR::BucketAlloc->new($p); + + # basic + pool + destroy + { + my $bb = APR::Brigade->new($p, $ba); + + t_debug('$bb is defined'); + ok defined $bb; + + t_debug('$bb ISA APR::Brigade object'); + ok $bb->isa('APR::Brigade'); + + my $pool = $bb->pool; + + t_debug('$pool is defined'); + ok defined $pool; + + t_debug('$pool ISA APR::Pool object'); + ok $pool->isa('APR::Pool'); + + t_debug("destroy"); + $bb->destroy; + ok 1; + } + + # concat / split / length / flatten + { + my $bb1 = APR::Brigade->new($p, $ba); + $bb1->insert_head(APR::Bucket->new($ba, "11")); + $bb1->insert_tail(APR::Bucket->new($ba, "12")); + + my $bb2 = APR::Brigade->new($p, $ba); + $bb2->insert_head(APR::Bucket->new($ba, "21")); + $bb2->insert_tail(APR::Bucket->new($ba, "22")); + + # concat + $bb1->concat($bb2); + # bb1: 11, 12, 21, 22 + ok t_cmp($bb1->length, 8, "total data length in bb"); + my $len = $bb1->flatten(my $data); + ok t_cmp($len, 8, "bb flatten/len"); + ok t_cmp($data, "11122122", "bb flatten/data"); + t_debug('$bb2 is empty'); + ok $bb2->is_empty; + + # split + my $b = $bb1->first; # 11 + $b = $bb1->next($b); # 12 + my $bb3 = $bb1->split($b); + + # bb1: 11, bb3: 12, 21, 22 + $len = $bb1->flatten($data); + ok t_cmp($len, 2, "bb1 flatten/len"); + ok t_cmp($data, "11", "bb1 flatten/data"); + $len = $bb3->flatten($data); + ok t_cmp($len, 6, "bb3 flatten/len"); + ok t_cmp($data, "122122", "bb3 flatten/data"); + } + + # out-of-scope pools + { + my $bb1 = APR::Brigade->new(APR::Pool->new, $ba); + $bb1->insert_head(APR::Bucket->new($ba, "11")); + $bb1->insert_tail(APR::Bucket->new($ba, "12")); + + # try to overwrite the temp pool data + require APR::Table; + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + # now test that we are still OK + + my $len = $bb1->flatten(my $data); + ok t_cmp($data, "1112", "correct data"); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/bucket.pm b/2_0_13/t/lib/TestAPRlib/bucket.pm new file mode 100644 index 0000000..2e9b542 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/bucket.pm
@@ -0,0 +1,211 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::bucket; + +# a mix of APR::Bucket and APR::BucketType tests + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use TestCommon::Utils; + +use APR::Pool (); +use APR::Bucket (); +use APR::BucketAlloc (); +use APR::BucketType (); +use APR::Table (); + +use APR::Const -compile => 'SUCCESS'; + +sub num_of_tests { + return 21; +} + +sub test { + + my $pool = APR::Pool->new(); + my $ba = APR::BucketAlloc->new($pool); + + # new: basic + { + my $data = "foobar"; + my $b = APR::Bucket->new($ba, $data); + + t_debug('$b is defined'); + ok defined $b; + + t_debug('$b ISA APR::Bucket object'); + ok $b->isa('APR::Bucket'); + + my $type = $b->type; + ok t_cmp $type->name, 'mod_perl SV bucket', "type"; + + ok t_cmp $b->length, length($data), "modperl b->length"; + } + + # new: offset + { + my $data = "foobartar"; + my $offset = 3; + my $real = substr $data, $offset; + my $b = APR::Bucket->new($ba, $data, $offset); + my $rlen = $b->read(my $read); + ok t_cmp $read, $real, 'new($data, $offset)/buffer'; + ok t_cmp $rlen, length($read), 'new($data, $offset)/len'; + ok t_cmp $b->start, $offset, 'offset'; + + } + + # new: offset+len + { + my $data = "foobartar"; + my $offset = 3; + my $len = 3; + my $real = substr $data, $offset, $len; + my $b = APR::Bucket->new($ba, $data, $offset, $len); + my $rlen = $b->read(my $read); + ok t_cmp $read, $real, 'new($data, $offset, $len)/buffer'; + ok t_cmp $rlen, length($read), 'new($data, $offse, $lent)/len'; + } + + # new: offset+ too big len + { + my $data = "foobartar"; + my $offset = 3; + my $len = 10; + my $real = substr $data, $offset, $len; + my $b = eval { APR::Bucket->new($ba, $data, $offset, $len) }; + ok t_cmp $@, + qr/the length argument can't be bigger than the total/, + 'new($data, $offset, $len_too_big)'; + } + + # modification of the source variable, affects the data + # inside the bucket + { + my $data = "A" x 10; + my $orig = $data; + my $b = APR::Bucket->new($ba, $data); + $data =~ s/^..../BBBB/; + $b->read(my $read); + ok t_cmp $read, $data, + "data inside the bucket should get affected by " . + "the changes to the Perl variable it's created from"; + } + + + # APR::Bucket->new() with the argument PADTMP (which happens when + # some function is re-entered) and the same SV is passed to + # different buckets, which must be detected and copied away. + { + my @buckets = (); + my @data = qw(ABCD EF); + my @received = (); + for my $str (@data) { + my $b = func($ba, $str); + push @buckets, $b; + } + + # the creating of buckets and reading from them is done + # separately on purpose + for my $b (@buckets) { + $b->read(my $out); + push @received, $out; + } + + # here we used to get: two pv: "ef\0d"\0, "ef"\0, as you can see + # the first bucket had corrupted data. + my @expected = map { lc } @data; + ok t_cmp \@received, \@expected, "new(PADTMP SV)"; + + # this function will pass the same SV to new(), causing two + # buckets point to the same SV, and having the latest bucket's + # data override the previous one + sub func { + my $ba = shift; + my $data = shift; + return APR::Bucket->new($ba, lc $data); + } + + } + + # read data is tainted + { + my $data = "xxx"; + my $b = APR::Bucket->new($ba, $data); + $b->read(my $read); + ok t_cmp $read, $data, 'new($data)'; + ok TestCommon::Utils::is_tainted($read); + } + + # remove/destroy + { + my $b = APR::Bucket->new($ba, "aaa"); + # remove $b when it's not attached to anything (not sure if + # that should be an error) + $b->remove; + ok 1; + + # a dangling bucket needs to be destroyed + $b->destroy; + ok 1; + + # real remove from bb is tested in many other filter tests + } + + # setaside + { + my $data = "A" x 10; + my $expected = $data; + my $b = APR::Bucket->new($ba, $data); + my $status = $b->setaside($pool); + ok t_cmp $status, APR::Const::SUCCESS, "setaside status"; + $data =~ s/^..../BBBB/; + $b->read(my $read); + ok t_cmp $read, $expected, + "data inside the setaside bucket is unaffected by " . + "changes to the Perl variable it's created from"; + $b->destroy; + } + + # alloc_create on out-of-scope pools + { + # later may move that into a dedicated bucket_alloc test + my $ba = APR::BucketAlloc->new(APR::Pool->new); + # here if the pool is gone of scope destroy() will segfault + $ba->destroy; + ok 1; + } + + # setaside on out-of-scope pools + { + # note that at the moment APR internally handles the situation + # when the pool goes out of scope, so modperl doesn't need to do + # any special handling of the pool object passed to setaside() + # to insure that it survives as long as $b is alive + # + # to make sure that this doesn't change internally in APR, the + # sub-test remains here + my $data = "A" x 10; + my $orig = $data; + my $b = APR::Bucket->new($ba, $data); + my $status = $b->setaside(APR::Pool->new); + ok t_cmp $status, APR::Const::SUCCESS, "setaside status"; + + # try to overwrite the temp pool data + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + + # now test that we are still OK + $b->read(my $read); + ok t_cmp $read, $data, + "data inside the setaside bucket is not corrupted"; + $b->destroy; + } + + $ba->destroy; +} + +1; +
diff --git a/2_0_13/t/lib/TestAPRlib/date.pm b/2_0_13/t/lib/TestAPRlib/date.pm new file mode 100644 index 0000000..2f3dd80 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/date.pm
@@ -0,0 +1,72 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::date; + +# testing APR::Date API + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Date (); + +my @http_dates = ( + 'Sun, 06 Nov 1994 08:49:37 GMT', # RFC 822, updated by RFC 1123 + 'Sunday, 06-Nov-94 08:49:37 GMT', # RFC 850, obsoleted by RFC 1036 + 'Sun Nov 6 08:49:37 1994', # ANSI C's asctime() format +); + +my @rfc_dates = ( + 'Sun, 06 Nov 1994 08:49:37 GMT' , # RFC 822, updated by RFC 1123 + 'Sunday, 06-Nov-94 08:49:37 GMT', # RFC 850, obsoleted by RFC 1036 + 'Sun Nov 6 08:49:37 1994', # ANSI C's asctime() format + 'Sun, 6 Nov 1994 08:49:37 GMT', # RFC 822, updated by RFC 1123 + 'Sun, 06 Nov 94 08:49:37 GMT', # RFC 822 + 'Sun, 6 Nov 94 08:49:37 GMT', # RFC 822 + 'Sun, 06 Nov 94 8:49:37 GMT', # Unknown [Elm 70.85] + 'Sun, 6 Nov 94 8:49:37 GMT', # Unknown [Elm 70.85] + 'Sun, 6 Nov 1994 08:49:37 GMT', # Unknown [Postfix] +); + +my @bogus_dates = ( + 'Sun, 06 Nov 94 08:49 GMT', # Unknown [drtr@ast.cam.ac.uk] + 'Sun, 6 Nov 94 08:49 GMT', # Unknown [drtr@ast.cam.ac.uk] +); + +my $date_msec = 784111777; +my $bogus_date_msec = 784111740; + +sub num_of_tests { + return @http_dates + @rfc_dates + @bogus_dates; +} + +sub test { + + # parse_http + for my $date_str (@http_dates) { + ok t_cmp(APR::Date::parse_http($date_str), + $date_msec, + "parse_http: $date_str"); + #t_debug "testing : parse_http: $date_str"; + } + + # parse_rfc + for my $date_str (@rfc_dates) { + ok t_cmp(APR::Date::parse_rfc($date_str), + $date_msec, + "parse_rfc: $date_str"); + #t_debug "testing : parse_rfc: $date_str"; + } + + # parse_rfc (bogus formats) + for my $date_str (@bogus_dates) { + ok t_cmp(APR::Date::parse_rfc($date_str), + $bogus_date_msec, + "parse_rfc: $date_str"); + #t_debug "testing : parse_rfc: $date_str"; + } + +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/error.pm b/2_0_13/t/lib/TestAPRlib/error.pm new file mode 100644 index 0000000..233045c --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/error.pm
@@ -0,0 +1,22 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::error; + +# testing APR::Error API + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Error; + +sub num_of_tests { + return 1; +} + +sub test { + ok 1; +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/finfo.pm b/2_0_13/t/lib/TestAPRlib/finfo.pm new file mode 100644 index 0000000..1f36a92 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/finfo.pm
@@ -0,0 +1,172 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::finfo; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; +use Apache::TestConfig; + +use File::Spec::Functions qw(catfile); +use Fcntl qw(:mode); + +use APR::Finfo (); +use APR::Pool (); + +use constant WIN32 => Apache::TestConfig::WIN32; +use constant OSX => Apache::TestConfig::OSX; + +use constant APACHE_2_0_49_PLUS => have_min_apache_version('2.0.49'); +use constant APACHE_2_2_PLUS => have_min_apache_version('2.2.0'); + +use APR::Const -compile => qw(SUCCESS FINFO_NORM FINFO_PROT FILETYPE_REG + FPROT_WREAD FPROT_WWRITE + FPROT_WEXECUTE); + +sub num_of_tests { + return 27; +} + +sub test { + + # for the file to be tested, use the httpd.conf generated + # by testing, so that it has a ctime that won't (usually) + # encounter a bug in Win32's stat() function for files that + # span across DST season boundaries. + my $file = catfile Apache::Test::vars->{t_dir}, 'conf', 'httpd.conf'; + + my $pool = APR::Pool->new(); + # populate the finfo struct first + my $wanted = APR::Const::FINFO_NORM; + if (WIN32) { + $wanted &= ~APR::Const::FINFO_PROT; + } + my $finfo = APR::Finfo::stat($file, $wanted, $pool); + + ok $finfo->isa('APR::Finfo'); + + # now, get information from perl's stat() + my %stat; + + @stat{qw(device inode protection nlink user group size atime mtime + ctime)} = (stat $file)[0..5, 7..10]; + + compare_with_perl($finfo, \%stat); + + # tests for stuff not in perl's stat + { + # BACK_COMPAT_MARKER - fixed as of 2.0.49. + if (WIN32 && !APACHE_2_0_49_PLUS) { + skip "finfo.fname requires Apache 2.0.49 or later", 0; + } + else { + ok t_cmp($finfo->fname, + $file, + '$finfo->fname()'); + } + + ok t_cmp($finfo->filetype, + APR::Const::FILETYPE_REG, + '$finfo->filetype()'); + } + + # stat() on out-of-scope pools + { + my $finfo = APR::Finfo::stat($file, $wanted, APR::Pool->new); + + # try to overwrite the temp pool data + require APR::Table; + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + + # now test that we are still OK + compare_with_perl($finfo, \%stat); + } + +} + + +sub compare_with_perl { + my ($finfo, $stat) = @_; + # skip certain tests on Win32 and others + my %skip = (); + + if (WIN32) { + # atime is wrong on NTFS, but OK on FAT32 + %skip = map {$_ => 1} qw(device inode user group atime); + } + elsif (OSX) { + # XXX both apr and perl report incorrect group values. sometimes. + # XXX skip until we can really figure out what is going on. + %skip = (group => 1); + } + + # compare stat fields between perl and apr_stat + { + foreach my $method (qw(device inode nlink user group + size atime mtime ctime)) { + if ($skip{$method}) { + skip "different file semantics", 0; + } + else { + ok t_cmp($finfo->$method(), + $stat->{$method}, + "\$finfo->$method()"); + } + } + } + + # stat tests (same as perl's stat) + { + + # XXX: untested + # ->name + + # XXX: are there any platforms csize is available at all? + # We don't want to see the skipped message all the time if + # it's not really used anywhere + # if (my $csize = $finfo->csize) { + # # The storage size is at least as big as the file size + # # perl's stat() doesn't have the equivalent of csize + # t_debug "csize=$csize, size=$stat{size}"; + # ok $csize >= $stat{size}; + # } + # else { + # skip "csize is not available on this platform", 0; + # } + + # match world bits + + # on Win32, there's a bug in the apr library supplied + # with Apache/2.2 that causes the following two tests + # to fail. This is slated to be fixed after apr-1.2.7. + if (WIN32 and APACHE_2_2_PLUS) { + skip "broken apr stat on Win32", 0; + } + else { + ok t_cmp($finfo->protection & APR::Const::FPROT_WREAD, + $stat->{protection} & S_IROTH, + '$finfo->protection() & APR::Const::FPROT_WREAD'); + } + if (WIN32 and APACHE_2_2_PLUS) { + skip "broken apr stat on Win32", 0; + } + else { + ok t_cmp($finfo->protection & APR::Const::FPROT_WWRITE, + $stat->{protection} & S_IWOTH, + '$finfo->protection() & APR::Const::FPROT_WWRITE'); + } + if (WIN32) { + skip "different file semantics", 0; + } + else { + ok t_cmp($finfo->protection & APR::Const::FPROT_WEXECUTE, + $stat->{protection} & S_IXOTH, + '$finfo->protection() & APR::Const::FPROT_WEXECUTE'); + } + } +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/os.pm b/2_0_13/t/lib/TestAPRlib/os.pm new file mode 100644 index 0000000..12344fb --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/os.pm
@@ -0,0 +1,22 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::os; + +# testing APR::OS API + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::OS (); + +sub num_of_tests { + return 1; +} + +sub test { + ok 1; +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/pool.pm b/2_0_13/t/lib/TestAPRlib/pool.pm new file mode 100644 index 0000000..519cba7 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/pool.pm
@@ -0,0 +1,502 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::pool; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use APR::Pool (); +use APR::Table (); + +sub num_of_tests { + return 77; +} + +sub test { + + my $pool = APR::Pool->new(); + my $table = APR::Table::make($pool, 2); + + ### custom pools ### + + # test: explicit pool object destroy destroys the custom pool + { + my $p = APR::Pool->new; + + $p->cleanup_register(\&set_cleanup, [$table, 'new destroy']); + + ok t_cmp(ancestry_count($p), 1, + "a new pool has one ancestor: the global pool"); + + # explicity destroy the object + $p->destroy; + + my @notes = $table->get('cleanup'); + + ok t_cmp(scalar(@notes), 1, "should be 1 note"); + + ok t_cmp($notes[0], 'new destroy'); + + $table->clear; + } + + + # test: lexical scoping DESTROYs the custom pool + { + { + my $p = APR::Pool->new; + + ok t_cmp(ancestry_count($p), 1, + "a new pool has one ancestor: the global pool"); + + $p->cleanup_register(\&set_cleanup, [$table, 'new scoped']); + } + + my @notes = $table->get('cleanup'); + + ok t_cmp(scalar(@notes), 1, "should be 1 note"); + + ok t_cmp($notes[0], 'new scoped'); + + $table->clear; + } + + + + ### custom pools + sub-pools ### + + # test: basic pool and sub-pool tests + implicit destroy of pool objects + { + { + my ($pp, $sp) = both_pools_create_ok($table); + } + + both_pools_destroy_ok($table); + + $table->clear; + } + + + # test: explicitly destroying a parent pool should destroy its + # sub-pool + { + my ($pp, $sp) = both_pools_create_ok($table); + + # destroying $pp should destroy the subpool $sp too + $pp->destroy; + + both_pools_destroy_ok($table); + + $table->clear; + } + + + + # test: destroying a sub-pool before the parent pool + { + my ($pp, $sp) = both_pools_create_ok($table); + + $sp->destroy; + $pp->destroy; + + both_pools_destroy_ok($table); + + $table->clear; + } + + + # test: destroying a sub-pool explicitly after the parent pool destroy + + # the parent pool should have already destroyed the child pool, so + # the object is invalid + { + my ($pp, $sp) = both_pools_create_ok($table); + + $pp->destroy; + $sp->destroy; + + both_pools_destroy_ok($table); + + $table->clear; + } + + + # test: destroying a sub-pool before the parent pool and trying to + # call APR::Pool methods on the a subpool object which points to a + # destroyed pool + { + my ($pp, $sp) = both_pools_create_ok($table); + + # parent pool destroys child pool + $pp->destroy; + + # this should "gracefully" fail, since $sp's guts were + # destroyed when the parent pool was destroyed + eval { $pp = $sp->parent_get }; + ok t_cmp($@, + qr/invalid pool object/, + "parent pool destroys child pool"); + + # since pool $sp now contains 0 pointer, if we try to make a + # new pool out of it, it's the same as APR->new (i.e. it'll + # use the global top level pool for it), so the resulting pool + # should have an ancestry length of exactly 1 + my $ssp = $sp->new; + ok t_cmp(ancestry_count($ssp), 1, + "a new pool has one ancestor: the global pool"); + + + both_pools_destroy_ok($table); + + $table->clear; + } + + # test: make sure that one pool won't destroy/affect another pool, + # which happened to be allocated at the same memory address after + # the pointer to the first pool was destroyed + { + my $pp2; + { + my $pp = APR::Pool->new; + $pp->destroy; + # $pp2 ideally should take the exact place of apr_pool + # previously pointed to by $pp + $pp2 = APR::Pool->new; + # $pp object didn't go away yet (it'll when exiting this + # scope). in the previous implementation, $pp will be + # destroyed second time on the exit of the scope and it + # could happen to work, because $pp2 pointer has allocated + # exactly the same address. and if so it would have killed + # the pool that $pp2 points to + + # this should "gracefully" fail, since $pp's guts were + # destroyed when the parent pool was destroyed + # must make sure that it won't try to hijack the new pool + # $pp2 that (hopefully) took over $pp's place + eval { $pp->parent_get }; + ok t_cmp($@, + qr/invalid pool object/, + "a dead pool is a dead pool"); + } + + # next make sure that $pp2's pool is still alive + $pp2->cleanup_register(\&set_cleanup, [$table, 'overtake']); + $pp2->destroy; + + my @notes = $table->get('cleanup'); + + ok t_cmp(scalar(@notes), 1, "should be 1 note"); + ok t_cmp($notes[0], 'overtake'); + + $table->clear; + + } + + # test: similar to the previous test, but this time, the parent + # pool destroys the child pool. a second allocation of a new pair + # of the parent and child pools take over exactly the same + # allocations. so if there are any ghost objects, they must not + # find the other pools and use them as they own. for example they + # could destroy the pools, and the perl objects of the pair would + # have no idea that someone has destroyed the pools without their + # knowledge. the previous implementation suffered from this + # problem. the new implementation uses an SV which is stored in + # the object and in the pool. when the pool is destroyed the SV + # gets its IVX pointer set to 0, which affects any perl object + # that is a ref to that SV. so once an apr pool is destroyed all + # perl objects pointing to it get automatically invalidated and + # there is no risk of hijacking newly created pools that happen to + # be at the same memory address. + + { + my ($pp2, $sp2); + { + my $pp = APR::Pool->new; + my $sp = $pp->new; + # parent destroys $sp + $pp->destroy; + + # hopefully these pool will take over the $pp and $sp + # allocations + ($pp2, $sp2) = both_pools_create_ok($table); + } + + # $pp and $sp shouldn't have triggered any cleanups + my @notes = $table->get('cleanup'); + ok t_cmp(scalar(@notes), 0, "should be 0 notes"); + $table->clear; + + # parent pool destroys child pool + $pp2->destroy; + + both_pools_destroy_ok($table); + + $table->clear; + } + + # test: only when the last references to the pool object is gone + # it should get destroyed + { + + my $cp; + + { + my $sp = APR::Pool->new(); + + $sp->cleanup_register(\&set_cleanup, [$table, 'several references']); + + $cp = $sp; + # destroy of $sp shouldn't call apr_pool_destroy, because + # $cp still references to it + } + + my @notes = $table->get('cleanup'); + ok t_cmp(scalar(@notes), 0, "should be 0 notes"); + $table->clear; + + # now the last copy is gone and the cleanup hooks will be called + $cp->destroy; + + @notes = $table->get('cleanup'); + ok t_cmp(scalar(@notes), 1, "should be 1 note"); + ok t_cmp($notes[0], 'several references'); + + $table->clear; + } + { + # and another variation + my $pp = APR::Pool->new(); + my $sp = $pp->new; + + my $gp = $pp->parent_get; + my $pp2 = $sp->parent_get; + + # parent destroys children + $pp->destroy; + + # grand parent ($pool) is undestroyable (core pool) + $gp->destroy; + + # now all custom pools are destroyed - $sp and $pp2 point nowhere + $pp2->destroy; + $sp->destroy; + + ok 1; + } + + # cleanup_register using a function name as a callback + { + { + my $p = APR::Pool->new; + $p->cleanup_register('set_cleanup', [$table, 'function name']); + } + + my @notes = $table->get('cleanup'); + ok t_cmp($notes[0], 'function name', "function name callback"); + + $table->clear; + } + + # cleanup_register using an anon sub callback + { + { + my $p = APR::Pool->new; + + $p->cleanup_register(sub { &set_cleanup }, [$table, 'anon sub']); + } + + my @notes = $table->get('cleanup'); + ok t_cmp($notes[0], 'anon sub', "anon callback"); + + $table->clear; + } + + # registered callbacks are run in reversed order LIFO + { + { + my $p = APR::Pool->new; + + $p->cleanup_register(\&add_cleanup, [$table, 'first']); + $p->cleanup_register(\&add_cleanup, [$table, 'second']); + } + + my @notes = $table->get('cleanup'); + ok t_cmp($notes[0], 'second', "two cleanup functions"); + ok t_cmp($notes[1], 'first', "two cleanup functions"); + + $table->clear; + } + + # undefined cleanup subs + { + my $p = APR::Pool->new; + $p->cleanup_register('TestAPR::pool::some_non_existing_sub', 1); + + my @warnings; + local $SIG{__WARN__} = sub {push @warnings, @_}; + $p->destroy; + + ok t_cmp($warnings[0], + qr/Undefined subroutine/, + "non existing function"); + } + { + my $p = APR::Pool->new; + $p->cleanup_register(\&non_existing1, 1); + + my @warnings; + local $SIG{__WARN__} = sub {push @warnings, @_}; + $p->destroy; + + ok t_cmp($warnings[0], + qr/Undefined subroutine/, + "non existing function"); + } + + # cleanups throwing exceptions + { + my $p = APR::Pool->new; + $p->cleanup_register(sub {die "1\n"}, 1); + $p->cleanup_register(sub {die "2\n"}, 1); + + my @warnings; + local $SIG{__WARN__} = sub {push @warnings, @_}; + local $@="to be preserved"; + undef $p; + + ok t_cmp(\@warnings, + [map "APR::Pool: cleanup died: $_\n", 2, 1], + "exceptions thrown by cleanups"); + ok t_cmp($@, "to be preserved", '$@ is preserved'); + } + + ### $p->clear ### + { + my ($pp, $sp) = both_pools_create_ok($table); + $pp->clear; + # both pools should have run their cleanups + both_pools_destroy_ok($table); + + # sub-pool $sp should be now bogus, as clear() destroys + # subpools + eval { $sp->parent_get }; + ok t_cmp($@, + qr/invalid pool object/, + "clear destroys sub pools"); + + # now we should be able to use the parent pool without + # allocating it + $pp->cleanup_register(\&set_cleanup, [$table, 're-using pool']); + $pp->destroy; + + my @notes = $table->get('cleanup'); + ok t_cmp('re-using pool', $notes[0]); + + $table->clear; + } + + + # a pool can be tagged, so when doing low level apr_pool tracing + # (when apr is compiled with -DAPR_POOL_DEBUG) it's possible to + # grep(1) for a certain tag, so it's a useful method + { + my $p = APR::Pool->new; + $p->tag("my pool"); + + # though there is no way we can get back the value to test, + # since there is no apr_pool_tag read accessor + ok 1; + } + + # out-of-scope pools + { + my $sp = APR::Pool->new->new; + # the parent temp pool must stick around + ok t_cmp(2, ancestry_count($sp), + "parent pool is still alive + global pool"); + } + + # other stuff + { + my $p = APR::Pool->new; + + # find some method that wants a pool object and try to pass it + # an object that was already destroyed e.g. APR::Table::make($p, 2); + + # only available with -DAPR_POOL_DEBUG + #my $num_bytes = $p->num_bytes; + #ok $num_bytes; + + } +} + +# returns how many ancestor generations the pool has (parent, +# grandparent, etc.) +sub ancestry_count { + my $child = shift; + my $gen = 0; + while (my $parent = $child->parent_get) { + # prevent possible endless loops + die "child pool reports to be its own parent, corruption!" + if $parent == $child; + $gen++; + die "child knows its parent, but the parent denies having that child" + unless $parent->is_ancestor($child); + $child = $parent; + } + return $gen; +} + +sub add_cleanup { + my $arg = shift; + debug "adding cleanup note: $arg->[1]"; + $arg->[0]->add(cleanup => $arg->[1]); + 1; +} + +sub set_cleanup { + my $arg = shift; + debug "setting cleanup note: $arg->[1]"; + $arg->[0]->set(cleanup => $arg->[1]); + 1; +} + +# +4 tests +sub both_pools_create_ok { + my $table = shift; + + my $pp = APR::Pool->new; + + ok t_cmp(1, $pp->isa('APR::Pool'), "isa('APR::Pool')"); + + ok t_cmp(1, ancestry_count($pp), + "a new pool has one ancestor: the global pool"); + + my $sp = $pp->new; + + ok t_cmp($sp->isa('APR::Pool'), 1, "isa('APR::Pool')"); + + ok t_cmp(ancestry_count($sp), 2, + "a subpool has 2 ancestors: the parent and global pools"); + + $pp->cleanup_register(\&add_cleanup, [$table, 'parent']); + $sp->cleanup_register(\&set_cleanup, [$table, 'child']); + + return ($pp, $sp); + +} + +# +3 tests +sub both_pools_destroy_ok { + my $table = shift; + my @notes = $table->get('cleanup'); + + ok t_cmp(scalar(@notes), 2, "should be 2 notes"); + ok t_cmp($notes[0], 'child'); + ok t_cmp($notes[1], 'parent'); +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/status.pm b/2_0_13/t/lib/TestAPRlib/status.pm new file mode 100644 index 0000000..6bf7f50 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/status.pm
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::status; + +# Testing APR::Status + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Const -compile => qw(EAGAIN ENOPOLL); +use APR::Status (); + +sub num_of_tests { + return 2; +} + +sub test { + ok APR::Status::is_EAGAIN(APR::Const::EAGAIN); + ok ! APR::Status::is_EAGAIN(APR::Const::ENOPOLL); +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/string.pm b/2_0_13/t/lib/TestAPRlib/string.pm new file mode 100644 index 0000000..9185e3b --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/string.pm
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::string; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::String (); + +my %size_string = ( + '-1' => " - ", + 0 => " 0 ", + 42 => " 42 ", + 42_000 => " 41K", + 42_000_000 => " 40M", +# 42_000_000_000 => "40G", +); + +sub num_of_tests { + return scalar keys %size_string; +} + +sub test { + + t_debug("size_string"); + while (my ($k, $v) = each %size_string) { + ok t_cmp($v, APR::String::format_size($k)); + } +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/table.pm b/2_0_13/t/lib/TestAPRlib/table.pm new file mode 100644 index 0000000..3310674 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/table.pm
@@ -0,0 +1,380 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::table; + +# testing APR::Table API + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Table (); +use APR::Pool (); + +use APR::Const -compile => ':table'; + +use constant TABLE_SIZE => 20; +our $filter_count; + +sub num_of_tests { + my $tests = 56; + + # tied hash values() for a table w/ multiple values for the same + # key + $tests += 2 if $] >= 5.008; + + return $tests; +} + +sub test { + + $filter_count = 0; + my $pool = APR::Pool->new(); + my $table = APR::Table::make($pool, TABLE_SIZE); + + ok UNIVERSAL::isa($table, 'APR::Table'); + + # get on non-existing key + { + # in scalar context + my $val = $table->get('foo'); + ok t_cmp($val, undef, '$val = $table->get("no_such_key")'); + + # in list context + my @val = $table->get('foo'); + ok t_cmp(+@val, 0, '@val = $table->get("no_such_key")'); + } + + # set/add/get/copy normal values + { + $table->set(foo => 'bar'); + + # get scalar context + my $val = $table->get('foo'); + ok t_cmp($val, 'bar', '$val = $table->get("foo")'); + + # add + get list context + $table->add(foo => 'tar'); + $table->add(foo => 'kar'); + my @val = $table->get('foo'); + ok @val == 3 && + $val[0] eq 'bar' && + $val[1] eq 'tar' && + $val[2] eq 'kar'; + + # copy + $table->set(too => 'boo'); + my $table_copy = $table->copy($pool); + my $val_copy = $table->get('too'); + ok t_cmp($val_copy, 'boo', '$val = $table->get("too")'); + my @val_copy = $table_copy->get('foo'); + ok @val_copy == 3 && + $val_copy[0] eq 'bar' && + $val_copy[1] eq 'tar' && + $val_copy[2] eq 'kar'; + } + + # make sure 0 comes through as 0 and not undef + { + $table->set(foo => 0); + my $zero = $table->get('foo'); + ok t_cmp($zero, 0, 'table value 0 is not undef'); + } + + # unset + { + $table->set(foo => "bar"); + $table->unset('foo'); + ok t_cmp(+$table->get('foo'), undef, '$table->unset("foo")'); + } + + # merge + { + $table->set( merge => '1'); + $table->merge(merge => 'a'); + my $val = $table->get('merge'); + ok t_cmp($val, "1, a", 'one val $table->merge(...)'); + + # if there is more than one value for the same key, merge does + # the job only for the first value + $table->add( merge => '2'); + $table->merge(merge => 'b'); + my @val = $table->get('merge'); + ok t_cmp($val[0], "1, a, b", '$table->merge(...)'); + ok t_cmp($val[1], "2", 'two values $table->merge(...)'); + + # if the key is not found, works like set/add + $table->merge(miss => 'a'); + my $val_miss = $table->get('miss'); + ok t_cmp($val_miss, "a", 'no value $table->merge(...)'); + } + + # clear + { + $table->set(foo => 0); + $table->set(bar => 1); + $table->clear(); + # t_cmp forces scalar context on get + ok t_cmp($table->get('foo'), undef, '$table->clear'); + ok t_cmp($table->get('bar'), undef, '$table->clear'); + } + + # filtering + { + for (1..TABLE_SIZE) { + $table->set(chr($_+97), $_); + } + + # Simple filtering + $filter_count = 0; + $table->do("my_filter"); + ok t_cmp($filter_count, TABLE_SIZE); + + # Filtering aborting in the middle + $filter_count = 0; + $table->do("my_filter_stop"); + ok t_cmp($filter_count, int(TABLE_SIZE)/2) ; + + # Filtering with anon sub + $filter_count=0; + $table->do(sub { + my ($key,$value) = @_; + $filter_count++; + unless ($key eq chr($value+97)) { + die "arguments I recieved are bogus($key,$value)"; + } + return 1; + }); + + ok t_cmp($filter_count, TABLE_SIZE, "table size"); + + $filter_count = 0; + $table->do("my_filter", "c", "b", "e"); + ok t_cmp($filter_count, 3, "table size"); + } + + #Tied interface + { + my $table = APR::Table::make($pool, TABLE_SIZE); + + ok UNIVERSAL::isa($table, 'HASH'); + + ok UNIVERSAL::isa($table, 'HASH') && tied(%$table); + + ok $table->{'foo'} = 'bar'; + + # scalar context + ok $table->{'foo'} eq 'bar'; + + ok delete $table->{'foo'} || 1; + + ok not exists $table->{'foo'}; + + for (1..TABLE_SIZE) { + $table->{chr($_+97)} = $_; + } + + $filter_count = 0; + foreach my $key (sort keys %$table) { + my_filter($key, $table->{$key}); + } + ok $filter_count == TABLE_SIZE; + } + + + # each, values + { + my $table = APR::Table::make($pool, 2); + + $table->add("first" => 1); + $table->add("second" => 2); + $table->add("first" => 3); + + my $i = 0; + while (my ($a,$b) = each %$table) { + my $key = ("first", "second")[$i % 2]; + my $val = ++$i; + + ok t_cmp $a, $key, "table each: key test"; + ok t_cmp $b, $val, "table each: value test"; + ok t_cmp $table->{$a}, $val, "table each: get test"; + + ok t_cmp tied(%$table)->FETCH($a), $val, + "table each: tied get test"; + } + + # this doesn't work with Perl < 5.8 + if ($] >= 5.008) { + ok t_cmp "1,2,3", join(",", values %$table), + "table values"; + ok t_cmp "first,1,second,2,first,3", join(",", %$table), + "table entries"; + } + } + + # overlap and compress routines + { + my $base = APR::Table::make($pool, TABLE_SIZE); + my $add = APR::Table::make($pool, TABLE_SIZE); + + $base->set(foo => 'one'); + $base->add(foo => 'two'); + + $add->set(foo => 'three'); + $add->set(bar => 'beer'); + + my $overlay = $base->overlay($add, $pool); + + my @foo = $overlay->get('foo'); + my @bar = $overlay->get('bar'); + + ok t_cmp(+@foo, 3); + ok t_cmp($bar[0], 'beer'); + + my $overlay2 = $overlay->copy($pool); + + # compress/merge + $overlay->compress(APR::Const::OVERLAP_TABLES_MERGE); + # $add first, then $base + ok t_cmp($overlay->get('foo'), + 'three, one, two', + "\$overlay->compress/merge"); + ok t_cmp($overlay->get('bar'), + 'beer', + "\$overlay->compress/merge"); + + # compress/set + $overlay->compress(APR::Const::OVERLAP_TABLES_SET); + # $add first, then $base + ok t_cmp($overlay2->get('foo'), + 'three', + "\$overlay->compress/set"); + ok t_cmp($overlay2->get('bar'), + 'beer', + "\$overlay->compress/set"); + } + + # overlap set + { + my $base = APR::Table::make($pool, TABLE_SIZE); + my $add = APR::Table::make($pool, TABLE_SIZE); + + $base->set(bar => 'beer'); + $base->set(foo => 'one'); + $base->add(foo => 'two'); + + $add->set(foo => 'three'); + + $base->overlap($add, APR::Const::OVERLAP_TABLES_SET); + + my @foo = $base->get('foo'); + my @bar = $base->get('bar'); + + ok t_cmp(+@foo, 1, 'overlap/set'); + ok t_cmp($foo[0], 'three'); + ok t_cmp($bar[0], 'beer'); + } + + # overlap merge + { + my $base = APR::Table::make($pool, TABLE_SIZE); + my $add = APR::Table::make($pool, TABLE_SIZE); + + $base->set(foo => 'one'); + $base->add(foo => 'two'); + + $add->set(foo => 'three'); + $add->set(bar => 'beer'); + + $base->overlap($add, APR::Const::OVERLAP_TABLES_MERGE); + + my @foo = $base->get('foo'); + my @bar = $base->get('bar'); + + ok t_cmp(+@foo, 1, 'overlap/set'); + ok t_cmp($foo[0], 'one, two, three'); + ok t_cmp($bar[0], 'beer'); + } + + + # temp pool objects. + # testing here that the temp pool object doesn't go out of scope + # before the object based on it was freed. the following tests + # were previously segfaulting when using apr1/httpd2.1 built w/ + # --enable-pool-debug CPPFLAGS="-DAPR_BUCKET_DEBUG", + # the affected methods are: + # - make + # - copy + # - overlay + { + { + my $table = APR::Table::make(APR::Pool->new, 10); + $table->set($_ => $_) for 1..20; + ok t_cmp $table->get(20), 20, "no segfault"; + } + + my $pool = APR::Pool->new; + my $table = APR::Table::make($pool, 10); + $table->set($_ => $_) for 1..20; + my $table_copy = $table->copy($pool->new); + { + # verify that the temp pool used to create $table_copy was + # not freed, by allocating a new table to fill with a + # different data. if that former pool was freed + # $table_copy will now contain bogus data (and may + # segfault) + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'a'..'z'; + ok t_cmp $table->get('z'), 'z', "helper test"; + + } + ok t_cmp $table_copy->get(20), 20, "no segfault/valid data"; + + my $table2 = APR::Table::make($pool, 1); + $table2->set($_**2 => $_**2) for 1..20; + my $table2_copy = APR::Table::make($pool, 1); + $table2_copy->set($_ => $_) for 1..20; + + my $overlay = $table2_copy->overlay($table2, $pool->new); + { + # see the comment for above's: + # $table_copy = $table->copy(APR::Pool->new); + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + ok t_cmp $table->get('za'), 'za', "helper test"; + + } + ok t_cmp $overlay->get(20), 20, "no segfault/valid data"; + } + { + { + my $p = APR::Pool->new; + $p->cleanup_register(sub { "whatever" }); + $table = APR::Table::make($p, 10) + }; + $table->set(a => 5); + ok t_cmp $table->get("a"), 5, "no segfault"; + } + +} + +sub my_filter { + my ($key, $value) = @_; + $filter_count++; + unless ($key eq chr($value+97)) { + die "arguments I received are bogus($key,$value)"; + } + return 1; +} + +sub my_filter_stop { + my ($key, $value) = @_; + $filter_count++; + unless ($key eq chr($value+97)) { + die "arguments I received are bogus($key,$value)"; + } + return $filter_count == int(TABLE_SIZE)/2 ? 0 : 1; +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/threadmutex.pm b/2_0_13/t/lib/TestAPRlib/threadmutex.pm new file mode 100644 index 0000000..c632a21 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/threadmutex.pm
@@ -0,0 +1,53 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::threadmutex; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Const -compile => qw(EBUSY SUCCESS); +use APR::Pool(); + +sub num_of_tests { + return 5; +} + +sub test { + + require APR::ThreadMutex; + + my $pool = APR::Pool->new(); + my $mutex = APR::ThreadMutex->new($pool); + + ok $mutex; + + ok t_cmp($mutex->lock, APR::Const::SUCCESS, + 'lock == APR::Const::SUCCESS'); + +#XXX: don't get what we expect on win23 +#need to use APR_STATUS_IS_EBUSY ? +# ok t_cmp($mutex->trylock, APR::Const::EBUSY, +# 'trylock == APR::Const::EBUSY'); + + ok t_cmp($mutex->unlock, APR::Const::SUCCESS, + 'unlock == APR::Const::SUCCESS'); + + # out-of-scope pool + { + my $mutex = APR::ThreadMutex->new(APR::Pool->new); + # try to overwrite the temp pool data + require APR::Table; + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + # now test that we are still OK + ok t_cmp($mutex->lock, APR::Const::SUCCESS, + 'lock == APR::Const::SUCCESS'); + ok t_cmp($mutex->unlock, APR::Const::SUCCESS, + 'unlock == APR::Const::SUCCESS'); + } + +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/threadrwlock.pm b/2_0_13/t/lib/TestAPRlib/threadrwlock.pm new file mode 100644 index 0000000..df07afb --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/threadrwlock.pm
@@ -0,0 +1,40 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::threadrwlock; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Const -compile => qw(EBUSY SUCCESS); +use APR::Pool(); + +sub num_of_tests { + return 5; +} + +sub test { + + require APR::ThreadRWLock; + + my $pool = APR::Pool->new(); + my $mutex = APR::ThreadRWLock->new($pool); + + ok $mutex; + + ok t_cmp($mutex->rdlock, APR::Const::SUCCESS, + 'rdlock == APR::Const::SUCCESS'); + + ok t_cmp($mutex->unlock, APR::Const::SUCCESS, + 'unlock == APR::Const::SUCCESS'); + + ok t_cmp($mutex->wrlock, APR::Const::SUCCESS, + 'wrlock == APR::Const::SUCCESS'); + + ok t_cmp($mutex->unlock, APR::Const::SUCCESS, + 'unlock == APR::Const::SUCCESS'); + +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/uri.pm b/2_0_13/t/lib/TestAPRlib/uri.pm new file mode 100644 index 0000000..8c01282 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/uri.pm
@@ -0,0 +1,189 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::uri; + +# Testing APR::URI (more tests in TestAPI::uri) + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::URI (); +use APR::Pool (); +use APR::Const -compile => qw(URI_UNP_OMITSITEPART URI_UNP_OMITUSER + URI_UNP_REVEALPASSWORD URI_UNP_OMITQUERY + URI_UNP_OMITPASSWORD URI_UNP_OMITPATHINFO + ); + +my %default_ports = ( + ftp => 21, + gopher => 70, + http => 80, + https => 443, + nntp => 119, + prospero => 191, + snews => 563, + wais => 210, +); + +my %url = ( + scheme => ["http", "ftp" ], + user => ["user", "log" ], + password => ["password", "pass" ], + hostname => ["www.example.com", "ftp.example.com"], + port => [8000, 21 ], + path => ["/path/file.pl", "/pub" ], + query => ["query", undef ], + fragment => ["fragment", undef ], +); + +my @keys_urls = qw(scheme user password hostname port path query + fragment); +my @keys_hostinfo = qw(user password hostname port); + +sub num_of_tests { + return 36; +} + +sub test { + + my $pool = APR::Pool->new(); + + ### parse ### + my $url0 = sprintf "%s://%s:%s\@%s:%d%s?%s#%s", + map { $url{$_}[0] } @keys_urls; + # warn "URL: $url\n"; + my $hostinfo0 = sprintf "%s:%s\@%s:%d", + map { $url{$_}[0] } @keys_hostinfo; + + my $parsed = APR::URI->parse($pool, $url0); + ok $parsed; + ok $parsed->isa('APR::URI'); + + for my $method (keys %url) { + no strict 'refs'; + ok t_cmp($parsed->$method, $url{$method}[0], $method); + } + + ok t_cmp($parsed->hostinfo, $hostinfo0, "hostinfo"); + + for my $method (keys %url) { + no strict 'refs'; + $parsed->$method($url{$method}[1]); + t_debug("$method: " . ($url{$method}[1]||'undef') . + " => " . ($parsed->$method||'undef')); + } + + ### unparse ### + my $url_unparsed = $parsed->unparse; + + # hostinfo is unaffected, since it's simply a field in the parsed + # record, and it's populated when parse is called, but when + # individual fields used to compose it are updated, it doesn't get + # updated: so we see the old value here + ok t_cmp($parsed->hostinfo, $hostinfo0, "hostinfo"); + + # - since 21 is the default port for ftp, unparse omits it + # - if no flags are passed to unparse, APR::Const::URI_UNP_OMITPASSWORD + # is passed by default -- it hides the password + my $url1 = sprintf "%s://%s\@%s%s", + map { $url{$_}[1] } qw(scheme user hostname path); + ok t_cmp($url_unparsed, $url1, "unparsed url"); + + # various unparse flags # + { + # restore the query/fragment fields first + my $query_new = "my_query"; + my $fragment_new = "my_fragment"; + $parsed->query($query_new); + $parsed->fragment($fragment_new); + local $url{query}[1] = $query_new; + local $url{fragment}[1] = $fragment_new; + + # omit the site part + { + my $url_unparsed = $parsed->unparse(APR::Const::URI_UNP_OMITSITEPART); + my $url2 = sprintf "%s?%s#%s", + map { $url{$_}[1] } qw(path query fragment); + ok t_cmp($url_unparsed, $url2, "unparsed url: omit site"); + } + + # this time the password should appear as XXXXXXXX + { + local $url{password}[1] = "XXXXXXXX"; + my $url_unparsed = $parsed->unparse(0); + my $url2 = sprintf "%s://%s:%s\@%s%s?%s#%s", + map { $url{$_}[1] } grep !/^port$/, @keys_urls; + ok t_cmp($url_unparsed, $url2, "unparsed url:reveal passwd"); + } + + # this time the user and the password should appear + { + my $url_unparsed = $parsed->unparse(APR::Const::URI_UNP_REVEALPASSWORD); + my $url2 = sprintf "%s://%s:%s\@%s%s?%s#%s", + map { $url{$_}[1] } grep !/^port$/, @keys_urls; + ok t_cmp($url_unparsed, $url2, "unparsed url:reveal passwd"); + } + + # omit the user part / show password + { + my $url_unparsed = $parsed->unparse( + APR::Const::URI_UNP_OMITUSER|APR::Const::URI_UNP_REVEALPASSWORD); + my $url2 = sprintf "%s://:%s\@%s%s?%s#%s", + map { $url{$_}[1] } grep !/^(port|user)$/, @keys_urls; + ok t_cmp($url_unparsed, $url2, "unparsed url: omit user"); + } + + # omit the path, query and fragment strings + { + my $url_unparsed = $parsed->unparse( + APR::Const::URI_UNP_OMITPATHINFO|APR::Const::URI_UNP_REVEALPASSWORD); + my $url2 = sprintf "%s://%s:%s\@%s", map { $url{$_}[1] } + grep !/^(port|path|query|fragment)$/, @keys_urls; + ok t_cmp($url_unparsed, $url2, "unparsed url: omit path"); + } + + # omit the query and fragment strings + { + my $url_unparsed = $parsed->unparse( + APR::Const::URI_UNP_OMITQUERY|APR::Const::URI_UNP_OMITPASSWORD); + my $url2 = sprintf "%s://%s\@%s%s", map { $url{$_}[1] } + grep !/^(password|port|query|fragment)$/, @keys_urls; + ok t_cmp($url_unparsed, $url2, "unparsed url: omit query"); + } + } + + ### port_of_scheme ### + while (my ($scheme, $port) = each %default_ports) { + my $apr_port = APR::URI::port_of_scheme($scheme); + ok t_cmp($apr_port, $port, "scheme: $scheme"); + } + + # parse + out-of-scope pools + { + + my $url0 = sprintf "%s://%s:%s\@%s:%d%s?%s#%s", + map { $url{$_}[0] } @keys_urls; + # warn "URL: $url\n"; + my $hostinfo0 = sprintf "%s:%s\@%s:%d", + map { $url{$_}[0] } @keys_hostinfo; + + require APR::Pool; + my $parsed = APR::URI->parse(APR::Pool->new, $url0); + + # try to overwrite the temp pool data + require APR::Table; + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + + for my $method (keys %url) { + no strict 'refs'; + ok t_cmp($parsed->$method, $url{$method}[0], $method); + } + + ok t_cmp($parsed->hostinfo, $hostinfo0, "hostinfo"); + } +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/util.pm b/2_0_13/t/lib/TestAPRlib/util.pm new file mode 100644 index 0000000..cd5f761 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/util.pm
@@ -0,0 +1,57 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::util; + +# test APR::Util + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Util (); + +use constant CRYPT_WORKS => $^O !~ /^(MSWin32|beos|NetWare)$/; + +my $clear = "this is some text"; +# to get the hash values used: +# htpasswd -nb[sm] user "this is some text" +my %hashes = ( + crypt => 'pHM3JfnL6isho', + md5 => '$apr1$Kld6H/..$o5OPPPWslI3zB20S54u9s1', + sha1 => '{SHA}A5NpTRa4TethLkfOYlK9NfDYbAY=', +); + +# BACK_COMPAT_MARKER (sha1 support added in 2.0.50) +delete $hashes{sha1} unless have_min_apache_version('2.0.50'); + +sub num_of_tests { + return 1 + scalar keys %hashes; +} + +sub test { + + # password_validate + { + ok ! APR::Util::password_validate("one", "two"); + + while (my ($mode, $hash) = each %hashes) { + t_debug($mode); + if ($mode eq 'crypt' && !CRYPT_WORKS) { + t_debug("crypt is not supported on $^O"); + ok 1; # don't make noise + } + else { + ok APR::Util::password_validate($clear, $hash); + } + } + } + +#this function seems unstable on certain platforms +# my $blen = 10; +# my $bytes = APR::generate_random_bytes($blen); +# ok length($bytes) == $blen; + +} + +1;
diff --git a/2_0_13/t/lib/TestAPRlib/uuid.pm b/2_0_13/t/lib/TestAPRlib/uuid.pm new file mode 100644 index 0000000..8942c79 --- /dev/null +++ b/2_0_13/t/lib/TestAPRlib/uuid.pm
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPRlib::uuid; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +my $dummy_uuid = 'd48889bb-d11d-b211-8567-ec81968c93c6'; + +require APR; +require APR::UUID; + +#XXX: apr_generate_random_bytes may block forever on /dev/random +# my $uuid = APR::UUID->new->format; + +sub num_of_tests { + return 3; +} + +sub test { + my $uuid = $dummy_uuid; + + ok $uuid; + + my $uuid_parsed = APR::UUID->parse($uuid); + + ok $uuid_parsed; + + ok $uuid eq $uuid_parsed->format; +} + +1;
diff --git a/2_0_13/t/lib/TestCommon/FilterDebug.pm b/2_0_13/t/lib/TestCommon/FilterDebug.pm new file mode 100644 index 0000000..8836f15 --- /dev/null +++ b/2_0_13/t/lib/TestCommon/FilterDebug.pm
@@ -0,0 +1,82 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCommon::FilterDebug; + +use strict; +use warnings FATAL => 'all'; + +use base qw(Apache2::Filter); +use APR::Brigade (); +use APR::Bucket (); +use APR::BucketType (); + +use Apache2::Const -compile => qw(OK DECLINED); +use APR::Const -compile => ':common'; + +# to use these functions add any or all of these filter handlers +# PerlModule TestCommon::FilterDebug +# PerlInputFilterHandler TestCommon::FilterDebug::snoop_request +# PerlInputFilterHandler TestCommon::FilterDebug::snoop_connection +# PerlOutputFilterHandler TestCommon::FilterDebug::snoop_request +# PerlOutputFilterHandler TestCommon::FilterDebug::snoop_connection +# + +sub snoop_connection : FilterConnectionHandler { snoop("connection", @_) } +sub snoop_request : FilterRequestHandler { snoop("request", @_) } + +sub snoop { + my $type = shift; + my ($filter, $bb, $mode, $block, $readbytes) = @_; # filter args + + # $mode, $block, $readbytes are passed only for input filters + my $stream = defined $mode ? "input" : "output"; + + # read the data and pass-through the bucket brigades unchanged + if (defined $mode) { + # input filter + my $rv = $filter->next->get_brigade($bb, $mode, $block, $readbytes); + return $rv unless $rv == APR::Const::SUCCESS; + bb_dump($type, $stream, $bb); + } + else { + # output filter + bb_dump($type, $stream, $bb); + my $rv = $filter->next->pass_brigade($bb); + return $rv unless $rv == APR::Const::SUCCESS; + } + #if ($bb->is_empty) { + # return -1; + #} + + return Apache2::Const::OK; +} + +sub bb_dump { + my ($type, $stream, $bb) = @_; + + my @data; + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + $b->read(my $bdata); + push @data, $b->type->name, $bdata; + } + + # send the sniffed info to STDERR so not to interfere with normal + # output + my $direction = $stream eq 'output' ? ">>>" : "<<<"; + print STDERR "\n$direction $type $stream filter\n"; + + unless (@data) { + print STDERR " No buckets\n"; + return; + } + + my $c = 1; + while (my ($btype, $data) = splice @data, 0, 2) { + print STDERR " o bucket $c: $btype\n"; + print STDERR "[$data]\n"; + $c++; + } +} + +1; + +__END__
diff --git a/2_0_13/t/lib/TestCommon/Handlers.pm b/2_0_13/t/lib/TestCommon/Handlers.pm new file mode 100644 index 0000000..de7bf33 --- /dev/null +++ b/2_0_13/t/lib/TestCommon/Handlers.pm
@@ -0,0 +1,62 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCommon::Handlers; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use TestCommon::Utils (); + +use Apache::TestTrace; + +use Apache2::Const -compile => qw(M_POST OK); + +# read the posted body and send it back to the client as is +sub pass_through_response_handler { + my $r = shift; + + if ($r->method_number == Apache2::Const::M_POST) { + my $data = TestCommon::Utils::read_post($r); + debug "pass_through_handler read: $data\n"; + $r->print($data); + } + + Apache2::Const::OK; +} + +1; + +__END__ + +=head1 NAME + +TestCommon::Handlers - Common Handlers + + + +=head1 Synopsis + + # PerlModule TestCommon::Handlers + # PerlResponseHandler TestCommon::Handlers::pass_through_response_handler + + +=head1 Description + +Various commonly used handlers + + + + +=head1 API + +=head2 pass_through_response_handler + + # PerlModule TestCommon::Handlers + # PerlResponseHandler TestCommon::Handlers::pass_through_response_handler + +this is a response handler, which reads the posted body and sends it +back to the client as is. + +=cut
diff --git a/2_0_13/t/lib/TestCommon/LogDiff.pm b/2_0_13/t/lib/TestCommon/LogDiff.pm new file mode 100644 index 0000000..36b8314 --- /dev/null +++ b/2_0_13/t/lib/TestCommon/LogDiff.pm
@@ -0,0 +1,94 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCommon::LogDiff; + +use strict; +use warnings FATAL => 'all'; + +use POSIX (); + +sub new { + my $class = shift; + my $path = shift; + + open my $fh, "<$path" or die "Can't open $path: $!"; + seek $fh, 0, POSIX::SEEK_END(); + my $pos = tell $fh; + + my %self = ( + path => $path, + fh => $fh, + pos => $pos, + ); + + return bless \%self, $class; +} + +sub DESTROY { + my $self = shift; + close $self->{fh}; +} + +sub diff { + my $self = shift; + + # XXX: is it possible that some system will be slow to flush the + # buffers and we may need to wait a bit and retry if we see no new + # logged data? + my $fh = $self->{fh}; + seek $fh, $self->{pos}, POSIX::SEEK_SET(); # not really needed + + local $/; # slurp mode + my $diff = <$fh>; + seek $fh, 0, POSIX::SEEK_END(); + $self->{pos} = tell $fh; + + return defined $diff ? $diff : ''; +} + +1; + +__END__ + +=head1 NAME + +TestCommon::LogDiff - get log file diffs + +=head1 Synopsis + + use TestCommon::LogDiff; + use Apache::Test; + + plan tests => 2; + + my $path = "/tmp/mylog"; + open my $fh, ">>$path" or die "Can't open $path: $!"; + + my $logdiff = TestCommon::LogDiff->new($path); + + print $fh "foo 123\n"; + my $expected = qr/^foo/; + ok t_cmp $logdiff->diff, $expected; + + print $fh "bar\n"; + my $expected = 'bar'; + ok t_cmp $logdiff->diff, $expected; + + +=head1 Description + +Useful for testing the warning, error and other messages going into +the log file. + +=head1 API + +=head2 new + +open the log file and point the filehandle pointer to its end. + +=head2 diff + +extract any newly logged information since the last check and move the +filehandle to the end of the file. + +=cut +
diff --git a/2_0_13/t/lib/TestCommon/MemoryLeak.pm b/2_0_13/t/lib/TestCommon/MemoryLeak.pm new file mode 100644 index 0000000..c007005 --- /dev/null +++ b/2_0_13/t/lib/TestCommon/MemoryLeak.pm
@@ -0,0 +1,88 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCommon::MemoryLeak; + +# handy functions to measure memory leaks. since it measures the total +# memory size of the process and not just perl leaks, you get your +# C/XS leaks discovered too +# +# For example to test TestAPR::Pool::handler for leaks, add to its +# top: +# +# TestCommon::MemoryLeak::start(); +# +# and just before returning from the handler add: +# +# TestCommon::MemoryLeak::end(); +# +# now start the server with only worker server +# +# % t/TEST -maxclients 1 -start +# +# of course use maxclients 1 only if your test be handled with one +# client, e.g. proxy tests need at least two clients. +# +# Now repeat the same test several times (more than 3) +# +# % t/TEST -run apr/pool -times=10 +# +# t/logs/error_log will include something like: +# +# size vsize resident share rss +# 196k 132k 196k 0M 196k +# 104k 132k 104k 0M 104k +# 16k 0k 16k 0k 16k +# 0k 0k 0k 0k 0k +# 0k 0k 0k 0k 0k +# 0k 0k 0k 0k 0k +# +# as you can see the first few runs were allocating memory, but the +# following runs should consume no more memory. The leak tester measures +# the extra memory allocated by the process since the last test. Notice +# that perl and apr pools usually allocate more memory than they +# need, so some leaks can be hard to see, unless many tests (like a +# hundred) were run. + +use strict; +use warnings FATAL => 'all'; + +# XXX: as of 5.8.4 when spawning ithreads we get an annoying +# Attempt to free unreferenced scalar ... perlbug #24660 +# because of $gtop's CLONE'd object, so pretend that we have no gtop +# for now if perl is threaded +# GTop v0.12 is the first version that will work under threaded mpms +use Config; +use constant HAS_GTOP => eval { !$Config{useithreads} && + require GTop && GTop->VERSION >= 0.12 }; + +my $gtop = HAS_GTOP ? GTop->new : undef; +my @attrs = qw(size vsize resident share rss); +my $format = "%8s %8s %8s %8s %8s\n"; + +my %before; + +sub start { + + die "No GTop avaible, bailing out" unless HAS_GTOP; + + unless (keys %before) { + my $before = $gtop->proc_mem($$); + %before = map { $_ => $before->$_() } @attrs; + # print the header once + warn sprintf $format, @attrs; + } +} + +sub end { + + die "No GTop avaible, bailing out" unless HAS_GTOP; + + my $after = $gtop->proc_mem($$); + my %after = map {$_ => $after->$_()} @attrs; + warn sprintf $format, + map GTop::size_string($after{$_} - $before{$_}), @attrs; + %before = %after; +} + +1; + +__END__
diff --git a/2_0_13/t/lib/TestCommon/SameInterp.pm b/2_0_13/t/lib/TestCommon/SameInterp.pm new file mode 100644 index 0000000..ad7a01d --- /dev/null +++ b/2_0_13/t/lib/TestCommon/SameInterp.pm
@@ -0,0 +1,166 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCommon::SameInterp; + +use Apache::Test; +use Apache::TestUtil; + +use Exporter; +use vars qw(@ISA @EXPORT); + +@ISA = qw(Exporter); + +@EXPORT = qw(same_interp_req same_interp_req_body + same_interp_skip_not_found); + +sub same_interp_req { + my $res = eval { + Apache::TestRequest::same_interp_do(@_); + }; + return undef if $@ && $@ =~ /unable to find interp/; + die $@ if $@; + return $res; +} + +sub same_interp_req_body { + my $res = same_interp_req(@_); + return $res ? $res->content : ""; +} + +sub same_interp_skip_not_found { + my $skip_cond = shift; + if ($skip_cond) { + skip "Skip couldn't find the same interpreter", 0; + } + else { + my ($package, $filename, $line) = caller; + # trick ok() into reporting the caller filename/line when a + # sub-test fails in sok() + return eval <<EOE; +#line $line $filename + ok &t_cmp; +EOE + } +} + +1; + +__END__ + +=head1 NAME + +TestCommon::SameInterp - Helper functions for same_interp framework + +=head1 Synopsis + + use Apache::Test; + use Apache::TestUtil; + use Apache::TestRequest; + + use TestCommon::SameInterp; + + plan tests => 3; + + my $url = "/path"; + + my $same_interp = Apache::TestRequest::same_interp_tie($url); + ok $same_interp; + + my $expected = 1; + my $skip = 0; + # test GET over the same same_interp + for (1..2) { + $expected++; + my $res = same_interp_req($same_interp, \&GET, $url, foo => 'bar'); + $skip++ unless defined $res; + same_interp_skip_not_found( + $skip, + defined $res && $res->content, + $expected, + "GET over the same interp" + ); + } + + +=head1 Description + +In addition to same_interp base blocks from Apache::TestRequest, this +helper module provides extra wrappers to simplify the writing of tests + +META: consider merging those into Apache::TestRequest (or add a new +module, e.g. Apache::TestRequestSameInterp) + +=head1 API + + + +=head2 C<same_interp_req> + +normally one runs: + + my $res = GET $url, @data; + +in the same_interp framework one runs + + my $res = Apache::TestRequest::same_interp_do($same_interp, + \&GET, $url, @data); + +but if there is a failure to find the same interpreter we get an +exception. and there could be other exceptions as well (e.g. failure +to run the request). This wrapper handles all exceptions, returning +C<undef> if the exception was in a failure to find the same +interpreter, re-throws the exception otherwise. If there is no +exception, the response object is returned. + +So one passes the same arguments to this wrapper as you'd to +Apache::TestRequest::same_interp_do: + + my $res = same_interp_req($same_interp, \&GET, $url, @data); + + + +=head2 C<same_interp_req_body> + +This function calls C<L<same_interp_req|/C_same_interp_req_>> and +extracts the response body if the response object is defined. (sort of +GET_BODY for same_interp) + + +=head2 C<same_interp_skip_not_found> + +make the tests resistant to a failure of finding the same perl +interpreter, which happens randomly and not an error. so instead of running: + + my $res = same_interp_req($same_interp, \&GET, $url, @data); + ok t_cmp(defined $res && $res->content, $expected, "comment") + +one can run: + + my $res = same_interp_req($same_interp, \&GET, $url, @data); + $skip = defined $res ? 0 : 1; + same_interp_skip_not_found( + $skip, + defined $res && $res->content, + $expected, + "comment" + ); + +the first argument is used to decide whether to skip the sub-test, the +rest of the arguments are passed to 'ok t_cmp'. + +This wrapper is smart enough to report the correct line number as if +ok() was run in the test file itself and not in the wrapper, by doing: + + my ($package, $filename, $line) = caller; + return eval <<EOE; + #line $line $filename + ok &t_cmp; + EOE + +C<&t_cmp> receives C<@_>, containing all but the skip argument, as if +the wrapper was never called. + + + + +=cut +
diff --git a/2_0_13/t/lib/TestCommon/TiePerlSection.pm b/2_0_13/t/lib/TestCommon/TiePerlSection.pm new file mode 100644 index 0000000..e7c0780 --- /dev/null +++ b/2_0_13/t/lib/TestCommon/TiePerlSection.pm
@@ -0,0 +1,22 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCommon::TiePerlSection; + +use strict; +use warnings FATAL => 'all'; + +# the following is needed for the tied %Location test in <Perl> +# sections. Unfortunately it can't be defined in the section itself +# due to the bug in perl: +# http://rt.perl.org:80/rt3/Ticket/Display.html?id=29018 + +use Tie::Hash; +our @ISA = qw(Tie::StdHash); +sub FETCH { + my ($hash, $key) = @_; + if ($key eq '/tied') { + return 'TIED'; + } + return $hash->{$key}; +} + +1;
diff --git a/2_0_13/t/lib/TestCommon/Utils.pm b/2_0_13/t/lib/TestCommon/Utils.pm new file mode 100644 index 0000000..672c439 --- /dev/null +++ b/2_0_13/t/lib/TestCommon/Utils.pm
@@ -0,0 +1,122 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCommon::Utils; + +use strict; +use warnings FATAL => 'all'; + +use APR::Brigade (); +use APR::Bucket (); +use Apache2::Filter (); +use Apache2::Connection (); + +use Apache2::Const -compile => qw(MODE_READBYTES); +use APR::Const -compile => qw(SUCCESS BLOCK_READ); + +use constant IOBUFSIZE => 8192; + +# perl 5.6.x only triggers taint protection on strings which are at +# least one char long +sub is_tainted { + return ! eval { + eval join '', '#', + map defined() ? substr($_, 0, 0) : (), @_; + 1; + }; +} + +# to enable debug start with: (or simply run with -trace=debug) +# t/TEST -trace=debug -start +sub read_post { + my $r = shift; + my $debug = shift || 0; + + my $bb = APR::Brigade->new($r->pool, + $r->connection->bucket_alloc); + + my $data = ''; + my $seen_eos = 0; + my $count = 0; + do { + $r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES, + APR::Const::BLOCK_READ, IOBUFSIZE); + + $count++; + + warn "read_post: bb $count\n" if $debug; + + while (!$bb->is_empty) { + my $b = $bb->first; + + if ($b->is_eos) { + warn "read_post: EOS bucket:\n" if $debug; + $seen_eos++; + last; + } + + if ($b->read(my $buf)) { + warn "read_post: DATA bucket: [$buf]\n" if $debug; + $data .= $buf; + } + + $b->delete; + } + + } while (!$seen_eos); + + $bb->destroy; + + return $data; +} + +1; + +__END__ + +=head1 NAME + +TestCommon::Utils - Common Test Utils + + + +=head1 Synopsis + + use TestCommon::Utils; + + # test whether some SV is tainted + $b->read(my $data); + ok TestCommon::Utils::is_tainted($data); + + my $data = TestCommon::Utils::read_post($r); + +=head1 Description + +Various handy testing utils + + + + +=head1 API + + + +=head2 is_tainted + + is_tainted(@data); + +returns I<TRUE> if at least one element in C<@data> is tainted, +I<FALSE> otherwise. + + + +=head2 read_post + + my $data = TestCommon::Utils::read_post($r); + my $data = TestCommon::Utils::read_post($r, $debug); + +reads the posted data using bucket brigades manipulation. + +To enable debug pass a true argument C<$debug> + + +=cut +
diff --git a/2_0_13/t/lib/TestExit/FromPerlModule.pm b/2_0_13/t/lib/TestExit/FromPerlModule.pm new file mode 100644 index 0000000..774c281 --- /dev/null +++ b/2_0_13/t/lib/TestExit/FromPerlModule.pm
@@ -0,0 +1,22 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestExit::FromPerlModule; + +use strict; +use warnings FATAL => qw(all); + +use Apache2::ServerRec; +use Apache2::ServerUtil; +use Apache2::Log; +use Apache2::Const -compile => qw(OK); + +sub exit_handler { + my ($p, $s) = @_; + + $s->log->info("Child process pid=$$ is exiting - server push"); + + Apache2::Const::OK; +} + +Apache2::ServerUtil->server->push_handlers(PerlChildExitHandler => \&exit_handler); + +1;
diff --git a/2_0_13/t/modperl/cookie.t b/2_0_13/t/modperl/cookie.t new file mode 100644 index 0000000..13d275b --- /dev/null +++ b/2_0_13/t/modperl/cookie.t
@@ -0,0 +1,58 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# The Cookie HTTP header can be accessed via $r->headers_in and in certain +# situations via $ENV{HTTP_COOKIE}. +# +# 'SetHandler perl-script', combined with 'PerlOptions -SetupEnv', or +# 'SetHandler modperl' do not populate %ENV with CGI variables. So in +# this test we call $r->subprocess_env, which adds them on demand, and +# we are able to get the cookie via %ENV. +# +# the last sub-test makes sure that mod_cgi env vars don't persist +# and are properly re-set at the end of each request. +# +# since the test is run against the same interpreter we also test that +# the cookie value doesn't persist if it makes it to %ENV. + + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +Apache::TestRequest::user_agent(keep_alive => 1); + +plan tests => 3, need 'HTML::HeadParser'; + +my $module = 'TestModperl::cookie'; +my $location = '/' . Apache::TestRequest::module2path($module); + +my $cookie = 'foo=bar'; +my %cookies = ( + header => $cookie, + env => $cookie, + nocookie => '', +); + +# 'nocookie' must be run last, server-side shouldn't find a cookie +# (testing that %ENV is reset to its original values for vars set by +# $r->subprocess_env, which is run internally for 'perl-script') +# this requires that all the tests are run against the same interpter + +my @tests_ordered = qw(header env nocookie); + +GET $location; + +for my $test (@tests_ordered) { + my $expected = $test eq 'nocookie' ? '' : "bar"; + my @headers = (); + push @headers, (Cookie => $cookies{$test}) unless $test eq 'nocookie'; + + my $received = GET "$location?$test", @headers; + + ok t_cmp( + $received->content, + $expected, + "perl-script+SetupEnv/cookie: $test" + ); +}
diff --git a/2_0_13/t/modperl/cookie2.t b/2_0_13/t/modperl/cookie2.t new file mode 100644 index 0000000..e49ae21 --- /dev/null +++ b/2_0_13/t/modperl/cookie2.t
@@ -0,0 +1,44 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +# The Cookie HTTP header can be accessed via $r->headers_in and in certain +# situations via $ENV{HTTP_COOKIE}. +# +# in this test we shouldn't be able get the cookie via %ENV, +# since 'SetHandler modperl' doesn't set up CGI env var. unless the +# handler calls "$r->subprocess_env" by itself +# +# since the test is run against the same interpreter we also test that +# the cookie value doesn't persist if it makes it to %ENV. + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +Apache::TestRequest::user_agent(keep_alive => 1); + +plan tests => 3, need 'HTML::HeadParser'; + +my $module = 'TestModperl::cookie2'; +my $location = '/' . Apache::TestRequest::module2path($module); + +my %expected = +( + header => "header", + subprocess_env => "subprocess_env", + env => '', +); + +my @tests_ordered = qw(header subprocess_env env); + +for my $test (@tests_ordered) { + my $cookie = "key=$test"; + + my $received = GET "$location?$test", Cookie => $cookie; + + ok t_cmp( + $received->content, + $expected{$test}, + "perl-script+SetupEnv/cookie: $test", + ); +}
diff --git a/2_0_13/t/modperl/exit.t b/2_0_13/t/modperl/exit.t new file mode 100644 index 0000000..b519d7a --- /dev/null +++ b/2_0_13/t/modperl/exit.t
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest 'GET_BODY_ASSERT'; + +use Apache::Test; +use Apache::TestUtil; + +use ModPerl::Const -compile => 'EXIT'; + +my $location = "/TestModperl__exit"; + +plan tests => 3; + +{ + ok t_cmp(GET_BODY_ASSERT("$location?noneval"), + 'exited', + "exit in non eval context"); + +} +{ + my $exit_excpt = ModPerl::EXIT; + my $body = GET_BODY_ASSERT("$location?eval"); + ok t_cmp($body, + qr/^ModPerl::Util::exit: \($exit_excpt\) exit was called/, + "exit in eval context"); + + ok !t_cmp($body, + qr/must not be reached/, + "exit in eval context"); + +}
diff --git a/2_0_13/t/modperl/getc.t b/2_0_13/t/modperl/getc.t new file mode 100644 index 0000000..62763f1 --- /dev/null +++ b/2_0_13/t/modperl/getc.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2; + +my $location = "/TestModperl__getc"; + +my $expect = join '', 'a'..'Z'; + +my $str = POST_BODY $location, content => $expect; + +ok $str; + +ok t_cmp($str, $expect, 'getc'); +
diff --git a/2_0_13/t/modperl/local_env.t b/2_0_13/t/modperl/local_env.t new file mode 100644 index 0000000..7aeb728 --- /dev/null +++ b/2_0_13/t/modperl/local_env.t
@@ -0,0 +1,15 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1, skip_reason('local %ENV is still broken'); + +my $module = 'TestModperl::local_env'; +my $url = Apache::TestRequest::module2url($module); + +t_debug "connecting to $url"; +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/merge.t b/2_0_13/t/modperl/merge.t new file mode 100644 index 0000000..9e1a5cd --- /dev/null +++ b/2_0_13/t/modperl/merge.t
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY_ASSERT); +use Apache::Test; +use Apache::TestUtil; + +my $module = 'TestModperl::merge'; +my $url = Apache::TestRequest::module2url($module, {path => '/merge/'}); + +# test server-to-container merging (without overrides) for: +# PerlSetEnv +# PerlPassEnv +# PerlSetVar +# PerlAddVar + +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/merge2.t b/2_0_13/t/modperl/merge2.t new file mode 100644 index 0000000..4b64e49 --- /dev/null +++ b/2_0_13/t/modperl/merge2.t
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY_ASSERT); +use Apache::Test; +use Apache::TestUtil; + +my $module = 'TestModperl::merge'; +my $url = Apache::TestRequest::module2url($module, {path => '/merge2/'}); + +# test server-to-container merging (with overrides) for: +# PerlSetEnv +# PerlPassEnv +# PerlSetVar +# PerlAddVar + +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/merge3.t b/2_0_13/t/modperl/merge3.t new file mode 100644 index 0000000..b208f37 --- /dev/null +++ b/2_0_13/t/modperl/merge3.t
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY_ASSERT); +use Apache::Test; +use Apache::TestUtil; + +my $module = 'TestModperl::merge'; +my $url = Apache::TestRequest::module2url($module, {path => '/merge3/'}); + +# test multi-level merging (server-to-container-to-htaccess) for: +# PerlSetEnv +# PerlPassEnv +# PerlSetVar +# PerlAddVar + +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/perl_options.t b/2_0_13/t/modperl/perl_options.t new file mode 100644 index 0000000..9d99cb3 --- /dev/null +++ b/2_0_13/t/modperl/perl_options.t
@@ -0,0 +1,13 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $module = 'TestModperl::perl_options'; +my $url = Apache::TestRequest::module2url($module); + +t_debug "connecting to $url"; +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/perl_options2.t b/2_0_13/t/modperl/perl_options2.t new file mode 100644 index 0000000..9223b30 --- /dev/null +++ b/2_0_13/t/modperl/perl_options2.t
@@ -0,0 +1,13 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $module = 'TestModperl::perl_options2'; +my $url = Apache::TestRequest::module2url($module); + +t_debug "connecting to $url"; +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/modperl/pnotes.t b/2_0_13/t/modperl/pnotes.t new file mode 100644 index 0000000..3ef4b37 --- /dev/null +++ b/2_0_13/t/modperl/pnotes.t
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY_ASSERT); +use Apache::Test; +use Apache::TestUtil; + +my $module = 'TestModperl::pnotes'; +my $url = Apache::TestRequest::module2url($module); + +t_debug("connecting to $url"); + +plan tests => (26 * 3), need_lwp; + +# first with keepalives +Apache::TestRequest::user_agent(reset => 1, keep_alive => 1); +t_debug("issuing first request"); +print GET_BODY_ASSERT "$url?1"; + +# now close the connection +t_debug("issuing second request"); +print GET_BODY_ASSERT "$url?2", Connection => 'close'; + +# finally, check for a cleared $c->pnotes +t_debug("issuing final request"); +print GET_BODY_ASSERT "$url?3"; +
diff --git a/2_0_13/t/modperl/pnotes2.t b/2_0_13/t/modperl/pnotes2.t new file mode 100644 index 0000000..87f752a --- /dev/null +++ b/2_0_13/t/modperl/pnotes2.t
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY); +use Apache::Test; +use Apache::TestUtil; +use Apache::TestUtil qw/t_start_error_log_watch t_finish_error_log_watch/; + +my $module = 'TestModperl::pnotes2'; +my $url = Apache::TestRequest::module2url($module); +my ($u, $ok); + +t_debug("connecting to $url"); + +plan tests => 12, need_lwp; + +Apache::TestRequest::user_agent(reset => 1, keep_alive => 0); + +for my $i (1..12) { + t_client_log_warn_is_expected(); + t_start_error_log_watch; + $u="$url?$i"; $ok=GET_BODY $u; + select undef, undef, undef, 0.2; # give it time to write the logfile + ok t_cmp scalar(grep { + /pnotes are destroyed after cleanup passed/; + } t_finish_error_log_watch), 1, $u; +}
diff --git a/2_0_13/t/modperl/post_utf8.t b/2_0_13/t/modperl/post_utf8.t new file mode 100644 index 0000000..83e6b28 --- /dev/null +++ b/2_0_13/t/modperl/post_utf8.t
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest; + +my $location = "/TestModperl__post_utf8"; + +# From A.S.Pushkin's "Evgeniy Onegin" +my $data_ascii = "I love you, (why lying?), but I belong to another"; +my $data_utf8 = "\x{042F} \x{0432}\x{0430}\x{0441} \x{043B}\x{044E}" . + "\x{0431}\x{043B}\x{044E} (\x{043A} \x{0447}\x{0435}\x{043C}\x{0443} " . + "\x{043B}\x{0443}\x{043A}\x{0430}\x{0432}\x{0438}\x{0442}\x{044C}?),\n" . + "\x{041D}\x{043E} \x{044F} \x{0434}\x{0440}\x{0443}\x{0433}\x{043E}" . + "\x{043C}\x{0443} \x{043E}\x{0442}\x{0434}\x{0430}\x{043D}\x{0430};"; + +my $data = join '=', $data_ascii, $data_utf8; + +# must encode the utf8 request body +# we will skip the response any way if perl < 5.008 +utf8::encode($data) if $] >= 5.008; + +# Accept-Charset is not really needed, since we don't expect the +# server side to send anything back but plain ASCII. +print POST_BODY_ASSERT $location, content => $data, + 'Accept-Charset' => "ISO-8859-1,UTF-8"; + +
diff --git a/2_0_13/t/modperl/print_utf8.t b/2_0_13/t/modperl/print_utf8.t new file mode 100644 index 0000000..d29d543 --- /dev/null +++ b/2_0_13/t/modperl/print_utf8.t
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +# utf encode/decode was added only in 5.8.0 +# XXX: currently binmode is only available with perlio (used on the +# server side on the tied/perlio STDOUT) +plan tests => 1, need need_min_perl_version(5.008), need_perl('perlio'); + +my $location = "/TestModperl__print_utf8"; +my $expected = "Hello Ayhan \x{263A} perlio rules!"; + +my $res = GET $location; +my $received = $res->content; + +# response body includes wide-chars, but perl doesn't know about it +utf8::decode($received) if ($res->header('Content-Type')||'') =~ /utf-8/i; + +# needed for debugging print out of utf8 strings +binmode(STDOUT, ':utf8'); +ok t_cmp($received, $expected, 'UTF8 response via tied/perlio STDOUT'); +
diff --git a/2_0_13/t/modperl/print_utf8_2.t b/2_0_13/t/modperl/print_utf8_2.t new file mode 100644 index 0000000..9a12dd2 --- /dev/null +++ b/2_0_13/t/modperl/print_utf8_2.t
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +use Config; + +# utf encode/decode was added only in 5.8.0 +# perlio is needed only for the client side, because it calls binmode(STDOUT, ':utf8'); +plan tests => 1, need_min_perl_version(5.008); + +my $location = "/TestModperl__print_utf8_2"; +my $expected = "\$r->print() just works \x{263A}"; + +my $res = GET $location; +my $received = $res->content; + +# response body includes wide-chars, but perl doesn't know about it +utf8::decode($received) if ($res->header('Content-Type')||'') =~ /utf-8/i; + +if ($Config{useperlio}) { + # needed for debugging print out of utf8 strings + # but works only if perl is built w/ perlio + binmode(STDOUT, ':utf8'); + ok t_cmp($received, $expected, 'UTF8 response via $r->print'); +} +else { + ok $expected eq $received; +} +
diff --git a/2_0_13/t/modperl/readline.t b/2_0_13/t/modperl/readline.t new file mode 100644 index 0000000..11b4cb7 --- /dev/null +++ b/2_0_13/t/modperl/readline.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2; + +my $location = "/TestModperl__readline"; + +my $expect = join "\n", map { $_ x 24 } 'a'..'e'; + +my $str = POST_BODY $location, content => $expect; + +ok $str; + +ok t_cmp($str, $expect, 'readline'); +
diff --git a/2_0_13/t/modperl/request_rec_perlio_api.t b/2_0_13/t/modperl/request_rec_perlio_api.t new file mode 100644 index 0000000..2801ddc --- /dev/null +++ b/2_0_13/t/modperl/request_rec_perlio_api.t
@@ -0,0 +1,30 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use Config; + +my $uri = "/TestModperl__request_rec_perlio_api"; + +plan tests => 2, need { "perl $]: TIEd IO is used instead of PerlIO" + => ($] >= 5.008 && $Config{useperlio}) }; + + +{ + my $content = join "", 'a'..'j', 'k'..'t'; + my $location = "$uri?STDIN"; + my $expected = join "", 'a'..'j', "# please", 'k'..'t'; + my $received = POST_BODY_ASSERT $location, content => $content; + ok t_cmp($received, $expected, "STDIN tests"); +} + +{ + my $location = "$uri?STDOUT"; + my $expected = "life is hard and then you die! next you reincarnate..."; + my $received = GET_BODY_ASSERT $location; + ok t_cmp($received, $expected, "STDOUT tests"); +}
diff --git a/2_0_13/t/modperl/setupenv.t b/2_0_13/t/modperl/setupenv.t new file mode 100644 index 0000000..a4611f6 --- /dev/null +++ b/2_0_13/t/modperl/setupenv.t
@@ -0,0 +1,47 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY_ASSERT); +use Apache::Test; +use Apache::TestUtil; + +my $module = 'TestModperl::setupenv'; +my $url = Apache::TestRequest::module2url($module); + +t_debug("connecting to $url"); + +my @locations = ("${url}_mpdefault", + "${url}_mpsetup", + "${url}_mpdefault", # make sure %ENV is cleared + "${url}_mpvoid", + "${url}_mpsetupvoid", + "${url}_psdefault", + "${url}_psnosetup", + "${url}_psvoid", + "${url}_psnosetupvoid"); + +# plan the tests from a handler so we can run +# tests from within handlers across multiple requests +# +# this requires keepalives and a per-connection interpreter +# to make certain we can plan in one request and test in another +# which requires LWP +unless (need_lwp() && need_module('mod_env')) { + plan tests => 63, 0; +} + +Apache::TestRequest::user_agent(keep_alive => 1); +print GET_BODY_ASSERT join '?', $url, scalar @locations; + +# this tests for when %ENV is populated with CGI variables +# as well as the contents of the subprocess_env table +# +# see setupenv.pm for a full description of the tests + +foreach my $location (@locations) { + + t_debug("trying $location"); + + print GET_BODY_ASSERT $location; +}
diff --git a/2_0_13/t/modperl/setupenv2.t b/2_0_13/t/modperl/setupenv2.t new file mode 100644 index 0000000..f8752b0 --- /dev/null +++ b/2_0_13/t/modperl/setupenv2.t
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $location = "/TestModperl__setupenv2"; + +my %expected = ( + mixed => [qw(loadmodule conf1 <perl> conf2 require conf3 + config_require conf4 perlmodule conf5 conf5 + conf6 conf7 conf8 post_config_require)], + perl => [qw(loadmodule <perl> require config_require + perlmodule post_config_require)], +); + +plan tests => 2 + scalar(@{ $expected{mixed} }) + scalar(@{ $expected{perl} }); + +while (my ($k, $v) = each %expected) { + my @expected = @$v; + my $elements = scalar @expected; + my $received = GET_BODY "$location?$k"; + t_debug "$k: $received"; + my @received = split / /, $received; + + ok t_cmp $received[$_], $expected[$_] for 0..$#expected; + + ok t_cmp scalar(@received), scalar(@expected), "elements"; + if (@received > @expected) { + t_debug "unexpected elements: " . + join " ", @received[$elements..$#received]; + } +} +
diff --git a/2_0_13/t/modperl/status.t b/2_0_13/t/modperl/status.t new file mode 100644 index 0000000..9cb8aba --- /dev/null +++ b/2_0_13/t/modperl/status.t
@@ -0,0 +1,158 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_cmp t_server_log_error_is_expected); + +use Apache2::Const -compile => qw(OK DECLINED + NOT_FOUND SERVER_ERROR FORBIDDEN + HTTP_OK); + +plan tests => 15, need 'HTML::HeadParser'; + +my $base = "/TestModperl__status"; + +# valid Apache return codes +{ + my $uri = join '?', $base, Apache2::Const::OK; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::HTTP_OK, + $uri); +} + +{ + my $uri = join '?', $base, Apache2::Const::DECLINED; + my $code = GET_RC $uri; + + # no Alias to map us to DocumentRoot + ok t_cmp($code, + Apache2::Const::NOT_FOUND, + $uri); +} + +# standard HTTP status codes +{ + my $uri = join '?', $base, Apache2::Const::NOT_FOUND; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::NOT_FOUND, + $uri); +} + +{ + my $uri = join '?', $base, Apache2::Const::FORBIDDEN; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::FORBIDDEN, + $uri); +} + +{ + my $uri = join '?', $base, Apache2::Const::SERVER_ERROR; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::SERVER_ERROR, + $uri); +} + +# apache translates non-HTTP codes into 500 +# see ap_index_of_response +{ + my $uri = join '?', $base, 601; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::SERVER_ERROR, + $uri); +} + +{ + my $uri = join '?', $base, 313; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::SERVER_ERROR, + $uri); +} + +{ + my $uri = join '?', $base, 1; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::SERVER_ERROR, + $uri); +} + +# HTTP_OK is treated as an error, since it's not +# OK, DECLINED, or DONE. while apache's lookups +# succeed so the 200 is propagated to the client, +# there's an error beneath that 200 code. +{ + my $uri = join '?', $base, Apache2::Const::HTTP_OK; + my $response = GET $uri; + + ok t_cmp($response->code, + Apache2::Const::HTTP_OK, + $uri); + + ok t_cmp($response->content, + qr/server encountered an internal error/, + $uri); +} + +# mod_perl-specific implementation tests +{ + # ModPerl::Util::exit - voids return OK + my $uri = join '?', $base, 'exit'; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::HTTP_OK, + $uri); +} + +{ + # die gets trapped + my $uri = join '?', $base, 'die'; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::SERVER_ERROR, + $uri); +} + +{ + my $uri = join '?', $base, 'foobar'; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::HTTP_OK, + $uri); +} + +{ + my $uri = join '?', $base, 'foo9bar'; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::HTTP_OK, + $uri); +} + +{ + my $uri = join '?', $base, 'undef'; + my $code = GET_RC $uri; + + ok t_cmp($code, + Apache2::Const::HTTP_OK, + $uri); +} +
diff --git a/2_0_13/t/modules/apache_resource.t b/2_0_13/t/modules/apache_resource.t new file mode 100644 index 0000000..316365d --- /dev/null +++ b/2_0_13/t/modules/apache_resource.t
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, need qw[BSD::Resource], + { "CGI.pm (2.93 or higher) or Apache2::Request is needed" => + !!(eval { require CGI && $CGI::VERSION >= 2.93 } || + eval { require Apache2::Request })}; + +{ + # Apache2::Status menu inserted by Apache::Resource + my $url = '/status/perl?rlimit'; + my $body = GET_BODY_ASSERT $url; + ok $body =~ /RLIMIT_CPU/; +} + +# more tests would be nice, but I'm not sure how to write those w/o +# causing problems to the rest of the test suite. +# we could enable $ENV{PERL_RLIMIT_DEFAULTS} = 1; before loading +# Apache2::Resource, which sets certain default values (works for me) +# but it's not guaranteed that it'll work for others (since it's very +# OS specific)
diff --git a/2_0_13/t/modules/apache_status.t b/2_0_13/t/modules/apache_status.t new file mode 100644 index 0000000..5d07703 --- /dev/null +++ b/2_0_13/t/modules/apache_status.t
@@ -0,0 +1,50 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $base_url = '/status/perl'; + +my @opts = qw(script myconfig rgysubs section_config env isa_tree + symdump inc inh_tree sig); + +plan tests => @opts + 5, need 'HTML::HeadParser', + { "CGI.pm (2.93 or higher) or Apache2::Request is needed" => + !!(eval { require CGI && $CGI::VERSION >= 2.93 } || + eval { require Apache2::Request })}; + +{ + my $url = "$base_url"; + my $body = GET_BODY_ASSERT $url; + # expecting: Embedded Perl version <b>v5.8.2</b> for ... + my $pver = $^V ? sprintf "v%vd", $^V : $]; + ok t_cmp($body, qr[Embedded Perl version <b>$pver</b> for]); + # menu_item, part 1 + # expecting: Test Entry + ok $body =~ /Test Menu Entry/; +} + +{ + # menu_item, part 2 + my $url = "$base_url?test_menu"; + my $body = GET_BODY_ASSERT $url; + ok $body =~ /This is just a test entry/; +} + +for my $opt (@opts) { + my $url = "$base_url?$opt"; + ok GET_BODY_ASSERT $url; +} + +# B::Terse has an issue with XS, but Apache::Status shouldn't crash on +# that +{ + # Syntax Tree Dump: syntax and execution order options + for (qw(slow exec)) { + my $url = "$base_url/$_/Apache2::Const::OK?noh_b_terse"; + ok GET_OK $url; + } +}
diff --git a/2_0_13/t/modules/cgi.t b/2_0_13/t/modules/cgi.t new file mode 100644 index 0000000..0445d8e --- /dev/null +++ b/2_0_13/t/modules/cgi.t
@@ -0,0 +1,61 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache2::Build (); + +my $build = Apache2::Build->build_config; + +use constant HAVE_LWP => have_lwp(); + +my $tests = 4; +$tests += 1 if HAVE_LWP; + +plan tests => $tests, need need_min_module_version('CGI', 3.08), + {"MP_COMPAT_1X is disabled" => $build->{MP_COMPAT_1X}}; + +my $module = 'TestModules::cgi'; +my $location = '/' . Apache::TestRequest::module2path($module); + +my($res, $str); + +sok { + my $url = "$location?PARAM=2"; + $res = GET $url; + $str = $res->content; + t_cmp($str, "ok 2", "GET $url"); +}; + +sok { + my $content = 'PARAM=%33'; + $str = POST_BODY $location, content => $content; + t_cmp($str, "ok 3", "POST $location\n$content"); +}; + +if (HAVE_LWP) { + sok { + t_client_log_warn_is_expected(4) + if $] < 5.008 && require CGI && $CGI::VERSION < 3.06; + $str = UPLOAD_BODY $location, content => 4; + t_cmp($str, "ok 4", 'file upload'); + }; +} + +sok { + my $header = 'Content-type'; + $res = GET $location; + t_cmp($res->header($header), + qr{^text/test-output}, + "$header header"); +}; + +sok { + my $header = 'X-Perl-Module'; + $res = GET $location; + t_cmp($res->header($header), + $module, + "$header header"); +};
diff --git a/2_0_13/t/modules/cgi2.t b/2_0_13/t/modules/cgi2.t new file mode 100644 index 0000000..491ee03 --- /dev/null +++ b/2_0_13/t/modules/cgi2.t
@@ -0,0 +1,61 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache2::Build (); + +my $build = Apache2::Build->build_config; + +use constant HAVE_LWP => have_lwp(); + +my $tests = 4; +$tests += 1 if HAVE_LWP; + +plan tests => $tests, need + need_min_module_version(CGI => 3.08); + +my $module = 'TestModules::cgi2'; +my $location = '/' . Apache::TestRequest::module2path($module); + +my($res, $str); + +sok { + my $url = "$location?PARAM=2"; + $res = GET $url; + $str = $res->content; + t_cmp($str, "ok 2", "GET $url"); +}; + +sok { + my $content = 'PARAM=%33'; + $str = POST_BODY $location, content => $content; + t_cmp($str, "ok 3", "POST $location\n$content"); +}; + +if (HAVE_LWP) { + sok { + t_client_log_warn_is_expected(4) + if $] < 5.008 && require CGI && $CGI::VERSION < 3.06; + $str = UPLOAD_BODY $location, content => 4; + t_cmp($str, "ok 4", 'file upload'); + }; +} + +sok { + my $header = 'Content-type'; + $res = GET $location; + t_cmp($res->header($header), + qr{^text/test-output}, + "$header header"); +}; + +sok { + my $header = 'X-Perl-Module'; + $res = GET $location; + t_cmp($res->header($header), + $module, + "$header header"); +};
diff --git a/2_0_13/t/modules/cgipost.t b/2_0_13/t/modules/cgipost.t new file mode 100644 index 0000000..0cd94f2 --- /dev/null +++ b/2_0_13/t/modules/cgipost.t
@@ -0,0 +1,37 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(POST_BODY_ASSERT); + +my $module = 'TestModules::cgipost'; +my $url = '/' . Apache::TestRequest::module2path($module); + +my @data = (25, 50, 75, 100, 125, 150); + +plan tests => scalar(@data), need_min_module_version(CGI => 3.08); + +foreach my $post (@data) { + my %param = (); + + foreach my $key (1 .. $post) { + $param{$key} = 'data' x $key; + } + + my $post_data = join '&', map { "$_=$param{$_}" } + sort { $a <=> $b } keys %param; + my $expected = join ':', map { $param{$_} } + sort { $a <=> $b } keys %param; + + my $e_length = length $expected; + + my $received = POST_BODY_ASSERT $url, content => $post_data; + + my $r_length = length $received; + + t_debug "expected $e_length bytes, received $r_length bytes\n"; + ok ($expected eq $received); +} +
diff --git a/2_0_13/t/modules/cgipost2.t b/2_0_13/t/modules/cgipost2.t new file mode 100644 index 0000000..8c062f6 --- /dev/null +++ b/2_0_13/t/modules/cgipost2.t
@@ -0,0 +1,37 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(POST_BODY_ASSERT); + +my $module = 'TestModules::cgipost2'; +my $url = '/' . Apache::TestRequest::module2path($module); + +my @data = (25, 50, 75, 100, 125, 150); + +plan tests => scalar(@data), need_min_module_version(CGI => 3.08); + +foreach my $post (@data) { + my %param = (); + + foreach my $key (1 .. $post) { + $param{$key} = 'data' x $key; + } + + my $post_data = join '&', map { "$_=$param{$_}" } + sort { $a <=> $b } keys %param; + my $expected = join ':', map { $param{$_} } + sort { $a <=> $b } keys %param; + + my $e_length = length $expected; + + my $received = POST_BODY_ASSERT $url, content => $post_data; + + my $r_length = length $received; + + t_debug "expected $e_length bytes, received $r_length bytes\n"; + ok ($expected eq $received); +} +
diff --git a/2_0_13/t/modules/cgiupload.t b/2_0_13/t/modules/cgiupload.t new file mode 100644 index 0000000..b0a961f --- /dev/null +++ b/2_0_13/t/modules/cgiupload.t
@@ -0,0 +1,38 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +use Apache2::Build (); + +use File::Spec::Functions qw(catfile); + +my $build = Apache2::Build->build_config; +plan tests => 2, need need_lwp(), need need_min_module_version('CGI', 3.08), + {"MP_COMPAT_1X is disabled" => $build->{MP_COMPAT_1X}}; + +my $location = "/TestModules__cgiupload"; + +my $filename; +my $pod = 'pod/perlfunc.pod'; + +for (@INC) { + if (-e "$_/$pod") { + $filename = "$_/$pod"; + last; + } +} + +$filename ||= catfile Apache::Test::vars('serverroot'), "..", 'Makefile'; + +for (1,2) { + t_client_log_warn_is_expected(4) + if $] < 5.008 && require CGI && $CGI::VERSION < 3.06; + my $str = UPLOAD_BODY $location, filename => $filename; + my $body_len = length $str; + my $file_len = -s $filename; + t_debug "body_len=$body_len, file_len=$file_len"; + ok $body_len == $file_len; +}
diff --git a/2_0_13/t/modules/cgiupload2.t b/2_0_13/t/modules/cgiupload2.t new file mode 100644 index 0000000..b298419 --- /dev/null +++ b/2_0_13/t/modules/cgiupload2.t
@@ -0,0 +1,38 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +use Apache2::Build (); + +use File::Spec::Functions qw(catfile); + +my $build = Apache2::Build->build_config; +plan tests => 2, need need_lwp(), + need_min_module_version(CGI => 3.08); + +my $location = "/TestModules__cgiupload2"; + +my $filename; +my $pod = 'pod/perlfunc.pod'; + +for (@INC) { + if (-e "$_/$pod") { + $filename = "$_/$pod"; + last; + } +} + +$filename ||= catfile Apache::Test::vars('serverroot'), "..", 'Makefile'; + +for (1,2) { + t_client_log_warn_is_expected(4) + if $] < 5.008 && require CGI && $CGI::VERSION < 3.06; + my $str = UPLOAD_BODY $location, filename => $filename; + my $body_len = length $str; + my $file_len = -s $filename; + t_debug "body_len=$body_len, file_len=$file_len"; + ok $body_len == $file_len; +}
diff --git a/2_0_13/t/modules/include.t b/2_0_13/t/modules/include.t new file mode 100644 index 0000000..a2c54b3 --- /dev/null +++ b/2_0_13/t/modules/include.t
@@ -0,0 +1,35 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +#test for mod_include include virtual of a mod_perl script +my @patterns = ( + 'mod_perl mod_include test', + 'Hello World', + 'cgi.pm', + 'footer', +); + +plan tests => 2 + @patterns, need need_module('mod_include', 'mod_mime'), + need_min_module_version(CGI => 3.08); + +my $location = "/includes/test.shtml"; + + +my($res, $str); + +$res = GET $location; + +ok $res->is_success; + +$str = $res->content; + +ok $str; + +for my $pat (@patterns) { + ok t_cmp($str, qr{$pat}, "/$pat/"); +}
diff --git a/2_0_13/t/modules/include2.t b/2_0_13/t/modules/include2.t new file mode 100644 index 0000000..80d51dd --- /dev/null +++ b/2_0_13/t/modules/include2.t
@@ -0,0 +1,32 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +#test for mod_include parsing of mod_perl script output +#XXX: needs to be more robust. see t/htdocs/includes-registry/test.spl +my @patterns = ( + 'Perl-SSI', #MY_TEST + 'mod_perl', #SERVER_SOFTWARE +); + +plan tests => 2 + @patterns, ['include', 'mod_mime', 'HTML::HeadParser']; + +my $location = "/includes-registry/test.spl"; + +my($res, $str); + +$res = GET $location; + +ok $res->is_success; + +$str = $res->content; + +ok $str; + +for my $pat (@patterns) { + ok t_cmp($str, qr{$pat}, "/$pat/"); +}
diff --git a/2_0_13/t/modules/include_subreq.t b/2_0_13/t/modules/include_subreq.t new file mode 100644 index 0000000..8295292 --- /dev/null +++ b/2_0_13/t/modules/include_subreq.t
@@ -0,0 +1,19 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $module = 'TestModules::include_subreq'; +my $location = '/' . Apache::TestRequest::module2path($module); + +plan tests => 1, ['include']; + +my($res, $str); + +my $expected = "subreq is quite ok"; +my $received = GET_BODY_ASSERT "$location/one"; +ok t_cmp($received, $expected, "handler => filter => handler"); +
diff --git a/2_0_13/t/modules/proxy.t b/2_0_13/t/modules/proxy.t new file mode 100644 index 0000000..2f4a53f --- /dev/null +++ b/2_0_13/t/modules/proxy.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $module = 'TestModules::proxy'; +my $url = Apache::TestRequest::module2url($module); + +t_debug("connecting to $url"); + +my @modules = qw(mod_proxy proxy_http.c); +push @modules, 'mod_access_compat' if have_min_apache_version("2.4.0"); +plan tests => 1, need need_module(@modules), need_access; + +my $expected = "ok"; +my $received = GET_BODY_ASSERT $url; +ok t_cmp($received, $expected, "internally proxified request");
diff --git a/2_0_13/t/perl/hash_attack.t b/2_0_13/t/perl/hash_attack.t new file mode 100644 index 0000000..bb91ef2 --- /dev/null +++ b/2_0_13/t/perl/hash_attack.t
@@ -0,0 +1,16 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use Apache::TestRequest 'GET_BODY_ASSERT'; + +plan tests => 1, + need { "relevant only for perl 5.8.2 and up to 5.17.6" => ($] >= 5.008002 && $] < 5.017006) }; + +my $expected = "ok"; +my $received = GET_BODY_ASSERT "/TestPerl__hash_attack"; +ok($expected eq $received);
diff --git a/2_0_13/t/perl/ithreads.t b/2_0_13/t/perl/ithreads.t new file mode 100644 index 0000000..53757a0 --- /dev/null +++ b/2_0_13/t/perl/ithreads.t
@@ -0,0 +1,17 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# perl/ithreads2 is a similar test but is running from within a +# virtual host with its own perl interpreter pool (+Parent) + +use Config; + +use Apache::Test; +use Apache::TestRequest 'GET_BODY_ASSERT'; + +# perl < 5.6.0 fails to compile code with 'shared' attributes, so we must skip +# it here. +unless ($] >= 5.008001 && $Config{useithreads}) { + plan tests => 1, need + {"perl 5.8.1 or higher w/ithreads enabled is required" => 0}; +} + +print GET_BODY_ASSERT "/TestPerl__ithreads";
diff --git a/2_0_13/t/perl/ithreads2.t b/2_0_13/t/perl/ithreads2.t new file mode 100644 index 0000000..ec2718b --- /dev/null +++ b/2_0_13/t/perl/ithreads2.t
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# perl/ithreads is a similar test but is running from the global perl +# interpreter pool. whereas this test is running against a +# virtual host with its own perl interpreter pool (+Parent) + +use strict; +use warnings FATAL => 'all'; + +use Config; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest 'GET_BODY_ASSERT'; + +# perl < 5.6.0 fails to compile code with 'shared' attributes, so we must skip +# it here. +unless ($] >= 5.008001 && $Config{useithreads}) { + plan tests => 1, need + {"perl 5.8.1 or higher w/ithreads enabled is required" => 0}; +} + +my $module = 'TestPerl::ithreads'; +my $url = Apache::TestRequest::module2url($module); + +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/perl/ithreads3.t b/2_0_13/t/perl/ithreads3.t new file mode 100644 index 0000000..ef3feb5 --- /dev/null +++ b/2_0_13/t/perl/ithreads3.t
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest 'GET_BODY'; + +plan tests => 6, need_apache_mpm('worker') && need_perl('ithreads'); + +my $module = 'TestPerl::ithreads3'; + +sub u {Apache::TestRequest::module2url($module, {path=>$_[0]})} +sub t { + my $rc; + eval { + local $SIG{ALRM}=sub {die "Timeout\n"}; + alarm 2; + eval { + $rc=GET_BODY u(shift); + }; + alarm 0; + }; + alarm 0; + return $rc; +} + +t_debug("connecting to ".u('')); +ok t_cmp t('/perl-script?1'), 2, 'perl-script 1'; +ok t_cmp t('/modperl?1'), 2, 'modperl 1'; + +ok t_cmp t('/perl-script?2'), 5, 'perl-script 2'; +ok t_cmp t('/modperl?2'), 5, 'modperl 2'; + +ok t_cmp t('/perl-script?3'), 3, 'perl-script 3'; +ok t_cmp t('/modperl?3'), 3, 'modperl 3';
diff --git a/2_0_13/t/preconnection/TestPreConnection/note.pm b/2_0_13/t/preconnection/TestPreConnection/note.pm new file mode 100644 index 0000000..f485952 --- /dev/null +++ b/2_0_13/t/preconnection/TestPreConnection/note.pm
@@ -0,0 +1,50 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestPreConnection::note; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); + +use Apache::TestTrace; +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); +use constant APACHE24 => have_min_apache_version('2.4.0'); + +sub handler { + my Apache2::Connection $c = shift; + + my $ip = APACHE24 ? $c->client_ip : $c->remote_ip; + + debug "ip: $ip"; + + $c->notes->set(preconnection => $ip); + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + $r->print($r->connection->notes->get('preconnection') || ''); + + return Apache2::Const::OK +} + +1; +__END__ +<NoAutoConfig> + <VirtualHost TestPreConnection::note> + PerlPreConnectionHandler TestPreConnection::note + + <Location /TestPreConnection__note> + SetHandler modperl + PerlResponseHandler TestPreConnection::note::response + </Location> + </VirtualHost> +</NoAutoConfig> + +
diff --git a/2_0_13/t/preconnection/note.t b/2_0_13/t/preconnection/note.t new file mode 100644 index 0000000..29453db --- /dev/null +++ b/2_0_13/t/preconnection/note.t
@@ -0,0 +1,20 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $module = 'TestPreConnection::note'; +my $url = Apache::TestRequest::module2url($module); +my $config = Apache::Test::config(); + +my $remote_addr = $config->{vars}->{remote_addr}; +t_debug("connecting to $url"); +plan tests => 1; + +ok t_cmp( + GET_BODY_ASSERT($url), + $remote_addr, + "connection notes");
diff --git a/2_0_13/t/protocol/TestProtocol/echo_bbs.pm b/2_0_13/t/protocol/TestProtocol/echo_bbs.pm new file mode 100644 index 0000000..1951b0e --- /dev/null +++ b/2_0_13/t/protocol/TestProtocol/echo_bbs.pm
@@ -0,0 +1,67 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestProtocol::echo_bbs; + +# this test is similar to TestProtocol::echo_filter, but performs the +# manipulations on the buckets inside the connection handler, rather +# then using filter + +# it also demonstrates how to use a single bucket bridade to do all +# the manipulation + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use APR::Socket (); +use APR::Bucket (); +use APR::Brigade (); +use APR::Error (); + +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK MODE_GETLINE); +use APR::Const -compile => qw(SUCCESS SO_NONBLOCK); +use APR::Status (); + +sub handler { + my $c = shift; + + # starting from Apache 2.0.49 several platforms require you to set + # the socket to a blocking IO mode + $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0); + + my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc); + + while (1) { + debug "asking new line"; + my $rc = $c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE); + last if APR::Status::is_EOF($rc); + die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS; + + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + + last if $b->is_eos; + + debug "processing new line"; + + if ($b->read(my $data)) { + last if $data =~ /^[\r\n]+$/; + my $nb = APR::Bucket->new($bb->bucket_alloc, uc $data); + # head->...->$nb->$b ->...->tail + # XXX: the next 3 lines could be replaced with a + # wrapper function $b->replace($nb); + $b->insert_before($nb); + $b->delete; + $b = $nb; + } + } + + $c->output_filters->fflush($bb); + } + + $bb->destroy; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/protocol/TestProtocol/echo_bbs2.pm b/2_0_13/t/protocol/TestProtocol/echo_bbs2.pm new file mode 100644 index 0000000..dacf27f --- /dev/null +++ b/2_0_13/t/protocol/TestProtocol/echo_bbs2.pm
@@ -0,0 +1,59 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestProtocol::echo_bbs2; + +# similar to TestProtocol::echo_bbs but here re-using one bucket +# brigade for input and output, using flatten to slurp all the data in +# the bucket brigade, and cleanup to get rid of the old buckets + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use APR::Socket (); +use APR::Bucket (); +use APR::Brigade (); +use APR::Error (); + +use Apache2::Const -compile => qw(OK MODE_GETLINE); +use APR::Const -compile => qw(SUCCESS SO_NONBLOCK); +use APR::Status (); + +sub handler { + my $c = shift; + + # starting from Apache 2.0.49 several platforms require you to set + # the socket to a blocking IO mode + $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0); + + my $bb_in = APR::Brigade->new($c->pool, $c->bucket_alloc); + my $bb_out = APR::Brigade->new($c->pool, $c->bucket_alloc); + + my $last = 0; + while (1) { + my $rc = $c->input_filters->get_brigade($bb_in, + Apache2::Const::MODE_GETLINE); + last if APR::Status::is_EOF($rc); + die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS; + + next unless $bb_in->flatten(my $data); + #warn "read: [$data]\n"; + last if $data =~ /^[\r\n]+$/; + + # transform data here + my $bucket = APR::Bucket->new($bb_in->bucket_alloc, uc $data); + $bb_out->insert_tail($bucket); + + $c->output_filters->fflush($bb_out); + + $bb_in->cleanup; + $bb_out->cleanup; + } + + # XXX: add DESTROY and remove explicit calls + $bb_in->destroy; + $bb_out->destroy; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/protocol/TestProtocol/echo_block.pm b/2_0_13/t/protocol/TestProtocol/echo_block.pm new file mode 100644 index 0000000..e13f93d --- /dev/null +++ b/2_0_13/t/protocol/TestProtocol/echo_block.pm
@@ -0,0 +1,48 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestProtocol::echo_block; + +# this test reads from/writes to the socket doing blocking IO +# +# see TestProtocol::echo_timeout for how to do the same with +# nonblocking IO but using the timeout + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use APR::Socket (); + +use TestCommon::Utils; + +use Apache2::Const -compile => 'OK'; +use APR::Const -compile => qw(SO_NONBLOCK); + +use constant BUFF_LEN => 1024; + +sub handler { + my Apache2::Connection $c = shift; + my APR::Socket $socket = $c->client_socket; + + # starting from Apache 2.0.49 several platforms require you to set + # the socket to a blocking IO mode + my $nonblocking = $socket->opt_get(APR::Const::SO_NONBLOCK); + if ($nonblocking) { + $socket->opt_set(APR::Const::SO_NONBLOCK, 0); + + # test that we really *are* in the blocking mode + !$socket->opt_get(APR::Const::SO_NONBLOCK) + or die "failed to set blocking mode"; + } + + while ($socket->recv(my $buffer, BUFF_LEN)) { + + die "recv() has returned untainted data:" + unless TestCommon::Utils::is_tainted($buffer); + + $socket->send($buffer); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/protocol/TestProtocol/echo_filter.pm b/2_0_13/t/protocol/TestProtocol/echo_filter.pm new file mode 100644 index 0000000..91d19f6 --- /dev/null +++ b/2_0_13/t/protocol/TestProtocol/echo_filter.pm
@@ -0,0 +1,64 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestProtocol::echo_filter; + +# see also TestFilter::both_str_con_add + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use APR::Socket (); +use APR::Bucket (); +use APR::Brigade (); +use APR::Error (); + +use base qw(Apache2::Filter); + +use APR::Const -compile => qw(SUCCESS SO_NONBLOCK); +use APR::Status (); +use Apache2::Const -compile => qw(OK MODE_GETLINE); + +use constant BUFF_LEN => 1024; + +sub uc_filter : FilterConnectionHandler { + my $filter = shift; + + while ($filter->read(my $buffer, BUFF_LEN)) { + $filter->print(uc $buffer); + } + + return Apache2::Const::OK; +} + +sub handler { + my $c = shift; + + # starting from Apache 2.0.49 several platforms require you to set + # the socket to a blocking IO mode + $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0); + + my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc); + + while (1) { + my $rc = $c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE); + last if APR::Status::is_EOF($rc); + die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS; + + # fflush is the equivalent of the following 3 lines of code: + # + # my $b = APR::Bucket::flush_create($c->bucket_alloc); + # $bb->insert_tail($b); + # $c->output_filters->pass_brigade($bb); + $c->output_filters->fflush($bb); + } + + $bb->destroy; + + Apache2::Const::OK; +} + +1; +__END__ +PerlModule TestProtocol::echo_filter +PerlOutputFilterHandler TestProtocol::echo_filter::uc_filter +
diff --git a/2_0_13/t/protocol/TestProtocol/echo_nonblock.pm b/2_0_13/t/protocol/TestProtocol/echo_nonblock.pm new file mode 100644 index 0000000..d99d576 --- /dev/null +++ b/2_0_13/t/protocol/TestProtocol/echo_nonblock.pm
@@ -0,0 +1,80 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestProtocol::echo_nonblock; + +# this test reads from/writes to the socket doing nonblocking IO + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use APR::Socket (); +use APR::Error (); + +use Apache::TestTrace; + +use Apache2::Const -compile => 'OK'; +use APR::Const -compile => qw(SO_NONBLOCK SUCCESS POLLIN); +use APR::Status (); + +use constant BUFF_LEN => 1024; + +sub handler { + my $c = shift; + my $socket = $c->client_socket; + + $socket->opt_set(APR::Const::SO_NONBLOCK, 1); + + my $counter = 0; + my $timeout = 0; + while (1) { + + debug "counter: $counter"; + if ($counter == 1) { + # this will certainly cause timeout + $timeout = 0; + } else { + # Wait up to ten seconds for data to arrive. + $timeout = 10_000_000; + } + $counter++; + + my $rc = $socket->poll($c->pool, $timeout, APR::Const::POLLIN); + if ($rc == APR::Const::SUCCESS) { + my $buf; + my $len = eval { $socket->recv($buf, BUFF_LEN) }; + if ($@) { + # rethrow + die $@ unless ref $@ eq 'APR::Error' + && (APR::Status::is_ECONNABORTED($@) || + APR::Status::is_ECONNRESET($@)); + # ECONNABORTED == 103 + # ECONNRESET == 104 + # ECONNABORTED is not an application error + # XXX: we don't really test that we always get this + # condition, since it depends on the timing of the + # client closing the socket. may be it'd be possible + # to make sure that APR::Const::ECONNABORTED was received + # when $counter == 2 if we have slept enough, but how + # much is enough is unknown + debug "caught '104: Connection reset by peer' error"; + last; + } + + last unless $len; + + debug "sending: $buf"; + $socket->send($buf); + } + elsif (APR::Status::is_TIMEUP($rc)) { + debug "timeout"; + $socket->send("TIMEUP\n"); + } + else { + die "poll error: $rc: " . APR::Error::strerror($rc); + } + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/protocol/TestProtocol/echo_timeout.pm b/2_0_13/t/protocol/TestProtocol/echo_timeout.pm new file mode 100644 index 0000000..50c81fa --- /dev/null +++ b/2_0_13/t/protocol/TestProtocol/echo_timeout.pm
@@ -0,0 +1,53 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestProtocol::echo_timeout; + +# this test reads from/writes to the socket doing nonblocking IO but +# using the timeout +# +# see TestProtocol::echo_block for how to do the same with blocking IO + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use APR::Socket (); + +use Apache2::Const -compile => 'OK'; +use APR::Const -compile => qw(SO_NONBLOCK); +use APR::Status (); + +use constant BUFF_LEN => 1024; + +sub handler { + my Apache2::Connection $c = shift; + my APR::Socket $socket = $c->client_socket; + + # starting from Apache 2.0.49 several platforms require you to set + # the socket to a blocking IO mode + $c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0); + + # set timeout (20 sec) so later we can do error checking on + # read/write timeouts + $socket->timeout_set(20_000_000); + + while (1) { + my $buff; + my $rlen = eval { $socket->recv($buff, BUFF_LEN) }; + if ($@) { + die "timed out, giving up: $@" if APR::Status::is_TIMEUP($@); + die $@; + } + + last unless $rlen; # EOF + + my $wlen = eval { $socket->send($buff) }; + if ($@) { + die "timed out, giving up: $@" if APR::Status::is_TIMEUP($@); + die $@; + } + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/protocol/TestProtocol/eliza.pm b/2_0_13/t/protocol/TestProtocol/eliza.pm new file mode 100644 index 0000000..3e1bdac --- /dev/null +++ b/2_0_13/t/protocol/TestProtocol/eliza.pm
@@ -0,0 +1,47 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestProtocol::eliza; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use APR::Socket (); + +require Chatbot::Eliza; + +use Apache2::Const -compile => 'OK'; +use APR::Const -compile => 'SO_NONBLOCK'; + +use constant BUFF_LEN => 1024; + +my $mybot = new Chatbot::Eliza; + +sub handler { + my Apache2::Connection $c = shift; + my APR::Socket $socket = $c->client_socket; + + # starting from Apache 2.0.49 several platforms require you to set + # the socket to a blocking IO mode + my $nonblocking = $socket->opt_get(APR::Const::SO_NONBLOCK); + if ($nonblocking) { + $socket->opt_set(APR::Const::SO_NONBLOCK, 0); + + # test that we really *are* in the blocking mode + !$socket->opt_get(APR::Const::SO_NONBLOCK) + or die "failed to set blocking mode"; + } + + my $last = 0; + while ($socket->recv(my $buff, BUFF_LEN)) { + # \r is sent instead of \n if the client is talking over telnet + $buff =~ s/[\r\n]*$//; + $last++ if $buff eq "Good bye, Eliza"; + $buff = $mybot->transform( $buff ) . "\n"; + $socket->send($buff); + last if $last; + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/protocol/TestProtocol/pseudo_http.pm b/2_0_13/t/protocol/TestProtocol/pseudo_http.pm new file mode 100644 index 0000000..3aede65 --- /dev/null +++ b/2_0_13/t/protocol/TestProtocol/pseudo_http.pm
@@ -0,0 +1,196 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestProtocol::pseudo_http; + +# this is a more advanced protocol implementation. While using a +# simplistic socket communication, the protocol uses an almost +# complete HTTP AAA (access and authentication, but not authorization, +# which can be easily added) provided by mod_auth (but can be +# implemented in perl too) +# +# see the protocols.pod document for the explanations of the code + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Connection (); +use Apache2::RequestUtil (); +use Apache2::HookRun (); +use Apache2::Access (); +use APR::Socket (); + +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK DONE DECLINED); +use APR::Const -compile => qw(SO_NONBLOCK); + +my @cmds = qw(date quit); +my %commands = map { $_, \&{$_} } @cmds; + +sub handler { + my $c = shift; + my $socket = $c->client_socket; + + if ($socket->opt_get(APR::Const::SO_NONBLOCK)) { + $socket->opt_set(APR::Const::SO_NONBLOCK => 0); + } + + if ((my $rc = greet($c)) != Apache2::Const::OK) { + $socket->send("Say HELO first\n"); + return $rc; + } + + if ((my $rc = login($c)) != Apache2::Const::OK) { + $socket->send("Access Denied\n"); + return $rc; + } + + $socket->send("Welcome to " . __PACKAGE__ . + "\nAvailable commands: @cmds\n"); + + while (1) { + my $cmd; + next unless $cmd = getline($socket); + + if (my $sub = $commands{$cmd}) { + last unless $sub->($socket) == Apache2::Const::OK; + } + else { + $socket->send("Commands: @cmds\n"); + } + } + + return Apache2::Const::OK; +} + +sub greet { + my $c = shift; + my $socket = $c->client_socket; + + $socket->send("HELO\n"); + my $reply = getline($socket) || ''; + + return $reply eq 'HELO' ? Apache2::Const::OK : Apache2::Const::DECLINED; +} + +sub login { + my $c = shift; + + my $r = Apache2::RequestRec->new($c); + + # test whether we can invoke modperl HTTP handlers on the fake $r + $r->push_handlers(PerlAccessHandler => \&my_access); + + $r->location_merge(__PACKAGE__); + + for my $method (qw(run_access_checker run_check_user_id + run_auth_checker)) { + + my $rc = $r->$method(); + + if ($rc != Apache2::Const::OK and $rc != Apache2::Const::DECLINED) { + return $rc; + } + + last unless $r->some_auth_required; + + unless ($r->user) { + my $socket = $c->client_socket; + + my $username = prompt($socket, "Login"); + my $password = prompt($socket, "Password"); + + $r->set_basic_credentials($username, $password); + } + } + + return Apache2::Const::OK; +} + +sub my_access { + # just test that we can invoke a mod_perl HTTP handler + debug "running my_access"; + return Apache2::Const::OK; +} + +sub getline { + my $socket = shift; + + my $line; + $socket->recv($line, 1024); + return unless $line; + $line =~ s/[\r\n]*$//; + + return $line; +} + +sub prompt { + my ($socket, $msg) = @_; + + $socket->send("$msg:\n"); + getline($socket); +} + +sub date { + my $socket = shift; + + $socket->send("The time is: " . scalar(localtime) . "\n"); + + return Apache2::Const::OK; +} + +sub quit { + my $socket = shift; + + $socket->send("Goodbye\n"); + + return Apache2::Const::DONE +} + +1; +__END__ +<NoAutoConfig> +<VirtualHost TestProtocol::pseudo_http> + + PerlProcessConnectionHandler TestProtocol::pseudo_http + + <Location TestProtocol::pseudo_http> + + <IfModule mod_version.c> + <IfVersion < 2.3.0> + <IfModule @ACCESS_MODULE@> + Order Deny,Allow + Allow from @servername@ + </IfModule> + </IfVersion> + <IfVersion > 2.4.1> + <IfModule mod_access_compat.c> + Order Deny,Allow + Allow from @servername@ + </IfModule> + </IfVersion> + </IfModule> + + <IfModule @AUTH_MODULE@> + # htpasswd -mbc basic-auth stas foobar + # using md5 password so it'll work on win32 too + AuthUserFile @ServerRoot@/htdocs/protocols/basic-auth + </IfModule> + + AuthName TestProtocol::pseudo_http + AuthType Basic + Require user stas + <IfModule mod_version.c> + <IfVersion < 2.3.0> + Satisfy any + </IfVersion> + <IfVersion > 2.4.1> + <IfModule mod_access_compat.c> + Satisfy any + </IfModule> + </IfVersion> + </IfModule> + + </Location> + +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/protocol/echo_bbs.t b/2_0_13/t/protocol/echo_bbs.t new file mode 100644 index 0000000..a5080cf --- /dev/null +++ b/2_0_13/t/protocol/echo_bbs.t
@@ -0,0 +1,21 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = qw(hello wonderful world); + +plan tests => 1 + @test_strings; + +my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_bbs'); + +ok $socket; + +for (@test_strings) { + print $socket "$_\n"; + chomp(my $reply = <$socket>||''); + ok t_cmp($reply, uc($_)); +}
diff --git a/2_0_13/t/protocol/echo_bbs2.t b/2_0_13/t/protocol/echo_bbs2.t new file mode 100644 index 0000000..1dd3329 --- /dev/null +++ b/2_0_13/t/protocol/echo_bbs2.t
@@ -0,0 +1,21 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = qw(hello world); + +plan tests => 1 + @test_strings; + +my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_bbs2'); + +ok $socket; + +for (@test_strings) { + print $socket "$_\n"; + chomp(my $reply = <$socket>||''); + ok t_cmp($reply, uc($_)); +}
diff --git a/2_0_13/t/protocol/echo_block.t b/2_0_13/t/protocol/echo_block.t new file mode 100644 index 0000000..30715b5 --- /dev/null +++ b/2_0_13/t/protocol/echo_block.t
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = qw(hello world); + +# blocking socket bug fixed in 2.0.52 +my $ok = $^O !~ /^(Open|Net)BSD$/i || need_min_apache_version('2.0.52'); + +plan tests => 1 + @test_strings, $ok; + +my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_block'); + +ok $socket; + +for (@test_strings) { + print $socket "$_\n"; + chomp(my $reply = <$socket>||''); + ok t_cmp($reply, $_); +}
diff --git a/2_0_13/t/protocol/echo_filter.t b/2_0_13/t/protocol/echo_filter.t new file mode 100644 index 0000000..b311af1 --- /dev/null +++ b/2_0_13/t/protocol/echo_filter.t
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = qw(hello world); + +# blocking socket bug fixed in 2.0.52 +my $ok = $^O !~ /^(Open|Net)BSD$/i || need_min_apache_version('2.0.52'); + +plan tests => 1 + @test_strings, $ok; + +my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_filter'); + +ok $socket; + +for (@test_strings) { + print $socket "$_\n"; + chomp(my $reply = <$socket>||''); + ok t_cmp($reply, uc($_)); +}
diff --git a/2_0_13/t/protocol/echo_nonblock.t b/2_0_13/t/protocol/echo_nonblock.t new file mode 100644 index 0000000..0de4da8 --- /dev/null +++ b/2_0_13/t/protocol/echo_nonblock.t
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +plan tests => 3; + +my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_nonblock'); + +ok $socket; + +my $received; +my $expected; + +$expected = "nonblocking"; +print $socket "$expected\n"; +chomp($received = <$socket> || ''); +ok t_cmp $received, $expected, "no timeout"; + +# now get a timed out request +$expected = "TIMEUP"; +sleep 1; # try to ensure a CPU context switch for the server +print $socket "should timeout\n"; +chomp($received = <$socket> || ''); +ok t_cmp $received, $expected, "timed out"; +
diff --git a/2_0_13/t/protocol/echo_timeout.t b/2_0_13/t/protocol/echo_timeout.t new file mode 100644 index 0000000..261b448 --- /dev/null +++ b/2_0_13/t/protocol/echo_timeout.t
@@ -0,0 +1,21 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = qw(good bye cruel world); + +plan tests => 1 + @test_strings; + +my $socket = Apache::TestRequest::vhost_socket('TestProtocol::echo_timeout'); + +ok $socket; + +for (@test_strings) { + print $socket "$_\n"; + chomp(my $reply = <$socket>||''); + ok t_cmp($reply, $_); +}
diff --git a/2_0_13/t/protocol/eliza.t b/2_0_13/t/protocol/eliza.t new file mode 100644 index 0000000..0df216f --- /dev/null +++ b/2_0_13/t/protocol/eliza.t
@@ -0,0 +1,34 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = ('Hello Eliza', + 'How are you?', + 'Why do I have core dumped?', + 'I feel like writing some tests today, what about you?', + 'Good bye, Eliza'); + +plan tests => 2 + @test_strings, need_module 'Chatbot::Eliza'; + +my $socket = Apache::TestRequest::vhost_socket('TestProtocol::eliza'); + +ok $socket; + +for (@test_strings) { + print $socket "$_\n"; + chomp(my $reply = <$socket> || ''); + t_debug "send: $_"; + t_debug "recv: $reply"; + ok $reply; +} + +# at this point 'Good bye, Eliza' should abort the connection. +my $string = 'Eliza should not hear this'; +print $socket "$string\n"; +chomp(my $reply = <$socket> || ''); +t_debug "Eliza shouldn't respond anymore"; +ok !$reply;
diff --git a/2_0_13/t/protocol/pseudo_http.t b/2_0_13/t/protocol/pseudo_http.t new file mode 100644 index 0000000..586c6ac --- /dev/null +++ b/2_0_13/t/protocol/pseudo_http.t
@@ -0,0 +1,148 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my $module = 'TestProtocol::pseudo_http'; + +{ + # debug + Apache::TestRequest::module($module); + my $hostport = Apache::TestRequest::hostport(Apache::Test::config()); + t_debug("connecting to $hostport"); +} + +my $login = "stas"; +my $passgood = "foobar"; +my $passbad = "foObaR"; + +# blocking socket bug fixed in 2.0.52 +my $ok = $^O !~ /^(Open|Net)BSD$/i || need_min_apache_version('2.0.52'); + +my @modules = (); +push @modules, 'mod_access_compat.c' if have_min_apache_version("2.4.0"); +plan tests => 13, need need_auth, need_access, @modules, $ok; + +{ + # supply correct credential when prompted for such and ask the + # server get the secret datetime information + my $socket = Apache::TestRequest::vhost_socket($module); + ok $socket; + + #################################################################### + # ACTION SEND RECEIVE + # + # greeting HELO + # HELO + # Login: + # + # login $login + # Password + # + # good pass $passgood + # banner Welcome to TestProtocol::pseudo_http + # Available commands: date quit + # date date + # The time is: Sat Jul 8 23:51:47 2006 + # + # eot quit + # Goodbye + + { + my $response = ""; + $response = Send($socket, 'HELO'); + ok t_cmp($response, 'HELO', 'greeting 1'); + $response = getline($socket); + ok t_cmp($response, 'Login:', 'greeeting 2') + } + + { + my $response = Send($socket, $login); + ok t_cmp($response, 'Password:', 'login'); + } + + { + my $response = ""; + $response = Send($socket, $passgood); + ok t_cmp($response, 'Welcome to TestProtocol::pseudo_http', 'good pass'); + $response = getline($socket); + ok t_cmp($response, 'Available commands: date quit', 'banner'); + } + + { + my $response = Send($socket, 'date'); + ok t_cmp($response, qr/The time is:/, 'date'); + } + + { + my $response = Send($socket, 'quit'); + ok t_cmp($response, 'Goodbye', 'eot'); + } +} + +{ + # supply correct credential when prompted for such and ask the + # server get the secret datetime information + my $socket = Apache::TestRequest::vhost_socket($module); + ok $socket; + + #################################################################### + # ACTION SEND RECEIVE + # + # greeting HELO + # HELO + # Login: + # + # login $login + # Password + # + # bad pass $passbad + # Access Denied + # + # eot quit + # Goodbye + + { + my $response = ""; + $response = Send($socket, 'HELO'); + ok t_cmp($response, 'HELO', 'greeting 1'); + $response = getline($socket); + ok t_cmp($response, 'Login:', 'greeeting 2') + } + + { + my $response = Send($socket, $login); + ok t_cmp($response, 'Password:', 'login'); + } + + { + my $response = ""; + $response = Send($socket, $passbad); + ok t_cmp($response, 'Access Denied', 'eot'); + } +} + +## send() is reserved +sub Send { + my ($socket, $str) = @_; + + t_debug("send: $str"); + print $socket $str; + + chomp(my $recv = <$socket> || ''); + t_debug("recv: $recv"); + + return $recv; +} + +sub getline { + my ($socket) = @_; + + chomp(my $recv = <$socket> || ''); + t_debug("getline: $recv"); + + return $recv; +}
diff --git a/2_0_13/t/response/TestAPI/access.pm b/2_0_13/t/response/TestAPI/access.pm new file mode 100644 index 0000000..82b1a03 --- /dev/null +++ b/2_0_13/t/response/TestAPI/access.pm
@@ -0,0 +1,65 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::access; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Access (); + +use Apache2::Const -compile => qw(OK :options :override :satisfy); + +sub handler { + my $r = shift; + + plan $r, tests => 11; + + $r->allow_methods(1, qw(GET POST)); + + ok 1; + + ok $r->allow_options & Apache2::Const::OPT_INDEXES; + + ok !($r->allow_options & Apache2::Const::OPT_EXECCGI); + + ok !($r->allow_overrides & Apache2::Const::OR_LIMIT); + + ok t_cmp $r->satisfies, Apache2::Const::SATISFY_NOSPEC, "satisfies"; + + ok t_cmp $r->auth_name, 'modperl', "auth_name"; + + $r->auth_name('modperl_test'); + ok t_cmp $r->auth_name, 'modperl_test', "auth_name"; + $r->auth_name('modperl'); + + ok t_cmp $r->auth_type, 'none', "auth_type"; + + $r->auth_type('Basic'); + ok t_cmp $r->auth_type, 'Basic', "auth_type"; + $r->auth_type('none'); + + ok !$r->some_auth_required; + + # XXX: this test requires a running identd, which we have no way + # to figure out whether it's running, or how to start one. so for + # now just check that the method is call-able. + my $remote_logname = $r->get_remote_logname() || ''; + t_debug "get_remote_logname: $remote_logname"; + ok 1; + + Apache2::Const::OK; +} + +1; +__END__ +Options None +Options Indexes FollowSymLinks +AuthName modperl +AuthType none + +# this directive was moved from core in Apache 2.1 +# since we're not testing that identd is running +# anyway we probably don't need to include it at all +#IdentityCheck On
diff --git a/2_0_13/t/response/TestAPI/access2.pm b/2_0_13/t/response/TestAPI/access2.pm new file mode 100644 index 0000000..5677408 --- /dev/null +++ b/2_0_13/t/response/TestAPI/access2.pm
@@ -0,0 +1,125 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::access2; + +# testing $r->requires +# in the POST test it returns: +# +# [ +# { +# 'method_mask' => -1, +# 'requirement' => 'user goo bar' +# }, +# { +# 'method_mask' => -1, +# 'requirement' => 'group bar tar' +# } +# { +# 'method_mask' => 4, +# 'requirement' => 'valid-user' +# } +# ]; +# +# otherwise it returns the same, sans the 'valid-user' entry +# +# also test: +# - $r->some_auth_required when it's required +# - $r->satisfies when Satisfy is set + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Access (); +use Apache2::RequestRec (); + +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED SERVER_ERROR + M_POST :satisfy); + +my $users = "goo bar"; +my $groups = "bar tar"; +my %users = ( + goo => "goopass", + bar => "barpass", +); + +sub handler { + my $r = shift; + die '$r->some_auth_required failed' unless $r->some_auth_required; + + my $satisfies = $r->satisfies; + die "wanted satisfies=" . Apache2::Const::SATISFY_ALL . ", got $satisfies" + unless $r->satisfies() == Apache2::Const::SATISFY_ALL; + + my ($rc, $sent_pw) = $r->get_basic_auth_pw; + return $rc if $rc != Apache2::Const::OK; + + # extract just the requirement entries + my %require = + map { my ($k, $v) = split /\s+/, $_->{requirement}, 2; ($k, $v||'') } + @{ $r->requires }; + debug \%require; + + # silly (we don't check user/pass here), just checking when + # the Limit options are getting through + if ($r->method_number == Apache2::Const::M_POST) { + if (exists $require{"valid-user"}) { + return Apache2::Const::OK; + } + else { + return Apache2::Const::SERVER_ERROR; + } + } + else { + # non-POST requests shouldn't see the Limit enclosed entry + return Apache2::Const::SERVER_ERROR if exists $require{"valid-user"}; + } + + return Apache2::Const::SERVER_ERROR unless $require{user} eq $users; + return Apache2::Const::SERVER_ERROR unless $require{group} eq $groups; + + my $user = $r->user; + my $pass = $users{$user} || ''; + unless (defined $pass and $sent_pw eq $pass) { + $r->note_basic_auth_failure; + return Apache2::Const::HTTP_UNAUTHORIZED; + } + + Apache2::Const::OK; +} + +1; +__DATA__ + +<NoAutoConfig> +<IfModule mod_version.c> +<IfVersion < 2.3.0> +<Location /TestAPI__access2> + PerlAuthenHandler TestAPI::access2 + PerlResponseHandler Apache::TestHandler::ok1 + SetHandler modperl + + <IfModule @ACCESS_MODULE@> + # needed to test $r->satisfies + Allow from All + </IfModule> + AuthType Basic + AuthName "Access" + Require user goo bar + Require group bar tar + <Limit POST> + Require valid-user + </Limit> + Satisfy All + <IfModule @AUTH_MODULE@> + # htpasswd -mbc auth-users goo foo + # htpasswd -mb auth-users bar mar + # using md5 password so it'll work on win32 too + AuthUserFile @DocumentRoot@/api/auth-users + # group: user1 user2 ... + AuthGroupFile @DocumentRoot@/api/auth-groups + </IfModule> +</Location> +</IfVersion> +</IfModule> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/access2_24.pm b/2_0_13/t/response/TestAPI/access2_24.pm new file mode 100644 index 0000000..b9ab26f --- /dev/null +++ b/2_0_13/t/response/TestAPI/access2_24.pm
@@ -0,0 +1,132 @@ +package TestAPI::access2_24; + +# testing $r->requires +# in the POST test it returns: +# +# [ +# { +# 'method_mask' => -1, +# 'requirement' => 'user goo bar' +# }, +# { +# 'method_mask' => -1, +# 'requirement' => 'group bar tar' +# } +# { +# 'method_mask' => 4, +# 'requirement' => 'valid-user' +# } +# ]; +# +# otherwise it returns the same, sans the 'valid-user' entry +# +# also test: +# - $r->some_auth_required when it's required +# - $r->satisfies when Satisfy is set + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Access (); +use Apache2::RequestRec (); + +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED SERVER_ERROR + AUTHZ_GRANTED AUTHZ_DENIED M_POST :satisfy + AUTHZ_DENIED_NO_USER); + +my $users = "goo bar"; +my $groups = "xar tar"; +my %users = ( + goo => "goopass", + bar => "barpass", +); + +sub authz_handler { + my $self = shift; + my $r = shift; + my $requires = shift; + + if (!$r->user) { + return Apache2::Const::AUTHZ_DENIED_NO_USER; + } + + return Apache2::Const::SERVER_ERROR unless + $requires eq $users or $requires eq $groups; + + my @require_args = split(/\s+/, $requires); + if (grep {$_ eq $r->user} @require_args) { + return Apache2::Const::AUTHZ_GRANTED; + } + + return Apache2::Const::AUTHZ_DENIED; +} + +sub authn_handler { + my $self = shift; + my $r = shift; + + die '$r->some_auth_required failed' unless $r->some_auth_required; + + my $satisfies = $r->satisfies; + die "wanted satisfies=" . Apache2::Const::SATISFY_ALL . ", got $satisfies" + unless $r->satisfies() == Apache2::Const::SATISFY_ALL; + + my ($rc, $sent_pw) = $r->get_basic_auth_pw; + return $rc if $rc != Apache2::Const::OK; + + if ($r->method_number == Apache2::Const::M_POST) { + return Apache2::Const::OK; + } + + my $user = $r->user; + my $pass = $users{$user} || ''; + unless (defined $pass and $sent_pw eq $pass) { + $r->note_basic_auth_failure; + return Apache2::Const::HTTP_UNAUTHORIZED; + } + + Apache2::Const::OK; +} + +1; +__DATA__ + +<NoAutoConfig> +<IfModule mod_version.c> +<IfVersion > 2.4.1> + +PerlAddAuthzProvider my-user TestAPI::access2_24->authz_handler +PerlAddAuthzProvider my-group TestAPI::access2_24->authz_handler +<Location /TestAPI__access2> + PerlAuthenHandler TestAPI::access2_24->authn_handler + PerlResponseHandler Apache::TestHandler::ok1 + SetHandler modperl + + <IfModule mod_access_compat.c> + # needed to test $r->satisfies + Allow from All + </IfModule> + AuthType Basic + AuthName "Access" + Require my-user goo bar + Require my-group xar tar + <Limit POST> + Require valid-user + </Limit> + <IfModule mod_access_compat.c> + Satisfy All + </IfModule> + <IfModule @AUTH_MODULE@> + # htpasswd -mbc auth-users goo foo + # htpasswd -mb auth-users bar mar + # using md5 password so it'll work on win32 too + AuthUserFile @DocumentRoot@/api/auth-users + # group: user1 user2 ... + AuthGroupFile @DocumentRoot@/api/auth-groups + </IfModule> +</Location> +</IfVersion> +</IfModule> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/add_config.pm b/2_0_13/t/response/TestAPI/add_config.pm new file mode 100644 index 0000000..661608c --- /dev/null +++ b/2_0_13/t/response/TestAPI/add_config.pm
@@ -0,0 +1,149 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::add_config; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Access (); +use Apache2::CmdParms (); +use Apache2::RequestUtil (); +use Apache2::Directive (); +use Apache2::ServerUtil (); +use base qw(Apache2::Module); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw( + OK + DECLINED + :options +); + +use constant KEY => "TestAddConfig"; +use constant APACHE22 => have_min_apache_version('2.2.0'); +use constant APACHE24 => have_min_apache_version('2.4.0'); + +my @directives = ( + { + name => KEY, + cmd_data => 'cmd_data', + errmsg => 'errmsg', + }, +); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub TestAddConfig { + my ($self, $parms, $args) = @_; + my $srv_cfg = $self->get_config($parms->server); + $srv_cfg->{override_opts} = $parms->override_opts(); +} + +sub map2storage { + my $r = shift; + + my $o = APACHE22 ? '=All,SymLinksIfOwnerMatch' : ''; + + eval { + $r->add_config(['AllowOverride All Options'.$o]); + }; + $r->pnotes(add_config1 => "$@"); + + eval { + $r->add_config(['Options ExecCGI'], -1, '/', 0); + }; + $r->pnotes(add_config2 => "$@"); + + # We can set AllowOverride only from .htacces in 2.4.0+ + if (!APACHE24) { + eval { + $r->add_config(['AllowOverride Options=FollowSymLinks'], -1); + }; + $r->pnotes(followsymlinks => "$@"); + } + + eval { + my $path="/a/path/to/somewhere"; + $r->add_config(['PerlResponseHandler '.__PACKAGE__], -1, $path); + # now overwrite the path in place to see if the location pointer + # is really copied: see modperl_config_dir_create + $path=~tr[a-z][n-za-m]; + }; + + return Apache2::Const::DECLINED; +} + +sub fixup { + my ($r) = @_; + + eval { + $r->add_config(['Options ExecCGI'], -1, '/', + Apache2::Const::OPT_EXECCGI); + }; + $r->pnotes(add_config3 => "$@"); + + eval { + $r->server->add_config(['ServerAdmin foo@bar.com']); + }; + $r->pnotes(add_config4 => "$@"); + + return Apache2::Const::DECLINED; +} + +sub handler : method { + my ($self, $r) = @_; + my $cf = $self->get_config($r->server); + + plan $r, tests => 9; + + ok t_cmp $r->pnotes('add_config1'), qr/.+\n/; + ok t_cmp $r->pnotes('add_config2'), (APACHE22 ? qr/.+\n/ : ''); + ok t_cmp $r->pnotes('add_config3'), ''; + ok t_cmp $r->pnotes('add_config4'), qr/after server startup/; + if (!APACHE24) { + ok t_cmp $r->pnotes('followsymlinks'), (APACHE22 ? '': qr/.*\n/); + } + else { + ok 1; + } + + my $expect = Apache2::Const::OPT_ALL | + Apache2::Const::OPT_UNSET | + (defined &Apache2::Const::OPT_INCNOEXEC + ? Apache2::Const::OPT_INCNOEXEC() : 0) | + Apache2::Const::OPT_MULTI | + Apache2::Const::OPT_SYM_OWNER; + + ok t_cmp $cf->{override_opts}, $expect; + ok t_cmp $r->allow_options, Apache2::Const::OPT_EXECCGI; + + my $opts = APACHE22 ? Apache2::Const::OPT_SYM_LINKS : $expect; + if (!APACHE24) { + ok t_cmp $r->allow_override_opts, $opts; + } + else { + ok 1; + } + + ok t_cmp $r->location, '/a/path/to/somewhere'; + + return Apache2::Const::OK; +} + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 +<NoAutoConfig> + <VirtualHost TestAPI::add_config> + PerlLoadModule TestAPI::add_config + AccessFileName htaccess + SetHandler modperl + <Directory @DocumentRoot@> + AllowOverride All + </Directory> + PerlMapToStorageHandler TestAPI::add_config::map2storage + PerlFixupHandler TestAPI::add_config::fixup + </VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/aplog.pm b/2_0_13/t/response/TestAPI/aplog.pm new file mode 100644 index 0000000..9cbef98 --- /dev/null +++ b/2_0_13/t/response/TestAPI/aplog.pm
@@ -0,0 +1,282 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::aplog; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::ServerRec qw(warn); # override warn locally +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use Apache2::Log (); +use Apache2::MPM (); + +use File::Spec::Functions qw(catfile); + +use Apache::Test; +use Apache::TestUtil; +use TestCommon::LogDiff; + +use Apache2::Const -compile => qw(OK :log); +use APR::Const -compile => qw(:error SUCCESS); +use constant APACHE24 => have_min_apache_version('2.4.0'); + +my @LogLevels = qw(emerg alert crit error warn notice info debug); +my $package = __PACKAGE__; + +my $path = catfile Apache::Test::vars('serverroot'), + qw(logs error_log); + +sub handler { + my $r = shift; + my $s = $r->server; + + plan $r, tests => (@LogLevels * 2) + 20; + + my $logdiff = TestCommon::LogDiff->new($path); + + my $rlog = $r->log; + + ok $rlog->isa('Apache2::Log::Request'); + + my $slog = $s->log; + + ok $slog->isa('Apache2::Log::Server'); + + t_server_log_warn_is_expected(); + $rlog->info($package, " test in progress"); + ok t_cmp $logdiff->diff, + qr/... TestAPI::aplog test in progress/, + '$r->log->info'; + + my ($file, $line) = Apache2::Log::LOG_MARK; + ok $file eq __FILE__; + ok $line == __LINE__ - 2; + + for my $method (@LogLevels) { + # wrap in sub {}, else Test.pm tries to run the return value + # of ->can + ok sub { $rlog->can($method) }; + ok sub { $slog->can($method) }; + } + + # log_serror + { + my $orig_log_level = 0; + if (APACHE24) { + $orig_log_level = $s->loglevel; + $s->loglevel(Apache2::Const::LOG_DEBUG); + } + t_server_log_warn_is_expected(); + $s->log_serror(Apache2::Log::LOG_MARK, + Apache2::Const::LOG_INFO|Apache2::Const::LOG_STARTUP, + APR::Const::SUCCESS, "This log message comes with no header"); + ok t_cmp $logdiff->diff, + qr/^This log message comes with no header$/m, + '$s->log_serror(LOG_MARK, LOG_INFO|LOG_STARTUP...)'; + + t_server_log_warn_is_expected(); + $s->log_serror(__FILE__, __LINE__, Apache2::Const::LOG_DEBUG, + APR::Const::SUCCESS, "log_serror test 1"); + ok t_cmp $logdiff->diff, + qr/: log_serror test 1$/m, + '$s->log_serror(__FILE__, __LINE__, LOG_DEBUG...)'; + + # the APR_EGENERAL error string changed for APR 1.0 + my $egeneral = have_min_apache_version('2.1.0') + ? qr/Internal error(?: \(specific information not available\))?/ + : "Error string not specified yet"; + + t_server_log_warn_is_expected(); + $s->log_serror(Apache2::Log::LOG_MARK, Apache2::Const::LOG_DEBUG, + APR::Const::EGENERAL, "log_serror test 2"); + ok t_cmp $logdiff->diff, + qr/$egeneral: log_serror test 2/, + '$s->log_serror(LOG_MARK, LOG_DEBUG, APR::Const::EGENERAL...)'; + if (APACHE24) { + $s->loglevel($orig_log_level); + } + } + + # log_rerror + t_server_log_error_is_expected(); + $r->log_rerror(Apache2::Log::LOG_MARK, Apache2::Const::LOG_CRIT, + APR::Const::ENOTIME, "log_rerror test"); + # can't match against the error string, since a locale may kick in + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:crit\] \[pid[^]]+\] .*?: \[[^]]+\] log_rerror test/, + '$r->log_rerror(LOG_MARK, LOG_CRIT, APR::Const::ENOTIME...)'; + } + else { + ok t_cmp $logdiff->diff, + qr/\[crit\] .*?: log_rerror test/, + '$r->log_rerror(LOG_MARK, LOG_CRIT, APR::Const::ENOTIME...)'; + } + + # log_error + { + t_server_log_error_is_expected(); + $r->log_error('$r->log_error test'); + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:error\] \[pid[^]]+\] \$r->log_error test/, + '$r->log_error(...)'; + } + else { + ok t_cmp $logdiff->diff, + qr/\[error\] \$r->log_error test/, + '$r->log_error(...)'; + } + + t_server_log_error_is_expected(); + $s->log_error('$s->log_error test'); + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:error\] \[pid[^]]+\] \$s->log_error test/, + '$s->log_error(...)'; + } + else { + ok t_cmp $logdiff->diff, + qr/\[error\] \$s->log_error test/, + '$s->log_error(...)'; + } + } + + # log_reason + { + t_server_log_error_is_expected(); + $r->log_reason('$r->log_reason test'); + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:error\] \[pid[^]]+\] access to.*failed.*reason: \$r->log_reason test/, + '$r->log_reason(msg)'; + } + else { + ok t_cmp $logdiff->diff, + qr/\[error\] access to.*failed.*reason: \$r->log_reason test/, + '$r->log_reason(msg)'; + } + + t_server_log_error_is_expected(); + $r->log_reason('$r->log_reason filename test','filename'); + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:error\] \[pid[^]]+\] access to filename failed.*\$r->log_reason filename test/, + '$r->log_reason(msg, filename)'; + } + else { + ok t_cmp $logdiff->diff, + qr/\[error\] access to filename failed.*\$r->log_reason filename test/, + '$r->log_reason(msg, filename)'; + } + } + + # XXX: at the moment we can't change loglevel after server startup + # in a threaded mpm environment + if (!Apache2::MPM->is_threaded) { + my $orig_log_level = $s->loglevel; + + $s->loglevel(Apache2::Const::LOG_INFO); + + if ($s->error_fname) { + #XXX: does not work under t/TEST -ssl + $slog->debug(sub { die "set loglevel no workie" }); + # ok t_cmp $logdiff->diff... + } + + t_server_log_warn_is_expected(); + $s->loglevel(Apache2::Const::LOG_DEBUG); + $slog->debug(sub { ok 1; "$package test done" }); + ok t_cmp $logdiff->diff, + qr/TestAPI::aplog test done/, + '$slog->debug(sub { })'; + + $s->loglevel($orig_log_level); + } + else { + ok 1; + ok 1; + } + + # notice() messages ignore the LogLevel value and always get + # logged by Apache design (unless error log is set to syslog) + if (!Apache2::MPM->is_threaded) { + my $orig_log_level = $s->loglevel; + + $r->server->loglevel(Apache2::Const::LOG_ERR); + my $ignore = $logdiff->diff; # reset fh + # notice < error + my $msg = "This message should appear with LogLevel=error!"; + $r->log->notice($msg); + ok t_cmp $logdiff->diff, + qr/[notice] .*? $msg/, + "notice() logs regardless of LogLevel"; + + $s->loglevel($orig_log_level); + } + else { + ok 1; + } + + + t_server_log_warn_is_expected(); + $s->warn('$s->warn test'); + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:warn\] \[pid[^]]+\] \$s->warn test/, + '$s->warn()'; + } + else { + ok t_cmp $logdiff->diff, + qr/\[warn\] \$s->warn test/, + '$s->warn()'; + } + + { + t_server_log_warn_is_expected(); + # this uses global server to get $s internally + Apache2::ServerRec::warn("Apache2::ServerRec::warn test"); + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:warn\] \[pid[^]]+\] Apache2::ServerRec::warn test/, + 'Apache2::ServerRec::warn() w/o Apache2::RequestUtil->request '; + } + else { + ok t_cmp $logdiff->diff, + qr/\[warn\] Apache2::ServerRec::warn test/, + 'Apache2::ServerRec::warn() w/o Apache2::RequestUtil->request '; + } + + Apache2::RequestUtil->request($r); + t_server_log_warn_is_expected(); + # this uses the global $r to get $s internally + Apache2::ServerRec::warn("Apache2::ServerRec::warn test"); + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:warn\] \[pid[^]]+\] Apache2::ServerRec::warn test/, + 'Apache2::ServerRec::warn() w/ Apache2::RequestUtil->request '; + } + else { + ok t_cmp $logdiff->diff, + qr/\[warn\] Apache2::ServerRec::warn test/, + 'Apache2::ServerRec::warn() w/ Apache2::RequestUtil->request '; + } + } + + t_server_log_warn_is_expected(); + warn "warn test"; + if (APACHE24) { + ok t_cmp $logdiff->diff, + qr/\[\w*:warn\] \[pid[^]]+\] warn test/, + 'overriden via export warn()'; + } + else { + ok t_cmp $logdiff->diff, + qr/\[warn\] warn test/, + 'overriden via export warn()'; + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/command.pm b/2_0_13/t/response/TestAPI/command.pm new file mode 100644 index 0000000..db32ea1 --- /dev/null +++ b/2_0_13/t/response/TestAPI/command.pm
@@ -0,0 +1,43 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::command; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Command (); +use Apache2::Module (); + +use Apache2::Const -compile => qw(OK ITERATE OR_ALL); + +sub handler { + my $r = shift; + + plan $r, tests => 6; + + my $mod_perl_module = Apache2::Module::find_linked_module('mod_perl.c'); + + ok $mod_perl_module; + + my $cmd = $mod_perl_module->cmds; + + ok defined $cmd; + + ok UNIVERSAL::isa($cmd, 'Apache2::Command'); + + while ($cmd) { + if ($cmd->name eq 'PerlResponseHandler') { + ok t_cmp($cmd->args_how, Apache2::Const::ITERATE, 'args_how'); + ok t_cmp($cmd->errmsg, qr/Subroutine name/, 'errmsg'); + ok t_cmp($cmd->req_override, Apache2::Const::OR_ALL, 'req_override'); + last; + } + $cmd = $cmd->next; + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/conn_rec.pm b/2_0_13/t/response/TestAPI/conn_rec.pm new file mode 100644 index 0000000..a561629 --- /dev/null +++ b/2_0_13/t/response/TestAPI/conn_rec.pm
@@ -0,0 +1,96 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::conn_rec; + +# this test module is only for testing fields in the conn_rec listed +# in apache_structures.map (but some fields are tested in other tests) + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use Apache2::Connection (); + +use Apache2::Const -compile => qw(OK CONN_CLOSE); + +use constant APACHE24 => have_min_apache_version('2.4.0'); + +sub handler { + my $r = shift; + + my $c = $r->connection; + + plan $r, tests => 16; + + ok $c; + + ok $c->pool->isa('APR::Pool'); + + ok $c->base_server->isa('Apache2::ServerRec'); + + ok $c->client_socket->isa('APR::Socket'); + + ok $c->local_addr->isa('APR::SockAddr'); + + if (APACHE24) { + ok $c->client_addr->isa('APR::SockAddr'); + + # client_ip + { + my $client_ip_org = $c->client_ip; + my $client_ip_new = "10.10.10.255"; + ok $client_ip_org; + + $c->client_ip($client_ip_new); + ok t_cmp $c->client_ip, $client_ip_new; + + # restore + $c->client_ip($client_ip_org); + ok t_cmp $c->client_ip, $client_ip_org; + } + } + else { + ok $c->remote_addr->isa('APR::SockAddr'); + # remote_ip + { + my $remote_ip_org = $c->remote_ip; + my $remote_ip_new = "10.10.10.255"; + ok $remote_ip_org; + + $c->remote_ip($remote_ip_new); + ok t_cmp $c->remote_ip, $remote_ip_new; + + + # restore + $c->remote_ip($remote_ip_org); + ok t_cmp $c->remote_ip, $remote_ip_org; + } + } + + ok $c->remote_host || 1; + + ok !$c->aborted; + + ok t_cmp($c->keepalive, + Apache2::Const::CONN_CLOSE, + "the client has issued a non-keepalive request"); + + ok $c->local_ip; + + ok $c->local_host || 1; + + t_debug "id ", ($c->id == 0 ? "zero" : $c->id); + ok $c->id || 1; + + ok $c->notes; + + # XXX: missing tests + # conn_config + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/conn_util.pm b/2_0_13/t/response/TestAPI/conn_util.pm new file mode 100644 index 0000000..b3e167f --- /dev/null +++ b/2_0_13/t/response/TestAPI/conn_util.pm
@@ -0,0 +1,38 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::conn_util; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use Apache2::Connection (); + +use Apache2::Const -compile => qw(OK REMOTE_HOST REMOTE_NAME + REMOTE_NOLOOKUP REMOTE_DOUBLE_REV); + +sub handler { + my $r = shift; + + my $c = $r->connection; + + plan $r, tests => 7; + + ok $c->get_remote_host() || 1; + + for (Apache2::Const::REMOTE_HOST, Apache2::Const::REMOTE_NAME, + Apache2::Const::REMOTE_NOLOOKUP, Apache2::Const::REMOTE_DOUBLE_REV) { + ok $c->get_remote_host($_) || 1; + } + + ok $c->get_remote_host(Apache2::Const::REMOTE_HOST, + $r->per_dir_config) || 1; + ok $c->get_remote_host(Apache2::Const::REMOTE_HOST, $r->per_dir_config) || 1; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/content_encoding.pm b/2_0_13/t/response/TestAPI/content_encoding.pm new file mode 100644 index 0000000..a405000 --- /dev/null +++ b/2_0_13/t/response/TestAPI/content_encoding.pm
@@ -0,0 +1,34 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::content_encoding; + +# tests: $r->content_encoding("gzip"); + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK DECLINED M_POST); + +sub handler { + my $r = shift; + + return Apache2::Const::DECLINED unless $r->method_number == Apache2::Const::M_POST; + + my $data = TestCommon::Utils::read_post($r); + + require Compress::Zlib; + + $r->content_type("text/plain"); + $r->content_encoding("gzip"); + + $r->print(Compress::Zlib::memGzip($data)); + + Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestAPI/custom_response.pm b/2_0_13/t/response/TestAPI/custom_response.pm new file mode 100644 index 0000000..b7dc429 --- /dev/null +++ b/2_0_13/t/response/TestAPI/custom_response.pm
@@ -0,0 +1,34 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::custom_response; + +# custom_response() doesn't alter the response code, but is used to +# replace the standard response body + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Response (); + +use Apache2::Const -compile => qw(FORBIDDEN); + +sub handler { + my $r = shift; + + my $how = $r->args || ''; + # warn "$how"; + # could be text or url + $r->custom_response(Apache2::Const::FORBIDDEN, $how); + + return Apache2::Const::FORBIDDEN; +} + +1; +__END__ +<NoAutoConfig> +<Location /TestAPI__custom_response> + AuthName dummy + AuthType none + PerlAccessHandler TestAPI::custom_response +</Location> +</NoAutoConfig> +
diff --git a/2_0_13/t/response/TestAPI/err_headers_out.pm b/2_0_13/t/response/TestAPI/err_headers_out.pm new file mode 100644 index 0000000..c8447ab --- /dev/null +++ b/2_0_13/t/response/TestAPI/err_headers_out.pm
@@ -0,0 +1,31 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::err_headers_out; + +# tests: $r->err_headers_out + +# when sending a non-2xx response one must use $r->err_headers_out to +# set extra headers + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use APR::Table (); + +use Apache2::Const -compile => qw(OK NOT_FOUND); + +sub handler { + my $r = shift; + + # this header will always make it to the client + $r->err_headers_out->add('X-err_headers_out' => "err_headers_out"); + + # this header will make it to the client only on 2xx response + $r->headers_out->add('X-headers_out' => "headers_out"); + + return $r->args eq "404" ? Apache2::Const::NOT_FOUND : Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestAPI/in_out_filters.pm b/2_0_13/t/response/TestAPI/in_out_filters.pm new file mode 100644 index 0000000..1bb03a2 --- /dev/null +++ b/2_0_13/t/response/TestAPI/in_out_filters.pm
@@ -0,0 +1,84 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::in_out_filters; + +# testing: $r->input_filters and $r->output_filters +# it's possible to read a POST data and send a response body w/o using +# $r->read/$r->print + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); + +use APR::Brigade (); +use APR::Bucket (); +use Apache2::Filter (); + +use Apache2::Const -compile => qw(OK M_POST DECLINED MODE_READBYTES); +use APR::Const -compile => qw(SUCCESS BLOCK_READ); + +use constant IOBUFSIZE => 8192; + +sub handler { + my $r = shift; + + return Apache2::Const::DECLINED unless $r->method_number == Apache2::Const::M_POST; + + $r->content_type("text/plain"); + + my $data = read_request_body($r); + send_response_body($r, lc($data)); + + Apache2::Const::OK; +} + +sub send_response_body { + my ($r, $data) = @_; + + my $bb = APR::Brigade->new($r->pool, + $r->connection->bucket_alloc); + + my $b = APR::Bucket->new($r->connection->bucket_alloc, $data); + $bb->insert_tail($b); + $r->output_filters->fflush($bb); + $bb->destroy; +} + +sub read_request_body { + my $r = shift; + + my $bb = APR::Brigade->new($r->pool, + $r->connection->bucket_alloc); + + my $data = ''; + my $seen_eos = 0; + my $count = 0; + do { + $r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES, + APR::Const::BLOCK_READ, IOBUFSIZE); + + $count++; + + for (my $b = $bb->first; $b; $b = $bb->next($b)) { + if ($b->is_eos) { + $seen_eos++; + last; + } + + if ($b->read(my $buf)) { + $data .= $buf; + } + + $b->delete; + } + + } while (!$seen_eos); + + $bb->destroy; + + return $data; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestAPI/internal_redirect.pm b/2_0_13/t/response/TestAPI/internal_redirect.pm new file mode 100644 index 0000000..1918f3b --- /dev/null +++ b/2_0_13/t/response/TestAPI/internal_redirect.pm
@@ -0,0 +1,66 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::internal_redirect; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache::TestTrace; + +use Apache2::Const -compile => 'OK'; + +sub modperl { + my $r = shift; + + my %args = map { split('=', $_, 2) } split /[&]/, $r->args; + if ($args{main}) { + # sub-req + $r->content_type('text/plain'); + debug "modperl: sub-req: response"; + $r->print("internal redirect: $args{main} => modperl"); + } + else { + # main-req + my $redirect_uri = $args{uri}; + debug "modperl: main-req => $redirect_uri?main=modperl"; + $r->internal_redirect("$redirect_uri?main=modperl"); + } + + Apache2::Const::OK; +} + +sub perl_script { + my $r = shift; + + my %args = map { split('=', $_, 2) } split /[&]/, $r->args; + if ($args{main}) { + # sub-req + $r->content_type('text/plain'); + debug "perl-script: sub-req: response"; + print "internal redirect: $args{main} => perl-script"; + } + else { + # main-req + my $redirect_uri = $args{uri}; + debug "perl-script: main-req => $redirect_uri?main=perl-script"; + $r->internal_redirect("$redirect_uri?main=perl-script"); + } + + Apache2::Const::OK; +} +1; +__DATA__ +<NoAutoConfig> + PerlModule TestAPI::internal_redirect + <Location /TestAPI__internal_redirect_modperl> + SetHandler modperl + PerlResponseHandler TestAPI::internal_redirect::modperl + </Location> + <Location /TestAPI__internal_redirect_perl_script> + SetHandler perl-script + PerlResponseHandler TestAPI::internal_redirect::perl_script + </Location> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/internal_redirect_handler.pm b/2_0_13/t/response/TestAPI/internal_redirect_handler.pm new file mode 100644 index 0000000..8bab332 --- /dev/null +++ b/2_0_13/t/response/TestAPI/internal_redirect_handler.pm
@@ -0,0 +1,39 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::internal_redirect_handler; + +# $r->internal_redirect_handler() is the same as +# $r->internal_redirect() but it uses the same content-type as the +# top-level handler + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache2::Const -compile => 'OK'; + +my $uri = '/' . Apache::TestRequest::module2path(__PACKAGE__); + +sub handler { + my $r = shift; + + my %args = map { split '=', $_, 2 } split /[&]/, $r->args; + if ($args{main}) { + # sub-req should see the same content-type as the top-level + my $ct = $r->content_type; + $r->content_type('text/plain'); + $r->print($ct); + } + else { + # main-req + $r->content_type($args{ct}); + $r->internal_redirect_handler("$uri?main=1"); + } + + Apache2::Const::OK; +} + +1; +__DATA__
diff --git a/2_0_13/t/response/TestAPI/lookup_misc.pm b/2_0_13/t/response/TestAPI/lookup_misc.pm new file mode 100644 index 0000000..57d39d3 --- /dev/null +++ b/2_0_13/t/response/TestAPI/lookup_misc.pm
@@ -0,0 +1,53 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::lookup_misc; + +# testing misc lookup_ methods. TestAPI::lookup_uri includes the tests +# for lookup_uri and for filters, which should be the same for all +# other lookup_ methods + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); +use Apache2::SubRequest (); +use Apache2::URI (); + +use Apache::TestTrace; + +use Apache2::Const -compile => 'OK'; + +my $uri = '/' . Apache::TestRequest::module2path(__PACKAGE__); + +sub handler { + my $r = shift; + + my %args = map { split '=', $_, 2 } split /;/, $r->args; + + if ($args{subreq} eq 'lookup_file') { + Apache2::URI::unescape_url($args{file}); + debug "lookup_file($args{file})"; + my $subr = $r->lookup_file($args{file}); + $subr->run; + } + elsif ($args{subreq} eq 'lookup_method_uri') { + debug "lookup_method_uri($args{uri})"; + my $subr = $r->lookup_method_uri("GET", $args{uri}); + $subr->run; + } + else { + $r->print("default"); + } + + + Apache2::Const::OK; +} + + +1; +__DATA__ +<Location /lookup_method_uri> + SetHandler modperl + PerlResponseHandler Apache::TestHandler::ok +</Location>
diff --git a/2_0_13/t/response/TestAPI/lookup_uri.pm b/2_0_13/t/response/TestAPI/lookup_uri.pm new file mode 100644 index 0000000..17fd9d2 --- /dev/null +++ b/2_0_13/t/response/TestAPI/lookup_uri.pm
@@ -0,0 +1,85 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::lookup_uri; + +# tests $r->lookup_uri and its work with filters + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Filter (); +use Apache2::SubRequest (); + +use Apache2::Const -compile => 'OK'; + +my $uri = '/' . Apache::TestRequest::module2path(__PACKAGE__); + +sub handler { + my $r = shift; + + my $args = $r->args || ''; + my %args = map { split '=', $_, 2 } split /;/, $args; + + if ($args{main}) { + $args =~ s/main=1;//; + $r->print($args); + } + else { + my $new_args = "$uri?main=1;$args"; + my $subr; + $args{filter} ||= ''; + if ($args{filter} eq 'first') { + # run all request filters + $subr = $r->lookup_uri($new_args, + $r->output_filters); + } + elsif ($args{filter} eq 'second') { + # run all request filters, but the top one + $subr = $r->lookup_uri($new_args, + $r->output_filters->next); + } + elsif ($args{filter} eq 'default') { + # run none of request filters + $subr = $r->lookup_uri($new_args); + } + elsif ($args{filter} eq 'none') { + # run none of request filters + $subr = $r->lookup_uri($new_args, + $r->proto_output_filters); + } + else { + die "no filter= argument was received"; + } + + $subr->run; + } + + Apache2::Const::OK; +} + +sub prefix_filter { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + $filter->print("pre+$buffer"); + } + + Apache2::Const::OK; +} + +sub suffix_filter { + my $filter = shift; + + while ($filter->read(my $buffer, 1024)) { + $filter->print("$buffer+suf"); + } + + Apache2::Const::OK; +} + +1; +__DATA__ +PerlModule TestAPI::lookup_uri +PerlOutputFilterHandler TestAPI::lookup_uri::prefix_filter +PerlOutputFilterHandler TestAPI::lookup_uri::suffix_filter
diff --git a/2_0_13/t/response/TestAPI/lookup_uri2.pm b/2_0_13/t/response/TestAPI/lookup_uri2.pm new file mode 100644 index 0000000..c167210 --- /dev/null +++ b/2_0_13/t/response/TestAPI/lookup_uri2.pm
@@ -0,0 +1,59 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::lookup_uri2; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::SubRequest (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); + +use Apache2::Const -compile => 'OK'; + +sub myplan { + my $r = shift; + + $r->puts("1..3\nok 1\n"); + + die "must indicate a sub-request" if $r->is_initial_req(); + + Apache2::Const::OK; +} + +sub ok3 { + my $r = shift; + + $r->puts("ok 3\n"); + + Apache2::Const::OK; +} + +sub subrequest { + my ($r, $sub) = @_; + (my $uri = join '::', __PACKAGE__, $sub) =~ s!::!__!g; + $r->lookup_uri($uri)->run; +} + +sub handler { + my $r = shift; + + subrequest($r, 'myplan'); + + $r->puts("ok 2\n"); + + subrequest($r, 'ok3'); + + Apache2::Const::OK; +} + +1; +__DATA__ +<Location /TestAPI__lookup_uri2__myplan> + SetHandler modperl + PerlResponseHandler TestAPI::lookup_uri2::myplan +</Location> + +<Location /TestAPI__lookup_uri2__ok3> + SetHandler modperl + PerlResponseHandler TestAPI::lookup_uri2::ok3 +</Location>
diff --git a/2_0_13/t/response/TestAPI/module.pm b/2_0_13/t/response/TestAPI/module.pm new file mode 100644 index 0000000..4d0754f --- /dev/null +++ b/2_0_13/t/response/TestAPI/module.pm
@@ -0,0 +1,98 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::module; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestConfig; +use Apache::TestUtil; +use Apache2::BuildConfig; + +use Apache2::Module (); +use DynaLoader (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $cfg = Apache::Test::config(); + + my $top_module = Apache2::Module::top_module(); + + my $module_count = 0; + for (my $modp = $top_module; $modp; $modp = $modp->next) { + $module_count++; + } + + my $tests = 12 + ( 5 * $module_count ); + + plan $r, tests => $tests; + + my $core = Apache2::Module::find_linked_module('core.c'); + ok defined $core && $core->name eq 'core.c'; + + #.c + ok t_cmp Apache2::Module::loaded('mod_perl.c'), 1, + "Apache2::Module::loaded('mod_perl.c')"; + + ok t_cmp Apache2::Module::loaded('Apache__Module_foo.c'), 0, + "Apache2::Module::loaded('Apache__Module_foo.c')"; + + #.so + { + my $build = Apache2::BuildConfig->new; + my $expect = $build->should_build_apache ? 0 : 1; + ok t_cmp Apache2::Module::loaded('mod_perl.so'), $expect, + "Apache2::Module::loaded('mod_perl.so')"; + } + + ok t_cmp Apache2::Module::loaded('Apache__Module__foo.so'), 0, + "Apache2::Module::loaded('Apache__Module_foo.so')"; + + #perl + { + ok t_cmp Apache2::Module::loaded('Apache2::Module'), 1, + "Apache2::Module::loaded('Apache2::Module')"; + + ok t_cmp Apache2::Module::loaded('Apache__Module_foo'), 0, + "Apache2::Module::loaded('Apache__Module_foo')"; + + # TestAPI::module::foo wasn't loaded but the stash exists + $TestAPI::module::foo::test = 1; + ok t_cmp Apache2::Module::loaded('TestAPI::module::foo'), 0, + "Apache2::Module::loaded('TestAPI::module::foo')"; + + # module TestAPI wasn't loaded but the stash exists, since + # TestAPI::module was loaded + ok t_cmp Apache2::Module::loaded('TestAPI'), 0, + "Apache2::Module::loaded('TestAPI')"; + } + + #bogus + ok t_cmp Apache2::Module::loaded('Apache__Module_foo.foo'), 0, + "Apache2::Module::loaded('Apache__Module_foo.foo')"; + + ok t_cmp Apache2::Module::loaded(''), 0, + "Apache2::Module::loaded('')"; + + ok t_cmp ref($top_module), 'Apache2::Module', 'top_module'; + + my $mmn_major = $cfg->{httpd_info}{MODULE_MAGIC_NUMBER_MAJOR}; + my $mmn_minor = $cfg->{httpd_info}{MODULE_MAGIC_NUMBER_MINOR}; + for (my $modp = $top_module; $modp; $modp = $modp->next) { + my $name = $modp->name; + ok $name; + t_debug("Testing module: " . $modp->name); + ok t_cmp $modp->ap_api_major_version, $mmn_major; + ok $modp->ap_api_minor_version <= $mmn_minor; + ok $modp->module_index >= 0; + my $cmds = $modp->cmds; + ok !defined($cmds) || ref($cmds) eq 'Apache2::Command'; + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/process.pm b/2_0_13/t/response/TestAPI/process.pm new file mode 100644 index 0000000..c137646 --- /dev/null +++ b/2_0_13/t/response/TestAPI/process.pm
@@ -0,0 +1,40 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::process; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::ServerRec (); +use Apache2::Process (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 4; + + my $s = $r->server; + my $proc = $s->process; + ok t_cmp(1, $proc->isa('Apache2::Process'), "isa('Apache2::Process')"); + + my $global_pool = $proc->pool; + ok t_cmp(1, $global_pool->isa('APR::Pool'), "pglob isa('APR::Pool')"); + + my $pconf = $proc->pconf; + ok t_cmp(1, $pconf->isa('APR::Pool'), "pconf isa('APR::Pool')"); + + my $proc_name = $proc->short_name; + t_debug($proc_name); + ok $proc_name; + + Apache2::Const::OK; +} + +1; + +__END__
diff --git a/2_0_13/t/response/TestAPI/query.pm b/2_0_13/t/response/TestAPI/query.pm new file mode 100644 index 0000000..78f1148 --- /dev/null +++ b/2_0_13/t/response/TestAPI/query.pm
@@ -0,0 +1,152 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::query; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use Apache2::MPM (); + +use Apache2::Const -compile => qw(OK :mpmq); + +sub handler { + + my $r = shift; + + plan $r, tests => 5; + + # ok, this isn't particularly pretty, but I can't think + # of a better way to do it + # all of these attributes I pulled right from the C sources + # so if, say, leader all of a sudden changes its properties, + # these tests will fail + + my $mpm = lc Apache2::MPM->show; + + if ($mpm eq 'prefork') { + + { + my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_THREADED); + + ok t_cmp($query, + Apache2::Const::MPMQ_NOT_SUPPORTED, + "MPMQ_IS_THREADED ($mpm)"); + + # is_threaded() is just a constsub set to the result from + # ap_mpm_query(AP_MPMQ_IS_THREADED) + + ok t_cmp($query, + Apache2::MPM->is_threaded, + "Apache2::MPM->is_threaded() equivalent to query(MPMQ_IS_THREADED)"); + + t_debug('Apache2::MPM->is_threaded returned ' . Apache2::MPM->is_threaded); + ok (! Apache2::MPM->is_threaded); + } + + { + my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_FORKED); + + ok t_cmp($query, + Apache2::Const::MPMQ_DYNAMIC, + "MPMQ_IS_FORKED ($mpm)"); + } + + } + elsif ($mpm eq 'worker') { + + { + my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_THREADED); + + ok t_cmp($query, + Apache2::Const::MPMQ_STATIC, + "MPMQ_IS_THREADED ($mpm)"); + + ok t_cmp($query, + Apache2::MPM->is_threaded, + "Apache2::MPM->is_threaded() equivalent to query(MPMQ_IS_THREADED)"); + + t_debug('Apache2::MPM->is_threaded returned ' . Apache2::MPM->is_threaded); + ok (Apache2::MPM->is_threaded); + } + + { + my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_FORKED); + + ok t_cmp($query, + Apache2::Const::MPMQ_DYNAMIC, + "MPMQ_IS_FORKED ($mpm)"); + } + } + elsif ($mpm eq 'leader') { + + { + my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_THREADED); + + ok t_cmp($query, + Apache2::Const::MPMQ_STATIC, + "MPMQ_IS_THREADED ($mpm)"); + + ok t_cmp($query, + Apache2::MPM->is_threaded, + "Apache2::MPM->is_threaded() equivalent to query(MPMQ_IS_THREADED)"); + + t_debug('Apache2::MPM->is_threaded returned ' . Apache2::MPM->is_threaded); + ok (Apache2::MPM->is_threaded); + } + + { + my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_FORKED); + + ok t_cmp($query, + Apache2::Const::MPMQ_DYNAMIC, + "MPMQ_IS_FORKED ($mpm)"); + } + } + elsif ($mpm eq 'winnt') { + + { + my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_THREADED); + + ok t_cmp($query, + Apache2::Const::MPMQ_STATIC, + "MPMQ_IS_THREADED ($mpm)"); + + ok t_cmp($query, + Apache2::MPM->is_threaded, + "Apache2::MPM->is_threaded() equivalent to query(MPMQ_IS_THREADED)"); + + t_debug('Apache2::MPM->is_threaded returned ' . Apache2::MPM->is_threaded); + ok (Apache2::MPM->is_threaded); + } + + { + my $query = Apache2::MPM->query(Apache2::Const::MPMQ_IS_FORKED); + + ok t_cmp($query, + Apache2::Const::MPMQ_NOT_SUPPORTED, + "MPMQ_IS_FORKED ($mpm)"); + } + } + else { + skip "skipping MPMQ_IS_THREADED test for $mpm MPM", 0; + skip "skipping Apache2::MPM->is_threaded equivalence test for $mpm MPM", 0; + skip "skipping MPMQ_IS_FORKED test for $mpm MPM", 0; + skip "skipping Apache2::MPM->is_threaded test for $mpm MPM", 0; + } + + # make sure that an undefined MPMQ constant yields undef + { + my $query = Apache2::MPM->query(72); + + ok t_cmp($query, + undef, + "unknown MPMQ value returns undef"); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/request_rec.pm b/2_0_13/t/response/TestAPI/request_rec.pm new file mode 100644 index 0000000..d5bfe52 --- /dev/null +++ b/2_0_13/t/response/TestAPI/request_rec.pm
@@ -0,0 +1,278 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::request_rec; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); + +use APR::Finfo (); +use APR::Pool (); + +use Apache2::Const -compile => qw(OK M_GET M_PUT); +use APR::Const -compile => qw(FINFO_SIZE); + +#this test module is only for testing fields in the request_rec +#listed in apache_structures.map +#XXX: GloabalRequest test should be moved elsewhere +# as should $| test + +sub handler { + my $r = shift; + + plan $r, tests => 55; + + #Apache2::RequestUtil->request($r); #PerlOptions +GlobalRequest takes care + my $gr = Apache2::RequestUtil->request; + + ok $$gr == $$r; + + my $newr = Apache2::RequestRec->new($r->connection, $r->pool); + Apache2::RequestUtil->request($newr); + $gr = Apache2::RequestUtil->request; + + ok $$gr == $$newr; + + Apache2::RequestUtil->request($r); + + ok $r->pool->isa('APR::Pool'); + + ok $r->connection->isa('Apache2::Connection'); + + ok $r->server->isa('Apache2::ServerRec'); + + for (qw(next prev main)) { + ok (! $r->$_()) || $r->$_()->isa('Apache2::RequestRec'); + } + + ok !$r->assbackwards; + + ok !$r->proxyreq; # see also TestModules::proxy + + ok !$r->header_only; + + ok $r->protocol =~ /http/i; + + # LWP >=6.00 uses HTTP/1.1, other HTTP/1.0 + ok t_cmp $r->proto_num, 1000+substr($r->the_request, -1), + 't->proto_num'; + + ok t_cmp lc($r->hostname), lc($r->get_server_name), '$r->hostname'; + + { + my $old_hostname = $r->hostname("other.hostname"); + ok t_cmp $r->hostname, "other.hostname", '$r->hostname rw'; + $r->hostname($old_hostname); + } + + ok $r->request_time; + + ok $r->status_line || 1; + + ok $r->status || 1; + + ok t_cmp $r->method, 'GET', '$r->method'; + + ok t_cmp $r->method_number, Apache2::Const::M_GET, '$r->method_number'; + + ok $r->headers_in; + + ok $r->headers_out; + + # tested in TestAPI::err_headers_out + ok $r->err_headers_out; + + ok $r->subprocess_env; + + ok $r->notes; + + ok $r->content_type; + + ok $r->handler; + + ok $r->ap_auth_type || 1; + + ok $r->no_cache || 1; + + ok !$r->no_local_copy; + + { + local $| = 0; + ok t_cmp $r->print("# buffered\n"), 11, "buffered print"; + ok t_cmp $r->print(), "0E0", "buffered print"; + + local $| = 1; + my $string = "# not buffered\n"; + ok t_cmp $r->print(split //, $string), length($string), + "unbuffered print"; + } + + # GET header components + { + my $args = "my_args=3"; + my $path_info = "/my_path_info"; + my $base_uri = "/TestAPI__request_rec"; + + ok t_cmp $r->unparsed_uri, "$base_uri$path_info?$args"; + + ok t_cmp $r->uri, "$base_uri$path_info", '$r->uri'; + + ok t_cmp $r->path_info, $path_info, '$r->path_info'; + + ok t_cmp $r->args, $args, '$r->args'; + + # LWP uses HTTP/1.1 since 6.00 + ok t_cmp $r->the_request, qr!GET + \x20 + \Q$base_uri$path_info\E\?\Q$args\E + \x20 + HTTP/1\.\d!x, + '$r->the_request'; + + { + my $new_request = "GET $base_uri$path_info?$args&foo=bar HTTP/1.0"; + my $old_request = $r->the_request($new_request); + ok t_cmp $r->the_request, $new_request, '$r->the_request rw'; + $r->the_request($old_request); + } + + ok $r->filename; + + my $location = '/' . Apache::TestRequest::module2path(__PACKAGE__); + ok t_cmp $r->location, $location, '$r->location'; + } + + # bytes_sent + { + $r->rflush; + my $sent = $r->bytes_sent; + t_debug "sent so far: $sent bytes"; + # at least 100 chars were sent already + ok $sent > 100; + } + + # mtime + { + my $mtime = (stat __FILE__)[9]; + $r->mtime($mtime); + ok t_cmp $r->mtime, $mtime, "mtime"; + } + + # finfo + { + my $size = (stat __FILE__)[7]; + my $finfo = APR::Finfo::stat(__FILE__, APR::Const::FINFO_SIZE, $r->pool); + $r->finfo($finfo); + # just one field test, all accessors are fully tested in + # TestAPR::finfo + ok t_cmp($r->finfo->size, + $size, + '$r->finfo'); + } + + # allowed + { + $r->allowed(1 << Apache2::Const::M_GET); + + ok $r->allowed & (1 << Apache2::Const::M_GET); + ok ! ($r->allowed & (1 << Apache2::Const::M_PUT)); + + $r->allowed($r->allowed | (1 << Apache2::Const::M_PUT)); + ok $r->allowed & (1 << Apache2::Const::M_PUT); + } + + # content_languages + { + my $def = [qw(fr)]; #default value + my $l = [qw(fr us cn)]; #new value + + if (have_module('mod_mime')) { + ok t_cmp $r->content_languages, $def, '$r->content_languages'; + } + else { + skip "Need mod_mime", 0; + } + + my $old = $r->content_languages($l); + if (have_module('mod_mime')) { + ok t_cmp $old, $def, '$r->content_languages'; + } + else { + skip "Need mod_mime", 0; + } + + ok t_cmp $r->content_languages, $l, '$r->content_languages'; + + eval { $r->content_languages({}) }; + ok t_cmp $@, qr/Not an array reference/, + '$r->content_languages(invalid)'; + } + + ### invalid $r + { + my $r = bless {}, "Apache2::RequestRec"; + my $err = q[method `uri' invoked by a `Apache2::RequestRec' ] . + q[object with no `r' key!]; + eval { $r->uri }; + ok t_cmp $@, qr/$err/, "invalid $r object"; + } + { + my $r = bless {}, "NonExisting"; + my $err = q[method `uri' invoked by a `NonExisting' ] . + q[object with no `r' key!]; + eval { Apache2::RequestRec::uri($r) }; + ok t_cmp $@, qr/$err/, "invalid $r object"; + } + { + my $r = {}; + my $err = q[method `uri' invoked by a `unknown' ] . + q[object with no `r' key!]; + eval { Apache2::RequestRec::uri($r) }; + ok t_cmp $@, qr/$err/, "invalid $r object"; + } + + # out-of-scope pools + { + my $newr = Apache2::RequestRec->new($r->connection, APR::Pool->new); + { + require APR::Table; + # try to overwrite the pool + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + } + # check if $newr is still OK + ok $newr->connection->isa('Apache2::Connection'); + } + + # tested in other tests + # - input_filters: TestAPI::in_out_filters + # - output_filters: TestAPI::in_out_filters + # - per_dir_config: in several other tests + # - content_encoding: TestAPI::content_encoding + # - user: TestHooks::authz / TestHooks::authen + + # XXX: untested + # - request_config + # - allowed_xmethods + # - allowed_methods + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +<Location /TestAPI__request_rec> + PerlOptions +GlobalRequest + <IfModule mod_mime.c> + DefaultLanguage fr + </IfModule> + SetHandler modperl + PerlResponseHandler TestAPI::request_rec +</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/request_subclass.pm b/2_0_13/t/response/TestAPI/request_subclass.pm new file mode 100644 index 0000000..1b76229 --- /dev/null +++ b/2_0_13/t/response/TestAPI/request_subclass.pm
@@ -0,0 +1,50 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::request_subclass; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +our @ISA = qw(Apache2::RequestRec); + +use Apache::Test; +use Apache::TestRequest; + +use Apache2::Const -compile => 'OK'; + +sub new { + my $class = shift; + my $r = shift; + bless { r => $r }, $class; +} + +my $location = '/' . Apache::TestRequest::module2path(__PACKAGE__); + +sub handler { + my $r = __PACKAGE__->new(shift); + + plan $r, tests => 5; + + eval { my $gr = Apache2::RequestUtil->request; }; + ok $@; + + ok $r->uri eq $location; + + ok ((bless { r => $r })->uri eq $location); #nested + + eval { (bless {})->uri }; + + ok $@ =~ /no .* key/; + + eval { (bless [])->uri }; + + ok $@ =~ /unsupported/; + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script +PerlOptions -GlobalRequest
diff --git a/2_0_13/t/response/TestAPI/request_util.pm b/2_0_13/t/response/TestAPI/request_util.pm new file mode 100644 index 0000000..2af76fe --- /dev/null +++ b/2_0_13/t/response/TestAPI/request_util.pm
@@ -0,0 +1,93 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::request_util; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestUtil (); +use Apache2::MPM (); +use Apache2::Log (); +use APR::Pool (); + +use Apache2::Const -compile => 'OK'; + +my %status_lines = ( + 200 => '200 OK', + 400 => '400 Bad Request', + 500 => '500 Internal Server Error', +); + +sub handler { + my $r = shift; + + plan $r, tests => (scalar keys %status_lines) + 11; + + # default_type() is gone as of httpd 2.3.2-dev + ok !defined(&Apache2::RequestRec::default_type) || $r->default_type; + + my $document_root = $r->document_root; + + ok $document_root; + + if (!Apache2::MPM->is_threaded) { + my $path_orig = my $path = '/tmp/foo'; + ok t_cmp($document_root, $r->document_root($path)); + # make sure that the new docroot string is copied internally, + # and later manipulations of the passed scalar don't affect it + $path .= "suffix"; + ok t_cmp($path_orig, $r->document_root($document_root)); + } + else { + eval { $r->document_root('/tmp/foo') }; + ok t_cmp($@, qr/Can't run.*in the threaded env/, + "document_root is read-only under threads"); + ok 1; + } + + ok $r->get_server_name; + + ok $r->get_server_port; + + ok $r->get_limit_req_body || 1; + + ok $r->is_initial_req; + + my $sig = $r->psignature("Here is the sig: "); + t_debug $sig; + ok $sig; + + my $pattern = + qr!(?s)GET /TestAPI__request_util.*Host:.*200 OK.*Content-Type:!; + + ok t_cmp($r->as_string, + $pattern, + "test for the request_line, host, status, and few " . + "headers that should always be there"); + + while (my ($code, $line) = each %status_lines) { + ok t_cmp(Apache2::RequestUtil::get_status_line($code), + $line, + "Apache2::RequestUtil::get_status_line($code)"); + } + + if (Apache2::MPM->is_threaded) { + eval { $r->child_terminate() }; + ok t_cmp($@, qr/Can't run.*in a threaded mpm/, "child_terminate"); + } + else { + t_server_log_error_is_expected(); + ok $r->child_terminate() || 1; + $r->pool->cleanup_register( + sub { + my $r = shift; + $r->log_error("Process $$ terminates itself\n"); + }, $r); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/response.pm b/2_0_13/t/response/TestAPI/response.pm new file mode 100644 index 0000000..352ced7 --- /dev/null +++ b/2_0_13/t/response/TestAPI/response.pm
@@ -0,0 +1,54 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::response; + +# testing Apache2::Response methods +# +# XXX: a proper test is needed (at the moment just test that methods +# can be invoked as documented) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::Response (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 7; + + my $etag = $r->make_etag(); + t_debug $etag; + ok $etag; + + $r->set_content_length(0); + + ok 1; + + ok $r->meets_conditions || 1; + + ok $r->rationalize_mtime(time) >= $r->request_time; + + my $mtime = (stat __FILE__)[9]; + + $r->update_mtime($mtime); + + ok $r->mtime == $mtime; + + ok $r->set_keepalive() || 1; + + $r->set_last_modified; + + # $r->custom_response() is tested in TestAPI::custom_response + + ok 1; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/rflush.pm b/2_0_13/t/response/TestAPI/rflush.pm new file mode 100644 index 0000000..41df75d --- /dev/null +++ b/2_0_13/t/response/TestAPI/rflush.pm
@@ -0,0 +1,79 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::rflush; + +use strict; +use warnings FATAL => 'all'; + +# this test verifies that rflush flushes bucket brigades + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Filter (); + +use Apache2::Const -compile => qw(OK); + +use constant READ_SIZE => 1024; + +sub bracket { + my $filter = shift; + + my $data = ''; + + while ($filter->read(my $buffer, 1024)) { + $data .= $buffer; + } + + $filter->print("[$data]") if $data; + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + + my $args = $r->args || ''; + if ($args eq 'nontied') { + # print is now unbuffered + local $| = 1; + $r->print("1"); # send the data in the buffer + flush bucket + $r->print("2"); # send the data in the buffer + flush bucket + + # print is now buffered + local $| = 0; + $r->print("3"); + $r->rflush; # send the data in the buffer + flush bucket + $r->print("4"); + $r->rflush; # send the data in the buffer + flush bucket + $r->print("5"); + $r->print("6"); # send the data in the buffer (end of handler) + } + elsif ($args eq 'tied') { + my $oldfh; + # print is now unbuffered ("rflush"-like functionality is + # called internally) + $oldfh = select(STDOUT); $| = 1; select($oldfh); + print "1"; # send the data in the buffer + flush bucket + print "2"; + + # print is now buffered + $oldfh = select(STDOUT); $| = 0; select($oldfh); + print "3"; + print "4"; + print "5"; + print "6"; # send the data in the buffer (end of handler) + } + + Apache2::Const::OK; +} +1; +__DATA__ +SetHandler perl-script +PerlModule TestAPI::rflush +PerlResponseHandler TestAPI::rflush::response +PerlOutputFilterHandler TestAPI::rflush::bracket
diff --git a/2_0_13/t/response/TestAPI/sendfile.pm b/2_0_13/t/response/TestAPI/sendfile.pm new file mode 100644 index 0000000..17f445a --- /dev/null +++ b/2_0_13/t/response/TestAPI/sendfile.pm
@@ -0,0 +1,49 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::sendfile; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use APR::Const -compile => 'SUCCESS'; +use Apache2::Const -compile => ':common'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + my $args = $r->args; + + if ($args eq 'withwrapper') { + # buffer output up, so we can test that sendfile flushes any + # buffered output before sending the file contents out + local $|; + $r->print("This is a header\n"); + $r->sendfile(__FILE__); + $r->print("This is a footer\n"); + } + elsif ($args eq 'offset') { + $r->sendfile(__FILE__, 3); + } + elsif ($args eq 'len') { + $r->sendfile(__FILE__, 3, 50); + } + elsif ($args eq 'noexist-n-nocheck.txt') { + eval { $r->sendfile($args) }; + return int $@; + } + else { + my $rc = $r->sendfile($args); + # warn APR::Error::strerror($rc); + return $rc unless $rc == APR::Const::SUCCESS; + } + + # XXX: can't quite test bogus offset and/or len, since ap_send_fd + # doesn't provide any error indications + + return Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/server_const.pm b/2_0_13/t/response/TestAPI/server_const.pm new file mode 100644 index 0000000..2e814ef --- /dev/null +++ b/2_0_13/t/response/TestAPI/server_const.pm
@@ -0,0 +1,61 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::server_const; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use File::Spec::Functions qw(canonpath); + +use Apache2::ServerUtil (); +use Apache2::Process (); + +use APR::Pool (); + +use Apache2::Const -compile => 'OK'; + +my $cfg = Apache::Test::config; + +my $root = $cfg->{vars}->{serverroot}; +my $built = $cfg->{httpd_info}->{BUILT}; +my $version = $cfg->{httpd_info}->{VERSION}; + +sub handler { + + my $r = shift; + + plan $r, tests => 6; + + # test Apache2::ServerUtil constant subroutines + + ok t_filepath_cmp(canonpath(Apache2::ServerUtil::server_root), + canonpath($root), + 'Apache2::ServerUtil::server_root()'); + + ok t_cmp(Apache2::ServerUtil::get_server_built, + $built, + 'Apache2::ServerUtil::get_server_built()'); + + my $server_descr = Apache2::ServerUtil::get_server_description; + ok t_cmp($server_descr, qr/^\Q$version\E/, + 'Apache2::ServerUtil::get_server_description()'); + + # added via $s->add_version_component in t/conf/modperl_extra.pl + ok t_cmp($server_descr, qr!\bworld domination series/2\.0\b!, + 'Apache2::ServerUtil::get_server_description() -- component'); + + # assuming ServerTokens Full (default) the banner equals description + ok t_cmp(Apache2::ServerUtil::get_server_banner, $server_descr, + 'Apache2::ServerUtil::get_server_banner()'); + + # version is just an alias for banner + ok t_cmp(Apache2::ServerUtil::get_server_version, $server_descr, + 'Apache2::ServerUtil::get_server_version()'); + + Apache2::Const::OK; +} + +1; + +__END__
diff --git a/2_0_13/t/response/TestAPI/server_rec.pm b/2_0_13/t/response/TestAPI/server_rec.pm new file mode 100644 index 0000000..7cd37fb --- /dev/null +++ b/2_0_13/t/response/TestAPI/server_rec.pm
@@ -0,0 +1,79 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::server_rec; + +# this test module is only for testing fields in the server_rec listed +# in apache_structures.map + +# XXX: This test needs to be mucho improved. currently it justs checks +# whether some value is set or not + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::ServerRec (); +use Apache2::ServerUtil (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $s = $r->server; + + plan $r, tests => 20; + + ok $s; + + ok $s->process; + + ok $s->next || 1; + + ok $s->server_admin; + + ok $s->server_hostname; + + ok $s->port || 1; + + ok $s->error_fname || 1; # vhost might not have its own (t/TEST -ssl) + + # XXX: error_log; + + ok $s->loglevel; + + ok $s->is_virtual || 1; + + # XXX: module_config + + # XXX: lookup_defaults + + ok $s->addrs; + + t_debug("timeout : ", $s->timeout); + ok $s->timeout; + + t_debug("keep_alive_timeout : ", $s->keep_alive_timeout); + ok $s->keep_alive_timeout || 1; + t_debug("keep_alive_max : ", $s->keep_alive_max); + ok $s->keep_alive_max || 1; + ok $s->keep_alive || 1; + + ok $s->path || 1; + + ok $s->names || 1; + + ok $s->wild_names || 1; + + ok $s->limit_req_line; + + ok $s->limit_req_fieldsize; + + ok $s->limit_req_fields; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/server_util.pm b/2_0_13/t/response/TestAPI/server_util.pm new file mode 100644 index 0000000..e7d3a05 --- /dev/null +++ b/2_0_13/t/response/TestAPI/server_util.pm
@@ -0,0 +1,139 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::server_util; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use File::Spec::Functions qw(canonpath catfile); + +use Apache2::RequestRec (); +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Process (); + +use APR::Pool (); + +use Apache2::Const -compile => 'OK'; + +my $serverroot = Apache::Test::config()->{vars}->{serverroot}; + +our @ISA = qw(Apache2::RequestRec); + +sub new { + my $class = shift; + my $r = shift; + bless { r => $r }, $class; +} + +sub handler { + my $r = shift; + + plan $r, tests => 17; + + { + my $s = $r->server; + my @expected = qw(ModPerl::Test::exit_handler TestExit::FromPerlModule::exit_handler); + my @handlers = + @{ $s->get_handlers('PerlChildExitHandler') || []}; + ok t_cmp(scalar(@handlers), scalar(@expected), "get_handlers"); + } + + t_debug('Apache2::ServerUtil::exists_config_define'); + ok Apache2::ServerUtil::exists_config_define('MODPERL2'); + ok ! Apache2::ServerUtil::exists_config_define('FOO'); + + t_debug('registering method FOO'); + ok $r->server->method_register('FOO'); + + server_root_relative_tests($r); + + eval { Apache2::ServerUtil::server_shutdown_cleanup_register( + sub { Apache2::Const::OK }); + }; + my $sub = "server_shutdown_cleanup_register"; + ok t_cmp $@, qr/Can't run '$sub' after server startup/, + "can't register server_shutdown cleanup after server startup"; + + # on start we get 1, and immediate restart gives 2 + ok t_cmp Apache2::ServerUtil::restart_count, 2, "restart count"; + + Apache2::Const::OK; +} + + +# 11 sub-tests +sub server_root_relative_tests { + my $r = shift; + + my %pools = ( + '$r->pool' => + $r->pool, + '$r->connection->pool' => + $r->connection->pool, + '$r->server->process->pool' => + $r->server->process->pool, + '$r->server->process->pconf' => + $r->server->process->pconf, + 'Apache2::ServerUtil->server->process->pconf' => + Apache2::ServerUtil->server->process->pconf, + 'APR::Pool->new' => + APR::Pool->new, + ); + + # syntax - an object or pool is required + t_debug("Apache2::ServerUtil::server_root_relative() died"); + eval { my $dir = Apache2::ServerUtil::server_root_relative() }; + t_debug("\$\@: $@"); + ok $@; + + foreach my $p (keys %pools) { + # we will leak memory here when calling the function with a + # pool whose life is longer than of $r, but it doesn't matter + # for the test + ok t_filepath_cmp( + canonpath(Apache2::ServerUtil::server_root_relative($pools{$p}, + 'conf')), + catfile($serverroot, 'conf'), + "Apache2::ServerUtil:::server_root_relative($p, 'conf')"); + } + + # syntax - unrecognized objects don't segfault + { + my $obj = bless {}, 'Apache2::Foo'; + eval { Apache2::ServerUtil::server_root_relative($obj, 'conf') }; + + ok t_cmp($@, + qr/p is not of type APR::Pool/, + "Apache2::ServerUtil::server_root_relative(\$obj, 'conf')"); + } + + # no file argument gives ServerRoot + { + my $server_root_relative = + Apache2::ServerUtil::server_root_relative($r->pool); + + ok t_filepath_cmp(canonpath($server_root_relative), + canonpath($serverroot), + 'server_root_relative($pool)'); + + # Apache2::ServerUtil::server_root is also the ServerRoot constant + ok t_filepath_cmp(canonpath(Apache2::ServerUtil::server_root), + canonpath($server_root_relative), + 'Apache2::ServerUtil::server_root'); + + } + + { + # absolute paths should resolve to themselves + my $dir1 = Apache2::ServerUtil::server_root_relative($r->pool, 'logs'); + my $dir2 = Apache2::ServerUtil::server_root_relative($r->pool, $dir1); + + ok t_filepath_cmp($dir1, $dir2, "absolute path"); + } +} + +1; + +__END__
diff --git a/2_0_13/t/response/TestAPI/show.pm b/2_0_13/t/response/TestAPI/show.pm new file mode 100644 index 0000000..aece5f0 --- /dev/null +++ b/2_0_13/t/response/TestAPI/show.pm
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::show; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::MPM (); +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 1; + + my $mpm = Apache::Test::config->{server}->{mpm}; + + ok t_cmp(Apache2::MPM->show(), + qr!$mpm!i, + 'Apache2::MPM->show()'); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/slurp_filename.pm b/2_0_13/t/response/TestAPI/slurp_filename.pm new file mode 100644 index 0000000..27bf236 --- /dev/null +++ b/2_0_13/t/response/TestAPI/slurp_filename.pm
@@ -0,0 +1,80 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::slurp_filename; + +# test slurp_filename()'s taintness options and that it works properly +# with utf8 data + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestUtil (); +use ModPerl::Util; + +use Apache2::Const -compile => 'OK'; + +my $expected = <<EOI; +English: Internet +Hebrew : \x{05D0}\x{05D9}\x{05E0}\x{05D8}\x{05E8}\x{05E0}\x{05D8} +EOI + +sub handler { + my $r = shift; + + plan $r, tests => 5, need 'mod_alias'; + + { + my $data = $r->slurp_filename(0); # untainted + my $received = eval $$data; + ok t_cmp($received, $expected, "slurp filename untainted"); + } + + { + my $data = $r->slurp_filename; # tainted + my $received = eval { eval $$data }; + ok t_cmp($@, qr/Insecure dependency in eval/, + "slurp filename tainted"); + + ModPerl::Util::untaint($$data); + $received = eval $$data; + ok t_cmp($received, $expected, "slurp filename untainted"); + } + + { + # just in case we will encounter some probs in the future, + # here is pure perl function for comparison + my $data = slurp_filename_perl($r); # tainted + my $received = eval { eval $$data }; + ok t_cmp($@, qr/Insecure dependency in eval/, + "slurp filename (perl) tainted"); + + ModPerl::Util::untaint($$data); + $received = eval $$data; + ok t_cmp($received, $expected, "slurp filename (perl) untainted"); + } + + Apache2::Const::OK; +} + +sub slurp_filename_perl { + my $r = shift; + open my $fh, $r->filename; + local $/; + my $data = <$fh>; + close $fh; + return \$data; +} + +1; +__END__ +<NoAutoConfig> + <IfModule mod_alias.c> + Alias /slurp/ @DocumentRoot@/api/ + </IfModule> + <Location /slurp/> + SetHandler modperl + PerlResponseHandler TestAPI::slurp_filename + </Location> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestAPI/status.pm b/2_0_13/t/response/TestAPI/status.pm new file mode 100644 index 0000000..b875a09 --- /dev/null +++ b/2_0_13/t/response/TestAPI/status.pm
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::status; + +# see the client for details + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Const -compile => 'OK'; + +my $body = "This is a response string"; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + my ($code, $string) = split /=/, $r->args || ''; + + if ($string) { + # status_line must be valid and match status + # or it is 'zapped' by httpd as of 2.2.1 + $r->status($code); + $r->status_line("$code $string"); + } + else { + $r->status($code); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPI/sub_request.pm b/2_0_13/t/response/TestAPI/sub_request.pm new file mode 100644 index 0000000..b5b55f0 --- /dev/null +++ b/2_0_13/t/response/TestAPI/sub_request.pm
@@ -0,0 +1,46 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::sub_request; + +# basic subrequest tests + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK SERVER_ERROR); + +my $uri = '/' . Apache::TestRequest::module2path(__PACKAGE__); + +sub handler { + my $r = shift; + + my $args = $r->args || ''; + return Apache2::Const::SERVER_ERROR if $args eq 'subreq'; + + plan $r, tests => 4; + + my $subr = $r->lookup_uri("$uri?subreq"); + ok $subr->isa('Apache2::SubRequest'); + + ok t_cmp $subr->uri, $uri, "uri"; + + my $rc = $subr->run; + ok t_cmp $rc, Apache2::Const::SERVER_ERROR, "rc"; + + # test an explicit DESTROY (which happens automatically on the + # scope exit) + undef $subr; + ok 1; + + Apache2::Const::OK; +} + +1; +__DATA__ +
diff --git a/2_0_13/t/response/TestAPI/uri.pm b/2_0_13/t/response/TestAPI/uri.pm new file mode 100644 index 0000000..87ff65d --- /dev/null +++ b/2_0_13/t/response/TestAPI/uri.pm
@@ -0,0 +1,188 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPI::uri; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use APR::Pool (); +use APR::URI (); +use Apache2::URI (); +use Apache2::RequestRec (); +use Apache2::RequestUtil (); + +use Apache2::Const -compile => 'OK'; + +my $location = '/' . Apache::TestRequest::module2path(__PACKAGE__); + +sub handler { + my $r = shift; + + plan $r, tests => 24; + + $r->args('query'); + + # basic + { + my $uri = $r->parsed_uri; + + ok $uri->isa('APR::URI'); + + ok t_cmp($uri->path, qr/^$location/, "path"); + + my $up = $uri->unparse; + ok t_cmp($up, qr/^$location/, "unparse"); + } + + # construct_server + { + my $server = $r->construct_server; + ok t_cmp(join(':', $r->get_server_name, $r->get_server_port), + $server, + "construct_server/get_server_name/get_server_port"); + } + { + my $hostname = "example.com"; + my $server = $r->construct_server($hostname); + ok t_cmp(join(':', $hostname, $r->get_server_port), + $server, + "construct_server($hostname)"); + } + { + my $hostname = "example.com"; + my $port = "9097"; + my $server = $r->construct_server($hostname, $port); + ok t_cmp(join(':', $hostname, $port), + $server, + "construct_server($hostname, $port)"); + + } + { + my $hostname = "example.com"; + my $port = "9097"; + my $server = $r->construct_server($hostname, $port, $r->pool->new); + ok t_cmp(join(':', $hostname, $port), + $server, + "construct_server($hostname, $port, new_pool)"); + + } + + # construct_url + { + # if no args are passed then only $r->uri will be included (no + # query and no fragment fields) + my $curl = $r->construct_url; + t_debug("construct_url: $curl"); + t_debug("r->uri: " . $r->uri); + my $parsed = APR::URI->parse($r->pool, $curl); + + ok $parsed->isa('APR::URI'); + + my $up = $parsed->unparse; + ok t_cmp($up, qr/$location/, "unparse"); + + my $path = '/foo/bar'; + + $parsed->path($path); + + ok t_cmp($parsed->path, $path, "parsed path"); + } + { + # this time include args in the constructed url + my $fragment = "fragment"; + $r->parsed_uri->fragment($fragment); + my $curl = $r->construct_url(sprintf "%s?%s", $r->uri, $r->args); + t_debug("construct_url: $curl"); + t_debug("r->uri: ", $r->uri); + my $parsed = APR::URI->parse($r->pool, $curl); + + my $up = $parsed->unparse; + ok t_cmp($up, qr/$location/, 'construct_url($uri)'); + ok t_cmp($parsed->query, $r->args, "args vs query"); + } + { + # this time include args and a pool object + my $curl = $r->construct_url(sprintf("%s?%s", $r->uri, $r->args), + $r->pool->new); + t_debug("construct_url: $curl"); + t_debug("r->uri: ", $r->uri); + my $up = APR::URI->parse($r->pool, $curl)->unparse; + ok t_cmp($up, qr/$location/, 'construct_url($uri, $pool)'); + } + + # segfault test + { + # test the segfault in apr < 0.9.2 (fixed on mod_perl side) + # passing only the /path + my $parsed = APR::URI->parse($r->pool, $r->uri); + # set hostname, but not the scheme + $parsed->hostname($r->get_server_name); + $parsed->port($r->get_server_port); + #$parsed->scheme('http'); + my $expected = $r->construct_url; + my $received = $parsed->unparse; + t_debug("the real received is: $received"); + # apr < 0.9.2-dev + fix in mpxs_apr_uri_unparse will return + # '://localhost.localdomain:8529/TestAPI::uri' + # apr >= 0.9.2 with internal fix will return + # '//localhost.localdomain:8529/TestAPI::uri' + # so in order to test pre-0.9.2 and post-0.9.2-dev we massage it + $expected =~ s|^http:||; + $received =~ s|^:||; + ok t_cmp($received, $expected, + "the bogus url is expected when 'hostname' is set " . + "but not 'scheme'"); + } + + # parse_uri + { + my $path = "/foo/bar"; + my $query = "query"; + my $fragment = "fragment"; + my $newr = Apache2::RequestRec->new($r->connection, $r->pool); + my $url_string = "$path?$query#$fragment"; + + # new request + $newr->parse_uri($url_string); + $newr->path_info('/bar'); + ok t_cmp($newr->uri, $path, "uri"); + ok t_cmp($newr->args, $query, "args"); + ok t_cmp($newr->path_info, '/bar', "path_info"); + + my $puri = $newr->parsed_uri; + ok t_cmp($puri->path, $path, "path"); + ok t_cmp($puri->query, $query, "query"); + ok t_cmp($puri->fragment, $fragment, "fragment"); + + #rpath + ok t_cmp($puri->rpath, '/foo', "rpath"); + + my $port = 6767; + $puri->port($port); + $puri->scheme('ftp'); + $puri->hostname('perl.apache.org'); + + ok t_cmp($puri->port, $port, "port"); + + ok t_cmp($puri->unparse, + "ftp://perl.apache.org:$port$path?$query#$fragment", + "unparse"); + } + + # unescape_url + { + my @c = qw(one two three); + my $url_string = join '%20', @c; + + Apache2::URI::unescape_url($url_string); + + ok $url_string eq "@c"; + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/base64.pm b/2_0_13/t/response/TestAPR/base64.pm new file mode 100644 index 0000000..9088fc0 --- /dev/null +++ b/2_0_13/t/response/TestAPR/base64.pm
@@ -0,0 +1,23 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::base64; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::base64; + +sub handler { + my $r = shift; + + my $num_of_tests = TestAPRlib::base64::num_of_tests(); + plan $r, tests => $num_of_tests; + + TestAPRlib::base64::test(); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/brigade.pm b/2_0_13/t/response/TestAPR/brigade.pm new file mode 100644 index 0000000..167592a --- /dev/null +++ b/2_0_13/t/response/TestAPR/brigade.pm
@@ -0,0 +1,107 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::brigade; + +# testing APR::Brigade in this tests. +# Other tests do that too: +# TestAPR::flatten : flatten() +# TestAPR::bucket : is_empty(), first(), last() + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use APR::Brigade (); + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::brigade; + +sub handler { + + my $r = shift; + my $ba = $r->connection->bucket_alloc; + + plan $r, tests => 14 + TestAPRlib::brigade::num_of_tests(); + + TestAPRlib::brigade::test(); + + # basic + pool + destroy + { + my $bb = APR::Brigade->new($r->pool, $ba); + + t_debug('$bb is defined'); + ok defined $bb; + + t_debug('$bb ISA APR::Brigade object'); + ok $bb->isa('APR::Brigade'); + + my $pool = $bb->pool; + + t_debug('$pool is defined'); + ok defined $pool; + + t_debug('$pool ISA APR::Pool object'); + ok $pool->isa('APR::Pool'); + + t_debug("destroy"); + $bb->destroy; + ok 1; + } + + # concat / split / length / flatten + { + my $bb1 = APR::Brigade->new($r->pool, $ba); + $bb1->insert_head(APR::Bucket->new($ba, "11")); + $bb1->insert_tail(APR::Bucket->new($ba, "12")); + + my $bb2 = APR::Brigade->new($r->pool, $ba); + $bb2->insert_head(APR::Bucket->new($ba, "21")); + $bb2->insert_tail(APR::Bucket->new($ba, "22")); + + # concat + $bb1->concat($bb2); + # bb1: 11, 12, 21, 22 + ok t_cmp($bb1->length, 8, "total data length in bb"); + my $len = $bb1->flatten(my $data); + ok t_cmp($len, 8, "bb flatten/len"); + ok t_cmp($data, "11122122", "bb flatten/data"); + t_debug('$bb2 is empty'); + ok $bb2->is_empty; + + # split + my $b = $bb1->first; # 11 + $b = $bb1->next($b); # 12 + my $bb3 = $bb1->split($b); + + # bb1: 11, bb3: 12, 21, 22 + $len = $bb1->flatten($data); + ok t_cmp($len, 2, "bb1 flatten/len"); + ok t_cmp($data, "11", "bb1 flatten/data"); + $len = $bb3->flatten($data); + ok t_cmp($len, 6, "bb3 flatten/len"); + ok t_cmp($data, "122122", "bb3 flatten/data"); + } + + # out-of-scope pools + { + my $bb1 = APR::Brigade->new(APR::Pool->new, $ba); + $bb1->insert_head(APR::Bucket->new($ba, "11")); + $bb1->insert_tail(APR::Bucket->new($ba, "12")); + + # try to overwrite the temp pool data + require APR::Table; + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + # now test that we are still OK + + my $len = $bb1->flatten(my $data); + ok t_cmp($data, "1112", "correct data"); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/bucket.pm b/2_0_13/t/response/TestAPR/bucket.pm new file mode 100644 index 0000000..6d85abf --- /dev/null +++ b/2_0_13/t/response/TestAPR/bucket.pm
@@ -0,0 +1,148 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::bucket; + +# a mix of APR::Brigade, APR::Bucket abd APR::BucketType tests + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use APR::Brigade (); +use APR::Bucket (); +use APR::BucketType (); +use Apache2::Connection (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::bucket; + +sub handler { + + my $r = shift; + + plan $r, tests => 20 + TestAPRlib::bucket::num_of_tests(); + + TestAPRlib::bucket::test(); + + my $ba = $r->connection->bucket_alloc; + + # eos_create / type / length + { + my $b = APR::Bucket::eos_create($ba); + my $type = $b->type; + ok t_cmp($type->name, 'EOS', "eos_create"); + + ok t_cmp($b->length, 0, "eos b->length"); + + # buckets with no data to read should return an empty string + my $rlen = $b->read(my $read); + ok t_cmp($read, "", 'eos b->read/buffer'); + ok t_cmp($rlen, 0, 'eos b->read/len'); + } + + # flush_create + { + my $b = APR::Bucket::flush_create($ba); + my $type = $b->type; + ok t_cmp($type->name, 'FLUSH', "flush_create"); + + ok t_cmp($b->length, 0, "flush b->length"); + } + + # insert_after / insert_before / is_eos / is_flush + { + my $d1 = APR::Bucket->new($ba, "d1"); + my $d2 = APR::Bucket->new($ba, "d2"); + my $f1 = APR::Bucket::flush_create($ba); + my $f2 = APR::Bucket::flush_create($ba); + my $e1 = APR::Bucket::eos_create($ba); + + ### create a chain of buckets + my $bb = APR::Brigade->new($r->pool, $ba); + + # head->tail + $bb->insert_head( $d1); # head->d1->tail + $d1->insert_after( $d2); # head->d1->d2->tail + $d2->insert_before($f1); # head->d1->f1->d2->tail + $d2->insert_after( $f2); # head->d1->f1->d2->f2->tail + $bb->insert_tail( $e1); # head->d1->f1->d2->f2->e1->tail + + ### now test + my $b = $bb->first; + $b->read(my $read); + ok t_cmp($read, "d1", "d1 bucket"); + + $b = $bb->next($b); + t_debug("is_flush"); + ok $b->is_flush; + + $b = $bb->next($b); + $b->read($read); + ok t_cmp($read, "d2", "d2 bucket"); + + $b = $bb->last(); + t_debug("is_eos"); + ok $b->is_eos; + + $b = $bb->prev($b); + t_debug("is_flush"); + ok $b->is_flush; + + t_debug("not empty"); + ok !$bb->is_empty; + + # delete all buckets from bb and test that it's empty + while (!$bb->is_empty) { + my $b = $bb->first; + $b->delete; + } + + t_debug("empty"); + ok $bb->is_empty; + } + + # check for non-existing buckets first/next/last + { + my $bb = APR::Brigade->new($r->pool, $ba); + + ok t_cmp($bb->first, undef, "no first bucket"); + ok t_cmp($bb->last, undef, "no last bucket"); + + ## now there is first + my $b = APR::Bucket->new($ba, "bbb"); + $bb->insert_head($b); + my $b_first = $bb->first; + $b->read(my $read); + ok t_cmp($read, "bbb", "first bucket"); + + # but there is no prev + ok t_cmp($bb->prev($b_first), undef, "no prev bucket"); + + # and no next + ok t_cmp($bb->next($b_first), undef, "no next bucket"); + } + + # delete+destroy + { + my $bb = APR::Brigade->new($r->pool, $ba); + $bb->insert_head(APR::Bucket->new($ba, "a")); + $bb->insert_head(APR::Bucket->new($ba, "b")); + + my $b1 = $bb->first; + $b1->remove; + $b1->destroy; + ok 1; + + # delete = remove + destroy + my $b2 = $bb->first; + $b2->delete; + ok 1; + } + + return Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/date.pm b/2_0_13/t/response/TestAPR/date.pm new file mode 100644 index 0000000..d427fbe --- /dev/null +++ b/2_0_13/t/response/TestAPR/date.pm
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::date; + +# testing APR::Date API + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::date; + +sub handler { + my $r = shift; + + my $num_of_tests = TestAPRlib::date::num_of_tests(); + plan $r, tests => $num_of_tests; + + TestAPRlib::date::test(); + + Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestAPR/finfo.pm b/2_0_13/t/response/TestAPR/finfo.pm new file mode 100644 index 0000000..49cf9df --- /dev/null +++ b/2_0_13/t/response/TestAPR/finfo.pm
@@ -0,0 +1,40 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::finfo; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use TestAPRlib::finfo; + +use APR::Finfo (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $tests = 1 + TestAPRlib::finfo::num_of_tests(); + plan $r, tests => $tests; + + { + my $finfo = $r->finfo; + my $isa = $finfo->isa('APR::Finfo'); + + t_debug "\$r->finfo $finfo"; + ok $isa; + } + + # a test assigning to $r->finfo is in TestAPI::request_rec + + TestAPRlib::finfo::test(); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/flatten.pm b/2_0_13/t/response/TestAPR/flatten.pm new file mode 100644 index 0000000..2246959 --- /dev/null +++ b/2_0_13/t/response/TestAPR/flatten.pm
@@ -0,0 +1,124 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::flatten; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use TestCommon::Utils; + +use Apache2::RequestRec (); +use APR::Bucket (); +use APR::Brigade (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + + my $r = shift; + + plan $r, tests => 26; + + # first, create a brigade + my $pool = $r->pool; + my $ba = $r->connection->bucket_alloc; + + my $bb = APR::Brigade->new($pool, $ba); + + # now, let's put several buckets in it + for (1 .. 10) { + my $data = 'x' x 20000; + my $bucket = APR::Bucket->new($ba, $data); + $bb->insert_tail($bucket); + } + + # ok, that's 10 buckets of 20,000 = 200,000 characters + ok t_cmp($bb->length, + 200000, + 'APR::Brigade::length()'); + + # syntax: require a $bb + eval { APR::Brigade::flatten("") }; + + ok t_cmp($@, + qr!usage: \$bb->flatten\(\$buf, \[\$wanted\]\)!, + 'APR::Brigade::flatten() requires a brigade'); + + # flatten() will slurp up the entire brigade + # equivalent to calling apr_brigade_pflatten + { + my $len = $bb->flatten(my $data); + + verify($len, 200000, $data, 1); + } + + # flatten(0) returns 0 bytes + { + my $len = $bb->flatten(my $data, 0); + + t_debug('$bb->flatten(0) returns a defined value'); + ok (defined $data); + + verify($len, 0, $data, 0); + } + + + # flatten($length) will return the first $length bytes + # equivalent to calling apr_brigade_flatten + { + # small + my $len = $bb->flatten(my $data, 30); + verify($len, 30, $data, 1); + } + + { + # large + my $len = $bb->flatten(my $data, 190000); + verify($len, 190000, $data, 1); + } + + { + # more than enough + my $len = $bb->flatten(my $data, 300000); + verify($len, 200000, $data, 1); + } + + # fetch from a brigade with no data in it + { + my $len = APR::Brigade->new($pool, $ba)->flatten(my $data); + + t_debug('empty brigade returns a defined value'); + ok (defined $data); + + verify($len, 0, $data, 0); + } + + Apache2::Const::OK; +} + +# this sub runs 3 sub-tests with a false $check_content +# and 4 otherwise +sub verify { + my ($len, $expected_len, $data, $check_content) = @_; + + ok t_cmp($len, + $expected_len, + "\$bb->flatten(\$data, $len) returned $len bytes"); + ok t_cmp(length($data), + $len, + "\$bb->flatten(\$data, $len) returned all expected data"); + + ok TestCommon::Utils::is_tainted($data); + + if ($check_content) { + # don't use t_cmp() here, else we get 200,000 characters + # to look at in verbose mode + t_debug("data all 'x' characters"); + ok ($data !~ m/[^x]/); + } + +} + + +1;
diff --git a/2_0_13/t/response/TestAPR/ipsubnet.pm b/2_0_13/t/response/TestAPR/ipsubnet.pm new file mode 100644 index 0000000..1aa3b2e --- /dev/null +++ b/2_0_13/t/response/TestAPR/ipsubnet.pm
@@ -0,0 +1,94 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::ipsubnet; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Connection (); +use Apache2::RequestRec (); +use APR::Pool (); +use APR::IpSubnet (); +use APR::SockAddr (); + +use Apache2::Const -compile => 'OK'; +use constant APACHE24 => have_min_apache_version('2.4.0'); + +sub handler { + my $r = shift; + my $c = $r->connection; + my $p = $r->pool; + + plan $r, tests => 8; + + my $ip = APACHE24 ? $c->client_ip : $c->remote_ip; + + ok $ip; + + if (APACHE24) { + ok t_cmp($c->client_addr->ip_get, $ip, + "client_ip eq client_addr->ip_get"); + } + else { + ok t_cmp($c->remote_addr->ip_get, $ip, + "remote_ip eq remote_addr->ip_get"); + } + + { + my $ipsub = APR::IpSubnet->new($p, $ip); + + ok $ipsub->test(APACHE24 ? $c->client_addr : $c->remote_addr); + } + + # use IP mask + { + my $ipsub = APR::IpSubnet->new($p, $ip, "255.0.0.0"); + + ok $ipsub->test(APACHE24 ? $c->client_addr : $c->remote_addr); + } + + # fail match + { + if ($ip =~ /^\d+\.\d+\.\d+\.\d+$/) { + # arrange for the subnet to match only one IP, which is + # one digit off the client IP, ensuring a mismatch + (my $mismatch = $ip) =~ s/(?<=\.)(\d+)$/$1 == 255 ? $1-1 : $1+1/e; + t_debug($mismatch); + my $ipsub = APR::IpSubnet->new($p, $mismatch, $mismatch); + ok ! $ipsub->test(APACHE24 ? $c->client_addr : $c->remote_addr); + } + else { + # XXX: similar ipv6 trick? + ok 1; + } + } + + # bogus IP + { + my $ipsub = eval { APR::IpSubnet->new($p, "345.234.678.987") }; + ok t_cmp($@, qr/The specified IP address is invalid/, "bogus IP"); + } + + # bogus mask + { + my $ipsub = eval { APR::IpSubnet->new($p, $ip, "255.0") }; + ok t_cmp($@, qr/The specified network mask is invalid/, "bogus mask"); + } + + # temp pool + { + my $ipsub = APR::IpSubnet->new(APR::Pool->new, $ip); + # try to overwrite the temp pool data + require APR::Table; + my $table = APR::Table::make(APR::Pool->new, 50); + $table->set($_ => $_) for 'aa'..'za'; + # now test that we are still OK + ok $ipsub->test(APACHE24 ? $c->client_addr : $c->remote_addr); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/os.pm b/2_0_13/t/response/TestAPR/os.pm new file mode 100644 index 0000000..0ecdafc --- /dev/null +++ b/2_0_13/t/response/TestAPR/os.pm
@@ -0,0 +1,31 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::os; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::MPM (); +use APR::OS (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 1; + + if (Apache2::MPM->is_threaded) { + my $tid = APR::OS::current_thread_id(); + ok t_cmp($tid, $tid, "current thread id: $tid / pid: $$"); + } + else { + ok t_cmp($$, $$, "current process id"); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/perlio.pm b/2_0_13/t/response/TestAPR/perlio.pm new file mode 100644 index 0000000..d2f4865 --- /dev/null +++ b/2_0_13/t/response/TestAPR/perlio.pm
@@ -0,0 +1,354 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::perlio; + +# to see what happens inside the io layer, assuming that you built +# mod_perl with MP_TRACE=1, run: +# env MOD_PERL_TRACE=o t/TEST -v -trace=debug apr/perlio + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Fcntl (); +use File::Spec::Functions qw(catfile); + +use Apache2::Const -compile => qw(OK CRLF); + +#XXX: APR::LARGE_FILES_CONFLICT constant? +#XXX: you can set to zero if largefile support is not enabled in Perl +use constant LARGE_FILES_CONFLICT => 1; + +# apr_file_dup has a bug on win32, +# should be fixed in apr 0.9.4 / httpd-2.0.48 +require Apache2::Build; +use constant APR_WIN32_FILE_DUP_BUG => + Apache2::Build::WIN32() && !have_min_apache_version('2.0.48'); + +sub handler { + my $r = shift; + + my $tests = 22; + $tests += 3 unless LARGE_FILES_CONFLICT; + $tests += 1 unless APR_WIN32_FILE_DUP_BUG; + + require APR::PerlIO; + plan $r, tests => $tests, + need { "This Perl build doesn't support PerlIO layers" => + APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED() }; + + my $vars = Apache::Test::config()->{vars}; + my $dir = catfile $vars->{documentroot}, "perlio"; + + t_mkdir($dir); + + my $sep = "-- sep --\n"; + my @lines = ("This is a test: $$\n", "test line --sep two\n"); + + my $expected = $lines[0]; + my $expected_all = join $sep, @lines; + + # write file + my $file = catfile $dir, "test"; + t_debug "open file $file for writing"; + my $foo = "bar"; + open my $fh, ">:APR", $file, $r->pool + or die "Cannot open $file for writing: $!"; + ok ref($fh) eq 'GLOB'; + + t_debug "write to a file:\n$expected\n"; + print $fh $expected_all; + close $fh; + + # open() failure test + { + # workaround for locale setups where the error message may be + # in a different language + open my $fh, "perlio_this_file_cannot_exist"; + my $errno_string = "$!"; + + # non-existent file + my $file = "/this/file/does/not/exist"; + if (open my $fh, "<:APR", $file, $r->pool) { + t_debug "must not be able to open $file!"; + ok 0; + close $fh; + } + else { + ok t_cmp("$!", + $errno_string, + "expected failure"); + } + } + + # seek/tell() tests + unless (LARGE_FILES_CONFLICT) { + open my $fh, "<:APR", $file, $r->pool + or die "Cannot open $file for reading: $!"; + + # read the whole file so we can test the buffer flushed + # correctly on seek. + my $dummy = join '', <$fh>; + + # Fcntl::SEEK_SET() + my $pos = 3; # rewinds after reading 6 chars above + seek $fh, $pos, Fcntl::SEEK_SET(); + my $got = tell($fh); + ok t_cmp($got, + $pos, + "seek/tell the file Fcntl::SEEK_SET"); + + # Fcntl::SEEK_CUR() + my $step = 10; + $pos = tell($fh) + $step; + seek $fh, $step, Fcntl::SEEK_CUR(); + $got = tell($fh); + ok t_cmp($got, + $pos, + "seek/tell the file Fcntl::SEEK_CUR"); + + # Fcntl::SEEK_END() + $pos = -s $file; + seek $fh, 0, Fcntl::SEEK_END(); + $got = tell($fh); + ok t_cmp($got, + $pos, + "seek/tell the file Fcntl::SEEK_END"); + + close $fh; + } + + # read() tests + { + open my $fh, "<:APR", $file, $r->pool + or die "Cannot open $file for reading: $!"; + + # basic open test + ok ref($fh) eq 'GLOB'; + + # basic single line read + ok t_cmp(scalar(<$fh>), + $expected, + "single line read"); + + # slurp mode + seek $fh, 0, Fcntl::SEEK_SET(); # rewind to the start + local $/; + + ok t_cmp(scalar(<$fh>), + $expected_all, + "slurp file"); + + # test ungetc (a long sep requires read ahead) + seek $fh, 0, Fcntl::SEEK_SET(); # rewind to the start + local $/ = $sep; + my @got_lines = <$fh>; + my @expect = ($lines[0] . $sep, $lines[1]); + ok t_cmp(\@got_lines, + \@expect, + "custom complex input record sep read"); + + close $fh; + } + + + # eof() tests + { + open my $fh, "<:APR", $file, $r->pool + or die "Cannot open $file for reading: $!"; + + ok t_cmp(0, + int eof($fh), # returns false, not 0 + "not end of file"); + # go to the end and read so eof will return 1 + seek $fh, 0, Fcntl::SEEK_END(); + my $received = <$fh>; + + t_debug($received); + + ok t_cmp(eof($fh), + 1, + "end of file"); + close $fh; + } + + # dup() test + { + open my $fh, "<:APR", $file, $r->pool + or die "Cannot open $file for reading: $!"; + + open my $dup_fh, "<&:APR", $fh + or die "Cannot dup $file for reading: $!"; + close $fh; + ok ref($dup_fh) eq 'GLOB'; + + my $received = <$dup_fh>; + + close $dup_fh; + unless (APR_WIN32_FILE_DUP_BUG) { + ok t_cmp($received, + $expected, + "read/write a dupped file"); + } + } + + # unbuffered write + { + open my $wfh, ">:APR", $file, $r->pool + or die "Cannot open $file for writing: $!"; + open my $rfh, "<:APR", $file, $r->pool + or die "Cannot open $file for reading: $!"; + + my $expected = "This is an un buffering write test"; + # unbuffer + my $oldfh = select($wfh); $| = 1; select($oldfh); + print $wfh $expected; # must be flushed to disk immediately + + ok t_cmp(scalar(<$rfh>), + $expected, + "file unbuffered write"); + + # buffer up + $oldfh = select($wfh); $| = 0; select($oldfh); + print $wfh $expected; # should be buffered up and not flushed + + ok t_cmp(scalar(<$rfh>), + undef, + "file buffered write"); + + close $wfh; + close $rfh; + + } + + # tests reading and writing text and binary files + { + for my $file ('MoonRise.jpeg', 'redrum.txt') { + my $in = catfile $dir, $file; + my $out = catfile $dir, "$file.out"; + my ($apr_content, $perl_content); + open my $rfh, "<:APR", $in, $r->pool + or die "Cannot open $in for reading: $!"; + { + local $/; + $apr_content = <$rfh>; + } + close $rfh; + open my $pfh, "<", $in + or die "Cannot open $in for reading: $!"; + binmode($pfh); + { + local $/; + $perl_content = <$pfh>; + } + close $pfh; + ok t_cmp(length $apr_content, + length $perl_content, + "testing data size of $file"); + + open my $wfh, ">:APR", $out, $r->pool + or die "Cannot open $out for writing: $!"; + print $wfh $apr_content; + close $wfh; + ok t_cmp(-s $out, + -s $in, + "testing file size of $file"); + unlink $out; + } + } + + # tests for various CRLF and utf-8 issues + { + my $scratch = catfile $dir, 'scratch.dat'; + my $text; + my $count = 2000; + open my $wfh, ">:crlf", $scratch + or die "Cannot open $scratch for writing: $!"; + print $wfh 'a' . ((('a' x 14) . "\n") x $count); + close $wfh; + open my $rfh, "<:APR", $scratch, $r->pool + or die "Cannot open $scratch for reading: $!"; + { + local $/; + $text = <$rfh>; + } + close $rfh; + ok t_cmp(count_chars($text, Apache2::Const::CRLF), + $count, + 'testing for presence of \015\012'); + ok t_cmp(count_chars($text, "\n"), + $count, + 'testing for presence of \n'); + + open $wfh, ">:APR", $scratch, $r->pool + or die "Cannot open $scratch for writing: $!"; + print $wfh 'a' . ((('a' x 14) . Apache2::Const::CRLF) x $count); + close $wfh; + open $rfh, "<:APR", $scratch, $r->pool + or die "Cannot open $scratch for reading: $!"; + { + local $/; + $text = <$rfh>; + } + close $rfh; + ok t_cmp(count_chars($text, Apache2::Const::CRLF), + $count, + 'testing for presence of \015\012'); + ok t_cmp(count_chars($text, "\n"), + $count, + 'testing for presence of \n'); + open $rfh, "<:crlf", $scratch + or die "Cannot open $scratch for reading: $!"; + { + local $/; + $text = <$rfh>; + } + close $rfh; + ok t_cmp(count_chars($text, Apache2::Const::CRLF), + 0, + 'testing for presence of \015\012'); + ok t_cmp(count_chars($text, "\n"), + $count, + 'testing for presence of \n'); + + my $utf8 = "\x{042F} \x{0432}\x{0430}\x{0441} \x{043B}\x{044E}"; + open $wfh, ">:APR", $scratch, $r->pool + or die "Cannot open $scratch for writing: $!"; + binmode($wfh, ':utf8'); + print $wfh $utf8; + close $wfh; + open $rfh, "<:APR", $scratch, $r->pool + or die "Cannot open $scratch for reading: $!"; + binmode($rfh, ':utf8'); + { + local $/; + $text = <$rfh>; + } + close $rfh; + ok t_cmp($text, + $utf8, + 'utf8 binmode test'); + unlink $scratch; + } + + # XXX: need tests + # - for stdin/out/err as they are handled specially + + # XXX: tmpfile is missing: + # consider to use 5.8's syntax: + # open $fh, "+>", undef; + + # cleanup: t_mkdir will remove the whole tree including the file + + Apache2::Const::OK; +} + +sub count_chars { + my ($text, $chars) = @_; + my $seen = 0; + $seen++ while $text =~ /$chars/g; + return $seen; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/pool.pm b/2_0_13/t/response/TestAPR/pool.pm new file mode 100644 index 0000000..1b04974 --- /dev/null +++ b/2_0_13/t/response/TestAPR/pool.pm
@@ -0,0 +1,78 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::pool; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use Apache2::RequestRec (); +use APR::Pool (); +use APR::Table (); + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::pool; + +sub handler { + my $r = shift; + + plan $r, tests => 4 + TestAPRlib::pool::num_of_tests(); + + ### native pools ### + + # explicit destroy shouldn't destroy native pools + { + my $p = $r->pool; + + my $count = TestAPRlib::pool::ancestry_count($p); + t_debug "\$r->pool has 2 or more ancestors (found $count)"; + ok $count >= 2; + + $p->cleanup_register(\&set_cleanup, [$r, 'native destroy']); + + $p->destroy; + + my @notes = $r->notes->get('cleanup'); + + ok t_cmp(scalar(@notes), 0, "should be 0 notes"); + + $r->notes->clear; + } + + + # implicit DESTROY shouldn't destroy native pools + { + { + my $p = $r->pool; + + my $count = TestAPRlib::pool::ancestry_count($p); + t_debug "\$r->pool has 2 or more ancestors (found $count)"; + ok $count >= 2; + + $p->cleanup_register(\&set_cleanup, [$r, 'native scoped']); + } + + my @notes = $r->notes->get('cleanup'); + + ok t_cmp(scalar(@notes), 0, "should be 0 notes"); + + $r->notes->clear; + } + + TestAPRlib::pool::test(); + + Apache2::Const::OK; +} + +sub set_cleanup { + my $arg = shift; + debug "setting cleanup note: $arg->[1]"; + $arg->[0]->notes->set(cleanup => $arg->[1]); + 1; +} + + +1;
diff --git a/2_0_13/t/response/TestAPR/pool_lifetime.pm b/2_0_13/t/response/TestAPR/pool_lifetime.pm new file mode 100644 index 0000000..8ac97ac --- /dev/null +++ b/2_0_13/t/response/TestAPR/pool_lifetime.pm
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::pool_lifetime; + +# this test verifies that if the perl pool object exceeds the +# life-span of the underlying pool struct we don't get segfaults + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Const -compile => 'OK'; + +my $pool; + +sub handler { + my $r = shift; + + $r->print("Pong"); + $pool = $r->pool; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/sockaddr.pm b/2_0_13/t/response/TestAPR/sockaddr.pm new file mode 100644 index 0000000..0b45937 --- /dev/null +++ b/2_0_13/t/response/TestAPR/sockaddr.pm
@@ -0,0 +1,43 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::sockaddr; + +# testing APR::SockAddr API + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Connection (); +use Apache2::RequestRec (); +use APR::SockAddr (); + +use Apache2::Const -compile => 'OK'; +use constant APACHE24 => have_min_apache_version('2.4.0'); + +sub handler { + my $r = shift; + my $c = $r->connection; + + plan $r, tests => 4; + + my $local = $c->local_addr; + my $remote = APACHE24 ? $c->client_addr : $c->remote_addr; + + ok t_cmp($local->ip_get, $c->local_ip, "local ip"); + if (APACHE24) { + ok t_cmp($remote->ip_get, $c->client_ip, "client ip"); + } + else { + ok t_cmp($remote->ip_get, $c->remote_ip, "remote ip"); + } + + $r->subprocess_env; + ok t_cmp($local->port, $ENV{SERVER_PORT}, "local port"); + ok t_cmp($remote->port, $ENV{REMOTE_PORT}, "remote port"); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/socket.pm b/2_0_13/t/response/TestAPR/socket.pm new file mode 100644 index 0000000..abbc192 --- /dev/null +++ b/2_0_13/t/response/TestAPR/socket.pm
@@ -0,0 +1,53 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::socket; + +# more tests in t/protocol/TestProtocol/echo_*.pm + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::Connection (); +use APR::Socket (); + +use Apache2::Const -compile => 'OK'; +use APR::Const -compile => 'EMISMATCH'; + +sub handler { + my $r = shift; + + my $tests = 5; + + plan $r, tests => $tests; + + my $c = $r->connection; + my $socket = $c->client_socket; + + ok $socket; + + # in microseconds + my $orig_val = $socket->timeout_get(); + t_debug "orig timeout was: $orig_val"; + ok $orig_val; + + my $new_val = 30_000_000; # 30 secs + $socket->timeout_set($new_val); + ok t_cmp($socket->timeout_get(), $new_val, "timeout_get()"); + + # reset the timeout + $socket->timeout_set($orig_val); + ok t_cmp($socket->timeout_get(), $orig_val, "timeout_get()"); + + skip $^O=~/mswin/i ? 'APR::Socket->fileno is not implemented on MSWin' : '', + sub { + t_debug "client socket fd=".$socket->fileno; + $socket->fileno>0 + }; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/status.pm b/2_0_13/t/response/TestAPR/status.pm new file mode 100644 index 0000000..b38b7dd --- /dev/null +++ b/2_0_13/t/response/TestAPR/status.pm
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::status; + +# Testing APR::Status + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::status; + +sub handler { + my $r = shift; + + my $num_of_tests = TestAPRlib::status::num_of_tests(); + plan $r, tests => $num_of_tests; + + TestAPRlib::status::test(); + + Apache2::Const::OK; +} + + + +1;
diff --git a/2_0_13/t/response/TestAPR/string.pm b/2_0_13/t/response/TestAPR/string.pm new file mode 100644 index 0000000..61b41f6 --- /dev/null +++ b/2_0_13/t/response/TestAPR/string.pm
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::string; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +require TestAPRlib::string; + +sub handler { + my $r = shift; + + my $num_of_tests = TestAPRlib::string::num_of_tests(); + plan $r, tests => $num_of_tests; + + TestAPRlib::string::test(); + + Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestAPR/table.pm b/2_0_13/t/response/TestAPR/table.pm new file mode 100644 index 0000000..abe452c --- /dev/null +++ b/2_0_13/t/response/TestAPR/table.pm
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::table; + +# testing APR::Table API + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::table; + +sub handler { + my $r = shift; + + my $tests = TestAPRlib::table::num_of_tests(); + plan $r, tests => $tests; + + TestAPRlib::table::test(); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/threadmutex.pm b/2_0_13/t/response/TestAPR/threadmutex.pm new file mode 100644 index 0000000..e1df238 --- /dev/null +++ b/2_0_13/t/response/TestAPR/threadmutex.pm
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::threadmutex; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::threadmutex; + +sub handler { + my $r = shift; + + my $tests = TestAPRlib::threadmutex::num_of_tests(); + plan $r, tests => $tests, need_threads; + + TestAPRlib::threadmutex::test(); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/threadrwlock.pm b/2_0_13/t/response/TestAPR/threadrwlock.pm new file mode 100644 index 0000000..a6ff19f --- /dev/null +++ b/2_0_13/t/response/TestAPR/threadrwlock.pm
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::threadrwlock; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::threadrwlock; + +sub handler { + my $r = shift; + + my $tests = TestAPRlib::threadrwlock::num_of_tests(); + plan $r, tests => $tests, need_threads; + + TestAPRlib::threadrwlock::test(); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/uri.pm b/2_0_13/t/response/TestAPR/uri.pm new file mode 100644 index 0000000..89b8471 --- /dev/null +++ b/2_0_13/t/response/TestAPR/uri.pm
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::uri; + +# Testing APR::URI (more tests in TestAPI::uri) + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::uri; + +sub handler { + my $r = shift; + + my $num_of_tests = TestAPRlib::uri::num_of_tests(); + plan $r, tests => $num_of_tests; + + TestAPRlib::uri::test(); + + Apache2::Const::OK; +} + + + +1;
diff --git a/2_0_13/t/response/TestAPR/util.pm b/2_0_13/t/response/TestAPR/util.pm new file mode 100644 index 0000000..19ccfc7 --- /dev/null +++ b/2_0_13/t/response/TestAPR/util.pm
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::util; + +# test APR::Util + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +use TestAPRlib::util; + +sub handler { + my $r = shift; + + my $num_of_tests = TestAPRlib::util::num_of_tests(); + plan $r, tests => $num_of_tests; + + TestAPRlib::util::test(); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestAPR/uuid.pm b/2_0_13/t/response/TestAPR/uuid.pm new file mode 100644 index 0000000..97e81f3 --- /dev/null +++ b/2_0_13/t/response/TestAPR/uuid.pm
@@ -0,0 +1,23 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestAPR::uuid; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use TestAPRlib::uuid; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => TestAPRlib::uuid::num_of_tests(); + + TestAPRlib::uuid::test(); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestApache/cgihandler.pm b/2_0_13/t/response/TestApache/cgihandler.pm new file mode 100644 index 0000000..be4f2cc --- /dev/null +++ b/2_0_13/t/response/TestApache/cgihandler.pm
@@ -0,0 +1,46 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::cgihandler; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use APR::Table (); + +use Apache2::Const -compile => qw(OK M_POST); + +#test the 1.x style perl-script handler + +sub handler { + my $r = shift; + + $ENV{FOO} = 2; + + if ($r->method_number == Apache2::Const::M_POST) { + my $cl = $r->headers_in->get('content-length'); + my $buff; +#XXX: working around a bug in ithreads Perl +#that would cause modules/cgi #3 to fail +# read STDIN, $buff, $cl; + read 'STDIN', $buff, $cl; + print $buff; + } + else { + print "1..3\n"; + print "ok 1\n", "ok ", "$ENV{FOO}\n"; +#XXX: current implementation of tie %ENV to $r->subprocess_env +# is not threadsafe +# my $foo = $r->subprocess_env->get('FOO'); + my $foo = $ENV{FOO}; + $foo++; + print "ok $foo\n"; + } + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script +PerlResponseHandler TestApache::cgihandler +
diff --git a/2_0_13/t/response/TestApache/conftree.pm b/2_0_13/t/response/TestApache/conftree.pm new file mode 100644 index 0000000..af13a6e --- /dev/null +++ b/2_0_13/t/response/TestApache/conftree.pm
@@ -0,0 +1,114 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::conftree; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestConfig (); + +use Apache2::Directive (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $cfg = Apache::Test::config(); + + my $node_count = node_count(); + + plan $r, tests => 8 + (5*$node_count); + + ok $cfg; + + my $vars = $cfg->{vars}; + + ok $vars; + + my $tree = Apache2::Directive::conftree(); + + ok $tree; + + my $hostname_lookups = $tree->lookup('HostnameLookups'); + + ok t_cmp($hostname_lookups, "Off"); + + my $documentroot = $tree->lookup('DocumentRoot'); + + ok t_cmp(ref($tree->as_hash()), 'HASH', 'as_hash'); + + ok t_cmp($documentroot, qq("$vars->{documentroot}")); + + ok t_cmp($tree->lookup("DocumentRoot"), qq("$vars->{documentroot}")); + + #XXX: This test isn't so good, but its quite problematic to try + #and _really_ compare $cfg and $tree... + { + my %vhosts = map { + $cfg->{vhosts}{$_}{name} => { %{$cfg->{vhosts}{$_}}, index => $_ } + } keys %{$cfg->{vhosts}}; + + for my $v (keys %vhosts) { + $vhosts{ $vhosts{$v}{index} } = $vhosts{$v}; + } + + my $vhost_failed; + for my $vhost ($tree->lookup("VirtualHost")) { + unless (exists $vhosts{$vhost->{'ServerName'} + || $vhost->{'PerlProcessConnectionHandler'}}) { + $vhost_failed++; + } + } + + ok !$vhost_failed; + } + + traverse_tree ( \&test_node ); + + Apache2::Const::OK; +} + +sub test_node { + my ($data, $node) = @_; + ok $node->directive; + #Args can be null for argless directives + ok $node->args || 1; + #As string can be null for containers + ok $node->as_string || 1; + ok $node->filename; + ok $node->line_num; +} + +sub traverse_tree { + my ($sub, $data) = @_; + my $node = Apache2::Directive::conftree(); + while ($node) { + $sub->($data, $node); + if (my $kid = $node->first_child) { + $node = $kid; + } + elsif (my $next = $node->next) { + $node = $next; + } + else { + if (my $parent = $node->parent) { + $node = $parent->next; + } + else { + $node = undef; + } + } + } + return; +} + +sub node_count { + my $node_count = 0; + + traverse_tree( sub { ${$_[0]}++ }, \$node_count ); + + return $node_count; +} +1;
diff --git a/2_0_13/t/response/TestApache/content_length_header.pm b/2_0_13/t/response/TestApache/content_length_header.pm new file mode 100644 index 0000000..acdca06 --- /dev/null +++ b/2_0_13/t/response/TestApache/content_length_header.pm
@@ -0,0 +1,42 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::content_length_header; + +# see the client t/apache/content_length_header.t for the comments + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Response (); + +use Apache2::Const -compile => 'OK'; + +my $body = "This is a response string"; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + my $args = $r->args || ''; + + if ($args =~ /set_content_length/) { + $r->set_content_length(length $body); + } + + if ($args =~ /send_body/) { + $r->print($body); + } + + if ($args =~ /head_no_body/) { + if ($r->header_only) { + # see #2 in the discussion in the client + $r->rflush; + } + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestApache/daemon.pm b/2_0_13/t/response/TestApache/daemon.pm new file mode 100644 index 0000000..c0ae342 --- /dev/null +++ b/2_0_13/t/response/TestApache/daemon.pm
@@ -0,0 +1,40 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::daemon; + +# Apache2::ServerUtil tests + +use strict; +use warnings FATAL => 'all'; + +use Apache2::ServerUtil (); + +use Apache::TestConfig (); +use Apache::TestUtil; +use Apache::Test; + +use constant WIN32 => Apache::TestConfig::WIN32; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 2; + + my $user_id = Apache2::ServerUtil->user_id; + my $user_id_expected = WIN32 ? 0 : $<; + + ok t_cmp $user_id, $user_id_expected, "user id"; + + my $group_id = Apache2::ServerUtil->group_id; + my ($group_id_expected) = WIN32 ? 0 : ($( =~ /^(\d+)/); + + ok t_cmp $group_id, $group_id_expected, "group id"; + + Apache2::Const::OK; +} + +1; + +__END__ +
diff --git a/2_0_13/t/response/TestApache/discard_rbody.pm b/2_0_13/t/response/TestApache/discard_rbody.pm new file mode 100644 index 0000000..27475e1 --- /dev/null +++ b/2_0_13/t/response/TestApache/discard_rbody.pm
@@ -0,0 +1,58 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::discard_rbody; + +# test $r->discard_request_body when the input body wasn't read at +# all, read partially or completely. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Connection (); +use Apache2::Filter (); +use APR::Brigade (); +use APR::Error (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => qw(OK MODE_READBYTES); +use APR::Const -compile => qw(SUCCESS BLOCK_READ); + +use constant IOBUFSIZE => 8192; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + my $test = $r->args; + + if ($test eq 'none') { + # don't read the request body + } + elsif ($test eq 'partial') { + # read some of request POSTed data (IOBUFSIZE bytes), + # but not all of it + my $filters = $r->input_filters(); + my $ba = $r->connection->bucket_alloc; + my $bb = APR::Brigade->new($r->pool, $ba); + $filters->get_brigade($bb, Apache2::Const::MODE_READBYTES, + APR::Const::BLOCK_READ, IOBUFSIZE); + } + elsif ($test eq 'all') { + # consume all of the request body + my $data = TestCommon::Utils::read_post($r); + die "failed to consume all the data" unless length($data) == 100000; + } + + # now get rid of the rest of the input data should work, no matter + # how little or how much of the body was read + my $rc = $r->discard_request_body; + die APR::Error::strerror($rc) unless $rc == Apache2::Const::OK; + + $r->print($test); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestApache/post.pm b/2_0_13/t/response/TestApache/post.pm new file mode 100644 index 0000000..40527eb --- /dev/null +++ b/2_0_13/t/response/TestApache/post.pm
@@ -0,0 +1,25 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::post; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + $r->content_type('text/plain'); + + my $data = TestCommon::Utils::read_post($r) || ""; + + $r->puts(join ':', length($data), $data); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestApache/read.pm b/2_0_13/t/response/TestApache/read.pm new file mode 100644 index 0000000..8b90c99 --- /dev/null +++ b/2_0_13/t/response/TestApache/read.pm
@@ -0,0 +1,47 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::read; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use TestCommon::Utils; + +use Apache2::Const -compile => 'OK'; + +use constant BUFSIZ => 512; #small for testing + +sub handler { + my $r = shift; + $r->content_type('text/plain'); + + my $cl = $r->headers_in->get('content-length'); + my $buffer = ""; + my $bufsiz = $r->args || BUFSIZ; + + my $offset = 0; + while (my $remain = $cl - $offset) { + my $len = $remain >= $bufsiz ? $bufsiz : $remain; + my $read = $r->read($buffer, $len, $offset); + if ($read != $len) { + die "read only ${read}b, while ${len}b were requested\n"; + } + last unless $read > 0; + $offset += $read; + } + + die "read() has returned untainted data:" + unless TestCommon::Utils::is_tainted($buffer); + + # make sure we dont block after all data is read + my $n = $r->read(my $x, BUFSIZ); + die unless $n == 0; + + $r->puts($buffer); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestApache/read2.pm b/2_0_13/t/response/TestApache/read2.pm new file mode 100644 index 0000000..4cf7348 --- /dev/null +++ b/2_0_13/t/response/TestApache/read2.pm
@@ -0,0 +1,42 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::read2; + +# extra tests in addition to TestApache::read + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +my $expected = "foobar"; + +sub handler { + my $r = shift; + + # test the case where the buffer to be filled has set magic + # attached. which is the case when one passes an non-existing hash + # entry value. it's not autovivified when passed to the function + # and it's not undef. running SetMAGIC inside read accomplishes + # the autovivication in this particular case. + my $data; + my $len = $r->read($data->{buffer}, $r->headers_in->{'Content-Length'}); + + # only print the plan out after reading to avoid chances of a deadlock + # see http://mail-archives.apache.org/mod_mbox/perl-dev/201408.mbox/%3C20140809104131.GA3670@estella.local.invalid%3E + plan $r, tests => 1; + + ok t_cmp($data->{buffer}, + $expected, + "reading into an autovivified hash entry"); + + Apache2::Const::OK; +} +1; +
diff --git a/2_0_13/t/response/TestApache/read3.pm b/2_0_13/t/response/TestApache/read3.pm new file mode 100644 index 0000000..b1522d5 --- /dev/null +++ b/2_0_13/t/response/TestApache/read3.pm
@@ -0,0 +1,41 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::read3; + +# extra tests in addition to TestApache::read + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +my $expected = "foobar"x2000; + +sub handler { + my $r = shift; + + # test to read data up to end of file is signaled + my $data = ''; + my $where = 0; + my $len; + do { + $len = $r->read($data, 100, $where); + $where += $len; + } while ($len > 0); + + # only print the plan out after reading to avoid chances of a deadlock + # see http://mail-archives.apache.org/mod_mbox/perl-dev/201408.mbox/%3C20140809104131.GA3670@estella.local.invalid%3E + plan $r, tests => 1; + + ok t_cmp($data, $expected, "reading up to end of file"); + + Apache2::Const::OK; +} +1; +
diff --git a/2_0_13/t/response/TestApache/read4.pm b/2_0_13/t/response/TestApache/read4.pm new file mode 100644 index 0000000..2b8f327 --- /dev/null +++ b/2_0_13/t/response/TestApache/read4.pm
@@ -0,0 +1,116 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::read4; + +# extra tests in addition to TestApache::read + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +my @expected = ("123foo", + "123456".("\0"x(1000-length("123456")))."bar", + "123f", + "23f\0\0o", + qr/\bread-?only\b/, + $^V, + "ARo", + qr/\bread-?only\b/, + ".........", + # Reading into $1 (the test above) eats up input since perl + # 5.10. This was also the version that blessed $^V as a + # "version" object. + (ref $^V ? "\0\0ar" : "\0\0bar"), + "12", + ""); + +sub X::TIESCALAR {bless []=>'X'} +sub X::FETCH {$_[0]->[0]} +sub X::STORE {$_[0]->[0]=$_[1]} + +sub handler { + my $r = shift; + + plan $r, tests => 12; + my $test = 0; + + # we get the string "foobarfoobar" as input here + + # this test consumes 3 bytes + my $data = 12345; + $r->read($data, 3, -2); + ok t_cmp($data, $expected[$test++], "negative offset"); + + + # "barfoobar" still to be read + $data = 123456; + # now $data is a valid IV but has a PV buffer assigned. + # read() has to convert to a valid PV. + $r->read($data, 3, 1000); + ok t_cmp($data, $expected[$test++], "offset > length of string"); + + + # "foobar" still to be read + $r->read($data, 1, 3); + ok t_cmp($data, $expected[$test++], "shrink string"); + + + # "oobar" still to be read + substr($data, 0, 1) = ''; # set the OOK flag (PV starts at offset 1) + $r->read($data, 1, 5); + ok t_cmp($data, $expected[$test++], "PV with OOK flag set"); + + + # "obar" still to be read + # this test dies BEFORE reading anything + eval {$r->read($^V, 1)}; + ok t_cmp($@, $expected[$test++], "read-only \$^V"); + ok t_cmp($^V, $expected[$test++], "\$^V untouched"); + + + # "obar" still to be read + $data=[]; + eval {$r->read($data, 1, 2)}; + ok t_cmp($data, $expected[$test++], "passing an RV as data"); + + + # "bar" still to be read + # this test consumes the "b" although it should not + "........."=~/(.*)/; + eval {$r->read($1, 1)}; + my $x="$1"; # just in case + ok t_cmp($@, $expected[$test++], "read-only \$1"); + ok t_cmp($x, $expected[$test++], "\$1 untouched"); + + + # "ar" still to be read + # now eat up the rest of input + tie $data, 'X'; + $data=''; + $r->read($data, 100, 2); + ok t_cmp(tied($data)->[0], $expected[$test++], "read into a tied buffer"); + + untie $data; + + + # input is empty + $data=123456; + $r->read($data, 1000, 2); + ok t_cmp($data, $expected[$test++], "read at eof"); + + + # input is empty + $r->read($data, 1000); + ok t_cmp($data, $expected[$test++], "repeated read at eof"); + + Apache2::Const::OK; +} +1; +
diff --git a/2_0_13/t/response/TestApache/scanhdrs.pm b/2_0_13/t/response/TestApache/scanhdrs.pm new file mode 100644 index 0000000..00e3050 --- /dev/null +++ b/2_0_13/t/response/TestApache/scanhdrs.pm
@@ -0,0 +1,31 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::scanhdrs; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::compat (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + print "Status: 200 Bottles of beer on the wall\n"; + print 'X-Perl-Module', ': ', __PACKAGE__; + print "\r\n"; + print "Content-type: text/test-"; + print "output\n"; + print "\n"; + + print "ok 1\n"; + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script +PerlOptions +ParseHeaders
diff --git a/2_0_13/t/response/TestApache/scanhdrs2.pm b/2_0_13/t/response/TestApache/scanhdrs2.pm new file mode 100644 index 0000000..7327941 --- /dev/null +++ b/2_0_13/t/response/TestApache/scanhdrs2.pm
@@ -0,0 +1,24 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::scanhdrs2; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $location = $r->args; + + print "Location: $location\n\n"; + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script +PerlOptions +ParseHeaders
diff --git a/2_0_13/t/response/TestApache/send_cgi_header.pm b/2_0_13/t/response/TestApache/send_cgi_header.pm new file mode 100644 index 0000000..9738038 --- /dev/null +++ b/2_0_13/t/response/TestApache/send_cgi_header.pm
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::send_cgi_header; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Response (); + +use Apache2::Const -compile => qw(OK); + +sub handler { + my $r = shift; + + # at the same time test the \0 binary at the beginning of the data + my $response = <<EOF; +Content-type: text/plain +X-Foo: X-Bar +Set-Cookie: Bad Programmer, No cookie! + +\000\000This not the end of the world\000\000 +EOF + + # bah, we can send the header and the response here + # don't tell anybody + $r->send_cgi_header($response); + + Apache2::Const::OK; +} + +1; +__END__ +# this should work regardless whether parse headers is on or off +PerlOptions -ParseHeaders
diff --git a/2_0_13/t/response/TestApache/subprocess.pm b/2_0_13/t/response/TestApache/subprocess.pm new file mode 100644 index 0000000..c6bc3bb --- /dev/null +++ b/2_0_13/t/response/TestApache/subprocess.pm
@@ -0,0 +1,180 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::subprocess; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache2::Build; + +use File::Spec::Functions qw(catfile catdir); +use IO::Select (); + +use Apache2::Const -compile => 'OK'; + +use Config; + +my $perl = Apache2::Build->build_config()->perl_config('perlpath'); + +my %scripts = ( + argv => 'print STDOUT "@ARGV";', + env => 'print STDOUT $ENV{SubProcess}', + in_out => 'print STDOUT scalar <STDIN>;', + in_err => 'print STDERR scalar <STDIN>;', + ); + +sub APACHE_TEST_CONFIGURE { + my ($class, $self) = @_; + + my $vars = $self->{vars}; + + my $target_dir = catdir $vars->{documentroot}, "util"; + + while (my ($file, $code) = each %scripts) { + $file = catfile $target_dir, "$file.pl"; + $self->write_perlscript($file, "$code\n"); + } +} + +sub handler { + my $r = shift; + + my $cfg = Apache::Test::config(); + my $vars = $cfg->{vars}; + + plan $r, tests => 5, need qw(APR::PerlIO Apache2::SubProcess); + + my $target_dir = catfile $vars->{documentroot}, "util"; + + { + # test: passing argv + void context + my $script = catfile $target_dir, "argv.pl"; + my @argv = qw(foo bar); + $r->spawn_proc_prog($perl, [$script, @argv]); + # can't really test if something is still returned since it + # will be no longer void context + ok 1; + } + + { + # test: passing argv + scalar context + my $script = catfile $target_dir, "argv.pl"; + my @argv = qw(foo bar); + my $out_fh = $r->spawn_proc_prog($perl, [$script, @argv]); + my $output = read_data($out_fh); + ok t_cmp([split / /, $output], + \@argv, + "passing ARGV" + ); + } + + { + # test: passing env to subprocess through subprocess_env + my $script = catfile $target_dir, "env.pl"; + my $value = "my cool proc"; + $r->subprocess_env->set(SubProcess => $value); + my $out_fh = $r->spawn_proc_prog($perl, [$script]); + my $output = read_data($out_fh); + ok t_cmp($output, + $value, + "passing env via subprocess_env" + ); + } + + { + # test: subproc's stdin -> stdout + list context + my $script = catfile $target_dir, "in_out.pl"; + my $value = "my cool proc\r\n"; # must have \n for <IN> + my ($in_fh, $out_fh, $err_fh) = + $r->spawn_proc_prog($perl, [$script]); + print $in_fh $value; + (my $output = read_data($out_fh)) =~ s/[\r\n]{1,2}/\r\n/; + ok t_cmp($output, + $value, + "testing subproc's stdin -> stdout + list context" + ); + } + + { + # test: subproc's stdin -> stderr + list context + my $script = catfile $target_dir, "in_err.pl"; + my $value = "my stderr\r\n"; # must have \n for <IN> + my ($in_fh, $out_fh, $err_fh) = + $r->spawn_proc_prog($perl, [$script]); + print $in_fh $value; + (my $output = read_data($err_fh)) =~ s/[\r\n]{1,2}/\r\n/; + ok t_cmp($output, + $value, + "testing subproc's stdin -> stderr + list context" + ); + } + +# could test send_fd($out), send_fd($err), but currently it's only in +# compat.pm. + +# these are wannabe's +# ok t_cmp( +# Apache2::SubProcess::spawn_proc_sub($r, $sub, \@args), +# Apache2::SUCCESS, +# "spawn a subprocess and run a subroutine in it" +# ); + +# ok t_cmp( +# Apache2::SubProcess::spawn_thread_prog($r, $command, \@argv), +# Apache2::SUCCESS, +# "spawn thread and run a program in it" +# ); + +# ok t_cmp( +# Apache2::SubProcess::spawn_thread_sub($r, $sub, \@args), +# Apache2::SUCCESS, +# "spawn thread and run a subroutine in it" +# ); + + Apache2::Const::OK; +} + + + +sub read_data { + my ($fh) = @_; + my @data = (); + my $sel = IO::Select->new($fh); + + # here is the catch: + # + # non-PerlIO pipe fh needs to select if the other end is not fast + # enough to send the data, since the read is non-blocking + # + # PerlIO-based pipe fh on the other hand does the select + # internally via apr_wait_for_io_or_timeout() in + # apr_file_read() (on *nix, but not on Win32). + # But you cannot call select() on the + # PerlIO-based, because its fileno() returns (-1), remember that + # apr_file_t is an opaque object, and on certain platforms + # fileno() is different from unix + # + # so we use the following wrapper: if we are under perlio we just + # go ahead and read the data, but with a short sleep first on Win32; + # if we are under non-perlio we first + # select for a few secs. (XXX: is 10 secs enough?) + # + # btw: we use perlIO only for perl 5.7+ + # + if (APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED() || $sel->can_read(10)) { + sleep(1) if $^O eq 'MSWin32' && APR::PerlIO::PERLIO_LAYERS_ARE_ENABLED(); + @data = wantarray ? (<$fh>) : <$fh>; + } + + if (wantarray) { + return @data; + } + else { + return defined $data[0] ? $data[0] : ''; + } +} + +1; + +
diff --git a/2_0_13/t/response/TestApache/util.pm b/2_0_13/t/response/TestApache/util.pm new file mode 100644 index 0000000..da61e38 --- /dev/null +++ b/2_0_13/t/response/TestApache/util.pm
@@ -0,0 +1,128 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::util; + +# Apache2::Util tests + +use strict; +use warnings FATAL => 'all'; + +# to fully test this test the following locale settings need to be run: +# +# some /^en_/ locale, e.g. /^en_GB* +# LC_CTYPE=en_GB.UTF-8 LC_TIME=en_GB.UTF-8 t/TEST -verbose apache/util.t +# LC_CTYPE=en_GB LC_TIME=en_GB t/TEST -verbose apache/util.t +# +# some non-/^en_/ locale, e.g. ru_RU +# LC_CTYPE=ru_RU.UTF-8 LC_TIME=ru_RU.UTF-8 t/TEST -verbose apache/util.t +# LC_CTYPE=ru_RU LC_TIME=ru_RU t/TEST -verbose apache/util.t + +# regex matching (LC_CTYPE) of strftime-like (LC_TIME) strings +use locale; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Util (); +use APR::Date (); + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +# those are passed via PerlPassEnv +my $locale = $ENV{LC_TIME} || ''; + +my $parse_time_ok = $locale =~ /^en_/ ? 1 : 0; +my $locale_is_utf8 = $locale =~ /UTF-8$/ ? 1 : 0; + +sub handler { + my $r = shift; + + plan $r, tests => 8; + + # ht_time + { + my $time = time; + my $fmt = "%a, %d %b %Y %H:%M:%S %Z"; + my $fmtdate; + + $fmtdate = Apache2::Util::ht_time($r->pool); + time_cmp($fmtdate, $time, + 'Apache2::Util::ht_time($pool)', 0); + + $fmtdate = Apache2::Util::ht_time($r->pool, $time); + time_cmp($fmtdate, $time, + 'Apache2::Util::ht_time($pool, $time)', 1); + + $fmtdate = Apache2::Util::ht_time($r->pool, $time, $fmt); + time_cmp($fmtdate, $time, + 'Apache2::Util::ht_time($pool, $time, $fmt)', 1); + + my $gmt = 0; + $fmtdate = Apache2::Util::ht_time($r->pool, $time, $fmt, $gmt); + time_cmp($fmtdate, $time, + 'Apache2::Util::ht_time($pool, $time, $fmt, $gmt)', 0); + } + + # escape_path + { + my ($uri, $received, $expected); + + $uri = "a 'long' file?.html"; + ($expected = $uri) =~ s/([\s?;])/sprintf "%%%x", ord $1/ge; + + $received = Apache2::Util::escape_path($uri, $r->pool); + ok t_cmp $received, $expected, + "Apache2::Util::escape_path / partial=1 / default"; + + $received = Apache2::Util::escape_path($uri, $r->pool, 1); + ok t_cmp $received, $expected, + "Apache2::Util::escape_path / partial=1 / explicit"; + + $received = Apache2::Util::escape_path($uri, $r->pool, 0); + ok t_cmp $received, $expected, + "Apache2::Util::escape_path / partial=0"; + + $uri = "a 'long' file?.html:"; + ($expected = $uri) =~ s/([\s?;])/sprintf "%%%x", ord $1/ge; + # XXX: why does it prepend ./ only if it sees : or :/? + $expected = "./$expected"; + + $received = Apache2::Util::escape_path($uri, $r->pool, 0); + ok t_cmp $received, $expected, + "Apache2::Util::escape_path / partial=0 / ./ prefix "; + + } + + Apache2::Const::OK; +} + +my $fmtdate_re = qr/^\w+, \d\d \w+ \d\d\d\d \d\d:\d\d:\d\d/; +sub time_cmp { + my ($fmtdate, $time, $comment, $exact_match) = @_; + + if ($parse_time_ok && $exact_match) { + my $ptime = APR::Date::parse_http($fmtdate); + t_debug "fmtdate: $fmtdate"; + ok t_cmp $ptime, $time, $comment; + } + else { + if ($locale_is_utf8) { + if (have_min_perl_version(5.008)) { + require Encode; + # perl doesn't know yet that $fmtdate is a utf8 string + $fmtdate = Encode::decode_utf8($fmtdate); + } + else { + skip "Skip locale $locale needs perl 5.8.0+", 0; + return; + } + } + ok t_cmp $fmtdate, $fmtdate_re, $comment; + } +} + +1; + +__END__ +
diff --git a/2_0_13/t/response/TestApache/write.pm b/2_0_13/t/response/TestApache/write.pm new file mode 100644 index 0000000..ebb7553 --- /dev/null +++ b/2_0_13/t/response/TestApache/write.pm
@@ -0,0 +1,31 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestApache::write; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Const -compile => 'OK'; + +use constant BUFSIZ => 512; #small for testing + +sub handler { + my $r = shift; + $r->content_type('text/plain'); + + $r->write("1..2"); + $r->write("\n", 1); + + my $ok = "ok 1\n"; + $r->write($ok, 2); + $r->write($ok, -1, 2); + + $ok = "not ok 2\n"; + $r->write($ok, 5, 4); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestCompat/apache.pm b/2_0_13/t/response/TestCompat/apache.pm new file mode 100644 index 0000000..9202916 --- /dev/null +++ b/2_0_13/t/response/TestCompat/apache.pm
@@ -0,0 +1,133 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::apache; + +# Apache->"method" and Apache::"function" compat layer tests + +# these tests are all run and validated on the server side. + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use ModPerl::Util (); +use Apache2::compat (); +use Apache::Constants qw(DIR_MAGIC_TYPE OPT_EXECCGI :common :response); + +use File::Spec::Functions qw(catfile canonpath); + +sub fixup { + my $r = shift; + Apache->httpd_conf('Options +ExecCGI'); + OK; +} + +sub handler { + my $r = shift; + + plan $r, tests => 24; + + $r->send_http_header('text/plain'); + + ### Apache-> tests + my $fh = Apache->gensym; + ok t_cmp(ref($fh), 'GLOB', "Apache->gensym"); + + ok t_cmp(Apache->module('mod_perl.c'), 1, + "Apache2::module('mod_perl.c')"); + ok t_cmp(Apache->module('mod_ne_exists.c'), 0, + "Apache2::module('mod_ne_exists.c')"); + + ok t_cmp(Apache->define('MODPERL2'), + Apache2::ServerUtil::exists_config_define('MODPERL2'), + 'Apache->define'); + + ok t_cmp($r->current_callback, + 'PerlResponseHandler', + 'inside PerlResponseHandler'); + + t_server_log_error_is_expected(); + Apache::log_error("Apache::log_error test ok"); + ok 1; + + t_server_log_warn_is_expected(); + Apache->warn('Apache->warn ok'); + ok 1; + + t_server_log_warn_is_expected(); + Apache::warn('Apache::warn ok'); + ok 1; + + t_server_log_warn_is_expected(); + Apache::Server->warn('Apache::Server->warn ok'); + ok 1; + + t_server_log_warn_is_expected(); + Apache::Server::warn('Apache::Server::warn ok'); + ok 1; + + # explicitly imported + ok t_cmp(DIR_MAGIC_TYPE, "httpd/unix-directory", + 'DIR_MAGIC_TYPE'); + + # :response is ignored, but is now aliased in :common + ok t_cmp(REDIRECT, "302", + 'REDIRECT'); + + # from :common + ok t_cmp(AUTH_REQUIRED, "401", + 'AUTH_REQUIRED'); + + ok t_cmp(OK, "0", + 'OK'); + + my $exec_cgi = $r->allow_options & Apache2::Const::OPT_EXECCGI; + ok t_cmp($exec_cgi, Apache2::Const::OPT_EXECCGI, 'Apache->httpd_conf'); + + # (Apache||$r)->server_root_relative + { + my $server_root = Apache::Test::config()->{vars}->{serverroot}; + ok t_filepath_cmp(canonpath($Apache::Server::CWD), + canonpath($server_root), + '$server_root'); + + ok t_filepath_cmp(canonpath($r->server_root_relative), + canonpath($server_root), + '$r->server_root_relative()'); + + ok t_filepath_cmp(canonpath($r->server_root_relative('conf')), + catfile($server_root, 'conf'), + "\$r->server_root_relative('conf')"); + + ok t_filepath_cmp(canonpath(Apache->server_root_relative('conf')), + catfile($server_root, 'conf'), + "Apache2::ServerUtil->server_root_relative('conf')"); + + ok t_filepath_cmp(canonpath(Apache->server_root_relative), + canonpath($server_root), + 'Apache2::ServerUtil->server_root_relative()'); + + my $path = catfile(Apache2::ServerUtil::server_root, 'logs'); + ok t_filepath_cmp(canonpath(Apache->server_root_relative($path)), + canonpath($path), + "Apache->server_root_relative('$path')"); + } + + ok t_cmp(Apache->unescape_url_info("/foo+bar%20baz"), + '/foo bar baz', + 'Apache->unescape_url_info'); + + ok t_cmp $Apache::Server::Starting, 0, '$Apache::Server::Starting'; + ok t_cmp $Apache::Server::ReStarting, 1, '$Apache::Server::ReStarting'; + + OK; +} + +1; + +__END__ +# so we can test whether send_httpd_header() works fine +PerlOptions +ParseHeaders +GlobalRequest +PerlModule TestCompat::apache +PerlFixupHandler TestCompat::apache::fixup
diff --git a/2_0_13/t/response/TestCompat/apache_file.pm b/2_0_13/t/response/TestCompat/apache_file.pm new file mode 100644 index 0000000..20f0c0c --- /dev/null +++ b/2_0_13/t/response/TestCompat/apache_file.pm
@@ -0,0 +1,128 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::apache_file; + +# Apache::File compat layer tests + +# these tests are all run and validated on the server side. + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::compat (); +use Apache::Constants qw(OK); + +sub handler { + my $r = shift; + + plan $r, tests => 18; + + $r->send_http_header('text/plain'); + + my $cfg = Apache::Test::config(); + my $vars = $cfg->{vars}; + + require Apache::File; + my $file = $vars->{t_conf_file}; + + t_debug "new Apache2::File file object"; + ok my $fh = Apache::File->new; + + t_debug "open itself"; + if ($fh->open($file)) { + ok 1; + t_debug "read from file"; + my $read = <$fh>; + ok $read; + t_debug "close file"; + ok $fh->close; + } + else { + t_debug "open $file failed: $!"; + ok 0; + t_debug "ok: cannot read from the closed fh"; + ok 1; + t_debug "ok: close file should fail, wasn't opened"; + ok !$fh->close; + } + + t_debug "open non-exists"; + ok !$fh->open("$file.nochance"); + + t_debug "new+open"; + if (my $fh = Apache::File->new($file)) { + ok 1; + $fh->close; + } + else { + ok 0; + } + + t_debug "new+open non-exists"; + ok !Apache::File->new("$file.yeahright"); + + # tmpfile + my ($tmpfile, $tmpfh) = Apache::File->tmpfile; + + t_debug "open tmpfile fh"; + ok $tmpfh; + + t_debug "open tmpfile name"; + ok $tmpfile; + + my $write = "test $$"; + print $tmpfh $write; + seek $tmpfh, 0, 0; + ok t_cmp(<$tmpfh>, $write, "write/read from tmpfile"); + + ok t_cmp($r->discard_request_body, + Apache2::Const::OK, + "\$r->discard_request_body"); + + ok t_cmp($r->meets_conditions, + Apache2::Const::OK, + "\$r->meets_conditions"); + + my $csize = 10; + $r->set_content_length($csize); + ok t_cmp($r->headers_out->{"Content-length"}, + $csize, + "\$r->set_content_length($csize) w/ setting explicit size"); + +# #$r->set_content_length(); +# #TODO +# ok t_cmp(0, # XXX: $r->finfo->csize is not available yet +# $r->headers_out->{"Content-length"}, +# "\$r->set_content_length() w/o setting explicit size"); + + + # XXX: how to test etag? + t_debug "\$r->set_etag"; + $r->set_etag; + ok 1; + + # $r->update_mtime + t_debug "\$r->update_mtime()"; + $r->update_mtime; # just check that it's valid + ok 1; + + my $time = time; + $r->update_mtime($time); + ok t_cmp($r->mtime, $time, "\$r->update_mtime(\$time)/\$r->mtime"); + + # $r->set_last_modified + $r->set_last_modified(); + ok t_cmp($r->mtime, $time, "\$r->set_last_modified()"); + + $r->set_last_modified($time); + ok t_cmp($r->mtime, $time, "\$r->set_last_modified(\$time)"); + + OK; +} + +1; + +__END__ +PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestCompat/apache_module.pm b/2_0_13/t/response/TestCompat/apache_module.pm new file mode 100644 index 0000000..2df1df4 --- /dev/null +++ b/2_0_13/t/response/TestCompat/apache_module.pm
@@ -0,0 +1,51 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::apache_module; + +# Apache2::Module compat layer tests + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::compat (); +use Apache::Constants qw(OK); + +my @directives = ( + { + name => 'TestCompatApacheModuleParms', + }, +); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub TestCompatApacheModuleParms { + my ($self, $parms, $args) = @_; + my $config = Apache2::Module->get_config($self, $parms->server); + $config->{data} = $args; +} + +sub handler : method { + my ($self, $r) = @_; + + plan $r, tests => 2; + + my $top_module = Apache2::Module->top_module(); + ok t_cmp (ref($top_module), 'Apache2::Module'); + + my $config = Apache2::Module->get_config($self, $r->server); + ok t_cmp ($config->{data}, 'Test'); + + OK; +} + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 + +<Base> +PerlLoadModule TestCompat::apache_module +</Base> +TestCompatApacheModuleParms "Test"
diff --git a/2_0_13/t/response/TestCompat/apache_table.pm b/2_0_13/t/response/TestCompat/apache_table.pm new file mode 100644 index 0000000..31d3992 --- /dev/null +++ b/2_0_13/t/response/TestCompat/apache_table.pm
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::apache_table; + +# Apache::Table compat layer tests + +# these tests are all run and validated on the server side. + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::compat (); +use Apache::Constants qw(OK); + +sub handler { + my $r = shift; + + plan $r, tests => 2; + + $r->send_http_header('text/plain'); + + my $t = Apache::Table->new($r); + my $t_class = ref $t; + + ok t_cmp($t_class, 'APR::Table', "Apache::Table->new"); + + ok t_cmp($r->is_main, !$r->main, + '$r->is_main'); + + OK; +} + +1; +
diff --git a/2_0_13/t/response/TestCompat/apache_uri.pm b/2_0_13/t/response/TestCompat/apache_uri.pm new file mode 100644 index 0000000..c830d60 --- /dev/null +++ b/2_0_13/t/response/TestCompat/apache_uri.pm
@@ -0,0 +1,59 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::apache_uri; + +# Apache::Util compat layer tests + +# these tests are all run and validated on the server side. + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::compat (); +use Apache::Constants qw(OK); + +sub handler { + my $r = shift; + + plan $r, tests => 19; + + { + # XXX: rpath is not implemented and not in compat + my @methods = qw(scheme hostinfo user password hostname path + query fragment port); + my $test_uri = 'http://foo:bar@perl.apache.org:80/docs?args#frag'; + + # Apache2::URI->parse internally returns an object blessed into + # APR::URI and all the methods are called on that object + for my $uri ($r->parsed_uri, Apache2::URI->parse($r, $test_uri)) { + t_debug("URI=" . $uri->unparse); + no strict 'refs'; + # just check that methods are call-able, the actual + # testing happens in TestAPR::uri test + for my $meth (@methods) { + my $val = $uri->$meth(); + t_debug("$meth: " . ($val||'')); + ok $val || 1; + } + } + } + + { + Apache2::compat::override_mp2_api('APR::URI::unparse'); + # test the segfault in apr < 0.9.2 (fixed on mod_perl side) + # passing only the /path + my $parsed = $r->parsed_uri; + # set hostname, but not the scheme + $parsed->hostname($r->get_server_name); + $parsed->port($r->get_server_port); + #$parsed->scheme('http'); # compat defaults to 'http' like apache-1.3 did + ok t_cmp($parsed->unparse, $r->construct_url); + Apache2::compat::restore_mp2_api('APR::URI::unparse'); + } + + OK; +} + +1;
diff --git a/2_0_13/t/response/TestCompat/apache_util.pm b/2_0_13/t/response/TestCompat/apache_util.pm new file mode 100644 index 0000000..ec1496f --- /dev/null +++ b/2_0_13/t/response/TestCompat/apache_util.pm
@@ -0,0 +1,104 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::apache_util; + +# Apache::Util compat layer tests + +# these tests are all run and validated on the server side. + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::compat (); +use Apache::Constants qw(OK); + +my %string_size = ( + '-1' => " -", + 0 => " 0k", + 42 => " 1k", + 42_000 => " 41k", + 42_000_000 => "40.1M", + 42_000_000_000 => "40054M", +); + +# list of platforms on which C (not Perl) crypt() is supported +# XXX: add other platforms that are known to have crypt +my %crypt_supported = map {$_ => 1} qw(linux); + +my $crypt_ok = $crypt_supported{lc $^O} ? 1 : 0; + +my $locale = $ENV{LANG} || $ENV{LC_TIME} || ''; +# XXX: will any en_XXX work with http_parse? +# XXX: should we set $ENV{LANG} to en_US instead of skipping? +my $parse_time_ok = $locale =~ /^en_/ ? 1 : 0; + +sub handler { + my $r = shift; + + plan $r, tests => 12 + $parse_time_ok*1 + $crypt_ok*2; + + $r->send_http_header('text/plain'); + + # size_string() + { + while (my ($k, $v) = each %string_size) { + ok t_cmp($v, Apache::Util::size_string($k)); + } + } + + # escape_uri(), escape_path(), unescape_uri() + my $uri = "http://foo.com/a file.html"; + (my $esc_uri = $uri) =~ s/ /\%20/g; + my $uri2 = $uri; + + $uri = Apache::Util::escape_uri($uri); + $uri2 = Apache::Util::escape_path($uri2, $r->pool); + + ok t_cmp($uri, $esc_uri, "Apache::Util::escape_uri"); + ok t_cmp($uri2, $esc_uri, "Apache::Util::escape_path"); + + ok t_cmp(Apache::Util::unescape_uri($uri2), + Apache2::URI::unescape_url($uri), + "Apache2::URI::unescape_uri vs Apache::Util::unescape_uri"); + + ok t_cmp($uri2, + $uri, + "Apache2::URI::unescape_uri vs Apache::Util::unescape_uri"); + + # escape_html() + my $html = '<p>"hi"&foo</p>'; + my $esc_html = '<p>"hi"&foo</p>'; + + ok t_cmp(Apache::Util::escape_html($html), $esc_html, + "Apache2::Util::escape_html"); + + + # ht_time(), parsedate() + my $time = time; + Apache2::compat::override_mp2_api('Apache2::Util::ht_time'); + my $fmtdate = Apache2::Util::ht_time($time); + Apache2::compat::restore_mp2_api('Apache2::Util::ht_time'); + + ok t_cmp($fmtdate, $fmtdate, "Apache::Util::ht_time"); + + if ($parse_time_ok) { + my $ptime = Apache::Util::parsedate($fmtdate); + ok t_cmp($ptime, $time, "Apache::Util::parsedate"); + } + + if ($crypt_ok) { + # not all platforms support C-level crypt + my $hash = "aX9eP53k4DGfU"; + ok t_cmp(Apache::Util::validate_password("dougm", $hash), 1); + ok t_cmp(Apache::Util::validate_password("mguod", $hash), 0); + } + + OK; +} + +1; + +__END__ +PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestCompat/conn_authen.pm b/2_0_13/t/response/TestCompat/conn_authen.pm new file mode 100644 index 0000000..1cb80ad --- /dev/null +++ b/2_0_13/t/response/TestCompat/conn_authen.pm
@@ -0,0 +1,75 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::conn_authen; + +# compat checks for +# $r->connection->auth_type +# $r->connection->user +# both records don't exist in 2.0 conn_rec and therefore require +# 'PerlOptions +GlobalRequest' to retrieve those via Apache2::RequestUtil->request + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::compat (); +use Apache::Constants qw(OK REMOTE_HOST); + +sub handler { + + my $r = shift; + + my $req_auth_type = $r->connection->auth_type || ''; + + die "request auth_type is '$req_auth_type', should be empty" + if $req_auth_type; + + # get_basic_auth_pw populates $r->user and $r->ap_auth_type + my ($rc, $sent_pw) = $r->get_basic_auth_pw; + + return $rc if $rc != Apache2::Const::OK; + + $req_auth_type = $r->connection->auth_type || ''; + + die "request auth_type is '$req_auth_type', should be 'Basic'" + unless $req_auth_type eq 'Basic'; + + my $config_auth_type = $r->auth_type || ''; + + die "httpd.conf auth_type is '$config_auth_type', should be 'Basic'" + unless $config_auth_type eq 'Basic'; + + my $user = $r->connection->user || ''; + + die "user is '$user', should be 'dougm'" + unless $user eq 'dougm'; + + # make sure we can set both + $r->connection->auth_type('sailboat'); + $r->connection->user('geoff'); + + $user = $r->connection->user || ''; + + die "user is '$user', should be 'geoff'" + unless $user eq 'geoff'; + + $req_auth_type = $r->connection->auth_type || ''; + + die "request auth_type is '$req_auth_type', should be 'sailboat'" + unless $req_auth_type eq 'sailboat'; + + OK; +} + +1; + +__DATA__ +require valid-user +AuthType Basic +AuthName simple +SetHandler modperl +PerlOptions +GlobalRequest +PerlAuthenHandler TestCompat::conn_authen +PerlResponseHandler Apache::TestHandler::ok1 +
diff --git a/2_0_13/t/response/TestCompat/conn_rec.pm b/2_0_13/t/response/TestCompat/conn_rec.pm new file mode 100644 index 0000000..a19339c --- /dev/null +++ b/2_0_13/t/response/TestCompat/conn_rec.pm
@@ -0,0 +1,42 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::conn_rec; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use Apache2::compat (); + +use Socket qw(sockaddr_in inet_ntoa); + +use Apache::Constants qw(OK); + +sub handler { + + my $r = shift; + + my $c = $r->connection; + + plan $r, tests => 4; + + Apache2::compat::override_mp2_api('Apache2::Connection::local_addr'); + my ($local_port, $local_addr) = sockaddr_in($c->local_addr); + Apache2::compat::restore_mp2_api('Apache2::Connection::local_addr'); + t_debug inet_ntoa($local_addr) . " :$local_port"; + ok $local_port; + ok inet_ntoa($local_addr); + + Apache2::compat::override_mp2_api('Apache2::Connection::remote_addr'); + my ($remote_port, $remote_addr) = sockaddr_in($c->remote_addr); + Apache2::compat::restore_mp2_api('Apache2::Connection::remote_addr'); + t_debug inet_ntoa($remote_addr) . " :$remote_port"; + ok $remote_port; + ok inet_ntoa($remote_addr); + + OK; +} + +1; +
diff --git a/2_0_13/t/response/TestCompat/request.pm b/2_0_13/t/response/TestCompat/request.pm new file mode 100644 index 0000000..c2406d3 --- /dev/null +++ b/2_0_13/t/response/TestCompat/request.pm
@@ -0,0 +1,150 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::request; + +# $r->"method" compat layer tests + +# these tests are all run and validated on the server side. + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test; + +use APR::Finfo (); + +use File::Spec::Functions qw(catfile); + +use Apache2::compat (); +use Apache::Constants qw(OK REMOTE_HOST); + +sub handler { + my $r = shift; + + plan $r, tests => 22; + + $r->send_http_header('text/plain'); + + # header_in() and header_out() and err_header_out() + for my $prefix ('err_', '') { + my @ways = 'out'; + push @ways, 'in' unless $prefix; + for my $way (@ways) { + my $sub_test = "${prefix}header_$way"; + my $sub_good = "${prefix}headers_$way"; + my $key = 'header-test'; + + # scalar context + { + my $key; + if ($way eq 'in') { + $key = "user-agent"; # should exist with lwp + } else { + # outgoing headers aren't set yet, so we set one + $key = "X-barabara"; + $r->$sub_good->set($key, $key x 2); + } + + ok t_cmp($r->$sub_test($key), + $r->$sub_good->get($key), + "\$r->$sub_test in scalar context"); + } + + # list context + { + my @exp = qw(foo bar); + $r->$sub_good->add($key => $_) for @exp; + ok t_cmp([ $r->$sub_test($key) ], + \@exp, + "\$r->$sub_test in list context"); + } + + # set + { + my $exp = $key x 2; + $r->$sub_test($key => $exp); + my $got = $r->$sub_test($key); + ok t_cmp($got, $exp, "\$r->$sub_test set()"); + } + + # unset + { + my $exp = undef; + $r->$sub_test($key => $exp); + my $got = $r->$sub_test($key); + ok t_cmp($got, $exp, "\$r->$sub_test unset()"); + } + } + } + + # $r->filename + { + Apache2::compat::override_mp2_api('Apache2::RequestRec::filename'); + my $orig = $r->filename; + my $new = catfile Apache::Test::vars("serverroot"), + "conf", "httpd.conf"; + + # in mp1 setting filename, updates $r's finfo (not in mp2) + $r->filename($new); + ok t_cmp $r->finfo->size, -s $new , "new filesize"; + + # restore + $new = __FILE__; + $r->filename($new); + ok t_cmp $r->finfo->size, -s $new , "new filesize"; + + # restore the real 2.0 filename() method, now that we are done + # with the compat one + Apache2::compat::restore_mp2_api('Apache2::RequestRec::filename'); + } + + # $r->notes + { + Apache2::compat::override_mp2_api('Apache2::RequestRec::notes'); + + my $key = 'notes-test'; + # get/set scalar context + { + my $val = 'ok'; + $r->notes($key => $val); + ok t_cmp($val, $r->notes->get($key), "\$r->notes->get(\$key)"); + ok t_cmp($val, $r->notes($key), "\$r->notes(\$key)"); + } + + # unset + { + my $exp = undef; + $r->notes($key => $exp); + my $got = $r->notes($key); + ok t_cmp($got, $exp, "\$r->notes unset()"); + } + + # get/set list context + { + my @exp = qw(foo bar); + $r->notes->add($key => $_) for @exp; + ok t_cmp([ $r->notes($key) ], \@exp, "\$r->notes in list context"); + } + + # restore the real 2.0 notes() method, now that we are done + # with the compat one + Apache2::compat::restore_mp2_api('Apache2::RequestRec::notes'); + } + + # get_remote_host() + ok $r->get_remote_host() || 1; + ok $r->get_remote_host(Apache2::Const::REMOTE_HOST) || 1; + + # post_connection() + $r->post_connection(sub { OK }); + ok 1; + + # register_cleanup + ok 1; + $r->register_cleanup(sub { OK }); + + OK; +} + +1; +
diff --git a/2_0_13/t/response/TestCompat/request_body.pm b/2_0_13/t/response/TestCompat/request_body.pm new file mode 100644 index 0000000..5f0f1e9 --- /dev/null +++ b/2_0_13/t/response/TestCompat/request_body.pm
@@ -0,0 +1,63 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::request_body; + +# $r->"method" tests that are validated by the client + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestUtil; +use Apache::Test (); + +use Apache2::compat (); +use Apache::Constants qw(OK M_POST DECLINED); + +use subs qw(ok debug); +my $gr; + +sub handler { + my $r = shift; + $gr = $r; + + $r->send_http_header('text/plain'); + + my $cfg = Apache::Test::config(); + my $vars = $cfg->{vars}; + + my %data; + if ($r->method_number == M_POST) { + %data = $r->content; + } + else { + %data = $r->Apache::args; + } + + return DECLINED unless exists $data{test}; + + if ($data{test} eq 'content' || $data{test} eq 'args') { + $r->print("test $data{test}"); + } + elsif ($data{test} eq 'decoding') { + $r->print(encode($data{body})); + } + elsif ($data{test} eq 'big_input') { + $r->print(length $data{body}); + } + else { + # nothing + } + + OK; +} + +sub encode { + my $val = shift; + $val =~ s/(.)/sprintf "%%%02X", ord $1/eg; + $val =~ s/\%20/+/g; + return $val; +} + + +1; +__END__ +PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestCompat/send_fd.pm b/2_0_13/t/response/TestCompat/send_fd.pm new file mode 100644 index 0000000..7ee2f53 --- /dev/null +++ b/2_0_13/t/response/TestCompat/send_fd.pm
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestCompat::send_fd; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::compat (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => ':common'; + +sub handler { + my $r = shift; + + my $file = $r->args || __FILE__; + + open my $fh, $file or return Apache2::Const::NOT_FOUND; + + my $bytes = $r->send_fd($fh); + + return Apache2::Const::SERVER_ERROR unless $bytes == -s $file; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestDirective/cmdparms.pm b/2_0_13/t/response/TestDirective/cmdparms.pm new file mode 100644 index 0000000..b3070d2 --- /dev/null +++ b/2_0_13/t/response/TestDirective/cmdparms.pm
@@ -0,0 +1,140 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::cmdparms; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::CmdParms (); +use Apache2::Directive (); +use base qw(Apache2::Module); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw( + ACCESS_CONF + M_GET + M_POST + M_PUT + M_DELETE + OK + OR_AUTHCFG + OR_FILEINFO + OR_INDEXES + OR_LIMIT + OR_OPTIONS + RSRC_CONF + NOT_IN_LOCATION +); + +use constant KEY => "TestCmdParms"; + +my @directives = ( + { + name => +KEY, + cmd_data => 'cmd_data', + errmsg => 'errmsg', + }, +); + +Apache2::Module::add(__PACKAGE__, \@directives); + +my @methods = qw(cmd context directive info override path + pool server temp_pool); + +sub TestCmdParms { + my ($self, $parms, $args) = @_; + my $srv_cfg = $self->get_config($parms->server); + foreach my $method (@methods) { + $srv_cfg->{$args}{$method} = $parms->$method(); + } + $srv_cfg->{$args}{check_ctx} = + $parms->check_cmd_context(Apache2::Const::NOT_IN_LOCATION); + + $srv_cfg->{$args}{limited} = $parms->method_is_limited('GET'); + + my $directive = $parms->directive; + $srv_cfg->{$args}{line_num} = $directive->line_num; + $srv_cfg->{$args}{filename} = $directive->filename; +} + +### response handler ### +sub handler : method { + my ($self, $r) = @_; + my $override; + my $srv_cfg = $self->get_config($r->server); + + plan $r, tests => 11 + ( 7 * keys(%$srv_cfg) ); + + foreach my $cfg (values %$srv_cfg) { + ok t_cmp(ref($cfg->{cmd}), 'Apache2::Command', 'cmd'); + ok t_cmp(ref($cfg->{context}), 'Apache2::ConfVector', 'context'); + ok t_cmp(ref($cfg->{directive}), 'Apache2::Directive', 'directive'); + ok t_cmp(ref($cfg->{pool}), 'APR::Pool', 'pool'); + ok t_cmp(ref($cfg->{temp_pool}), 'APR::Pool', 'temp_pool'); + ok t_cmp(ref($cfg->{server}), 'Apache2::ServerRec', 'server'); + ok t_cmp($cfg->{info}, 'cmd_data', 'cmd_data'); + } + + # vhost + { + my $vhost = $srv_cfg->{Vhost}; + + my $wanted = Apache2::Const::RSRC_CONF | + Apache2::Const::OR_INDEXES | + Apache2::Const::OR_FILEINFO | + Apache2::Const::OR_OPTIONS; + my $masked = $vhost->{override} & $wanted; + + ok t_cmp($masked, $wanted, 'override bitmask'); + ok t_cmp($vhost->{path}, undef, 'path'); + ok t_cmp($vhost->{check_ctx}, undef, 'check_cmd_ctx'); + ok $vhost->{limited}; + + ok t_cmp $vhost->{filename}, qr|httpd.conf$|, "config filename"; + ok t_cmp $vhost->{line_num}, qr|^\d+$|, "config filename line_num"; + } + + # Location + { + my $loc = $srv_cfg->{Location}; + + my $wanted = Apache2::Const::ACCESS_CONF | + Apache2::Const::OR_INDEXES | + Apache2::Const::OR_AUTHCFG | + Apache2::Const::OR_FILEINFO | + Apache2::Const::OR_OPTIONS | + Apache2::Const::OR_LIMIT; + my $masked = $loc->{override} & $wanted; + + ok t_cmp($masked, $wanted, 'override bitmask'); + ok t_cmp($loc->{path}, '/TestDirective__cmdparms', 'path'); + ok t_cmp($loc->{check_ctx}, KEY . + ' cannot occur within <Location> section', 'check_cmd_ctx'); + ok $loc->{limited}; + } + + # Limit + { + my $limit = $srv_cfg->{Limit}; + ok !$limit->{limited}; + } + + return Apache2::Const::OK; +} + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 + +<Base> +PerlLoadModule TestDirective::cmdparms +TestCmdParms "Vhost" +</Base> + +TestCmdParms "Location" +#FIXME! httpd 2.4 does not allow LimitExcept here +#<LimitExcept GET> + #TestCmdParms "Limit" +#</LimitExcept>
diff --git a/2_0_13/t/response/TestDirective/env.pm b/2_0_13/t/response/TestDirective/env.pm new file mode 100644 index 0000000..8a048ab --- /dev/null +++ b/2_0_13/t/response/TestDirective/env.pm
@@ -0,0 +1,101 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::env; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use APR::Table (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 8; + + # %ENV + ok t_cmp(env_get('srv1'), + 'env_dir1', + '%ENV per-dir override per-srv'); + + ok t_cmp(env_get('srv2'), + 'env_srv2', + '%ENV per-srv'); + + ok t_cmp(env_get('dir2'), + 'env_dir2', + '%ENV per-dir'); + + # setup by Apache::TestRun + ok t_cmp($ENV{APACHE_TEST_HOSTNAME}, + 'test.host.name', + '%ENV PerlPassEnv'); + + # $r->subprocess_env + ok t_cmp(env_get('srv1', $r), + 'env_dir1', + '$r->subprocess_env per-dir override per-srv'); + + ok t_cmp(env_get('srv2', $r), + 'env_srv2', + '$r->subprocess_env per-srv'); + + ok t_cmp(env_get('dir2', $r), + 'env_dir2', + '$r->subprocess_env per-dir'); + + # setup by Apache::TestRun + ok t_cmp($r->subprocess_env->get('APACHE_TEST_HOSTNAME'), + 'test.host.name', + '$r->subprocess_env PerlPassEnv'); + + Apache2::Const::OK; +} + +sub env_get { + my ($name, $r) = @_; + my $key = 'TestDirective__env_' . $name; + + my $value = $ENV{$key}; + + if ($r) { + my @values = $r->subprocess_env->get($key); + + if (@values > 1) { + $value = "too many values for $key!"; + } + else { + $value = $values[0]; + } + } + + return $value; +} + +1; +__END__ +# SetupEnv ought to have no effect on PerlSetEnv or PerlPassEnv +PerlOptions -SetupEnv + +<Base> + # per-server entry overwritten by per-directory entry + PerlSetEnv TestDirective__env_srv1 env_srv1 + + # per-server entry not overwritten + PerlSetEnv TestDirective__env_srv2 env_srv2 + + # PerlPassEnv is only per-server + PerlPassEnv APACHE_TEST_HOSTNAME +</Base> + +# per-directory entry overwrites per-server +PerlSetEnv TestDirective__env_srv1 env_dir1 + +# PerlSetEnv resets the table for each directive +PerlSetEnv TestDirective__env_dir2 ToBeLost +PerlSetEnv TestDirective__env_dir2 env_dir2 +
diff --git a/2_0_13/t/response/TestDirective/perlcleanuphandler.pm b/2_0_13/t/response/TestDirective/perlcleanuphandler.pm new file mode 100644 index 0000000..1908932 --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlcleanuphandler.pm
@@ -0,0 +1,66 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlcleanuphandler; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use Apache2::Connection (); +use Apache2::ConnectionUtil (); +use Apache2::Const -compile => 'OK', 'DECLINED'; + +# This test is to show an error that occurs if in the whole request cycle +# only a PerlCleanupHandler is defined. In this case it is not called. +# To check that "/get?incr" is called first. This returns "UNDEF" to the +# browser and sets the counter to "1". Next "/get" is called again without +# args to check the counter without increment. Then we fetch +# "/index.html?incr". Here no other Perl*Handler save the PerlCleanupHandler +# is involved. So the next "/get" must return "2" but it shows "1". + +sub cleanup { + my $r=shift; + $r->connection->pnotes->{counter}++ if( $r->args eq 'incr' ); + return Apache2::Const::OK; +} + +sub get { + my $r=shift; + $r->content_type('text/plain'); + $r->print($r->connection->pnotes->{counter} || "UNDEF"); + return Apache2::Const::OK; +} + +1; + +__END__ +<VirtualHost TestDirective::perlcleanuphandler> + + <IfDefine PERL_USEITHREADS> + # a new interpreter pool + PerlOptions +Parent + PerlInterpStart 1 + PerlInterpMax 1 + PerlInterpMinSpare 0 + PerlInterpMaxSpare 1 + # PerlInterpScope connection + </IfDefine> + + KeepAlive On + KeepAliveTimeout 300 + MaxKeepAliveRequests 100 + + # use test system's @INC + PerlSwitches -I@serverroot@ + PerlRequire "conf/modperl_inc.pl" + PerlModule TestDirective::perlcleanuphandler + + <Location /get> + SetHandler modperl + PerlResponseHandler TestDirective::perlcleanuphandler::get + </Location> + + PerlCleanupHandler TestDirective::perlcleanuphandler::cleanup + +</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perldo.pm b/2_0_13/t/response/TestDirective/perldo.pm new file mode 100644 index 0000000..a825089 --- /dev/null +++ b/2_0_13/t/response/TestDirective/perldo.pm
@@ -0,0 +1,76 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perldo; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache2::Const -compile => 'OK'; +use Apache2::PerlSections; + +sub handler { + my $r = shift; + + plan $r, tests => 22, need_module('mod_alias'); + + ok t_cmp('yes', $TestDirective::perl::worked); + + ok t_cmp($TestDirective::perl::PACKAGE, + qr/t::conf::extra_last_conf::line_\d+$/, + '__PACKAGE__'); + + my %Location; + { + no strict 'refs'; + %Location = %{$TestDirective::perl::PACKAGE . '::Location'}; + } + + ok not exists $Location{'/perl_sections'}; + ok exists $Location{'/perl_sections_saved'}; + ok t_cmp($Location{'/perl_sections_saved'}{'AuthName'}, 'PerlSection'); + + ok t_cmp($Location{'/tied'}, 'TIED', 'Tied %Location'); + + ok t_cmp($TestDirective::perl::comments, 'yes', ); + + ok t_cmp($TestDirective::perl::dollar_zero, qr/extra.last.conf/, '$0'); + ok t_cmp($TestDirective::perl::filename, qr/extra.last.conf/, '__FILE__'); + + # 3 would mean we are still counting lines from the context of the eval + ok $TestDirective::perl::line > 3; + + ok !t_cmp($0, '-e', '$0'); + my $target = Apache::Test::vars('target'); + ok t_cmp($0, qr/$target/i, '$0'); + + ok t_cmp($TestDirective::perl::Included, 1, "Include"); + + my $dump = Apache2::PerlSections->dump; + ok t_cmp($dump, qr/__END__/, "Apache2::PerlSections->dump"); + + eval "package TestDirective::perldo::test;\nno strict;\n$dump"; + ok t_cmp($@, "", "PerlSections dump syntax check"); + + ok t_cmp($TestDirective::perldo::test::Include, qr/perlsection.conf/); + + #Check for correct Apache2::ServerUtil->server behavior + my $bport = $TestDirective::perl::base_server->port; + my $vport = $TestDirective::perl::vhost_server->port; + ok defined $bport && defined $vport && $vport != $bport; + + foreach my $url (qw(scalar scalar1 scalar2)) { + my $res = GET "/perl_sections_perlconfig_$url/"; + ok t_cmp($res->is_success, 1, '$PerlConfig'); + } + + foreach my $url (qw(array1 array2)) { + my $res = GET "/perl_sections_perlconfig_$url/"; + ok t_cmp($res->is_success, 1, '@PerlConfig'); + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule.pm b/2_0_13/t/response/TestDirective/perlloadmodule.pm new file mode 100644 index 0000000..8c85288 --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlloadmodule.pm
@@ -0,0 +1,152 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlloadmodule; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use Apache2::Const -compile => qw(OK OR_ALL RSRC_CONF TAKE1 TAKE23); + +use Apache2::CmdParms (); +use Apache2::Module (); + +my @directives = ( + { + name => 'MyTest', + func => __PACKAGE__ . '::MyTest', + req_override => Apache2::Const::RSRC_CONF, +# req_override => 'RSRC_CONF', #test 1.x compat for strings +# args_how => Apache2::Const::TAKE23, + args_how => 'TAKE23', #test 1.x compat for strings + errmsg => 'A test', + }, + { + name => 'MyOtherTest', + cmd_data => 'some info', + }, + { + name => 'ServerTest', + req_override => Apache2::Const::RSRC_CONF, + } +); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub DIR_CREATE { + my ($class, $parms) = @_; + + bless { + path => $parms->path || "/", + }, $class; +} + +sub merge { + my ($base, $add) = @_; + + my %new = (); + + @new{keys %$base, keys %$add} = + (values %$base, values %$add); + + return bless \%new, ref($base); +} + +sub DIR_MERGE { + my $class = ref $_[0]; + debug "$class->DIR_MERGE\n"; + merge(@_); +} + +#sub SERVER_MERGE { +# my $class = ref $_[0]; +# debug "$class->SERVER_MERGE\n"; +# merge(@_); +#} + +sub SERVER_CREATE { + my ($class, $parms) = @_; + debug "$class->SERVER_CREATE\n"; + return bless { + name => __PACKAGE__, + }, $class; +} + +sub MyTest { + my ($self, $parms, @args) = @_; + $self->{MyTest} = \@args; + $self->{MyTestInfo} = $parms->info; +} + +sub MyOtherTest { + my ($self, $parms, $arg) = @_; + $self->{MyOtherTest} = $arg; + $self->{MyOtherTestInfo} = $parms->info; +} + +sub ServerTest { + my ($self, $parms, $arg) = @_; + my $srv_cfg = $self->get_config($parms->server); + $srv_cfg->{ServerTest} = $arg; +} + +sub get_config { + my ($self, $s) = (shift, shift); + Apache2::Module::get_config($self, $s, @_); +} + +sub handler : method { + my ($self, $r) = @_; + + my $s = $r->server; + my $dir_cfg = $self->get_config($s, $r->per_dir_config); + my $srv_cfg = $self->get_config($s); + + plan $r, tests => 9; + + t_debug("per-dir config:", $dir_cfg); + t_debug("per-srv config:", $srv_cfg); + + ok $dir_cfg->isa($self); + ok $srv_cfg->isa($self); + + my $path = $dir_cfg->{path}; + + ok t_cmp($r->uri, qr{^$path}, + 'r->uri =~ parms->path'); + + ok t_cmp($srv_cfg->{name}, $self, + '$self eq $srv_cfg->{name}'); + + ok t_cmp($dir_cfg->{MyOtherTest}, 'value', + 'MyOtherTest value'); + + ok t_cmp($dir_cfg->{MyOtherTestInfo}, 'some info', + 'MyOtherTest cmd_data'); + + ok t_cmp($dir_cfg->{MyTest}, ['one', 'two'], + 'MyTest one two'); + + ok ! $dir_cfg->{MyTestInfo}; + + ok t_cmp($srv_cfg->{ServerTest}, 'per-server'); + + Apache2::Const::OK; +} + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 + +<Base> + PerlLoadModule TestDirective::perlloadmodule + + MyTest one two + ServerTest per-server +</Base> + +MyOtherTest value +
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule2.pm b/2_0_13/t/response/TestDirective/perlloadmodule2.pm new file mode 100644 index 0000000..5829678 --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlloadmodule2.pm
@@ -0,0 +1,114 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlloadmodule2; + +# in this test the merge is inherits all the values from the ancestors +# and adds new values if such were set + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Const -compile => qw(OK OR_ALL ITERATE); + +use Apache2::CmdParms (); +use Apache2::Module (); + +my @directives = ( + { + name => 'MyMergeTest', + func => __PACKAGE__ . '::MyMergeTest', + req_override => Apache2::Const::OR_ALL, + args_how => Apache2::Const::ITERATE, + errmsg => 'Values that get merged', + }, +); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub merge { + my ($base, $add) = @_; + + my %new = (); + + # be careful if the object values are references and not scalars. + # If that's the case a deep copy must be performed, or the merged + # object will affect the based object, which will break things + # when DIR_MERGE is called twice for the same $base/$add during + # the same request + push @{ $new{$_} }, @{ $base->{$_}||[] } for keys %$base; + push @{ $new{$_} }, @{ $add->{$_} ||[] } for keys %$add; + + return bless \%new, ref($base); +} + +sub DIR_MERGE { + my $class = ref $_[0]; + #warn "$class->DIR_MERGE\n"; + merge(@_); +} + +sub SERVER_MERGE { + my $class = ref $_[0]; + #warn "$class->SERVER_MERGE\n"; + merge(@_); +} + +# this variable is of type ITERATE, so it'll get called as many times +# as arguments, a single argument at a time. This function is called +# only during the server startup and when the directive appears in the +# .htaccess files +sub MyMergeTest { + my ($self, $parms, $arg) = @_; + #warn "MyMergeTest: @{[$parms->path||'']}\n\t$arg\n"; + push @{ $self->{MyMergeTest} }, $arg; + + # store the top level srv values in the server struct as well, so + # during the request you can query what was the top level (srv) + # setting, before it was merged with the current container's + # setting if any + unless ($parms->path) { + my $srv_cfg = $self->get_config($parms->server); + push @{ $srv_cfg->{MyMergeTest} }, $arg; + } +} + +sub get_config { + my ($self, $s) = (shift, shift); + Apache2::Module::get_config($self, $s, @_); +} + +sub handler : method { + my ($self, $r) = @_; + + $r->content_type('text/plain'); + + my $s = $r->server; + + if (defined $r->args and $r->args eq 'srv') { + my $srv_cfg = $self->get_config($s); + $r->print("srv: @{ $srv_cfg->{MyMergeTest}||[] }"); + } + else { + my $dir_cfg = $self->get_config($s, $r->per_dir_config); + $r->print("dir: @{ $dir_cfg->{MyMergeTest}||[] }"); + } + + return Apache2::Const::OK; +} + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 + +<Base> + PerlLoadModule TestDirective::perlloadmodule2 + + MyMergeTest one two +</Base> +<Location /TestDirective__perlloadmodule2> + MyMergeTest three four +</Location> +<Location /TestDirective__perlloadmodule2/subdir> + MyMergeTest five + MyMergeTest six +</Location>
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule3.pm b/2_0_13/t/response/TestDirective/perlloadmodule3.pm new file mode 100644 index 0000000..facb918 --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlloadmodule3.pm
@@ -0,0 +1,165 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlloadmodule3; + +# in this test we test various merging techniques. As a side effect it +# tests how mod_perl works when its forced to start early outside +# vhosts and how it works with vhosts. See perlloadmodule4.pm and +# perlloadmodule5.pm, for similar tests that starts mod_perl early +# from a vhost. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::CmdParms (); +use Apache2::Module (); +use Apache2::ServerUtil (); + +use Apache2::Const -compile => qw(OK); + + +my @directives = ( + { name => 'MyPlus' }, + { name => 'MyList' }, + { name => 'MyAppend' }, + { name => 'MyOverride' }, +); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub MyPlus { set_val('MyPlus', @_) } +sub MyAppend { set_val('MyAppend', @_) } +sub MyOverride { set_val('MyOverride', @_) } +sub MyList { push_val('MyList', @_) } + +sub DIR_MERGE { merge(@_) } +sub SERVER_MERGE { merge(@_) } + +sub set_val { + my ($key, $self, $parms, $arg) = @_; + $self->{$key} = $arg; + unless ($parms->path) { + my $srv_cfg = Apache2::Module::get_config($self, $parms->server); + $srv_cfg->{$key} = $arg; + } +} + +sub push_val { + my ($key, $self, $parms, $arg) = @_; + push @{ $self->{$key} }, $arg; + unless ($parms->path) { + my $srv_cfg = Apache2::Module::get_config($self, $parms->server); + push @{ $srv_cfg->{$key} }, $arg; + } +} + +sub merge { + my ($base, $add) = @_; + + my %mrg = (); + for my $key (keys %$base, %$add) { + next if exists $mrg{$key}; + if ($key eq 'MyPlus') { + $mrg{$key} = ($base->{$key}||0) + ($add->{$key}||0); + } + elsif ($key eq 'MyList') { + push @{ $mrg{$key} }, + @{ $base->{$key}||[] }, @{ $add->{$key}||[] }; + } + elsif ($key eq 'MyAppend') { + $mrg{$key} = join " ", grep defined, $base->{$key}, $add->{$key}; + } + else { + # override mode + $mrg{$key} = $base->{$key} if exists $base->{$key}; + $mrg{$key} = $add->{$key} if exists $add->{$key}; + } + } + + return bless \%mrg, ref($base); +} + +### response handler ### + + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Module (); + +use Apache2::Const -compile => qw(OK); + +sub get_config { + Apache2::Module::get_config(__PACKAGE__, @_); +} + +sub handler { + my ($r) = @_; + my %secs = (); + + $r->content_type('text/plain'); + + my $s = $r->server; + my $dir_cfg = get_config($s, $r->per_dir_config); + my $srv_cfg = get_config($s); + + if ($s->is_virtual) { + $secs{"1: Main Server"} = get_config(Apache2::ServerUtil->server); + $secs{"2: Virtual Host"} = $srv_cfg; + $secs{"3: Location"} = $dir_cfg; + } + else { + $secs{"1: Main Server"} = $srv_cfg; + $secs{"2: Location"} = $dir_cfg; + } + + $r->printf("Processing by %s.\n", + $s->is_virtual ? "virtual host" : "main server"); + + for my $sec (sort keys %secs) { + $r->print("\nSection $sec\n"); + for my $k (sort keys %{ $secs{$sec}||{} }) { + my $v = exists $secs{$sec}->{$k} ? $secs{$sec}->{$k} : 'UNSET'; + $v = '[' . (join ", ", map {qq{"$_"}} @$v) . ']' + if ref($v) eq 'ARRAY'; + $r->printf("%-10s : %s\n", $k, $v); + } + } + + return Apache2::Const::OK; +} + + + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 + +<Base> + PerlLoadModule TestDirective::perlloadmodule3 + MyPlus 5 + MyList "MainServer" + MyAppend "MainServer" + MyOverride "MainServer" +</Base> +<VirtualHost TestDirective::perlloadmodule3> + MyPlus 2 + MyList "VHost" + MyAppend "VHost" + MyOverride "VHost" + <Location /TestDirective__perlloadmodule3> + MyPlus 3 + MyList "Dir" + MyAppend "Dir" + MyOverride "Dir" + SetHandler modperl + PerlResponseHandler TestDirective::perlloadmodule3 + </Location> + <Location /TestDirective__perlloadmodule3/subdir> + MyPlus 1 + MyList "SubDir" + MyAppend "SubDir" + MyOverride "SubDir" + </Location> +</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule4.pm b/2_0_13/t/response/TestDirective/perlloadmodule4.pm new file mode 100644 index 0000000..6edc88a --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlloadmodule4.pm
@@ -0,0 +1,98 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlloadmodule4; + +# XXX: the package is 99% the same as perlloadlmodule5 and 6, just the +# configuration is different. Consider removing the code dups. +# +# in this test we test an early mod_perl startup caused by an +# EXEC_ON_READ directive in the baseserver. In this test the +# non-native mod_perl directive sets scfg on behalf of mod_perl in +# that vhost. +# +# See also perlloadmodule5.pm, which is almost the same, but uses a +# mod_perl native directive before a non-native directive in vhost. In +# that test mod_perl sets scfg for that vhost by itself. +# +# see perlloadmodule6.pm for the case where mod_perl starts early, but +# from within the vhost. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::CmdParms (); +use Apache2::Module (); +use Apache2::ServerUtil (); + +use Apache2::Const -compile => qw(OK); + +use constant KEY => "MyTest4"; + +my @directives = ({ name => +KEY },); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub MyTest4 { + my ($self, $parms, $arg) = @_; + $self->{+KEY} = $arg; + + unless ($parms->path) { + my $srv_cfg = Apache2::Module::get_config($self, $parms->server); + $srv_cfg->{+KEY} = $arg; + } +} + +### response handler ### + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Module (); +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +sub get_config { + Apache2::Module::get_config(__PACKAGE__, @_); +} + +sub handler { + my ($r) = @_; + my %secs = (); + + $r->content_type('text/plain'); + + my $s = $r->server; + my $dir_cfg = get_config($s, $r->per_dir_config); + my $srv_cfg = get_config($s); + + plan $r, tests => 3; + + ok $s->is_virtual; + + ok t_cmp($dir_cfg->{+KEY}, "Dir", "Section"); + + ok t_cmp($srv_cfg->{+KEY}, "Vhost", "Section"); + + return Apache2::Const::OK; +} + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 + +<Base> + PerlLoadModule TestDirective::perlloadmodule4 +</Base> +<VirtualHost TestDirective::perlloadmodule4> + # here perlloadmodule sets scfg on behalf of the base server + MyTest4 "Vhost" + <Location /TestDirective__perlloadmodule4> + MyTest4 "Dir" + SetHandler modperl + PerlResponseHandler TestDirective::perlloadmodule4 + </Location> +</VirtualHost> +
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule5.pm b/2_0_13/t/response/TestDirective/perlloadmodule5.pm new file mode 100644 index 0000000..9e88e2c --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlloadmodule5.pm
@@ -0,0 +1,96 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlloadmodule5; + +# in this test we test an early mod_perl startup caused by an +# EXEC_ON_READ directive in the baseserver. In this test we have a +# mod_perl native directive before a non-native directive inside vhost +# section. Here mod_perl sets scfg for that vhost by itself. +# +# See also perlloadmodule4.pm, which is almost the same, but has no +# mod_perl native directive before a non-native directive in vhost. In +# that test the non-native mod_perl directive sets scfg on behalf of +# mod_perl in that vhost. +# +# see perlloadmodule6.pm for the case where mod_perl starts early, but +# from within the vhost. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::CmdParms (); +use Apache2::Module (); +use Apache2::ServerUtil (); + +use Apache2::Const -compile => qw(OK); + +use constant KEY => "MyTest5"; + +my @directives = ({ name => +KEY },); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub MyTest5 { + my ($self, $parms, $arg) = @_; + $self->{+KEY} = $arg; + unless ($parms->path) { + my $srv_cfg = Apache2::Module::get_config($self, $parms->server); + $srv_cfg->{+KEY} = $arg; + } +} + +### response handler ### + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Module (); +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +sub get_config { + Apache2::Module::get_config(__PACKAGE__, @_); +} + +sub handler { + my ($r) = @_; + my %secs = (); + + $r->content_type('text/plain'); + + my $s = $r->server; + my $dir_cfg = get_config($s, $r->per_dir_config); + my $srv_cfg = get_config($s); + + plan $r, tests => 3; + + ok $s->is_virtual; + + ok t_cmp($dir_cfg->{+KEY}, "Dir", "Section"); + + ok t_cmp($srv_cfg->{+KEY}, "Vhost", "Section"); + + return Apache2::Const::OK; +} + + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 + +<Base> + PerlLoadModule TestDirective::perlloadmodule5 +</Base> +<VirtualHost TestDirective::perlloadmodule5> + # here mod_perl sets the scfg by itself for this vhost + PerlModule File::Spec + MyTest5 "Vhost" + <Location /TestDirective__perlloadmodule5> + MyTest5 "Dir" + SetHandler modperl + PerlResponseHandler TestDirective::perlloadmodule5 + </Location> +</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule6.pm b/2_0_13/t/response/TestDirective/perlloadmodule6.pm new file mode 100644 index 0000000..fd8cdfe --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlloadmodule6.pm
@@ -0,0 +1,90 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlloadmodule6; + +# in this test we test an early mod_perl startup caused by an +# EXEC_ON_READ directive in vhost. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::CmdParms (); +use Apache2::Module (); +use Apache2::ServerUtil (); + +use Apache2::Const -compile => qw(OK); + +use constant KEY => "MyTest6"; + +my @directives = ({ name => +KEY },); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub MyTest6 { + my ($self, $parms, $arg) = @_; + $self->{+KEY} = $arg; + unless ($parms->path) { + my $srv_cfg = Apache2::Module::get_config($self, $parms->server); + $srv_cfg->{+KEY} = $arg; + } +} + +### response handler ### + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::Module (); +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +sub get_config { + Apache2::Module::get_config(__PACKAGE__, @_); +} + +sub handler { + my ($r) = @_; + my %secs = (); + + $r->content_type('text/plain'); + + my $s = $r->server; + my $dir_cfg = get_config($s, $r->per_dir_config); + my $srv_cfg = get_config($s); + + plan $r, tests => 3; + + ok $s->is_virtual; + + ok t_cmp($dir_cfg->{+KEY}, "Dir", "Section"); + + ok t_cmp($srv_cfg->{+KEY}, "Vhost", "Section"); + + return Apache2::Const::OK; +} + +1; +__END__ + +# XXX: we want to have this configuration section to come first +# amongst other perlloadmodule tests (<950), so we can test how +# mod_perl starts from vhost. but currently we can't because +# PerlSwitches from other tests are ignored, so the test suite fails +# to startup. +# +# tmp solution: ensure that it's configured *after* all other +# perlloadmodule tests +# +# APACHE_TEST_CONFIG_ORDER 951 + +<VirtualHost TestDirective::perlloadmodule6> + PerlLoadModule TestDirective::perlloadmodule6 + MyTest6 "Vhost" + <Location /TestDirective__perlloadmodule6> + MyTest6 "Dir" + SetHandler modperl + PerlResponseHandler TestDirective::perlloadmodule6 + </Location> +</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perlloadmodule7.pm b/2_0_13/t/response/TestDirective/perlloadmodule7.pm new file mode 100644 index 0000000..a4fc27a --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlloadmodule7.pm
@@ -0,0 +1,68 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlloadmodule7; + +# this test was written to reproduce a segfault under worker +# due to a bug in custom directive implementation, where +# the code called from modperl_module_config_merge() was setting the +# global context after selecting the new interpreter which was leading +# to a segfault in any handler called thereafter, whose context was +# different beforehand. + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Module (); + +use Apache2::Const -compile => qw(OK); + +use constant KEY1 => "MyTest7_1"; +use constant KEY2 => "MyTest7_2"; + +my @directives = ({ name => +KEY1 }, { name => +KEY2 }); + +Apache2::Module::add(__PACKAGE__, \@directives); + +sub MyTest7_1 { + my ($self, $parms, $arg) = @_; + $self->{+KEY1} = $arg; +} + +sub MyTest7_2 { + my ($self, $parms, $arg) = @_; + $self->{+KEY2} = $arg; +} + +### response handler ### + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +sub handler { + my ($r) = @_; + + plan $r, tests => 1; + + ok 1; + + return Apache2::Const::OK; +} + +1; +__END__ + +<NoAutoConfig> +# APACHE_TEST_CONFIG_ORDER 950 +PerlLoadModule TestDirective::perlloadmodule7 + +MyTest7_1 test +<Location /TestDirective__perlloadmodule7> + MyTest7_2 test + SetHandler modperl + PerlResponseHandler TestDirective::perlloadmodule7 +</Location> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestDirective/perlmodule.pm b/2_0_13/t/response/TestDirective/perlmodule.pm new file mode 100644 index 0000000..8f926a4 --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlmodule.pm
@@ -0,0 +1,62 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlmodule; + +# This test is similar to TestDirective::perlrequire. Here we test +# whether vhost inheriting the parent perl from the base can handle +# PerlModule directives. + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test (); + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use File::Spec::Functions qw(catfile); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + $r->puts($ApacheTest::PerlModuleTest::MAGIC || ''); + + Apache2::Const::OK; +} + +sub APACHE_TEST_CONFIGURE { + my ($class, $self) = @_; + + my $vars = $self->{vars}; + my $target_dir = catfile $vars->{documentroot}, 'testdirective'; + + my $magic = __PACKAGE__; + my $content = <<EOF; +package ApacheTest::PerlModuleTest; +\$ApacheTest::PerlModuleTest::MAGIC = '$magic'; +1; +EOF + my $file = catfile $target_dir, + 'perlmodule-vh', 'ApacheTest', 'PerlModuleTest.pm'; + $self->writefile($file, $content, 1); +} + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 940 + +<Base> + PerlSwitches -I@documentroot@/testdirective/perlmodule-vh +</Base> + +<VirtualHost TestDirective::perlmodule> + PerlModule ApacheTest::PerlModuleTest + + <Location /TestDirective__perlmodule> + SetHandler modperl + PerlResponseHandler TestDirective::perlmodule + </Location> + +</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/perlrequire.pm b/2_0_13/t/response/TestDirective/perlrequire.pm new file mode 100644 index 0000000..1a37130 --- /dev/null +++ b/2_0_13/t/response/TestDirective/perlrequire.pm
@@ -0,0 +1,88 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::perlrequire; + +# Test whether vhost with 'PerlOptions +Parent', which doesn't inherit +# from the base, has its own INC and therefore can have a modules with +# the same namespace as the base, but different content. +# +# Also see the parallel TestDirective::perlmodule handler + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test (); + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use File::Spec::Functions qw(catfile); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + $r->puts($ApacheTest::PerlRequireTest::MAGIC || ''); + + Apache2::Const::OK; +} + +my %require_tests = + ( + main => 'PerlRequired by Parent', + vh => 'PerlRequired by VirtualHost', + ); + +sub APACHE_TEST_CONFIGURE { + my ($class, $self) = @_; + + my $vars = $self->{vars}; + my $target_dir = catfile $vars->{documentroot}, 'testdirective'; + + # create two different PerlRequireTest.pm packages to be loaded by + # vh and main interpreters, on the fly before the tests start + while (my ($test, $magic) = each %require_tests) { + my $content = <<EOF; +package ApacheTest::PerlRequireTest; +\$ApacheTest::PerlRequireTest::MAGIC = '$magic'; +1; +EOF + my $file = catfile $target_dir, + $test, 'ApacheTest', 'PerlRequireTest.pm'; + $self->writefile($file, $content, 1); + } +} + +1; +__END__ +# APACHE_TEST_CONFIG_ORDER 940 + +<Base> + PerlSwitches -I@documentroot@/testdirective/main + PerlRequire "ApacheTest/PerlRequireTest.pm" +</Base> + +<VirtualHost TestDirective::perlrequire> + + <IfDefine PERL_USEITHREADS> + # a new interpreter pool + PerlOptions +Parent + PerlInterpStart 1 + PerlInterpMax 1 + PerlInterpMinSpare 1 + PerlInterpMaxSpare 1 + </IfDefine> + + # use test system's @INC + PerlSwitches -I@serverroot@ + PerlRequire "conf/modperl_inc.pl" + + PerlSwitches -I@documentroot@/testdirective/vh + PerlRequire "ApacheTest/PerlRequireTest.pm" + + <Location /TestDirective__perlrequire> + SetHandler modperl + PerlResponseHandler TestDirective::perlrequire + </Location> + +</VirtualHost>
diff --git a/2_0_13/t/response/TestDirective/pod.pm b/2_0_13/t/response/TestDirective/pod.pm new file mode 100644 index 0000000..b220f2b --- /dev/null +++ b/2_0_13/t/response/TestDirective/pod.pm
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::pod; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 4; + + ok t_cmp $r->dir_config->get('TestDirective__pod_hidden'), undef; + ok t_cmp $r->dir_config->get('TestDirective__pod_over_worked'), 'yes'; + ok t_cmp $r->dir_config->get('TestDirective__pod_cut_worked'), 'yes'; + + #XXX: How to test that __END__ works proprely without cloberring all the other tests? + ok t_cmp '__END__', '__END__'; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestDirective/setupenv.pm b/2_0_13/t/response/TestDirective/setupenv.pm new file mode 100644 index 0000000..dfcdfe7 --- /dev/null +++ b/2_0_13/t/response/TestDirective/setupenv.pm
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestDirective::setupenv; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $ENV{QS} = $r->args if $r->args; + + while (my ($key, $val) = each %ENV) { + next unless $key and $val; + $r->puts("$key=$val\n"); + } + + Apache2::Const::OK; +} + +1; +__END__ +PerlOptions +SetupEnv +
diff --git a/2_0_13/t/response/TestError/api.pm b/2_0_13/t/response/TestError/api.pm new file mode 100644 index 0000000..831d99a --- /dev/null +++ b/2_0_13/t/response/TestError/api.pm
@@ -0,0 +1,34 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestError::api; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use Apache2::RequestIO (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +sub handler { + my $r = shift; + + plan $r, tests => 1; + + $r->content_type('text/plain'); + + # PerlOptions -GlobalRequest is in effect + eval { my $gr = Apache2::RequestUtil->request; }; + ok t_cmp($@, + qr/\$r object is not available/, + "unavailable global $r object"); + + return Apache2::Const::OK; +} + +1; +__END__ +PerlOptions -GlobalRequest
diff --git a/2_0_13/t/response/TestError/runtime.pm b/2_0_13/t/response/TestError/runtime.pm new file mode 100644 index 0000000..91ca446 --- /dev/null +++ b/2_0_13/t/response/TestError/runtime.pm
@@ -0,0 +1,162 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestError::runtime; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Connection (); +use APR::Socket (); +use APR::Status (); + +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); +use APR::Const -compile => qw(EACCES); + +use constant SIZE => 2048; + +sub handler { + my $r = shift; + my $socket = $r->connection->client_socket; + my $args = $r->args; + + $r->content_type('text/plain'); + + # set timeout to 0 to make sure that any socket read call will + # fail + $socket->timeout_set(0); + + no strict 'refs'; + $args->($r, $socket); + + return Apache2::Const::OK; +} + +sub overload_test { + my ($r, $socket) = @_; + + eval { mp_error($socket) }; + + die "there should have been an exception" unless $@; + + die "the exception should have been an APR::Error object" + unless ref $@ eq 'APR::Error'; + + # == && != (expecting an EAGAIN error) + die "APR::Status is broken" unless APR::Status::is_EAGAIN($@); + die "'==' overload is broken" unless $@ == $@; + die "'!=' overload is broken" unless $@ != APR::Const::EACCES; + die "'!=' overload is broken" unless APR::Const::EACCES != $@; + die "'!=' overload is broken" if $@ != $@; + + # XXX: add more overload tests + + $r->print("ok overload_test"); + +} + +sub plain_mp_error { + my ($r, $socket) = @_; + t_server_log_error_is_expected(); + mp_error($socket); +} + +sub plain_non_mp_error { + my ($r, $socket) = @_; + t_server_log_error_is_expected(); + non_mp_error($socket); +} + +sub die_hook_confess_mp_error { + my ($r, $socket) = @_; + local $SIG{__DIE__} = \&APR::Error::confess; + t_server_log_error_is_expected(); + mp_error($socket); +} + +sub die_hook_confess_non_mp_error { + my ($r, $socket) = @_; + local $SIG{__DIE__} = \&APR::Error::confess; + t_server_log_error_is_expected(); + non_mp_error($socket); +} + +sub die_hook_custom_mp_error { + my ($r, $socket) = @_; + local $SIG{__DIE__} = sub { die "custom die hook: $_[0]" }; + t_server_log_error_is_expected(); + mp_error($socket); +} + +sub die_hook_custom_non_mp_error { + my ($r, $socket) = @_; + local $SIG{__DIE__} = sub { die "custom die hook: $_[0]" }; + t_server_log_error_is_expected(); + non_mp_error($socket); +} + +sub eval_block_mp_error { + my ($r, $socket) = @_; + + # throw in some retry attempts + my $tries = 0; + RETRY: eval { mp_error($socket) }; + if ($@ && ref($@) && APR::Status::is_EAGAIN($@)) { + if ($tries++ < 3) { + goto RETRY; + } + else { + $r->print("ok eval_block_mp_error"); + } + } + else { + die "eval block has failed: $@"; + } +} + +sub eval_string_mp_error { + my ($r, $socket) = @_; + eval '$socket->recv(my $buffer, SIZE)'; + if ($@ && ref($@) && APR::Status::is_EAGAIN($@)) { + $r->print("ok eval_string_mp_error"); + } + else { + die "eval string has failed: $@"; + } +} + +sub eval_block_non_mp_error { + my ($r, $socket) = @_; + eval { non_mp_error($socket) }; + if ($@ && !ref($@)) { + $r->print("ok eval_block_non_mp_error"); + } + else { + die "eval eval_non_mp_error has failed: $@"; + } +} + +sub eval_block_non_error { + my ($r, $socket) = @_; + eval { 1; }; + if ($@) { + die "eval eval_block_non_mp_error has failed"; + } + $r->print("ok eval_block_non_error"); +} + +sub non_mp_error { + no_such_func(); +} + +# fails because of the timeout set earlier in the handler +sub mp_error { + my $socket = shift; + $socket->recv(my $buffer, SIZE); +} + +1; +__END__ +
diff --git a/2_0_13/t/response/TestError/syntax.pm b/2_0_13/t/response/TestError/syntax.pm new file mode 100644 index 0000000..3886a8c --- /dev/null +++ b/2_0_13/t/response/TestError/syntax.pm
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestError::syntax; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Const -compile => qw(OK); + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + # the following syntax error is here on purpose! + lkj;\; + + $r->print('ok'); + + return Apache2::Const::OK; +} + +1; +__END__ +
diff --git a/2_0_13/t/response/TestModperl/cookie.pm b/2_0_13/t/response/TestModperl/cookie.pm new file mode 100644 index 0000000..32fccf0 --- /dev/null +++ b/2_0_13/t/response/TestModperl/cookie.pm
@@ -0,0 +1,54 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::cookie; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestTrace; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Const -compile => 'OK'; + +sub access { + my $r = shift; + + # setup CGI variables early + $r->subprocess_env() if $r->args eq 'env'; + + my ($key, $val) = cookie($r); + my $cookie_is_expected = + ($r->args eq 'header' or $r->args eq 'env') ? 1 : 0; + die "Can't get the cookie" if $cookie_is_expected && !defined $val; + + return Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + my ($key, $val) = cookie($r); + $r->print($val) if defined $val; + + return Apache2::Const::OK; +} + +sub cookie { + my $r = shift; + + my $header = $r->headers_in->{Cookie} || ''; + my $env = $ENV{HTTP_COOKIE} || $ENV{COOKIE} || ''; # from CGI::Cookie + debug "cookie (" .$r->args . "): header: [$header], env: [$env]"; + + return split '=', $r->args eq 'header' ? $header : $env; +} + +1; + +__DATA__ +SetHandler perl-script +PerlModule TestModperl::cookie +PerlAccessHandler TestModperl::cookie::access +PerlResponseHandler TestModperl::cookie +PerlOptions -SetupEnv
diff --git a/2_0_13/t/response/TestModperl/cookie2.pm b/2_0_13/t/response/TestModperl/cookie2.pm new file mode 100644 index 0000000..1f8a289 --- /dev/null +++ b/2_0_13/t/response/TestModperl/cookie2.pm
@@ -0,0 +1,49 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::cookie2; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestTrace; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +use Apache2::Const -compile => 'OK'; + +sub access { + my $r = shift; + + $r->subprocess_env if $r->args eq 'subprocess_env'; + my ($key, $val) = cookie($r); + die "I shouldn't get the cookie" if $r->args eq 'env' && defined $val; + + return Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + my ($key, $val) = cookie($r); + $r->print($val) if defined $val; + + return Apache2::Const::OK; +} + +sub cookie { + my $r = shift; + + my $header = $r->headers_in->{Cookie} || ''; + my $env = $ENV{HTTP_COOKIE} || $ENV{COOKIE} || ''; # from CGI::cookie2 + debug "cookie (" .$r->args . "): header: [$header], env: [$env]"; + + return split '=', $r->args eq 'header' ? $header : $env; +} + +1; + +__DATA__ +SetHandler modperl +PerlModule TestModperl::cookie2 +PerlAccessHandler TestModperl::cookie2::access +PerlResponseHandler TestModperl::cookie2
diff --git a/2_0_13/t/response/TestModperl/current_callback.pm b/2_0_13/t/response/TestModperl/current_callback.pm new file mode 100644 index 0000000..a80425f --- /dev/null +++ b/2_0_13/t/response/TestModperl/current_callback.pm
@@ -0,0 +1,50 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::current_callback; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use ModPerl::Util; + +use APR::Table (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => qw(OK DECLINED); + +sub handler { + my $r = shift; + + plan $r, tests => 1; + my $callback = ModPerl::Util::current_callback(); + ok t_cmp($callback, + 'PerlResponseHandler', + 'inside PerlResponseHandler'); + + #warn "in callback: $callback\n"; + + Apache2::Const::OK; +} + +sub log { check('Log') } +sub fixup { check('Fixup') } +sub headerparser { check('HeaderParser') } + +sub check { + my $expected = 'Perl' . shift() . 'Handler'; + my $callback = ModPerl::Util::current_callback(); + die "expecting $expected callback, instead got $callback" + unless $callback eq $expected; + #warn "in callback: $callback\n"; + return Apache2::Const::OK; +} + +1; +__DATA__ +PerlModule TestModperl::current_callback +PerlHeaderParserHandler TestModperl::current_callback::headerparser +PerlFixupHandler TestModperl::current_callback::fixup +PerlResponseHandler TestModperl::current_callback +PerlLogHandler TestModperl::current_callback::log +SetHandler modperl
diff --git a/2_0_13/t/response/TestModperl/dir_config.pm b/2_0_13/t/response/TestModperl/dir_config.pm new file mode 100644 index 0000000..b5608fd --- /dev/null +++ b/2_0_13/t/response/TestModperl/dir_config.pm
@@ -0,0 +1,189 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::dir_config; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::RequestUtil (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 15; + + #Apache2::RequestRec::dir_config tests + + # this test doesn't test all $r->dir_config->*(), since + # dir_config() returns a generic APR::Table which is tested in + # apr/table.t. + + # object test + my $dir_config = $r->dir_config; + ok defined $dir_config && ref($dir_config) eq 'APR::Table'; + + # make sure trying to get something that's not defined + # doesn't blow up + my $undef = $r->dir_config('EDOESNOTEXIST'); + + ok t_cmp($undef, undef, + 'no PerlSetVar to get data from'); + + # PerlAddVar ITERATE2 test + { + my $key = make_key('1'); + my @received = $dir_config->get($key); + my @expected = qw(1_SetValue 2_AddValue 3_AddValue 4_AddValue); + + ok t_cmp(\@received, \@expected, + 'PerlAddVar ITERATE2'); + } + + # sub-section inherits from super-section if it doesn't override it + { + my $key = make_key('_set_in_Base'); + ok t_cmp($r->dir_config($key), + 'BaseValue', + "sub-section inherits from super-section " . + "if it doesn't override it"); + } + + # sub-section overrides super-section for the same key + { + my $key = 'TestModperl__server_rec_Key_set_in_Base'; + ok t_cmp($r->dir_config->get($key), 'SubSecValue', + "sub-section overrides super-section for the same key"); + } + + { + my $key = make_key('0'); + + # object interface test in a scalar context (for a single + # PerlSetVar key) + ok t_cmp($dir_config->get($key), + 'SetValue0', + "table get() in a scalar context"); + + # direct fetch test in a scalar context (for a single + # PerlSetVar key) + ok t_cmp($r->dir_config($key), + 'SetValue0', + "direct value fetch in a scalar context"); + } + + # make sure 0 comes through as 0 and not undef + { + my $key = 'TestModperl__request_rec_ZeroKey'; + + ok t_cmp($r->dir_config($key), + 0, + 'table value 0 is not undef'); + } + + # test non-existent key + { + my $key = make_key(); + + ok t_cmp($r->dir_config($key), + undef, + "non-existent key"); + } + + # test set interface + { + my $key = make_key(); + my $val = "DirConfig"; + + $r->dir_config($key => $val); + + ok t_cmp($r->dir_config($key), + $val, + "set && get"); + } + + # test unset interface + { + my $key = make_key(); + + $r->dir_config($key => 'whatever'); + $r->dir_config($key => undef); + + ok t_cmp(undef, + $r->dir_config($key), + "unset"); + } + + + #Apache2::ServerUtil::dir_config tests + + my $s = $r->server; + + # this test doesn't test all $s->dir_config->*(), since + # dir_config() returns a generic APR::Table which is tested in + # apr/table.t. + + # object test + $dir_config = $s->dir_config; + ok defined $dir_config && ref($dir_config) eq 'APR::Table'; + + # PerlAddVar ITERATE2 test + { + my $key = 'TestModperl__server_rec_Key_set_in_Base'; + my @received = $dir_config->get($key); + my @expected = qw(1_SetValue 2_AddValue 3_AddValue); + + ok t_cmp(\@received, \@expected, + "testing PerlAddVar ITERATE2 in \$s"); + } + + { + # base server test + my $bs = Apache2::ServerUtil->server; + ok t_cmp(($bs && ref($bs)), + 'Apache2::ServerRec', + "base server's object retrieval"); + + my $key = 'TestModperl__server_rec_Key_set_in_Base'; + ok t_cmp(scalar ($bs->dir_config->get($key)), + '1_SetValue', + "read dir_config of the base server"); + } + + Apache2::Const::OK; +} + +my $key_base = "TestModperl__request_rec_Key"; +my $counter = 0; + +sub make_key { + return $key_base . + (defined $_[0] + ? $_[0] + : unpack "H*", pack "n", ++$counter . rand(100)); +} +1; +__END__ +<Base> + PerlSetVar TestModperl__request_rec_Key_set_in_Base BaseValue + + PerlSetVar TestModperl__server_rec_Key_set_in_Base 1_SetValue + PerlAddVar TestModperl__server_rec_Key_set_in_Base 2_AddValue 3_AddValue +</Base> + +PerlSetVar TestModperl__request_rec_ZeroKey 0 + +PerlSetVar TestModperl__request_rec_Key0 SetValue0 + +PerlSetVar TestModperl__request_rec_Key1 ToBeLost +PerlSetVar TestModperl__request_rec_Key1 1_SetValue +PerlAddVar TestModperl__request_rec_Key1 2_AddValue +PerlAddVar TestModperl__request_rec_Key1 3_AddValue 4_AddValue + +PerlSetVar TestModperl__server_rec_Key_set_in_Base SubSecValue
diff --git a/2_0_13/t/response/TestModperl/endav.pm b/2_0_13/t/response/TestModperl/endav.pm new file mode 100644 index 0000000..5860d52 --- /dev/null +++ b/2_0_13/t/response/TestModperl/endav.pm
@@ -0,0 +1,59 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::endav; + +use strict; +use warnings FATAL => 'all'; + +use ModPerl::Global (); + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 4; + + #just to make sure we dont segv with bogus values + my $not = 'NoSuchPackage'; + for my $name ('END', $not) { + ModPerl::Global::special_list_call( $name => $not); + ModPerl::Global::special_list_clear($name => $not); + } + + # register the current package to set its END blocks aside + ModPerl::Global::special_list_register(END => __PACKAGE__); + # clear anything that was previously set + ModPerl::Global::special_list_clear(END => __PACKAGE__); + eval 'END { ok 1 }'; + + # now run them twice:ok 1 (1), ok 1 (2) + ModPerl::Global::special_list_call(END => __PACKAGE__); + ModPerl::Global::special_list_call(END => __PACKAGE__); + + ModPerl::Global::special_list_clear(END => __PACKAGE__); + #should do nothing + ModPerl::Global::special_list_call( END => __PACKAGE__); + + # this we've already registered this package's END blocks, adding + # new ones will set them aside + eval 'END { ok 1 }'; + + # so this will run ok 1 (3) + ModPerl::Global::special_list_call( END => __PACKAGE__); + ModPerl::Global::special_list_clear(END => __PACKAGE__); + + ModPerl::Global::special_list_clear(END => __PACKAGE__); + #should do nothing + ModPerl::Global::special_list_call( END => __PACKAGE__); + + # one plain ok 1 (4) + ok 1; + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/env.pm b/2_0_13/t/response/TestModperl/env.pm new file mode 100644 index 0000000..ac057a9 --- /dev/null +++ b/2_0_13/t/response/TestModperl/env.pm
@@ -0,0 +1,87 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::env; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 23 + 3 * keys(%ENV); + + my $env = $r->subprocess_env; + + ok $ENV{MODPERL_EXTRA_PL}; #set in t/conf/modperl_extra.pl + ok $ENV{MOD_PERL}; + ok $ENV{MOD_PERL_API_VERSION}; + + ok $ENV{SERVER_SOFTWARE}; + ok $env->get('SERVER_SOFTWARE'); + + { + $ENV{FOO} = 2; + ok $ENV{FOO} == 2; + ok $env->get('FOO') == 2; + + $ENV{FOO}++; + ok $ENV{FOO} == 3; + ok $env->get('FOO') == 3; + + $ENV{FOO} .= 6; + ok $ENV{FOO} == 36; + ok $env->get('FOO') == 36; + + delete $ENV{FOO}; + ok ! $ENV{FOO}; + ok ! $env->get('FOO'); + } + + { + local %ENV = (FOO => 1, BAR => 2); + + ok $ENV{FOO} == 1; + ok $env->get('FOO') == 1; + + ok ! $ENV{SERVER_SOFTWARE}; + ok ! $env->get('SERVER_SOFTWARE'); + } + + ok ! $ENV{FOO}; + skip "r->subprocess_env + local() doesnt fully work yet", 1; + #ok ! $env->get('FOO'); + + { + my $key = 'SERVER_SOFTWARE'; + my $val = $ENV{SERVER_SOFTWARE}; + ok $val; + ok t_cmp $env->get($key), $val, '$r->subprocess_env->get($key)'; + ok t_cmp $r->subprocess_env($key), $val, '$r->subprocess_env($key)'; + + $val = 'BAR'; + $r->subprocess_env($key => $val); + ok t_cmp $r->subprocess_env($key), $val, + '$r->subprocess_env($key => $val)'; + } + + # make sure each key can be deleted + for my $key (sort keys %ENV) { + eval { delete $ENV{$key}; }; + ok t_cmp($@, '', $key); + ok t_cmp($ENV{$key}, undef, "ENV{$key} is empty"); + ok t_cmp($env->get($key), undef, "subprocess_env($key) is empty"); + } + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/exit.pm b/2_0_13/t/response/TestModperl/exit.pm new file mode 100644 index 0000000..31b8e33 --- /dev/null +++ b/2_0_13/t/response/TestModperl/exit.pm
@@ -0,0 +1,45 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::exit; + +# there is no need to call ModPerl::Util::exit() explicitly, a plain +# exit() will do. We do the explicit fully qualified call in this +# test, in case something has messed up with CORE::GLOBAL::exit and we +# want to make sure that we test the right API + +use strict; +use warnings FATAL => 'all'; + +use ModPerl::Util (); + +use Apache2::Const -compile => 'OK'; +use ModPerl::Const -compile => 'EXIT'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + my $args = $r->args; + + if ($args eq 'eval') { + eval { + my $whatever = 1; + ModPerl::Util::exit(); + }; + # test whether we can stringify our custom error messages + $r->print("$@"); + ModPerl::Util::exit if $@ && ref $@ && $@ == ModPerl::EXIT; + } + elsif ($args eq 'noneval') { + $r->print("exited"); + ModPerl::Util::exit(); + } + + # must not be reached + $r->print("must not be reached"); + + Apache2::Const::OK; +} + +1; +__END__ +
diff --git a/2_0_13/t/response/TestModperl/getc.pm b/2_0_13/t/response/TestModperl/getc.pm new file mode 100644 index 0000000..1b49f22 --- /dev/null +++ b/2_0_13/t/response/TestModperl/getc.pm
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::getc; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + untie *STDIN; + tie *STDIN, $r; + + while (my $c = getc) { + die "got more than 1 char" unless length($c) == 1; + $r->puts($c); + } + + untie *STDIN; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestModperl/interpreter.pm b/2_0_13/t/response/TestModperl/interpreter.pm new file mode 100644 index 0000000..0e01f9b --- /dev/null +++ b/2_0_13/t/response/TestModperl/interpreter.pm
@@ -0,0 +1,81 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::interpreter; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::MPM (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $is_threaded=Apache2::MPM->is_threaded; + + plan $r, tests => $is_threaded?17:5, need + need_threads, + {"perl >= 5.8.1 is required (this is $])" => ($] >= 5.008001)}; + + require ModPerl::Interpreter; + require ModPerl::InterpPool; + require ModPerl::TiPool; + require ModPerl::TiPoolConfig; + + my $interp = ModPerl::Interpreter->current; + + ok t_cmp(ref($interp), 'ModPerl::Interpreter', + 'interp is a ModPerl::Interpreter'); + + ok t_cmp($$interp==${ModPerl::Interpreter::current()}, !!1, + 'ModPerl::Interpreter->current == ModPerl::Interpreter::current'); + + my $mip = $interp->mip; + + ok t_cmp(ref($mip), 'ModPerl::InterpPool', + 'interp->mip is a ModPerl::InterpPool'); + + ok t_cmp(${$mip->server}==${$r->server}, !!1, + 'mip->server == r->server'); + + ok t_cmp(ref($mip->parent), 'ModPerl::Interpreter', + 'mip->parent is a ModPerl::Interpreter'); + + if($is_threaded) { + ok t_cmp($interp->perl!=0, !!1, 'interp->perl'); + ok t_cmp($interp->num_requests>0, !!1, 'interp->num_requests'); + ok t_cmp($interp->refcnt>0, !!1, 'interp->refcnt'); + + my $tipool = $mip->tipool; + + ok t_cmp(ref($tipool), 'ModPerl::TiPool', + 'mip->tipool is a ModPerl::TiPool'); + + ok t_cmp($tipool->in_use!=0, !!1, 'tipool->in_use'); + + ok t_cmp($tipool->size!=0, !!1, 'tipool->size'); + + my $tipcfg = $tipool->cfg; + + ok t_cmp(ref($tipcfg), 'ModPerl::TiPoolConfig', + 'tipool->cfg is a ModPerl::TiPoolConfig'); + + ok t_cmp($tipcfg->start!=0, !!1, 'tipcfg->start'); + + ok t_cmp($tipcfg->min_spare!=0, !!1, 'tipcfg->min_spare'); + + ok t_cmp($tipcfg->max_spare!=0, !!1, 'tipcfg->max_spare'); + + ok t_cmp($tipcfg->max!=0, !!1, 'tipcfg->max'); + + ok t_cmp($tipcfg->max_requests!=0, !!1, 'tipcfg->max_requests'); + } + + Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestModperl/io_nested_with_closed_stds.pm b/2_0_13/t/response/TestModperl/io_nested_with_closed_stds.pm new file mode 100644 index 0000000..f87373c --- /dev/null +++ b/2_0_13/t/response/TestModperl/io_nested_with_closed_stds.pm
@@ -0,0 +1,64 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::io_nested_with_closed_stds; + +# test that we can successfully override STD(IN|OUT) for +# 'perl-script', even if they are closed. Here we use +# internal_redirect(), which causes a nested override of already +# overriden STD streams + +# in this test we can't use my $foo as a filehandle, since perl 5.6 +# doesn't know how to dup via: 'open STDIN, "<&", $oldin' +# so use the old FOO filehandle style + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $args = $r->args || ''; + if ($args eq 'redirect') { + # sub-req + $r->content_type('text/plain'); + # do not use plan() here, since it messes up with STDOUT, + # which affects this test. + print "1..1\nok 1\n"; + } + else { + # main-req + my $redirect_uri = $r->uri . "?redirect"; + + # we must close STDIN as well, due to a perl bug (5.8.0 - 5.8.3 + # w/useperlio), which emits a warning if dup is called with + # one of the STD streams is closed. + # but we must restore the STD streams so not to affect other + # tests. + open OLDIN, "<&STDIN" or die "Can't dup STDIN: $!"; + open OLDOUT, ">&STDOUT" or die "Can't dup STDOUT: $!"; + close STDIN; + close STDOUT; + + $r->internal_redirect($redirect_uri); + + open STDIN, "<&OLDIN" or die "Can't dup OLDIN: $!"; + open STDOUT, ">&OLDOUT" or die "Can't dup OLDOUT: $!"; + close OLDIN; + close OLDOUT; + } + + Apache2::Const::OK; +} + +1; +__DATA__ +SetHandler perl-script +
diff --git a/2_0_13/t/response/TestModperl/io_with_closed_stds.pm b/2_0_13/t/response/TestModperl/io_with_closed_stds.pm new file mode 100644 index 0000000..b07a7cd --- /dev/null +++ b/2_0_13/t/response/TestModperl/io_with_closed_stds.pm
@@ -0,0 +1,67 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::io_with_closed_stds; + +# test that we can successfully override STD(IN|OUT) for +# 'perl-script', even if they are closed. + +# in this test we can't use my $foo as a filehandle, since perl 5.6 +# doesn't know how to dup via: 'open STDIN, "<&", $oldin' +# so use the old FOO filehandle style, which is also global, so we +# don't even need to pass it around (very bad code style, but I see no +# better solution if we want to have this test run under perl 5.6) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestUtil (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +sub fixup { + my $r = shift; + + # we must close STDIN as well, due to a perl bug (5.8.0 - 5.8.3 + # w/useperlio), which emits a warning if dup is called with + # one of the STD streams is closed. + open OLDIN, "<&STDIN" or die "Can't dup STDIN: $!"; + open OLDOUT, ">&STDOUT" or die "Can't dup STDOUT: $!"; + close STDIN; + close STDOUT; + + Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + plan $r, tests => 1; + + ok 1; + + Apache2::Const::OK; +} + +sub cleanup { + my $r = shift; + + # restore the STD(IN|OUT) streams so not to affect other tests. + open STDIN, "<&OLDIN" or die "Can't dup OLDIN: $!"; + open STDOUT, ">&OLDOUT" or die "Can't dup OLDOUT: $!"; + close OLDIN; + close OLDOUT; + + Apache2::Const::OK; +} + +1; +__DATA__ +PerlModule TestModperl::io_with_closed_stds +SetHandler perl-script +PerlFixupHandler TestModperl::io_with_closed_stds::fixup +PerlResponseHandler TestModperl::io_with_closed_stds +PerlCleanupHandler TestModperl::io_with_closed_stds::cleanup
diff --git a/2_0_13/t/response/TestModperl/local_env.pm b/2_0_13/t/response/TestModperl/local_env.pm new file mode 100644 index 0000000..ed18c6a --- /dev/null +++ b/2_0_13/t/response/TestModperl/local_env.pm
@@ -0,0 +1,54 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::local_env; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +# local %ENV used to cause segfaults +# Report: http://thread.gmane.org/gmane.comp.apache.mod-perl/22236 +# Fixed in: http://svn.apache.org/viewcvs.cgi?rev=357236&view=rev +sub handler { + my $r = shift; + + plan $r, tests => 6; + + my %copy_ENV = %ENV; ## this is not a deep copy; + + ok t_cmp($ENV{MOD_PERL_API_VERSION}, 2, + "\$ENV{MOD_PERL_API_VERSION} is 2 before local \%ENV"); + + { + local %ENV; + + ok t_cmp($ENV{MOD_PERL_API_VERSION}, undef, + "\$ENV{MOD_PERL_API_VERSION} is undef after local \%ENV"); + + ok t_cmp(scalar keys %ENV, 0, + "\%ENV has 0 keys after local"); + + $ENV{LOCAL} = 1; + + ok t_cmp($ENV{LOCAL}, 1, + "can set value after local, but still in block"); + } + + ok t_cmp($ENV{LOCAL}, undef, + "valuee set in local {} block is gone after leaving scope"); + + ok t_cmp(\%copy_ENV, \%ENV, "\%ENV was restored correctly"); + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/merge.pm b/2_0_13/t/response/TestModperl/merge.pm new file mode 100644 index 0000000..da4460a --- /dev/null +++ b/2_0_13/t/response/TestModperl/merge.pm
@@ -0,0 +1,188 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::merge; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::ServerRec (); +use Apache2::ServerUtil (); +use Apache2::RequestUtil (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +# this is the configuration and handler for t/modperl/merge.t, +# t/modperl/merge2.t, and t/modperl/merge3.t. see any of those +# tests and/or the below configuration for more details + +# result tables for the below tests (trying to make the code more +# simple...) the hash itself represents a request +# the keys to the main hash represent merge levels - 1 for the +# non-overriding merge, 2 for an overriding merge, and 3 for a +# two-level merge the rest should be self-explanatory - settings and +# expected values. +our %merge1 = ( + 1 => { PerlPassEnv => [APACHE_TEST_HOSTTYPE => 'z80'], + PerlSetEnv => [MergeSetEnv1 => 'SetEnv1Val'], + PerlSetVar => [MergeSetVar1 => 'SetVar1Val'], + PerlAddVar => [MergeAddVar1 => ['AddVar1Val1', + 'AddVar1Val2']], + }, + 2 => { PerlSetEnv => [MergeSetEnv2 => 'SetEnv2Val'], + PerlSetVar => [MergeSetVar2 => 'SetVar2Val'], + PerlAddVar => [MergeAddVar2 => ['AddVar2Val1', + 'AddVar2Val2']], + }, + 3 => { PerlSetEnv => [MergeSetEnv3 => 'SetEnv3Val'], + PerlSetVar => [MergeSetVar3 => 'SetVar3Val'], + PerlAddVar => [MergeAddVar3 => ['AddVar3Val1', + 'AddVar3Val2']], + }, +); + +our %merge2 = ( + 1 => { PerlPassEnv => [APACHE_TEST_HOSTTYPE => 'z80'], + PerlSetEnv => [MergeSetEnv1 => 'SetEnv1Val'], + PerlSetVar => [MergeSetVar1 => 'SetVar1Val'], + PerlAddVar => [MergeAddVar1 => ['AddVar1Val1', + 'AddVar1Val2']], + }, + 2 => { PerlSetEnv => [MergeSetEnv2 => 'SetEnv2Merge2Val'], + PerlSetVar => [MergeSetVar2 => 'SetVar2Merge2Val'], + PerlAddVar => [MergeAddVar2 => ['AddVar2Merge2Val1', + 'AddVar2Merge2Val2']], + }, + 3 => { PerlSetEnv => [MergeSetEnv3 => 'SetEnv3Val'], + PerlSetVar => [MergeSetVar3 => 'SetVar3Val'], + PerlAddVar => [MergeAddVar3 => ['AddVar3Val1', + 'AddVar3Val2']], + }, +); + +our %merge3 = ( + 1 => { PerlPassEnv => [APACHE_TEST_HOSTTYPE => 'z80'], + PerlSetEnv => [MergeSetEnv1 => 'SetEnv1Val'], + PerlSetVar => [MergeSetVar1 => 'SetVar1Val'], + PerlAddVar => [MergeAddVar1 => ['AddVar1Val1', + 'AddVar1Val2']], + }, + 2 => { PerlSetEnv => [MergeSetEnv2 => 'SetEnv2Merge3Val'], + PerlSetVar => [MergeSetVar2 => 'SetVar2Merge3Val'], + PerlAddVar => [MergeAddVar2 => ['AddVar2Merge3Val1', + 'AddVar2Merge3Val2']], + }, + 3 => { PerlSetEnv => [MergeSetEnv3 => 'SetEnv3Merge3Val'], + PerlSetVar => [MergeSetVar3 => 'SetVar3Merge3Val'], + PerlAddVar => [MergeAddVar3 => ['AddVar3Merge3Val1', + 'AddVar3Merge3Val2']], + }, +); + +sub handler { + my $r = shift; + + plan $r, tests => 10; + + my $uri = $r->uri; + my $hash; + + if ($uri =~ m/(merge3)/) { + $hash = $1; + } elsif ($uri =~ m/(merge2)/) { + $hash = $1; + } else { + $hash = 'merge1'; + } + + t_debug("testing against results in $hash"); + + no strict qw(refs); + foreach my $level (sort keys %$hash) { + foreach my $directive (sort keys %{ $hash->{$level} }) { + my $key = $hash->{$level}->{$directive}->[0]; + my $value = $hash->{$level}->{$directive}->[1]; + + my @expected = ref $value ? @$value : $value; + + my $comment = join ' ', $directive, $key, @expected; + + if ($directive =~ m/Env/) { + my $received = $ENV{$key}; + ok t_cmp($received, $expected[0], $comment); + } + elsif ($directive =~ m/Set/) { + my $received = $r->dir_config->get($key); + ok t_cmp($received, $expected[0], $comment); + } + else { + my @received = $r->dir_config->get($key); + ok t_cmp(\@received, \@expected, $comment); + } + } + } + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> + PerlModule TestModperl::merge + + <VirtualHost TestModperl::merge> + # these should pass through all merges untouched + PerlPassEnv APACHE_TEST_HOSTTYPE + PerlSetEnv MergeSetEnv1 SetEnv1Val + PerlSetVar MergeSetVar1 SetVar1Val + PerlSetVar MergeAddVar1 AddVar1Val1 + PerlAddVar MergeAddVar1 AddVar1Val2 + + # these are overridden in /merge2 and /merge3 + PerlSetEnv MergeSetEnv2 SetEnv2Val + PerlSetVar MergeSetVar2 SetVar2Val + PerlSetVar MergeAddVar2 AddVar2Val1 + PerlAddVar MergeAddVar2 AddVar2Val2 + + # these are overridden in /merge3 only + PerlSetEnv MergeSetEnv3 SetEnv3Val + PerlSetVar MergeSetVar3 SetVar3Val + PerlSetVar MergeAddVar3 AddVar3Val1 + PerlAddVar MergeAddVar3 AddVar3Val2 + + <Location /merge> + # same as per-server level + SetHandler perl-script + PerlResponseHandler TestModperl::merge + </Location> + + <Location /merge2> + # overrides "2" values - "1" and "3" values left untouched + PerlSetEnv MergeSetEnv2 SetEnv2Merge2Val + PerlSetVar MergeSetVar2 SetVar2Merge2Val + PerlSetVar MergeAddVar2 AddVar2Merge2Val1 + PerlAddVar MergeAddVar2 AddVar2Merge2Val2 + + SetHandler perl-script + PerlResponseHandler TestModperl::merge + </Location> + + AccessFileName htaccess + <Directory @DocumentRoot@/merge3> + # overrides "2" values + PerlSetEnv MergeSetEnv2 SetEnv2Merge3Val + PerlSetVar MergeSetVar2 SetVar2Merge3Val + PerlSetVar MergeAddVar2 AddVar2Merge3Val1 + PerlAddVar MergeAddVar2 AddVar2Merge3Val2 + + SetHandler perl-script + PerlResponseHandler TestModperl::merge + + # override "3" values + AllowOverride all + </Directory> + + </VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestModperl/method.pm b/2_0_13/t/response/TestModperl/method.pm new file mode 100644 index 0000000..568784e --- /dev/null +++ b/2_0_13/t/response/TestModperl/method.pm
@@ -0,0 +1,56 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::method; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +use Apache2::Const -compile => 'OK'; + +sub new { + my $class = shift; + + bless { + perl_version => $], + }, $class; +} + +sub handler : method { + my ($self, $r) = @_; + + my $tests = 3; + + my $is_obj = ref($self); + + if ($is_obj) { + $tests += 1; + } + + plan $r, tests => $tests; + + ok t_cmp(scalar @_, 2, + '@_ == 2'); + + my $class = ref($self) || $self; + + ok t_cmp($class, $class, + 'handler class'); + + ok t_cmp( + $r->uri, + '/' . Apache::TestRequest::module2path($class), + '$r->uri eq $location'); + + if ($is_obj) { + ok t_cmp($self->{perl_version}, $], + 'object handler data'); + } + + Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestModperl/methodname.pm b/2_0_13/t/response/TestModperl/methodname.pm new file mode 100644 index 0000000..e5464a6 --- /dev/null +++ b/2_0_13/t/response/TestModperl/methodname.pm
@@ -0,0 +1,21 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::methodname; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +use TestModperl::method (); + +#no : method attribute required when -> config syntax is used +sub response { + TestModperl::method::handler(@_); +} + +1; +__END__ +PerlResponseHandler TestModperl::methodname->response
diff --git a/2_0_13/t/response/TestModperl/methodobj.pm b/2_0_13/t/response/TestModperl/methodobj.pm new file mode 100644 index 0000000..3d8f3af --- /dev/null +++ b/2_0_13/t/response/TestModperl/methodobj.pm
@@ -0,0 +1,16 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::methodobj; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Const -compile => 'OK'; + +use TestModperl::method (); + +our @ISA = qw(TestModperl::method); + +1; +__END__ +PerlResponseHandler $TestModperl::MethodObj->handler +
diff --git a/2_0_13/t/response/TestModperl/perl.pm b/2_0_13/t/response/TestModperl/perl.pm new file mode 100644 index 0000000..a49c784 --- /dev/null +++ b/2_0_13/t/response/TestModperl/perl.pm
@@ -0,0 +1,30 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::perl; + +# this test includes tests for buggy Perl functions for which mod_perl +# provides a workaround + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 1; + + ok t_cmp("SNXJvM5I.PJrE", + crypt("testing", "SNXJvM5I.PJrE"), + "crypt"); + + Apache2::Const::OK; +} + +1; +__END__ + +
diff --git a/2_0_13/t/response/TestModperl/perl_options.pm b/2_0_13/t/response/TestModperl/perl_options.pm new file mode 100644 index 0000000..9908650 --- /dev/null +++ b/2_0_13/t/response/TestModperl/perl_options.pm
@@ -0,0 +1,63 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::perl_options; + +# test whether PerlOptions options are enabled + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use Apache2::ServerUtil (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +my @srv_plus = qw(ChildInit ChildExit Fixup); +my @srv_minus = qw(PreConnection ProcessConnection Autoload + Log InputFilter OutputFilter); +my @dir_plus = qw(ParseHeaders MergeHandlers); +my @dir_minus = qw(SetupEnv GlobalRequest); + +sub handler { + my $r = shift; + + plan $r, tests => @srv_plus + @srv_minus + @dir_plus + @dir_minus; + my $s = $r->server; + + ok t_cmp($s->is_perl_option_enabled($_), 1, + "PerlOptions +$_") for @srv_plus; + + ok t_cmp($s->is_perl_option_enabled($_), 0, + "PerlOptions -$_") for @srv_minus; + + ok t_cmp($r->is_perl_option_enabled($_), 1, + "PerlOptions +$_") for @dir_plus; + + ok t_cmp($r->is_perl_option_enabled($_), 0, + "PerlOptions -$_") for @dir_minus; + + return Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> +<VirtualHost TestModperl::perl_options> + PerlOptions -PreConnection -ProcessConnection + PerlOptions -Autoload -Log -InputFilter -OutputFilter + PerlOptions +ChildInit +ChildExit + PerlModule TestModperl::perl_options + PerlOptions +ParseHeaders + <Location /TestModperl__perl_options> + SetHandler modperl + PerlOptions -GlobalRequest -SetupEnv + PerlOptions +MergeHandlers + PerlResponseHandler TestModperl::perl_options + </Location> +</VirtualHost> +</NoAutoConfig> +
diff --git a/2_0_13/t/response/TestModperl/perl_options2.pm b/2_0_13/t/response/TestModperl/perl_options2.pm new file mode 100644 index 0000000..29f8a46 --- /dev/null +++ b/2_0_13/t/response/TestModperl/perl_options2.pm
@@ -0,0 +1,70 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::perl_options2; + +# test whether PerlOptions None works + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use Apache2::ServerUtil (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK); + +my @srv = qw( + OpenLogs + PostConfig + ChildInit + ChildExit + + PreConnection + ProcessConnection + + InputFilter + OutputFilter + + PostReadRequest + Trans + MapToStorage + HeaderParser + Access + Authen + Authz + Type + Fixup + Log + Cleanup +); + +sub handler { + my $r = shift; + + plan $r, tests => scalar @srv, skip_reason('PerlOptions None is broken'); + + my $s = $r->server; + + ok t_cmp($s->is_perl_option_enabled($_), 0, + "$_ is off under PerlOptions None") for @srv; + + ok t_cmp($s->is_perl_option_enabled('Response'), 1, + "Response is off under PerlOptions None"); + + return Apache2::Const::OK; +} + +1; +__DATA__ +<NoAutoConfig> +<VirtualHost TestModperl::perl_options2> + PerlOptions None +Response + <Location /TestModperl__perl_options2> + SetHandler modperl + PerlResponseHandler TestModperl::perl_options2 + </Location> +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestModperl/pnotes.pm b/2_0_13/t/response/TestModperl/pnotes.pm new file mode 100644 index 0000000..1a354aa --- /dev/null +++ b/2_0_13/t/response/TestModperl/pnotes.pm
@@ -0,0 +1,127 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::pnotes; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestUtil (); +use Apache2::ConnectionUtil (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + # make it ok to call ok() here while plan()ing elsewhere + Apache::Test::init_test_pm($r); + + Test::_reset_globals() if Test->can('_reset_globals'); + $Test::ntest = 1 + (26 * ($r->args - 1)); + $Test::planned = 26; + + my $c = $r->connection; + + # we call this handler 3 times. + # $r->pnotes('request') should be unset each time + # $c->pnotes('connection') should be unset the first + # time but set the second time due to the keepalive + # request. the second request then cleans up after + # itself, leaving $c->pnotes again unset at the + # start of the third request + if ($r->args == 2) { + ok t_cmp($c->pnotes('connection'), + 'CSET', + '$c->pnotes() persists across keepalive requests'); + } + else { + t_debug('testing $c->pnotes is empty'); + ok (! $c->pnotes('connection')); + } + + # $r->pnotes should be reset each time + t_debug('testing $r->pnotes is empty'); + ok (! $r->pnotes('request')); + + foreach my $map ({type => 'r', object => $r}, + {type => 'c', object => $c}) { + + my $type = $map->{type}; + + my $o = $map->{object}; + + t_debug("testing $type->pnotes call"); + ok $o->pnotes; + + ok t_cmp($o->pnotes('pnotes_foo', 'pnotes_bar'), + 'pnotes_bar', + "$type->pnotes(key,val)"); + + ok t_cmp($o->pnotes('pnotes_foo'), + 'pnotes_bar', + "$type->pnotes(key)"); + + ok t_cmp(ref($o->pnotes), 'HASH', "ref($type->pnotes)"); + + ok t_cmp($o->pnotes()->{'pnotes_foo'}, 'pnotes_bar', + "$type->pnotes()->{}"); + + # unset the entry (but the entry remains with undef value) + $o->pnotes('pnotes_foo', undef); + ok t_cmp($o->pnotes('pnotes_foo'), undef, + "unset $type contents"); + + my $exists = exists $o->pnotes->{'pnotes_foo'}; + $exists = 1 if $] < 5.008001; # changed in perl 5.8.1 + ok $exists; + + # now delete completely (possible only via the hash inteface) + delete $o->pnotes()->{'pnotes_foo'}; + ok t_cmp($o->pnotes('pnotes_foo'), undef, + "deleted $type contents"); + ok !exists $o->pnotes->{'pnotes_foo'}; + + # test blessed references, like DBI + # DBD::DBM ships with DBI... + if (have_module(qw(DBI DBD::DBM))) { + my $dbh = DBI->connect('dbi:DBM:'); + + $o->pnotes(DBH => $dbh); + + my $pdbh = $o->pnotes('DBH'); + + ok t_cmp(ref($pdbh), 'DBI::db', "ref($type->pnotes('DBH'))"); + + my $quote = $pdbh->quote("quoth'me"); + + # see the DBI manpage for why quote() returns the string + # wrapped in ' marks + ok t_cmp($quote, "'quoth\\'me'", '$pdbh->quote() works'); + } + else { + skip ('skipping $dbh retrival test - no DBI or DBD::DBM'); + skip ('skipping $dbh->quote() test - no DBI or DBD::DBM'); + } + } + + # set pnotes so we can test unset on later connections + $r->pnotes(request => 'RSET'); + $c->pnotes(connection => 'CSET'); + + ok t_cmp($r->pnotes('request'), + 'RSET', + '$r->pnotes() set'); + + ok t_cmp($c->pnotes('connection'), + 'CSET', + '$c->pnotes() set'); + + Apache2::Const::OK; +} + +1; +__END__ + +
diff --git a/2_0_13/t/response/TestModperl/pnotes2.pm b/2_0_13/t/response/TestModperl/pnotes2.pm new file mode 100644 index 0000000..fd3d14a --- /dev/null +++ b/2_0_13/t/response/TestModperl/pnotes2.pm
@@ -0,0 +1,85 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::pnotes2; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Log (); +use Apache2::RequestUtil (); +use Apache2::ConnectionUtil (); + +use Apache2::Const -compile => 'OK'; + +{ + package TestModerl::pnotes2::x; + use strict; + use warnings FATAL => 'all'; + + sub new {shift;bless [@_];} + sub DESTROY {my $f=shift @{$_[0]}; $f->(@{$_[0]});} +} + +sub line { + our $cleanup; + + Apache2::ServerRec::warn "pnotes are destroyed after cleanup ".$cleanup; +} + +sub cleanup { + our $cleanup; + $cleanup='passed'; + + return Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + our $cleanup; + $cleanup=''; + + $r->push_handlers( PerlCleanupHandler=>__PACKAGE__.'::cleanup' ); + + if(!defined $r->args) { + } elsif($r->args == 1) { + $r->pnotes(x1 => TestModerl::pnotes2::x->new(\&line)); + } elsif($r->args == 2) { + $r->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line); + } elsif($r->args == 3) { + $r->pnotes(x1 => TestModerl::pnotes2::x->new(\&line)); + $r->pnotes(x2 => 2); + } elsif($r->args == 4) { + $r->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line); + $r->pnotes->{x2} = 2; + } elsif($r->args == 5) { + $r->pnotes(x1 => TestModerl::pnotes2::x->new(\&line)); + $r->pnotes->{x2} = 2; + } elsif($r->args == 6) { + $r->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line); + $r->pnotes(x2 => 2); + } elsif($r->args == 7) { + $r->connection->pnotes(x1 => TestModerl::pnotes2::x->new(\&line)); + } elsif($r->args == 8) { + $r->connection->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line); + } elsif($r->args == 9) { + $r->connection->pnotes(x1 => TestModerl::pnotes2::x->new(\&line)); + $r->connection->pnotes(x2 => 2); + } elsif($r->args == 10) { + $r->connection->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line); + $r->connection->pnotes->{x2} = 2; + } elsif($r->args == 11) { + $r->connection->pnotes(x1 => TestModerl::pnotes2::x->new(\&line)); + $r->connection->pnotes->{x2} = 2; + } elsif($r->args == 12) { + $r->connection->pnotes->{x1} = TestModerl::pnotes2::x->new(\&line); + $r->connection->pnotes(x2 => 2); + } + + $r->content_type('text/plain'); + $r->print("OK"); + + Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestModperl/post_utf8.pm b/2_0_13/t/response/TestModperl/post_utf8.pm new file mode 100644 index 0000000..48d7aa2 --- /dev/null +++ b/2_0_13/t/response/TestModperl/post_utf8.pm
@@ -0,0 +1,68 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::post_utf8; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use APR::Table (); + +use TestCommon::Utils (); + +use Apache2::Const -compile => 'OK'; + +my $expected_ascii = "I love you, (why lying?), but I belong to another"; +my $expected_utf8 = "\x{042F} \x{0432}\x{0430}\x{0441} \x{043B}\x{044E}" . + "\x{0431}\x{043B}\x{044E} (\x{043A} \x{0447}\x{0435}\x{043C}\x{0443} " . + "\x{043B}\x{0443}\x{043A}\x{0430}\x{0432}\x{0438}\x{0442}\x{044C}?),\n" . + "\x{041D}\x{043E} \x{044F} \x{0434}\x{0440}\x{0443}\x{0433}\x{043E}" . + "\x{043C}\x{0443} \x{043E}\x{0442}\x{0434}\x{0430}\x{043D}\x{0430};"; + +sub handler { + my $r = shift; + +# # visual debug, e.g. in lynx/mozilla +# $r->content_type("text/plain; charset=utf-8"); +# $r->print("expected: $expected_utf8\n"); + + my $received = TestCommon::Utils::read_post($r) || ""; + + # utf encode/decode was added only in 5.8.0 + # XXX: currently binmode is only available with perlio (used on the + # server side on the tied/perlio STDOUT) + plan $r, tests => 2, + need need_min_perl_version(5.008), need_perl('perlio'); + + # workaround for perl-5.8.0, which doesn't decode correctly a + # tainted variable + require ModPerl::Util; + ModPerl::Util::untaint($received) if $] == 5.008; + + # assume that we know that it's utf8 + require Encode; # since 5.8.0 + $received = Encode::decode('utf8', $received); + # utf8::decode() doesn't work under -T + my ($received_ascii, $received_utf8) = split /=/, $received; + + ok t_cmp($received_ascii, $expected_ascii, "ascii"); + + ok $expected_utf8 eq $received_utf8; + # if you want to see the utf8 data run with: + # t/TEST -trace=debug -v modperl/post_utf8 + # and look for this data in t/logs/error_log + # needed for sending utf-8 to STDERR for debug + binmode(STDERR, ':utf8'); + debug "expected: $expected_utf8"; + debug "received: $received_utf8"; + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/print.pm b/2_0_13/t/response/TestModperl/print.pm new file mode 100644 index 0000000..64d8968 --- /dev/null +++ b/2_0_13/t/response/TestModperl/print.pm
@@ -0,0 +1,49 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::print; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 6; + + binmode STDOUT; #Apache2::RequestRec::BINMODE (noop) + + ok 1; + + ok 2; + + { + # print should return true on success, even + # if it sends no data. + my $rc = print ''; + + ok ($rc); + ok ($rc == 0); # 0E0 is still numerically 0 + } + + { + my $rc = print "# 11 bytes\n"; # don't forget the newline + + ok ($rc == 11); + } + + printf "ok %d\n", 6; + + Apache2::Const::OK; +} + +END { + my $package = __PACKAGE__; + warn "END in $package, pid=$$\n"; +} + +1;
diff --git a/2_0_13/t/response/TestModperl/print_utf8.pm b/2_0_13/t/response/TestModperl/print_utf8.pm new file mode 100644 index 0000000..f95ca48 --- /dev/null +++ b/2_0_13/t/response/TestModperl/print_utf8.pm
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::print_utf8; + +# testing the utf8-encoded response via a tied STDOUT/perlio STDOUT, +# the latter if perl was built with perlio. +# see Modperl/print_utf8_2.pm for $r->print + +# must test against a tied STDOUT/perlio STDOUT. $r->print does the +# right thing without any extra provisions + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain; charset=UTF-8'); + + # prevent warning: "Wide character in print" + binmode(STDOUT, ':utf8'); # Apache2::RequestRec::BINMODE() + + # must be non-$r->print(), so we go through the tied STDOUT + # \x{263A} == :-) + print "Hello Ayhan \x{263A} perlio rules!"; + + Apache2::Const::OK; +} + +1; +__DATA__ +SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/print_utf8_2.pm b/2_0_13/t/response/TestModperl/print_utf8_2.pm new file mode 100644 index 0000000..423c7de --- /dev/null +++ b/2_0_13/t/response/TestModperl/print_utf8_2.pm
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::print_utf8_2; + +# testing the utf8-encoded response via direct $r->print, which does the +# right thing without any extra provisions. +# see print_utf8.pm for tied STDOUT/perlio STDOUT, which requires extra work + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); +use Apache2::RequestRec (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain; charset=UTF-8'); + + # \x{263A} == :-) + $r->print("\$r->print() just works \x{263A}"); + + Apache2::Const::OK; +} + +1; +__DATA__ +SetHandler modperl
diff --git a/2_0_13/t/response/TestModperl/printf.pm b/2_0_13/t/response/TestModperl/printf.pm new file mode 100644 index 0000000..54b1e89 --- /dev/null +++ b/2_0_13/t/response/TestModperl/printf.pm
@@ -0,0 +1,63 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::printf; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); +use Apache2::RequestRec (); +use APR::Table (); + +use Apache2::Const -compile => qw(OK); + +sub handler { + my $r = shift; + + my $tests = 4; + + $r->printf("1..%d\n", $tests); + + # ok 1 + $r->printf("ok"); + $r->printf(" %d\n", 1); + + # ok 2 + my $fmt = "%s%s %d\n"; + $r->printf($fmt, qw(o k), 2); + + # ok 3 + my @a = ("ok %d%c", 3, ord("\n")); + $r->PRINTF(@a); + + # ok 4 (gets input from the fixup handler via notes) + { + my $note = $r->notes->get("fixup") || ''; + my $ok = $note =~ + /\$r->printf can't be called before the response phase/; + $r->print("not ") unless $ok; + $r->print("ok 4\n"); + $r->print("# either fixup was successful at printing to the\n", + "# client (which shouldn't happen before the\n", + "# response phase), or the note was lost/never set\n") + unless $ok; + $r->notes->clear; + } + + Apache2::Const::OK; +} + +sub fixup { + my $r = shift; + + # it's not possible to send a response body before the response + # phase + eval { $r->printf("whatever") }; + $r->notes->set(fixup => "$@") if $@; + + Apache2::Const::OK; +} + +1; +__END__ +PerlModule TestModperl::printf +PerlFixupHandler TestModperl::printf::fixup
diff --git a/2_0_13/t/response/TestModperl/readline.pm b/2_0_13/t/response/TestModperl/readline.pm new file mode 100644 index 0000000..705cf0f --- /dev/null +++ b/2_0_13/t/response/TestModperl/readline.pm
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::readline; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); +use Apache2::compat (); #XXX + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + untie *STDIN; + tie *STDIN, $r; + + while (defined(my $line = <STDIN>)) { + $r->puts($line); + } + + untie *STDIN; + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestModperl/request_rec_perlio_api.pm b/2_0_13/t/response/TestModperl/request_rec_perlio_api.pm new file mode 100644 index 0000000..c8a225f --- /dev/null +++ b/2_0_13/t/response/TestModperl/request_rec_perlio_api.pm
@@ -0,0 +1,105 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::request_rec_perlio_api; + +# this test is relevant only when the PerlIO STDIN/STDOUT are used (when +# $Config{useperlio} is defined.) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); +use Apache2::RequestRec (); + +use Apache::Test; + +use File::Spec::Functions qw(catfile catdir); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->args eq 'STDIN' ? test_STDIN($r) : test_STDOUT($r); + + return Apache2::Const::OK; +} + +sub test_STDIN { + my $r = shift; + + { + # read the first 10 POST chars + my $data; + read STDIN, $data, 10; + print STDOUT $data; + } + + { + # re-open STDIN to something else, and then see if we don't + # lose any chars when we restore it to the POST stream + open my $stdin, "<&STDIN" or die "Can't dup STDIN: $!"; + + open STDIN, "<", __FILE__ + or die "failed to open STDIN as 'in memory' file : $!"; + my $data; + read STDIN, $data, length("# please"); + print STDOUT $data; + close STDIN; + + open STDIN, "<&", $stdin or die "failed to restore STDIN: $!"; + } + + { + # read the last 10 POST chars + my $data; + read STDIN, $data, 10; + print STDOUT $data; + } + +} + +sub test_STDOUT { + my $r = shift; + + local $| = 0; + print STDOUT "life is hard "; + + my $vars = Apache::Test::config()->{vars}; + my $target_dir = catdir $vars->{documentroot}, 'perlio'; + my $file = catfile $target_dir, "apache_stdout"; + + # re-open STDOUT to something else, and then see if we can + # continue printing to the client via STDOUT, after restoring it + open my $stdout, ">&STDOUT" or die "Can't dup STDOUT: $!"; + + # this should flush the above print to STDOUT + open STDOUT, ">", $file or die "Can't open $file: $!"; + print STDOUT "and then "; + close STDOUT; + + # flush things that went into the file as STDOUT + open STDOUT, ">&", $stdout or die "failed to restore STDOUT: $!"; + open my $fh, $file or die "Can't open $file: $!"; + local $\; + print <$fh>; + + # cleanup + unlink $file; + + # close the dupped fh + close $stdout; + + print "you die! "; + + # now close it completely and restore it, without using any dupped + # filehandle + close STDOUT; + open STDOUT, ">:Apache2", $r + or die "can't open STDOUT via :Apache2 layer : $!"; + print "next you reincarnate..."; + +} + +1; +__DATA__ +SetHandler perl-script
diff --git a/2_0_13/t/response/TestModperl/request_rec_tie_api.pm b/2_0_13/t/response/TestModperl/request_rec_tie_api.pm new file mode 100644 index 0000000..d27c44e --- /dev/null +++ b/2_0_13/t/response/TestModperl/request_rec_tie_api.pm
@@ -0,0 +1,68 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::request_rec_tie_api; + +# this test is relevant only when the tied STDIN/STDOUT are used (when +# $Config{useperlio} is not defined.) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestIO (); + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestConfig; + +use File::Spec::Functions qw(catfile catdir); + +use Apache2::Const -compile => 'OK'; + +use Config; + +sub handler { + my $r = shift; + + require Apache2::Build; + my @todo; + push @todo, 1 if Apache2::Build::AIX(); + plan $r, tests => 3, todo => \@todo, + need { "perl $]: PerlIO is used instead of TIEd IO" + => !($] >= 5.008 && $Config{useperlio}) }; + + # XXX: on AIX 4.3.3 we get: + # STDIN STDOUT STDERR + # perl : 0 1 2 + # mod_perl: 0 0 2 + my $fileno = fileno STDOUT; + ok $fileno; + t_debug "fileno STDOUT: $fileno"; + + { + my $vars = Apache::Test::config()->{vars}; + my $target_dir = catdir $vars->{serverroot}, 'logs'; + my $file = catfile $target_dir, "stdout"; + + # test OPEN + my $received = open STDOUT, ">", $file or die "Can't open $file: $!"; + ok t_cmp($received, 1, "OPEN"); + + # test CLOSE, which is a noop + ok $r->CLOSE; + close $file; + + # restore the tie + tie *STDOUT, $r; + + # flush things that went into the file as STDOUT + open my $fh, $file or die "Can't open $file: $!"; + local $\; + print <$fh>; + + # cleanup + unlink $file; + } + + return Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestModperl/setauth.pm b/2_0_13/t/response/TestModperl/setauth.pm new file mode 100644 index 0000000..ce992cd --- /dev/null +++ b/2_0_13/t/response/TestModperl/setauth.pm
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::setauth; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Access (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 2; + + ok t_cmp($r->auth_type(), "none", 'auth_type'); + + t_server_log_error_is_expected(); + $r->get_basic_auth_pw(); + + ok t_cmp($r->auth_type(), 'Basic', 'default auth_type'); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestModperl/setupenv.pm b/2_0_13/t/response/TestModperl/setupenv.pm new file mode 100644 index 0000000..7dbcf9a --- /dev/null +++ b/2_0_13/t/response/TestModperl/setupenv.pm
@@ -0,0 +1,343 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::setupenv; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use APR::Table (); + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::Const -compile => qw(OK DECLINED); + +sub handler { + + my $r = shift; + + # how many different URIs will be hit? + my $requests = $r->args; + + # $requests locations with 7 tests each + plan $r, tests => $requests * 7; + + return Apache2::Const::OK; +} + +sub env { + + my $r = shift; + + Apache::Test::init_test_pm($r); # tie STDOUT + + (my $value) = $r->uri =~ /TestModperl__setupenv_(\w+)/; + + ok t_cmp($ENV{REMOTE_ADDR}, + Apache::Test::vars('remote_addr'), + 'found REMOTE_ADDR in %ENV'); + + ok t_cmp($ENV{SRV_SUBPROCESS}, + 'server', + 'found subprocess_env table entry SRV_SUBPROCESS in %ENV'); + + ok t_cmp($ENV{DIR_SUBPROCESS}, + $value, + 'found subprocess_env table entry DIR_SUBPROCESS in %ENV'); + + ok t_cmp($ENV{DIR_SETENV}, + $value, + 'found per-directory SetEnv entry in %ENV'); + + ok t_cmp($ENV{SRV_SETENV}, + 'server', + 'found per-server SetEnv entry in %ENV'); + + # PerlSetEnv always set + ok t_cmp($ENV{DIR_PERLSETENV}, + $value, + 'found per-directory PerlSetEnv entry in %ENV'); + + ok t_cmp($ENV{SRV_PERLSETENV}, + 'server', + 'found per-server PerlSetEnv entry in %ENV'); + + return Apache2::Const::OK; +} + +sub noenv { + + my $r = shift; + + Apache::Test::init_test_pm($r); # tie STDOUT + + (my $value) = $r->uri =~ /TestModperl__setupenv_(\w+)/; + + ok t_cmp($ENV{REMOTE_ADDR}, + undef, + 'REMOTE_ADDR not found in %ENV'); + + ok t_cmp($ENV{SRV_SUBPROCESS}, + undef, + 'subprocess_env table entry SRV_SUBPROCESS not found in %ENV'); + + ok t_cmp($ENV{DIR_SUBPROCESS}, + undef, + 'subprocess_env table entry DIR_SUBPROCESS not found in %ENV'); + + ok t_cmp($ENV{DIR_SETENV}, + undef, + 'per-directory SetEnv entry not found in %ENV'); + + ok t_cmp($ENV{SRV_SETENV}, + undef, + 'per-server SetEnv entry not found in %ENV'); + + # PerlSetEnv always set + ok t_cmp($ENV{DIR_PERLSETENV}, + $value, + 'found per-directory PerlSetEnv entry in %ENV'); + + ok t_cmp($ENV{SRV_PERLSETENV}, + 'server', + 'found per-server PerlSetEnv entry in %ENV'); + + return Apache2::Const::OK; +} + +sub someenv { + + my $r = shift; + + Apache::Test::init_test_pm($r); # tie STDOUT + + (my $value) = $r->uri =~ /TestModperl__setupenv_(\w+)/; + + ok t_cmp($ENV{REMOTE_ADDR}, + Apache::Test::vars('remote_addr'), + 'found REMOTE_ADDR in %ENV'); + + # set before void call + ok t_cmp($ENV{SRV_SUBPROCESS}, + 'server', + 'found subprocess_env table entry one in %ENV'); + + ok t_cmp($ENV{DIR_SUBPROCESS}, + undef, + 'subprocess_env table entry DIR_SUBPROCESS not found in %ENV'); + + ok t_cmp($ENV{DIR_SETENV}, + undef, + 'per-directory SetEnv entry not found in %ENV'); + + ok t_cmp($ENV{SRV_SETENV}, + undef, + 'per-server SetEnv entry not found in %ENV'); + + # PerlSetEnv always set + ok t_cmp($ENV{DIR_PERLSETENV}, + $value, + 'found per-directory PerlSetEnv entry in %ENV'); + + ok t_cmp($ENV{SRV_PERLSETENV}, + 'server', + 'found per-server PerlSetEnv entry in %ENV'); + + return Apache2::Const::OK; +} + +sub subenv_void { + + shift->subprocess_env; + + return Apache2::Const::OK; +} + +sub subenv_one { + + shift->subprocess_env->set(SRV_SUBPROCESS => 'server'); + + return Apache2::Const::OK; +} + +sub subenv_two { + + my $r = shift; + + (my $value) = $r->uri =~ /TestModperl__setupenv_(\w+)/; + + $r->subprocess_env->set(DIR_SUBPROCESS => $value); + + return Apache2::Const::OK; +} + +1; +__DATA__ +# create a separate virtual host so we can use +# keepalives - a per-connection interpreter is +# the only way to make sure that we can plan in +# one request and test in subsequent tests +<NoAutoConfig> +<VirtualHost TestModperl::setupenv> + + KeepAlive On + +# <IfDefine PERL_USEITHREADS> +# PerlInterpScope connection +# </Ifdefine> + + PerlModule TestModperl::setupenv + + PerlPostReadRequestHandler TestModperl::setupenv::subenv_one + + # SetEnv is affected by +SetupEnv + <IfModule mod_env.c> + SetEnv SRV_SETENV server + </IfModule> + + # PerlSetEnv is not affected by +SetupEnv or -SetupEnv + # it is entirely separate and always set if configured + PerlSetEnv SRV_PERLSETENV server + + # plan + <Location /TestModperl__setupenv> + SetHandler modperl + PerlResponseHandler TestModperl::setupenv + </Location> + + # default modperl handler + # %ENV should not contain standard CGI variables + # or entries from the subprocess_env table + <Location /TestModperl__setupenv_mpdefault> + SetHandler modperl + PerlResponseHandler TestModperl::setupenv::noenv + + PerlFixupHandler TestModperl::setupenv::subenv_two + <IfModule mod_env.c> + SetEnv DIR_SETENV mpdefault + </IfModule> + PerlSetEnv DIR_PERLSETENV mpdefault + </Location> + + # modperl handler + SetupEnv + # %ENV should contain CGI variables as well as + # anything put into the subprocess_env table + <Location /TestModperl__setupenv_mpsetup> + SetHandler modperl + PerlResponseHandler TestModperl::setupenv::env + + PerlOptions +SetupEnv + + PerlFixupHandler TestModperl::setupenv::subenv_two + + <IfModule mod_env.c> + SetEnv DIR_SETENV mpsetup + </IfModule> + PerlSetEnv DIR_PERLSETENV mpsetup + </Location> + + # $r->subprocess_env in a void context with no args + # should do the same as +SetupEnv wrt CGI variables + # and entries already in the subprocess_env table + # but subprocess_env entries that appear later will + # not show up in %ENV + <Location /TestModperl__setupenv_mpvoid> + SetHandler modperl + PerlResponseHandler TestModperl::setupenv::someenv + + PerlHeaderParserHandler TestModperl::setupenv::subenv_void + PerlFixupHandler TestModperl::setupenv::subenv_two + + <IfModule mod_env.c> + SetEnv DIR_SETENV mpvoid + </IfModule> + PerlSetEnv DIR_PERLSETENV mpvoid + </Location> + + # +SetupEnv should always populate %ENV fully prior + # to running the content handler (regardless of when + # $r->subprocess_env() was called) to ensure that + # %ENV is an accurate representation of the + # subprocess_env table + <Location /TestModperl__setupenv_mpsetupvoid> + SetHandler modperl + PerlResponseHandler TestModperl::setupenv::env + + PerlOptions +SetupEnv + + PerlHeaderParserHandler TestModperl::setupenv::subenv_void + PerlFixupHandler TestModperl::setupenv::subenv_two + + <IfModule mod_env.c> + SetEnv DIR_SETENV mpsetupvoid + </IfModule> + PerlSetEnv DIR_PERLSETENV mpsetupvoid + </Location> + + # default perl-script handler is equivalent to +SetupEnv + # CGI variables and subprocess_env entries will be in %ENV + <Location /TestModperl__setupenv_psdefault> + SetHandler perl-script + PerlResponseHandler TestModperl::setupenv::env + + PerlFixupHandler TestModperl::setupenv::subenv_two + + <IfModule mod_env.c> + SetEnv DIR_SETENV psdefault + </IfModule> + PerlSetEnv DIR_PERLSETENV psdefault + </Location> + + # -SetupEnv should not put CGI variables or subprocess_env + # entries in %ENV + <Location /TestModperl__setupenv_psnosetup> + SetHandler perl-script + PerlResponseHandler TestModperl::setupenv::noenv + + PerlOptions -SetupEnv + + PerlFixupHandler TestModperl::setupenv::subenv_two + + <IfModule mod_env.c> + SetEnv DIR_SETENV psnosetup + </IfModule> + PerlSetEnv DIR_PERLSETENV psnosetup + </Location> + + # +SetupEnv should always populate %ENV fully prior + # to running the content handler (regardless of when + # $r->subprocess_env() was called) to ensure that + # %ENV is an accurate representation of the + # subprocess_env table + <Location /TestModperl__setupenv_psvoid> + SetHandler perl-script + PerlResponseHandler TestModperl::setupenv::env + + PerlHeaderParserHandler TestModperl::setupenv::subenv_void + PerlFixupHandler TestModperl::setupenv::subenv_two + + <IfModule mod_env.c> + SetEnv DIR_SETENV psvoid + </IfModule> + PerlSetEnv DIR_PERLSETENV psvoid + </Location> + + # equivalent to modperl handler with $r->subprocess_env() - + # CGI variables are there, but not subprocess_env entries + # that are populated after the void call + <Location /TestModperl__setupenv_psnosetupvoid> + SetHandler perl-script + PerlResponseHandler TestModperl::setupenv::someenv + + PerlOptions -SetupEnv + + PerlHeaderParserHandler TestModperl::setupenv::subenv_void + PerlFixupHandler TestModperl::setupenv::subenv_two + + <IfModule mod_env.c> + SetEnv DIR_SETENV psnosetupvoid + </IfModule> + PerlSetEnv DIR_PERLSETENV psnosetupvoid + </Location> +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestModperl/setupenv2.pm b/2_0_13/t/response/TestModperl/setupenv2.pm new file mode 100644 index 0000000..bb27314 --- /dev/null +++ b/2_0_13/t/response/TestModperl/setupenv2.pm
@@ -0,0 +1,135 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::setupenv2; + +# Test the mixing of PerlSetEnv in httpd.conf and %ENV of the same +# key in PerlRequire, PerlConfigRequire, PerlPostConfigRequire and +# <Perl> sections + +use strict; +use warnings FATAL => 'all'; + +use Apache2::Const -compile => qw(OK OR_ALL NO_ARGS); + +use Apache2::CmdParms (); +use Apache2::Module (); +use Apache2::RequestIO (); +use Apache2::RequestRec (); + +my @directives = ( + { + name => 'MyEnvRegister', + func => __PACKAGE__ . '::MyEnvRegister', + req_override => Apache2::Const::OR_ALL, + args_how => Apache2::Const::NO_ARGS, + errmsg => 'cannot fail :)', + }, +); + +Apache2::Module::add(__PACKAGE__, \@directives); + +# testing PerlLoadModule +$ENV{EnvChangeMixedTest} = 'loadmodule'; +$ENV{EnvChangePerlTest} = 'loadmodule'; + +sub MyEnvRegister { + register_mixed(); +} + +sub register_mixed { + push @TestModperl::setupenv2::EnvChangeMixedTest, + $ENV{EnvChangeMixedTest} || 'notset'; +} + +sub register_perl { + push @TestModperl::setupenv2::EnvChangePerlTest, + $ENV{EnvChangePerlTest} || 'notset'; +} + +sub get_config { + my ($self, $s) = (shift, shift); + Apache2::Module::get_config($self, $s, @_); +} + +sub handler { + my ($r) = @_; + + my $args = $r->args || ''; + + $r->content_type('text/plain'); + + if ($args eq 'mixed') { + my @vals = (@TestModperl::setupenv2::EnvChangeMixedTest, + $ENV{EnvChangeMixedTest}); # what's the latest env value + $r->print(join " ", @vals); + } + elsif ($args eq 'perl') { + my @vals = (@TestModperl::setupenv2::EnvChangePerlTest, + $ENV{EnvChangePerlTest}); # what's the latest env value + $r->print(join " ", @vals); + } + else { + die "no such case"; + } + + return Apache2::Const::OK; +} + +1; +__END__ + +# APACHE_TEST_CONFIG_ORDER 950 + +<NoAutoConfig> +PerlLoadModule TestModperl::setupenv2 +MyEnvRegister + +PerlSetEnv EnvChangeMixedTest "conf1" + +<Perl > +TestModperl::setupenv2::register_mixed(); +TestModperl::setupenv2::register_perl(); +$ENV{EnvChangeMixedTest} = "<perl>"; +$ENV{EnvChangePerlTest} = "<perl>"; +</Perl> +MyEnvRegister + +PerlSetEnv EnvChangeMixedTest "conf2" + +PerlRequire "@documentroot@/modperl/setupenv2/require.pl" +MyEnvRegister + +PerlSetEnv EnvChangeMixedTest "conf3" + +PerlConfigRequire "@documentroot@/modperl/setupenv2/config_require.pl" +MyEnvRegister + +PerlSetEnv EnvChangeMixedTest "conf4" + +PerlModule htdocs::modperl::setupenv2::module +MyEnvRegister + +PerlSetEnv EnvChangeMixedTest "conf5" +MyEnvRegister + +PerlPostConfigRequire "@documentroot@/modperl/setupenv2/post_config_require.pl" +MyEnvRegister + +PerlSetEnv EnvChangeMixedTest "conf6" +MyEnvRegister + +PerlSetEnv EnvChangeMixedTest "conf7" +MyEnvRegister + +<Location /TestModperl__setupenv2> + SetHandler modperl + PerlResponseHandler TestModperl::setupenv2 +</Location> + +PerlSetEnv EnvChangeMixedTest "conf8" + +# Since PerlPostConfigRequire runs in the post-config phase it will +# see 'conf8'. And when it sets that value to 'post_config_require' at +# request time $ENV{EnvChangeMixedTest} will see the value set by +# PerlPostConfigRequire. + +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestModperl/status.pm b/2_0_13/t/response/TestModperl/status.pm new file mode 100644 index 0000000..26964db --- /dev/null +++ b/2_0_13/t/response/TestModperl/status.pm
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::status; + +use strict; +use warnings; + +use Apache2::RequestRec; +use Apache2::Const -compile => qw(DECLINED); + +use ModPerl::Util; +use Apache::TestUtil qw(t_server_log_error_is_expected); + +sub handler { + + my $rc = shift->args; + + if ($rc eq 'die' || + $rc eq Apache2::Const::DECLINED || + $rc =~ m/foo/) { + t_server_log_error_is_expected(); + } + + ModPerl::Util::exit if $rc eq 'exit'; + + die if $rc eq 'die'; + + return if $rc eq 'undef'; + + return $rc; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestModperl/stdfd.pm b/2_0_13/t/response/TestModperl/stdfd.pm new file mode 100644 index 0000000..906bbaf --- /dev/null +++ b/2_0_13/t/response/TestModperl/stdfd.pm
@@ -0,0 +1,41 @@ +package TestModperl::stdfd; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache2::Const -compile => 'OK'; + +sub fixup { + my $r = shift; + + $r->handler($r->main ? 'perl-script' : 'modperl'); + return Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + return Apache2::Const::OK if $r->main; + + my @fds=(fileno(STDIN), fileno(STDOUT)); + + $r->lookup_uri($r->uri)->run; + + $r->print("1..2\n"); + $r->print((fileno(STDIN)==$fds[0] ? '' : 'not '). + "ok 1 - fileno(STDIN)=".fileno(STDIN)." expected $fds[0]\n"); + $r->print((fileno(STDOUT)==$fds[1] ? '' : 'not '). + "ok 2 - fileno(STDOUT)=".fileno(STDOUT)." expected $fds[1]\n"); + + return Apache2::Const::OK; +} + +1; +__DATA__ +PerlModule TestModperl::stdfd +PerlFixupHandler TestModperl::stdfd::fixup +PerlResponseHandler TestModperl::stdfd
diff --git a/2_0_13/t/response/TestModperl/stdfd2.pm b/2_0_13/t/response/TestModperl/stdfd2.pm new file mode 100644 index 0000000..b99ccf1 --- /dev/null +++ b/2_0_13/t/response/TestModperl/stdfd2.pm
@@ -0,0 +1,44 @@ +package TestModperl::stdfd2; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::SubRequest (); + +use Apache2::Const -compile => 'OK'; + +sub fixup { + my $r = shift; + + $r->handler($r->main ? 'perl-script' : 'modperl'); + return Apache2::Const::OK; +} + +sub handler { + my $r = shift; + + return Apache2::Const::OK if $r->main; + + local *STDIN; + open STDIN, '<', $INC{'TestModperl/stdfd2.pm'} + or die "Cannot open $INC{'TestModperl/stdfd2.pm'}"; + scalar readline STDIN for(1..2); + + my $expected=$.; + + $r->lookup_uri($r->uri)->run; + + $r->print("1..1\n"); + $r->print(($.==$expected ? '' : 'not '). + "ok 1 - \$.=$. expected $expected\n"); + + return Apache2::Const::OK; +} + +1; +__DATA__ +PerlModule TestModperl::stdfd2 +PerlFixupHandler TestModperl::stdfd2::fixup +PerlResponseHandler TestModperl::stdfd2
diff --git a/2_0_13/t/response/TestModperl/subenv.pm b/2_0_13/t/response/TestModperl/subenv.pm new file mode 100644 index 0000000..bd02d4b --- /dev/null +++ b/2_0_13/t/response/TestModperl/subenv.pm
@@ -0,0 +1,118 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::subenv; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec (); +use APR::Table (); + +use Apache::Test; + +use Apache2::Const -compile => 'OK'; + +sub handler { + + my $r = shift; + + plan $r, tests => 31; + + # subprocess_env in void context with arguments does + # nothing to %ENV + { + my $env = $r->subprocess_env; + + my $key = 'ONCE'; + + ok_false($r, $key); + + $r->subprocess_env($key => 1); # void context but with args + + ok_true($r, $key); + + ok ! $ENV{$key}; # %ENV not populated yet + } + + # subprocess_env in void context with no arguments + # populates the same as +SetEnv + { + my $env = $r->subprocess_env; + + my $key = 'REMOTE_ADDR'; + + ok_false($r, $key); # still not not there yet + + ok ! $ENV{$key}; # %ENV not populated yet + + $r->subprocess_env; # void context with no arguments + + ok_true($r, $key); + + ok $ENV{$key}; # mod_cgi emulation + } + + # handlers can use a void context more than once to force + # population of %ENV with new table entries + { + my $env = $r->subprocess_env; + + my $key = 'AGAIN'; + + $env->set($key => 1); # new table entry + + ok_true($r, $key); + + ok ! $ENV{$key}; # shouldn't affect %ENV yet + + $r->subprocess_env; # now called in in void context twice + + ok $ENV{$key}; # so %ENV is populated with new entry + } + + { + my $env = $r->subprocess_env; # table may have been overlayed + + my $key = 'FOO'; + + $env->set($key => 1); # direct call to set() + + ok_true($r, $key); + + ok ! $ENV{$key}; # shouldn't affect %ENV + + $r->subprocess_env($key => undef); + + ok_false($r, $key); # removed + + $r->subprocess_env($key => 1); + + ok_true($r, $key); # reset + + ok ! $ENV{$key}; # still shouldn't affect %ENV + } + + Apache2::Const::OK; +} + +sub ok_true { + my ($r, $key) = @_; + + my $env = $r->subprocess_env; + ok $env->get($key); + ok $env->{$key}; + ok $r->subprocess_env($key); +} + +sub ok_false { + my ($r, $key) = @_; + + my $env = $r->subprocess_env; + ok ! $env->get($key); + ok ! $env->{$key}; + ok ! $r->subprocess_env($key); +} + +1; +__END__ +PerlOptions -SetupEnv +
diff --git a/2_0_13/t/response/TestModperl/taint.pm b/2_0_13/t/response/TestModperl/taint.pm new file mode 100644 index 0000000..090c524 --- /dev/null +++ b/2_0_13/t/response/TestModperl/taint.pm
@@ -0,0 +1,41 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::taint; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestIO (); +use Apache2::RequestUtil (); +use Apache2::Build (); + +use Apache2::Const -compile => 'OK'; + +my $build = Apache2::Build->build_config; + +sub handler { + my $r = shift; + + my $tests = $build->{MP_COMPAT_1X} ? 4 : 2; + + plan $r, tests => $tests; + + ok t_cmp(${^TAINT}, 1, "\${^TAINT}"); + + eval { ${^TAINT} = 0 }; + ok t_cmp($@, qr/read-only/, "\${^TAINT} is read-only"); + + if ($build->{MP_COMPAT_1X}) { + ok t_cmp($Apache2::__T, 1, "\$Apache2::__T"); + + eval { $Apache2::__T = 0 }; + ok t_cmp($@, qr/read-only/, "\$Apache2::__T is read-only"); + } + + Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestModperl/util.pm b/2_0_13/t/response/TestModperl/util.pm new file mode 100644 index 0000000..d622992 --- /dev/null +++ b/2_0_13/t/response/TestModperl/util.pm
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModperl::util; + +# Modperl::Util tests + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use ModPerl::Util (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 1; + + ok t_cmp ModPerl::Util::current_perl_id(), qr/0x\w+/, + "perl interpreter id"; + + Apache2::Const::OK; +} + +1; +__END__
diff --git a/2_0_13/t/response/TestModules/cgi.pm b/2_0_13/t/response/TestModules/cgi.pm new file mode 100644 index 0000000..7fcf883 --- /dev/null +++ b/2_0_13/t/response/TestModules/cgi.pm
@@ -0,0 +1,58 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModules::cgi; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::compat (); +use CGI (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + unless ($ENV{MOD_PERL}) { + die "\$ENV{MOD_PERL} is not set"; + } + + unless ($ENV{MOD_PERL_API_VERSION} == 2) { + die "\$ENV{MOD_PERL_API_VERSION} is not set"; + } + + if ($CGI::Q) { + die "CGI.pm globals were not reset"; + } + + unless ($CGI::MOD_PERL) { + die "CGI.pm does not think this is mod_perl"; + } + + my $cgi = CGI->new; + + my $param = $cgi->param('PARAM'); + my $httpupload = $cgi->param('HTTPUPLOAD'); + + print $cgi->header('-type' => 'text/test-output', + '-X-Perl-Module' => __PACKAGE__); + + if ($httpupload) { + no strict; + local $/; + my $content = <$httpupload>; + print "ok $content"; + } + elsif ($param) { + print "ok $param"; + } + else { + print "no param or upload data\n"; + } + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script +PerlOptions -SetupEnv
diff --git a/2_0_13/t/response/TestModules/cgi2.pm b/2_0_13/t/response/TestModules/cgi2.pm new file mode 100644 index 0000000..8d87638 --- /dev/null +++ b/2_0_13/t/response/TestModules/cgi2.pm
@@ -0,0 +1,59 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModules::cgi2; + +# this handler doesn't use the :Apache layer, so CGI.pm needs to do +# $r->read(...) instead of read(STDIN,...) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::compat (); +use CGI (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + unless ($ENV{MOD_PERL}) { + die "\$ENV{MOD_PERL} is not set"; + } + + unless ($ENV{MOD_PERL_API_VERSION} == 2) { + die "\$ENV{MOD_PERL_API_VERSION} is not set"; + } + + if ($CGI::Q) { + die "CGI.pm globals were not reset"; + } + + unless ($CGI::MOD_PERL) { + die "CGI.pm does not think this is mod_perl"; + } + + my $cgi = CGI->new($r); + + my $param = $cgi->param('PARAM'); + my $httpupload = $cgi->param('HTTPUPLOAD'); + + $r->print($cgi->header('-type' => 'text/test-output', + '-X-Perl-Module' => __PACKAGE__)); + + if ($httpupload) { + no strict; + local $/; + my $content = <$httpupload>; + $r->print("ok $content"); + } + elsif ($param) { + $r->print("ok $param"); + } + else { + $r->print("no param or upload data\n"); + } + + Apache2::Const::OK; +} + +1; +
diff --git a/2_0_13/t/response/TestModules/cgipost.pm b/2_0_13/t/response/TestModules/cgipost.pm new file mode 100644 index 0000000..48c0820 --- /dev/null +++ b/2_0_13/t/response/TestModules/cgipost.pm
@@ -0,0 +1,26 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModules::cgipost; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::compat (); +use CGI (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + my $cgi = CGI->new; + + print join ":", map { $cgi->param($_) } $cgi->param; + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script +PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestModules/cgipost2.pm b/2_0_13/t/response/TestModules/cgipost2.pm new file mode 100644 index 0000000..57dc9fe --- /dev/null +++ b/2_0_13/t/response/TestModules/cgipost2.pm
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModules::cgipost2; + +# this handler doesn't use the :Apache layer, so CGI.pm needs to do +# $r->read(...) instead of read(STDIN,...) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::compat (); +use CGI (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + my $cgi = CGI->new($r); + + $r->print(join ":", map { $cgi->param($_) } $cgi->param); + + Apache2::Const::OK; +} + +1; +__END__ +
diff --git a/2_0_13/t/response/TestModules/cgiupload.pm b/2_0_13/t/response/TestModules/cgiupload.pm new file mode 100644 index 0000000..7952268 --- /dev/null +++ b/2_0_13/t/response/TestModules/cgiupload.pm
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModules::cgiupload; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::compat (); +use CGI (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $cgi = CGI->new; + + my $file = $cgi->param('filename'); + + while (<$file>) { + print; + } + + Apache2::Const::OK; +} + +1; +__END__ +SetHandler perl-script +PerlOptions +GlobalRequest
diff --git a/2_0_13/t/response/TestModules/cgiupload2.pm b/2_0_13/t/response/TestModules/cgiupload2.pm new file mode 100644 index 0000000..3c4a522 --- /dev/null +++ b/2_0_13/t/response/TestModules/cgiupload2.pm
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModules::cgiupload2; + +# this handler doesn't use the :Apache layer, so CGI.pm needs to do +# $r->read(...) instead of read(STDIN,...) + +use strict; +use warnings FATAL => 'all'; + +use Apache2::compat (); +use CGI (); + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + my $cgi = CGI->new($r); + + local $\; + local $/; + my $file = $cgi->param('filename'); + $r->print(<$file>); + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestModules/include_subreq.pm b/2_0_13/t/response/TestModules/include_subreq.pm new file mode 100644 index 0000000..cf2bc2c --- /dev/null +++ b/2_0_13/t/response/TestModules/include_subreq.pm
@@ -0,0 +1,78 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModules::include_subreq; + +# this test calls a simple response handler, whose output includes a +# simple SSI directive, processed by the INCLUDES output filter, which +# triggers another response handler, which again returns an SSI +# directive, again processed by INCLUDES, which again calls a response +# handler +# +# main +# resp => INCLUDES => => client +# => 1st => +# subreq => INCLUDES => => +# response => => +# => 2nd => +# subreq => +# response +# +# +# +# here we test whether :Apache perlio (STDOUT) is reentrant, since the test +# overrides STDOUT 3 times, recursively. + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestTrace; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + $r->content_type('text/plain'); + + my $path_info = $r->path_info || ''; + my $uri = $r->uri; + + debug "uri: $uri, path_info: $path_info"; + + if ($path_info eq '/one') { + $uri =~ s/one/two/; + print qq[subreq <!--#include virtual="$uri" -->ok]; + } + elsif ($path_info eq '/two') { + $uri = "/TestModules__include_subreq_dup/three"; + #$uri =~ s/two/three/; + print qq[is <!--#include virtual="$uri" -->]; + #print "is"; + } + elsif ($path_info eq '/three') { + print "quite "; + } + else { + die "something is wrong, didn't get path_info"; + } + + Apache2::Const::OK; +} + +1; +__END__ +# notice that perl-script is used on purpose here - testing whether +# :Apache perlio is reentrant (SetHandler modperl doesn't go through +# :Apache perlio layer) +SetHandler perl-script +PerlSetOutputFilter INCLUDES +Options +IncludesNoExec +<Base> +# it's silly that we have to duplicate the resource, but mod_include +# otherwise thinks we have a recursive call loop +<Location /TestModules__include_subreq_dup> + PerlSetOutputFilter INCLUDES + Options +IncludesNoExec + SetHandler perl-script + PerlResponseHandler TestModules::include_subreq +</Location> +</Base>
diff --git a/2_0_13/t/response/TestModules/proxy.pm b/2_0_13/t/response/TestModules/proxy.pm new file mode 100644 index 0000000..178ce69 --- /dev/null +++ b/2_0_13/t/response/TestModules/proxy.pm
@@ -0,0 +1,77 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestModules::proxy; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +use Apache2::ServerRec (); +use Apache2::RequestRec (); +use Apache2::RequestIO (); + +my $uri_real = "/TestModules__proxy_real"; + +use Apache2::Const -compile => qw(DECLINED OK PROXYREQ_REVERSE); + +sub proxy { + my $r = shift; + + return Apache2::Const::DECLINED if $r->proxyreq; + return Apache2::Const::DECLINED unless $r->uri eq '/TestModules__proxy'; + + my $s = $r->server; + my $real_url = sprintf "http://%s:%d%s", + $s->server_hostname, $s->port, $uri_real; + + $r->proxyreq(Apache2::Const::PROXYREQ_REVERSE); + $r->uri($real_url); + $r->filename("proxy:$real_url"); + $r->handler('proxy-server'); + + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + $r->content_type('text/plain'); + $r->print("ok"); + + return Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> + <VirtualHost TestModules::proxy> + <IfModule mod_proxy.c> + <Proxy http://@servername@:@port@/*> + <IfModule mod_version.c> + <IfVersion < 2.3.0> + <IfModule @ACCESS_MODULE@> + Order Deny,Allow + Deny from all + Allow from @servername@ + </IfModule> + </IfVersion> + <IfVersion > 2.4.1> + <IfModule mod_access_compat.c> + Order Deny,Allow + Deny from all + Allow from @servername@ + </IfModule> + </IfVersion> + </IfModule> + </Proxy> + + PerlModule TestModules::proxy + PerlTransHandler TestModules::proxy::proxy + <Location /TestModules__proxy_real> + SetHandler modperl + PerlResponseHandler TestModules::proxy::response + </Location> + </IfModule> + </VirtualHost> +</NoAutoConfig> +
diff --git a/2_0_13/t/response/TestPerl/api.pm b/2_0_13/t/response/TestPerl/api.pm new file mode 100644 index 0000000..c034f08 --- /dev/null +++ b/2_0_13/t/response/TestPerl/api.pm
@@ -0,0 +1,54 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestPerl::api; + +# some perl APIs that we need to test that they work alright under mod_perl + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use Apache2::Build; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + # - XXX: with perl 5.6.1 this test works fine on its own, but if + # run in the same interpreter after a test that involves a complex die + # call, as in the case of t/filter/in_error, which dies inside a + # filter, perl gets messed up here. this can be reproduced by + # running: + # t/TEST -maxclients 1 t/filter/in_error.t t/perl/api.t + # so skip that test for now on 5.6 + # + # - win32 is an unrelated issue + plan $r, tests => 2, + need { "getppid() is not implemented on Win32" + => !Apache2::Build::WIN32(), + "getppid() is having problems with perl 5.6" + => !($] < 5.008), + }; + + { + # 5.8.1 w/ ithreads has a bug where it caches ppid in PL_ppid, + # but updates the record only if perl's fork is called, which + # is not the case with mod_perl. This results in getppid() + # returning 1. A local workaround in the mod_perl source at + # the child_init phase fixes the problem. + my $ppid = getppid(); + t_debug "ppid $ppid"; + ok $ppid > 1; + + # verify that $pid != $ppid + t_debug "pid $$"; + ok $ppid != $$; + } + + Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestPerl/hash_attack.pm b/2_0_13/t/response/TestPerl/hash_attack.pm new file mode 100644 index 0000000..e76b432 --- /dev/null +++ b/2_0_13/t/response/TestPerl/hash_attack.pm
@@ -0,0 +1,187 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestPerl::hash_attack; + +# if the rehashing of the keys in the stash happens due to the hash attack, +# mod_perl must not fail to find the previously cached stash entry (response +# and fixup handlers in this test). Moreover it must not fail to find +# that entry on the subsequent requests. +# +# the hash attack is detected when HV_MAX_LENGTH_BEFORE_REHASH keys find +# themselves in the same hash bucket on splitting (which happens when the +# number of keys crosses the threshold of a power of 2), in which case +# starting from 5.8.2 the hash will rehash all its keys using a random hash +# seed (PL_new_hash_seed, set in mod_perl or via PERL_HASH_SEED environment +# variable) +# +# Prior to the attack condition hashes use the PL_hash_seed, which is +# always 0. +# +# only in 5.8.1 hashes always use a non-zero PL_hash_seed (unless set +# to 0 via PERL_HASH_SEED environment variable or compiled without +# -DUSE_HASH_SEED or -DUSE_HASH_SEED_EXPLICIT + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestTrace; + +use Apache2::Const -compile => 'OK'; + +use Math::BigInt; + +use constant MASK_U32 => 2**32; +use constant HASH_SEED => 0; # 5.8.2: always zero before the rehashing +use constant THRESHOLD => 14; #define HV_MAX_LENGTH_BEFORE_(SPLIT|REHASH) +use constant START => "a"; + +# create conditions which will trigger a rehash on the current stash +# (__PACKAGE__::). Relevant for perl 5.8.2 and higher. +sub init { + my $r = shift; + + no strict 'refs'; + my @attack_keys = attack(\%{__PACKAGE__ . "::"}) if $] >= 5.008002; + + # define a new symbol (sub) after the attack has caused a re-hash + # check that mod_perl finds that symbol (fixup2) in the stash + no warnings 'redefine'; + eval qq[sub fixup2 { return Apache2::Const::OK; }]; + $r->push_handlers(PerlFixupHandler => \&fixup2); + + return Apache2::Const::DECLINED; +} + +sub fixup { return Apache2::Const::OK; } + +sub handler { + my $r = shift; + $r->print("ok"); + return Apache2::Const::OK; +} + +sub buckets { scalar(%{$_[0]}) =~ m#/([0-9]+)\z# ? 0+$1 : 8 } + +sub attack { + my $stash = shift; + + #require Hash::Util; # avail since 5.8.0 + debug "starting attack (it may take a long time!)"; + + my @keys; + + # the minimum of bits required to mount the attack on a hash + my $min_bits = log(THRESHOLD)/log(2); + + # if the hash has already been populated with a significant amount + # of entries the number of mask bits can be higher + my $keys = scalar keys %$stash; + my $bits = $keys ? log($keys)/log(2) : 0; + $bits = $min_bits if $min_bits > $bits; + + $bits = ceil($bits); + # need to add 3 bits to cover the internal split cases + $bits += 3; + my $mask = 2**$bits-1; + debug "mask: $mask ($bits)"; + + my $s = START; + my $c = 0; + # get 2 keys on top of the THRESHOLD + my $h; + while (@keys < THRESHOLD+2) { + next if exists $stash->{$s}; + $h = hash($s); + next unless ($h & $mask) == 0; + $c++; + $stash->{$s}++; + debug sprintf "%2d: %5s, %08x %s", $c, $s, $h, scalar(%$stash); + push @keys, $s; + debug "The hash collision attack has been successful" + if Internals::HvREHASH(%$stash); + } continue { + $s++; + } + + # If the rehash hasn't been triggered yet, it's being delayed until the + # next bucket split. Add keys until a split occurs. + unless (Internals::HvREHASH(%$stash)) { + debug "Will add padding keys until hash split"; + my $old_buckets = buckets($stash); + while (buckets($stash) == $old_buckets) { + next if exists $stash->{$s}; + $h = hash($s); + $c++; + $stash->{$s}++; + debug sprintf "%2d: %5s, %08x %s", $c, $s, $h, scalar(%$stash); + push @keys, $s; + debug "The hash collision attack has been successful" + if Internals::HvREHASH(%$stash); + $s++; + } + } + + # this verifies that the attack was mounted successfully. If + # HvREHASH is on it is. Otherwise the sequence wasn't successful. + die "Failed to mount the hash collision attack" + unless Internals::HvREHASH(%$stash); + + debug "ending attack"; + + return @keys; +} + +# least integer >= n +sub ceil { + my $value = shift; + return int($value) < $value ? int($value) + 1 : int($value); +} + +# trying to provide the fastest equivalent of C macro's PERL_HASH in +# Perl - the main complication is that the C macro uses U32 integer +# (unsigned int), which we can't do it Perl (it can do I32, with 'use +# integer'). So we outsmart Perl and take modules 2*32 after each +# calculation, emulating overflows that happen in C. +sub hash { + my $s = shift; + my @c = split //, $s; + my $u = HASH_SEED; + for (@c) { + # (A % M) + (B % M) == (A + B) % M + # This works because '+' produces a NV, which is big enough to hold + # the intermidiate result. We only need the % before any "^" and "&" + # to get the result in the range for an I32. + # and << doesn't work on NV, so using 1 << 10 + $u += ord; + $u += $u * (1 << 10); $u %= MASK_U32; + $u ^= $u >> 6; + } + $u += $u << 3; $u %= MASK_U32; + $u ^= $u >> 11; $u %= MASK_U32; + $u += $u << 15; $u %= MASK_U32; + $u; +} + +# a bit slower but simpler version +sub hash_original { + my $s = shift; + my @c = split //, $s; + my $u = HASH_SEED; + for (@c) { + $u += ord; $u %= MASK_U32; + $u += $u << 10; $u %= MASK_U32; + $u ^= $u >> 6; $u %= MASK_U32; + } + $u += $u << 3; $u %= MASK_U32; + $u ^= $u >> 11; $u %= MASK_U32; + $u += $u << 15; $u %= MASK_U32; + $u; +} + +1; + +__END__ +PerlModule TestPerl::hash_attack +PerlInitHandler TestPerl::hash_attack::init +# call twice to verify an access to the same hash value after the rehash +PerlFixupHandler TestPerl::hash_attack::fixup TestPerl::hash_attack::fixup +
diff --git a/2_0_13/t/response/TestPerl/ithreads.pm b/2_0_13/t/response/TestPerl/ithreads.pm new file mode 100644 index 0000000..84f11f6 --- /dev/null +++ b/2_0_13/t/response/TestPerl/ithreads.pm
@@ -0,0 +1,103 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestPerl::ithreads; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestTrace; + +use Apache2::Const -compile => 'OK'; + +# XXX: at this moment ithreads can be used only with 5.8.1. However +# once ithreads will be available on CPAN, we will need to change the +# check for perl 5.8.0 and this certain version of ithreads (here and +# in t/conf/post_config_startup.pl + +sub handler { + my $r = shift; + + plan $r, tests => 4, need + need_threads, + {"perl >= 5.8.1 is required (this is $])" => ($] >= 5.008001)}; + + # threads must have been preloaded at the server startup for this + # test (this is done at t/conf/post_config_startup.pl) + require threads; + threads->import(); + + # sky: the more modules are loaded, the slower new ithreads start + # because more things need to be cloned + debug '%INC size: ' . scalar(keys %INC) . "\n"; + + { + my $tid = threads->self->tid; + debug "1st TID is $tid" if defined $tid; + ok defined $tid; + } + + { + my $thr = threads->new(sub { + my $tid = threads->self->tid; + debug "2nd TID is $tid" if defined $tid; + return 2; + }); + ok t_cmp($thr->join, 2, "thread callback returned value"); + } + + { + require threads::shared; + my $counter_priv = 1; + my $counter_shar : shared = 1; + + my $thr = threads->new(sub { + my $tid = threads->self->tid; + debug "2nd TID is $tid" if defined $tid; + $counter_priv += $counter_priv for 1..10; + { + lock $counter_shar; + $counter_shar += $counter_shar for 1..10; + } + }); + + $counter_priv += $counter_priv for 1..10; + { + lock $counter_shar; + $counter_shar += $counter_shar for 1..10; + } + + $thr->join; + ok t_cmp($counter_shar, 2**20, "shared counter"); + ok t_cmp($counter_priv, 2**10, "private counter"); + } + + Apache2::Const::OK; +} + +1; + +__END__ +# APACHE_TEST_CONFIG_ORDER 941 + +<VirtualHost TestPerl::ithreads> + + <IfDefine PERL_USEITHREADS> + # a new interpreter pool + PerlOptions +Parent + PerlInterpStart 1 + PerlInterpMax 1 + PerlInterpMinSpare 1 + PerlInterpMaxSpare 1 + </IfDefine> + + # use test system's @INC + PerlSwitches -I@serverroot@ + PerlRequire "conf/modperl_inc.pl" + + <Location /TestPerl__ithreads> + SetHandler modperl + PerlResponseHandler TestPerl::ithreads + </Location> + +</VirtualHost>
diff --git a/2_0_13/t/response/TestPerl/ithreads3.pm b/2_0_13/t/response/TestPerl/ithreads3.pm new file mode 100644 index 0000000..3edae5e --- /dev/null +++ b/2_0_13/t/response/TestPerl/ithreads3.pm
@@ -0,0 +1,109 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestPerl::ithreads3; + +use strict; +use warnings FATAL => 'all'; + +use Apache2::RequestRec; +use Apache2::RequestIO; +use Apache2::RequestUtil; +use APR::Pool; +use Apache2::Const -compile => 'OK', 'DECLINED'; + +# XXX: These tests rely on the assumption that the virtual host is not +# otherwise accessed. In this case the same interpreter is chosen +# for each phase. The $counter counts them. +# Of course if only 1 interp is configured it must be hit each time. + +my $counter=0; + +sub response { + my $r=shift; + $r->content_type('text/plain'); + $r->print($counter); + return Apache2::Const::OK; +} + +sub count { $counter++; return Apache2::Const::DECLINED; } + +sub clear_pool { + delete $_[0]->pnotes->{my_pool}; + return Apache2::Const::DECLINED; +} + +sub trans { + my $r=shift; + my $test=$r->args; + $counter=0; + if( $test eq '1' ) { + # this is to check for a bug in modperl_response_handler versus + # modperl_response_handler_cgi. The former used to allocate an + # extra interpreter for its work. In both cases $counter should be + # 2 in the response phase + $r->push_handlers( PerlMapToStorageHandler=>__PACKAGE__.'::count' ); + $r->push_handlers( PerlFixupHandler=>__PACKAGE__.'::count' ); + } + elsif( $test eq '2' ) { + # now add an extra PerlCleanupHandler. It is run each time the + # interp is released. So it is run after Trans, MapToStorage and + # Fixup. In the response phase $counter should be 5. After Response + # it is run again but that is after. + # This used to eat up all interpreters because modperl_interp_unselect + # calls modperl_config_request_cleanup that allocates a new interp + # to handle the cleanup. When this interp is then unselected + # modperl_interp_unselect gets called again but the cleanup handler is + # still installed. So the cycle starts again until all interpreters + # are in use or the stack runs out. Then the thread is locked infinitely + # or a segfault appears. + $r->push_handlers( PerlMapToStorageHandler=>__PACKAGE__.'::count' ); + $r->push_handlers( PerlFixupHandler=>__PACKAGE__.'::count' ); + $r->push_handlers( PerlCleanupHandler=>__PACKAGE__.'::count' ); + } + elsif( $test eq '3' ) { + # a subpool adds an extra reference to the interp. So it is preserved + # and bound to the request until the pool is destroyed. So the cleanup + # handler is run only once after Fixup. Hence the counter is 3. + $r->push_handlers( PerlMapToStorageHandler=>__PACKAGE__.'::count' ); + $r->push_handlers( PerlFixupHandler=>__PACKAGE__.'::count' ); + $r->push_handlers( PerlCleanupHandler=>__PACKAGE__.'::count' ); + $r->pnotes->{my_pool}=$r->pool->new; + $r->push_handlers( PerlFixupHandler=>__PACKAGE__.'::clear_pool' ); + } + return Apache2::Const::DECLINED; +} + +1; + +__END__ +# APACHE_TEST_CONFIG_ORDER 942 + +<VirtualHost TestPerl::ithreads3> + + <IfDefine PERL_USEITHREADS> + # a new interpreter pool + PerlOptions +Parent + PerlInterpStart 3 + PerlInterpMax 3 + PerlInterpMinSpare 1 + PerlInterpMaxSpare 3 + # PerlInterpScope handler + </IfDefine> + + # use test system's @INC + PerlSwitches -I@serverroot@ + PerlRequire "conf/modperl_inc.pl" + PerlModule TestPerl::ithreads3 + + <Location /modperl> + SetHandler modperl + PerlResponseHandler TestPerl::ithreads3::response + </Location> + + <Location /perl-script> + SetHandler perl-script + PerlResponseHandler TestPerl::ithreads3::response + </Location> + + PerlTransHandler TestPerl::ithreads3::trans + +</VirtualHost>
diff --git a/2_0_13/t/response/TestPerl/ithreads_args.pm b/2_0_13/t/response/TestPerl/ithreads_args.pm new file mode 100644 index 0000000..b3e6eb8 --- /dev/null +++ b/2_0_13/t/response/TestPerl/ithreads_args.pm
@@ -0,0 +1,33 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestPerl::ithreads_args; + +# reproducing a bug in perl ithreads: [perl #34342] +# https://rt.perl.org/rt3/Ticket/Display.html?id=34342 +# +# here an unshifted $r (i.e. as it leaves @_ populated causes a scalar +# leak in the thread). + +use Devel::Peek; +use Apache::Test; + +sub handler { # XXX: unshifted $_[0] leaks scalar + #Dump $_[0]; + #my $r = shift; # shift removes the leak + my $r = $_[0]; + #Dump $r; # here PADBUSY,PADMY prevent the ithread from cloning it + + plan $r, tests => 1, need + need_threads, + {"perl >= 5.8.1 is required (this is $])" => ($] >= 5.008001)}; + + require threads; + + warn "\n*** The following leak is expected (perl bug #34342) ***\n"; + threads->new(sub {})->join; + + ok 1; + + return 0; +} + +1;
diff --git a/2_0_13/t/response/TestPerl/ithreads_eval.pm b/2_0_13/t/response/TestPerl/ithreads_eval.pm new file mode 100644 index 0000000..fe1b0af --- /dev/null +++ b/2_0_13/t/response/TestPerl/ithreads_eval.pm
@@ -0,0 +1,51 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestPerl::ithreads_eval; + +# reproducing a bug in perl ithreads: [perl #34341] +# https://rt.perl.org/rt3/Ticket/Display.html?id=34341 +# +# $thr->join triggers the following leak: +# - due to to local $0, (its second MAGIC's MG_OBJ, +# you can see it in the output of Dump $0). This leak was first +# spotted in the RegistryCooker.pm which localizes $0 + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Devel::Peek; + +use Apache2::Const -compile => 'OK'; + +sub handler { + my $r = shift; + + plan $r, tests => 1, need + need_threads, + {"perl >= 5.8.1 is required (this is $])" => ($] >= 5.008001)}; + + require threads; + + eval <<'EOI'; +sub mytest { + local $0 = 'mememe'; # <== XXX: leaks scalar + my $thr; + $thr = threads->new(\&mythread); + $thr->join; # <== XXX: triggers scalar leak +} +sub mythread { + #Dump $0; +} +EOI + + warn "\n*** The following leak is expected (perl bug #34341) ***\n"; + mytest(); + + ok 1; + + return Apache2::Const::OK; +} + +1;
diff --git a/2_0_13/t/response/TestPerl/signals.pm b/2_0_13/t/response/TestPerl/signals.pm new file mode 100644 index 0000000..2c08d43 --- /dev/null +++ b/2_0_13/t/response/TestPerl/signals.pm
@@ -0,0 +1,86 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestPerl::signals; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache2::BuildConfig; +use Apache::TestConfig; + +use Apache2::MPM (); + +use POSIX qw(SIGALRM); + +use constant OSX => Apache::TestConfig::OSX; + +use Apache2::Const -compile => qw(OK); + +my $mpm = lc Apache2::MPM->show; + +# signal handlers don't work anywhere but with prefork, since signals +# and threads don't mix +# moreover "unsafe"-non-POSIX sighandlers don't work under static prefork + +sub handler { + my $r = shift; + + my $build = Apache2::BuildConfig->new; + my $static = $build->should_build_apache ? 1 : 0; + + my $tests = $static ? 1 : 2; + + plan $r, tests => $tests, + need { "works only for prefork" => ($mpm eq 'prefork') }; + + # doesn't work under static prefork + if (!$static) { + if (OSX) { + skip "ALRM can't be used on darwin", 0; + } + else { + local $ENV{PERL_SIGNALS} = "unsafe"; + + eval { + local $SIG{ALRM} = sub { die "alarm" }; + alarm 2; + run_for_5_sec(); + alarm 0; + }; + ok t_cmp $@, qr/alarm/, "SIGALRM / unsafe %SIG"; + } + } + + # POSIX::sigaction doesn't work under 5.6.x + if ($] >= 5.008) { + my $mask = POSIX::SigSet->new( SIGALRM ); + my $action = POSIX::SigAction->new(sub { die "alarm" }, $mask); + my $oldaction = POSIX::SigAction->new(); + POSIX::sigaction(SIGALRM, $action, $oldaction ); + eval { + alarm 2; + run_for_5_sec(); + alarm 0; + }; + POSIX::sigaction(SIGALRM, $oldaction); # restore original + + ok t_cmp $@, qr/alarm/, "SIGALRM / POSIX"; + } + else { + skip "POSIX::sigaction doesn't work under 5.6.x", 0; + } + + return Apache2::Const::OK; +} + +sub run_for_5_sec { + for (1..20) { # ~5 sec + my $x = 3**20; + select undef, undef, undef, 0.25; + } +} + +1; + +__END__
diff --git a/2_0_13/t/response/TestUser/rewrite.pm b/2_0_13/t/response/TestUser/rewrite.pm new file mode 100644 index 0000000..0416612 --- /dev/null +++ b/2_0_13/t/response/TestUser/rewrite.pm
@@ -0,0 +1,76 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestUser::rewrite; + +# test here the technique of rewriting the URI namespace and +# pushing/changing the query string (args). Note that in this test we +# use a custom maptostorage handler so Apache won't complain that we +# didn't set r->filename in the core maptostorage handler. the custom +# handler simply shortcuts that phase, with the added benefit of +# skipping the ap_directory_walk's stat() calls which speeds up the +# whole thing. +# +# an alternative solution is to return Apache2::Const::DECLINED from the trans +# handler, in which case map2storage is not required (but it'll do a +# bunch of stat() calls then, which you may want to avoid) + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::URI (); + +use Apache2::Const -compile => qw(DECLINED OK); + +my $uri_real = "/TestUser__rewrite_real"; +my $args_real = "foo=bar&boo=tar"; + +sub trans { + my $r = shift; + + return Apache2::Const::DECLINED unless $r->uri eq '/TestUser__rewrite'; + + $r->uri($uri_real); + $r->args($args_real); + + return Apache2::Const::OK; +} + +sub map2storage { + my $r = shift; + + return Apache2::Const::DECLINED unless $r->uri eq $uri_real; + + # skip ap_directory_walk stat() calls + return Apache2::Const::OK; +} + +sub response { + my $r = shift; + + plan $r, tests => 1; + + my $args = $r->args(); + + ok t_cmp($args, $args_real, "args"); + + return Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> + <VirtualHost TestUser::rewrite> + PerlModule TestUser::rewrite + PerlTransHandler TestUser::rewrite::trans + PerlMapToStorageHandler TestUser::rewrite::map2storage + <Location /TestUser__rewrite_real> + SetHandler modperl + PerlResponseHandler TestUser::rewrite::response + </Location> + </VirtualHost> +</NoAutoConfig> +
diff --git a/2_0_13/t/response/TestVhost/config.pm b/2_0_13/t/response/TestVhost/config.pm new file mode 100644 index 0000000..4a581b6 --- /dev/null +++ b/2_0_13/t/response/TestVhost/config.pm
@@ -0,0 +1,72 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestVhost::config; + +# Test whether under threaded mpms (and not) a vhost with 'PerlOptions +# +Parent', can run <Perl> sections, which call into config again via +# add_config(). + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; + +use Apache2::RequestUtil (); +use APR::Table (); + +use File::Spec::Functions qw(canonpath catdir); + +use Apache2::Const -compile => 'OK'; + +# initialized in t/htdocs/vhost/post_config.pl +our $restart_count; + +# using a different from 'handler' name on purpose, to make sure +# that the module is preloaded at the server startup +sub my_handler { + my $r = shift; + + plan $r, tests => 2; + + { + my $expected = $r->document_root; + my $received = $r->dir_config->get('DocumentRootCheck'); + ok t_cmp(canonpath($received), canonpath($expected), "DocumentRoot"); + } + + { + ok t_cmp($restart_count, 2, "PerlPostConfigRequire"); + } + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +<VirtualHost TestVhost::config> + DocumentRoot @documentroot@/vhost + + <IfDefine PERL_USEITHREADS> + # a new interpreter pool + PerlOptions +Parent + PerlInterpStart 1 + PerlInterpMax 1 + PerlInterpMinSpare 1 + PerlInterpMaxSpare 1 + </IfDefine> + + # use test system's @INC + PerlSwitches -I@serverroot@ + + # mp2 modules + PerlRequire "@serverroot@/conf/modperl_inc.pl" + + # private to this vhost stuff + PerlRequire "@documentroot@/vhost/startup.pl" + PerlPostConfigRequire "@documentroot@/vhost/post_config.pl" + + # <Location /TestVhost__config> container is added via add_config + # in t/htdocs/vhost/startup.pl +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/response/TestVhost/log.pm b/2_0_13/t/response/TestVhost/log.pm new file mode 100644 index 0000000..2bbf438 --- /dev/null +++ b/2_0_13/t/response/TestVhost/log.pm
@@ -0,0 +1,99 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package TestVhost::log; + +# testing that the warn and other logging functions are writing into +# the vhost error_log and not the main one. + +use strict; +use warnings; +# don't use: +# use warnings FATAL => 'all'; +# here as it breaks the $SIG{__WARN__} sub test for perl 5.6, though +# it works fine with perl 5.8+ + +use Apache2::RequestUtil (); +use Apache2::Log (); +use Apache2::ServerRec qw(warn); # override warn locally + +use File::Spec::Functions qw(catfile); + +use Apache::Test; +use Apache::TestUtil; +use TestCommon::LogDiff; + +use Apache2::Const -compile => 'OK'; + +my @methods1 = ( + '$r->log->warn', + '$r->log_error', + '$r->warn', + '$s->log->warn', + '$s->log_error', + '$s->warn', +); + +my @methods2 = ( + 'Apache2::ServerRec::warn', + 'warn', +); + +my $path = catfile Apache::Test::vars('documentroot'), + qw(vhost error_log); + +sub handler { + my $r = shift; + + plan $r, tests => 1 + @methods1 + @methods2; + + my $s = $r->server; + my $logdiff = TestCommon::LogDiff->new($path); + + ### $r|$s logging + for my $m (@methods1) { + eval "$m(q[$m])"; + ok t_cmp $logdiff->diff, qr/\Q$m/, $m; + } + + ### object-less logging + # set Apache2::RequestUtil->request($r) instead of using + # PerlOptions +GlobalRequest + # in order to make sure that the above tests work fine, + # w/o having the global request set + Apache2::RequestUtil->request($r); + for my $m (@methods2) { + eval "$m(q[$m])"; + ok t_cmp $logdiff->diff, qr/\Q$m/, $m; + } + + # internal warnings (also needs +GlobalRequest) + { + no warnings; # avoid FATAL warnings + use warnings; + local $SIG{__WARN__} = \&Apache2::ServerRec::warn; + eval q[my $x = "aaa" + 1;]; + ok t_cmp + $logdiff->diff, + qr/Argument "aaa" isn't numeric in addition/, + "internal warning"; + } + + # die logs into the vhost log just fine + #die "horrible death!"; + + Apache2::Const::OK; +} + +1; +__END__ +<NoAutoConfig> +<VirtualHost TestVhost::log> + DocumentRoot @documentroot@/vhost + ErrorLog @documentroot@/vhost/error_log + + <Location /TestVhost__log> + SetHandler modperl + PerlResponseHandler TestVhost::log + </Location> + +</VirtualHost> +</NoAutoConfig>
diff --git a/2_0_13/t/user/README b/2_0_13/t/user/README new file mode 100644 index 0000000..7e2e782 --- /dev/null +++ b/2_0_13/t/user/README
@@ -0,0 +1,2 @@ +This directory contains userspace tests, such as those that excercise +non-unit, multiple-API tests, or Apache integration tests, etc.
diff --git a/2_0_13/t/user/rewrite.t b/2_0_13/t/user/rewrite.t new file mode 100644 index 0000000..64afec6 --- /dev/null +++ b/2_0_13/t/user/rewrite.t
@@ -0,0 +1,13 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest qw(GET_BODY_ASSERT); +use Apache::Test; +use Apache::TestUtil; + +my $module = 'TestUser::rewrite'; +my $url = Apache::TestRequest::module2url($module); + +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url;
diff --git a/2_0_13/t/vhost/config.t b/2_0_13/t/vhost/config.t new file mode 100644 index 0000000..36d1a49 --- /dev/null +++ b/2_0_13/t/vhost/config.t
@@ -0,0 +1,29 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# the handler is configured in modperl_extra.pl via +# Apache2::ServerUtil->server->add_config + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest 'GET'; + +my $module = 'TestVhost::config'; +my $url = Apache::TestRequest::module2url($module); + +t_debug("connecting to $url"); +my $res = GET $url; + +if ($res->is_success) { + print $res->content; +} +else { + if ($res->code == 404) { + my $docroot = Apache::Test::vars('documentroot'); + die "this test gets its <Location> configuration added via " . + "$docroot/vhost/startup.pl, this could be the cause " . + "of the failure"; + } + else { + die "server side has failed (response code: ", $res->code, "),\n", + "see t/logs/error_log for more details\n"; + } +}
diff --git a/2_0_13/t/vhost/log.t b/2_0_13/t/vhost/log.t new file mode 100644 index 0000000..3205905 --- /dev/null +++ b/2_0_13/t/vhost/log.t
@@ -0,0 +1,10 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use Apache::TestUtil; +use Apache::TestRequest 'GET_BODY_ASSERT'; + +my $module = 'TestVhost::log'; +my $url = Apache::TestRequest::module2url($module); + +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url; +
diff --git a/2_0_13/todo/2.0.6 b/2_0_13/todo/2.0.6 new file mode 100644 index 0000000..d64c996 --- /dev/null +++ b/2_0_13/todo/2.0.6
@@ -0,0 +1,10 @@ +SHOW STOPPERS +==================== +- Windows Segfaults [needs windows developer owner, ] +- MANIFEST verifications [needs detail, ] +- rt.cpan.org PRs [pgollucci, phred, ] + +NICE TO HAVE +============= +- Smolder, https://issues.apache.org/jira/browse/INFRA-1612 [pgollucci, ] +
diff --git a/2_0_13/todo/README b/2_0_13/todo/README new file mode 100644 index 0000000..c87880d --- /dev/null +++ b/2_0_13/todo/README
@@ -0,0 +1,9 @@ +this directory contains notes on whats left to be done: + +release - showstopper issues for mod_perl 2.0 release + +features_* - + +bugs_* - + +docs - docs todo
diff --git a/2_0_13/todo/api_status b/2_0_13/todo/api_status new file mode 100644 index 0000000..22fd6a6 --- /dev/null +++ b/2_0_13/todo/api_status
@@ -0,0 +1,156 @@ +This file provides the status of the supported API, via the +API documentation files. + +col1 legend +----------- +-: not started/unknown ++: in process +V: done (for 2.0 release) +g = gozer at work + +col2 legend +----------- +-: not started/unknown +P: post 2.0 (has API to be polished after 2.0 release) +V: done completely + +- the file path is relative to the modperl-docs cvs repository +######################################################### +VV src/docs/2.0/api/Apache.pod +VV src/docs/2.0/api/Apache/Access.pod +VP src/docs/2.0/api/Apache/CmdParms.pod + context +VV src/docs/2.0/api/Apache/Command.pod +VP src/docs/2.0/api/Apache/Connection.pod + conn_config +VP src/docs/2.0/api/Apache/Const.pod + (this will never be complete, fill it in as we go) +VV src/docs/2.0/api/Apache/Directive.pod +VP src/docs/2.0/api/Apache/Filter.pod + The whole TIE interface +VV src/docs/2.0/api/Apache/FilterRec.pod +VV src/docs/2.0/api/Apache/HookRun.pod +VP src/docs/2.0/api/Apache/Log.pod + log_pid +VV src/docs/2.0/api/Apache/Module.pod +VV src/docs/2.0/api/Apache/PerlSections.pod +VV src/docs/2.0/api/Apache/Process.pod +VV src/docs/2.0/api/Apache/Reload.pod +VV src/docs/2.0/api/Apache/RequestIO.pod +VP src/docs/2.0/api/Apache/RequestRec.pod + allowed_methods + allowed_xmethods + content_languages (was in mp1, need to implement APR::ArrayHeader ) + request_config + used_path_info +VV src/docs/2.0/api/Apache/RequestUtil.pod +VP src/docs/2.0/api/Apache/Response.pod + send_error_response + send_mmap +VP src/docs/2.0/api/Apache/ServerRec.pod + addrs + lookup_defaults + module_config + names + wild_names +VP src/docs/2.0/api/Apache/ServerUtil.pod + error_log2stderr +VV src/docs/2.0/api/Apache/SubProcess.pod +VV src/docs/2.0/api/Apache/SubRequest.pod + internal_fast_redirect + lookup_dirent +VV src/docs/2.0/api/Apache/URI.pod +VV src/docs/2.0/api/Apache/Util.pod + +VV src/docs/2.0/api/ModPerl/Const.pod +VV src/docs/2.0/api/ModPerl/Global.pod +VV src/docs/2.0/api/ModPerl/Util.pod + +VV src/docs/2.0/api/APR.pod +VV src/docs/2.0/api/APR/Base64.pod +VV src/docs/2.0/api/APR/Brigade.pod +VP src/docs/2.0/api/APR/Bucket.pod + data + start +VV src/docs/2.0/api/APR/BucketAlloc.pod +VV src/docs/2.0/api/APR/BucketType.pod +VP src/docs/2.0/api/APR/Const.pod + (this will never be complete, fill it in as we go) +VV src/docs/2.0/api/APR/Date.pod +VV src/docs/2.0/api/APR/Error.pod +VV src/docs/2.0/api/APR/Finfo.pod +VV src/docs/2.0/api/APR/IpSubnet.pod +VV src/docs/2.0/api/APR/OS.pod ++V src/docs/2.0/api/APR/PerlIO.pod + (convert to use exceptions) +VP src/docs/2.0/api/APR/Pool.pod + cleanup_for_exec + (clean has some win32 problems) +VP src/docs/2.0/api/APR/SockAddr.pod + equal +VP src/docs/2.0/api/APR/Socket.pod + bind + close + connect + listen + recvfrom + sendto +VV src/docs/2.0/api/APR/String.pod +VV src/docs/2.0/api/APR/Table.pod +VP src/docs/2.0/api/APR/ThreadMutex.pod + DESTROY + lock + new + pool_get + trylock + unlock +VV src/docs/2.0/api/APR/URI.pod +VP src/docs/2.0/api/APR/Util.pod + filepath_name_get + password_get +VV src/docs/2.0/api/APR/UUID.pod + +##################### +### other modules ### +##################### + +VV src/docs/2.0/api/Apache/Status.pod +VV src/docs/2.0/api/Apache/SizeLimit.pod +VV src/docs/2.0/api/Apache/Resource.pod +VV src/docs/2.0/api/Apache/compat.pod +VV src/docs/2.0/api/Apache/porting.pod +-- src/docs/2.0/api/ModPerl/BuildMM.pod +-- src/docs/2.0/api/ModPerl/MM.pod +VV src/docs/2.0/api/ModPerl/MethodLookup.pod +-- src/docs/2.0/api/ModPerl/PerlRun.pod +-- src/docs/2.0/api/ModPerl/Registry.pod +-- src/docs/2.0/api/ModPerl/RegistryBB.pod +-- src/docs/2.0/api/ModPerl/RegistryCooker.pod +-- src/docs/2.0/api/ModPerl/RegistryLoader.pod + + +################################ +### Other API related things ### +################################ + +* the following accessors might be turned into read/write (they are + readonly at the moment). if you think that should be the case, + please document the change and hopefully add a new sub-test. + + conn_rec: + --------- + local_addr + remote_addr + remote_host + aborted + local_ip + local_host + + ap_directive_t: + --------------- + next + first_child + parent + filename + line_num +
diff --git a/2_0_13/todo/bugs_apr_ext b/2_0_13/todo/bugs_apr_ext new file mode 100644 index 0000000..33ff108 --- /dev/null +++ b/2_0_13/todo/bugs_apr_ext
@@ -0,0 +1,26 @@ +######################################## +# external (non-mod_perl) APR:: issues # +######################################## + +* As mike chamberlain told me over irc, apr-ext/perlio was faling for + him because of the modperl_perl_gensym not being resolved in + APR/PerlIO.so. I didn't see that error since on linux by default + symbols resolution is lazy and since that part of the api wasn't + tested I did see the problem. On MacOSX the loading is RTLD_NOW + (non-lazy) so it detects any missing symbols problems immediately. + + Luckily DynaLoader allows us to force the non-lazy mode by setting + an env var: PERL_DL_NONLAZY=1. We need to force this env variable on + when building with MP_MAINTAINER=1. I suppose that it should be + added to the autogenerated t/TEST and t/SMOKE. and to + t/conf/modperl_extra.pl ($ENV{PERL_DL_NONLAZY}=1) so it affects the + server-side as well as the client-side (normally env var aren't + propogated to the server). + +* APR::Pool relies on interpreter management function: + modperl_interp_unselect. At the moment I've worked around it by + defining an empty function in APR.xs. But a cleaner solution is + desirable. + +* modules that we need to add tests for in apr-ext: + APR::IpSubnet
diff --git a/2_0_13/todo/bugs_build b/2_0_13/todo/bugs_build new file mode 100644 index 0000000..9a1ca38 --- /dev/null +++ b/2_0_13/todo/bugs_build
@@ -0,0 +1,85 @@ +####################### +# Build/Startup Issue # +####################### + + +OS Ver Mod Comments +---------------------------------------------------------------------- +OpenBSD 2.9 DSO Builds but won't start, with segfaults in the + Perl lexer. I wasn't even able to start mp1-dso with + the customly built perl (tried 5.6.1 .. 5.9.0) + -- the segfault is again in lexer. It seems that + the standard OpenBSD perl package has been heavily + patched, when the core system perl 5.6.0 package was + built, since I can run 'make test' on mp1-dso, but not + with a customly built 5.6.0 with the same + options. Since 2.9 is no longer supported by OpenBSD, + there is no 5.6.1 or higher to try, so at this moment + we simply give up on 2.9. We think that the static mp2 + build should work just fine (once it's available). + +AIX 3.3 DSO Works with -berok to ignore linking errors (symbol + resolution). Should replace -berok with a proper + symbol resolution at linking time, but I had not much + success with using this approach (dlopen fails). + +AIX 4.3.3 DSO reported to work with mod_perl_1.99_12 and + Apache 2.0.48/prefork mpm + but doesn't start with worker: + http://marc.theaimsgroup.com/?t=106894906200003&r=1&w=2 + +FreeBSD ?? DSO Works with non-threaded perl (4.8-RELEASE-5.2-RELEASE, 6.0-CURRENT) + http://marc.theaimsgroup.com/?l=apache-modperl&m=106399870822612&w=2 + The following combo is known to work: + http://gossamer-threads.com/lists/modperl/modperl/82887 + FreeBSD 5.4-RELEASE + gcc 3.4.2 + perl 5.8.7 WITH ithreads + httpd 2.0.54 apr IS THREADED (worker mpm) + mod_perl2.0.1 + +HPUX11i DSO + PA-RISC2.0-thread-multi-LP64 + hp-ux loire b.11.11 u 9000800 1756907651 unlimited-user license + Cannot load .../modules/mod_perl.so into server: Error 0 + http://marc.theaimsgroup.com/?t=108325310800002&r=1&w=2 + Bill Rowe gives some hints here + http://marc.theaimsgroup.com/?l=apache-modperl&m=108334017416318&w=2 + Static works OK! + +* Does not compile with bleedperl (5.9.x) due to modperl_error.c and Perl_croak() + on FreeBSD. This is a PERL bug, but p5p and myself, and not sure where the problem is yet. + +* gcc 4.x and higher compiles break under -Werror +[pgollucci volunteers] + +* AAA changes in httpd break httpd 2.3.x+ (svn trunk) builds terribly on all platforms. + +* Need to cleanup functions only needed for certain build flavors + (perlio/threads/etc) out of lib/ModPerl/WrapXS.pm:$ithread_exports + and use the newer, simpler #ifdef technique (see modperl_io_apache_init + for an example) + +* we should stop generating xs/apache_*, at least for a reason that + it's incomplete and will be never complete as we don't keep up with + changes with ap_/apr_ namespace. Also we don't have the logic to + handle cases where functions aren't available on certain + platforms. Importing these unavailable functions may cause loading + problems on some platforms (aix?). If developers need to import + symbols from ap_/apr_ namespace they should use .exp files installed + by httpd/apr/aprutil. + +* we have a dependency check problem when xs/*/*.h use code from + xs/modperl_xs*.h, when the latter change 'make' won't rebuild the + dependant files + +* Testing: + Need to put Philippe's smoking test into the core + -- shouldn't forget to test with perlio enabled and disabled + +* source_scan won't create Wrap/Foo/Bar.xs if + xs/maps/modperl_functions.map defines only a boot section: + MODULE=APR::IO PACKAGE=APR::IO BOOT=1 + unless there is at least one function added to the .map file + http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=100702825506778&w=2 +
diff --git a/2_0_13/todo/bugs_mp b/2_0_13/todo/bugs_mp new file mode 100644 index 0000000..e0e9412 --- /dev/null +++ b/2_0_13/todo/bugs_mp
@@ -0,0 +1,136 @@ +################# +# mod_perl bugs # +################# + +* local %ENV doesn't work, see t/modperl/local_ent. + +* PerlOptions None needs to be implemented, see t/modperl/perl_options2.t + +* PerlIOApache_flush() + Setting local $| = 0 doesn't work with regular print statements under ModPerl::* + + http://p6m7g8.net/MP2/84625 + http://www.gossamer-threads.com/lists/modperl/dev/85365 + [pgollucci volunteers] + +* $r->rflush doesn't work. see: + http://marc.theaimsgroup.com/?l=apache-modperl&m=103847990813285&w=2 + I also see a weird behavior where it does sends FLUSH buckets but + they all seem to fall through the data, thus not really flushing + anything. this can be easily reproduced with MyApache::FilterSnoop. + + See also + http://www.gossamer-threads.com/lists/modperl/dev/84744?search_string=%23%7C%2C%20flushing%2C%20etc;#84743 + for a related $| but not the same issue. + [pgollucci volunteers] + +* early pool destruction issues + http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=108872944815382&w=2 + +* PassEnv/SetEnv propogation in <Perl> section + http://www.gossamer-threads.com/archive/mod_perl_C1/dev_F4/%5BMP2_BUG%5D_PerlPassEnv_issues_P70500/ + +* there was a report about PerlRun leaking memory. the reporter didn't + give any more details, but I suspect that it's due to + ModPerl::Util::unload_package() which perfectly fits the timing when + the leak was introduced (when PerlRun started to use unload_package). + + Report: http://gossamer-threads.com/lists/modperl/modperl/77162 + +* most of the xs wrappers print no "Usage: " when wrong args/wrong + number of args are passed, would be nice to add the usage message + whenever incorrect arguments error is logged. e.g., when + APR::URI->parse() gets the wrong first arg (non-pool) it prints: + + p is not of type APR::Pool at ... + + whereas it's not so obvious that the function expected the pool + object, neither it specifies which ("arg number") of the arguments + is wrong. + + possible solution: add a new field to the map files, which will be + used as a usage message whenever an argument error occurs. + +* 'SetHandler modperl' doesn't reset $|, so if anything turns it on + anywhere, it's going to stay that way. Meaning excessive flushing + probably causing a performance hit. I've tried to add the code to + reset it, but this requires getting a perl interpreter at the early + stage and it breaks several filter tests, which has relied before on + the coincidence that both the response handler and the filter were + run by the same interpreter (in particular this breaks the code + where push_handlers() uses a string as a handler, rather a CODE + reference, see t/filter/TestFilter/both_str_rec_add.pm, to + reproduce the problem, simply s/modperl/perl-script/) + + +* Apache::PerlSection->dump() will not preserve tied'edness. This is + handled proprely in Storable, so either switch dump/restore to + non-human readable (-0.5) or borrow the same logic to dump/restore + tied objects. + + + +* Apache::Log compat issues: + + Apache->warn, Apache::warn, Apache::Server->warn and + Apache->Apache::Server->log_error are all doing: + s = modperl_global_get_server_rec(); + and this function is thread safe only during the startup. + + possible solutions: + + 1) enforce that these functions are used only at the server startup + + 2) require +GlobalRequest, which gives us r->server, now thread + safe (though slow). + + 3) drop them all from the API and move to compat. + [remember that Apache::warn is needed for registry scripts to + override warn()] + + For Apache::warn and registry, the solution is to supply + GLOBAL::CORE::warn for the current request and get $r inside of it + and] + + Report: Message-ID: <Pine.LNX.4.33.0206201011070.2590-100000@mako.covalent.net> + Status: <img alt="Doug, contemplating"> + +* see if we can avoid touching environ[] until a fork() from Perl + happens + +* Apache::Status prints a bogus filename via B::CV (e.g. from the test + suite) + + http://localhost:8529/status/perl/APR::Brigade::bootstrap/FUNCTION?cv_dump + Subroutine info for APR::Brigade::bootstrap + File: xYµ + Package: APR::Brigade + ... + + notice the bogus filename. For some reason this problem doesn't + exist with APR::Bucket: + + http://localhost:8529/status/perl/APR::Bucket::bootstrap/FUNCTION?cv_dump + + I have tested that the bogus filename comes from $obj->FILE in + Apache::Stats::cv_file, where $obj is blessed into B::CV. + + The problem has been noticed with threaded 5.8.1 perl, didn't test + any other builds. + + Apparently it's a known to p5p problem: + http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-08/msg00514.html + http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-11/msg01126.html + + Report: + http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=106893251911930&w=2 + Priority: Low + +* mpxs_Apache2__RequestRec_GETC in Apache_RequestIO.h is out to be + reimplemented similar to read() w/o using the deprecated + client_block interface + +* Segfaults under Apache::Reload (could be uncovering a bug in mp): + http://marc.theaimsgroup.com/?t=111145169900002&r=1&w=2 + owner: gozer +-
diff --git a/2_0_13/todo/bugs_registry b/2_0_13/todo/bugs_registry new file mode 100644 index 0000000..7aaece4 --- /dev/null +++ b/2_0_13/todo/bugs_registry
@@ -0,0 +1,20 @@ +########################## +# Registry specific bugs # +########################## + + +* An open issue with chdir, which is process-scoped. Arthur Bergman + has started the work on ex::threads::safecwd, which is discussed + here: http://www.perl.com/pub/a/2002/06/11/threads.html?page=2 + +RegistryLoader: + +- chdir() needs to be adjusted when RegistryCooker implements it + +RegistryCooker: + +- consider not to use $$ in debug tracing. Not all platforms give out + a different pid for different threads. + +- some problems with setting the DEBUG() constant based on the value of + Apache->server->dir_config('ModPerl::RegistryCooker::DEBUG')
diff --git a/2_0_13/todo/design_notes b/2_0_13/todo/design_notes new file mode 100644 index 0000000..3895bda --- /dev/null +++ b/2_0_13/todo/design_notes
@@ -0,0 +1,105 @@ +(dunno where to put it but don't want to lose these design notes, so +just land them here for now) + + +Filters: direct C api mapping +-------------------- + +Apache::register_output_filter($filtername, $callback, $filter_type) + +Apache::register_input_filter($filtername, $callback, $filter_type) + + filter_type can be one of: + Apache::FTYPE_CONTENT + Apache::FTYPE_HTTP_HEADER + Apache::FTYPE_TRANSCODE + Apache::FTYPE_CONNECTION + Apache::FTYPE_NETWORK + +$r->add_output_filter($name, $ctx) +$c->add_output_filter($name, $ctx) + +$r->add_input_filter($name, $ctx) +$c->add_input_filter($name, $ctx) + +note: $ctx will default to NULL + +Filters: directives +---------- + +PerlInputFilterHandler + +PerlOutputFilterHandler + +each will be the equivalent of: + +ap_register_{input,output}_filter($handler_name, $handler, $filter_type) + +where: + $handler_name is the Perl name, at the moment is "MODPERL_OUTPUT" and + "MODPERL_INPUT", would be easy to switch that to the handler name + + $handler is the modperl C callback + + $filter_type defaults to AP_FTYPE_CONTENT, subroutine attributes can + be used to specify the filter_types list above + + based on attributes, add_{input,output}_filter may need to happen at + different times, e.g. input filters who want to filter headers + + content vs. input filters who want to filter only content + +alternative to those directives would be: + +PerlInputFilter + +PerlOutputFilter + +combined with: + +SetInputFilter + +SetOutputFilter + +pros: can use Perl{Input,Output}Filter to register the filter in + httpd.conf, rather than using the API. can then call + $r->add_{input,output}_filter($filter_name) at request time + +cons: in the common case, requires two directives that use the same + values (the $handler_name) + + - and/or - + +PerlSetInputFilter + +PerlSetOutputFilter + +as aliases for SetInputFilter, SetOutputFilter which also take care of +filter registration (which PerlInputFilter, PerlOutputFilter would +have done) + +pros: similar to Set{Input,Output}Filter + only need to use one directive + +cons: the filter module needs to register the filter in order to add + the filter at request time without using a directive + however: PerlModule Apache::FooFilter + where Apache::FooFilter registers the filter, can provide this + functionality without requiring new Perl{Input,Output}Filter + directives + + - in any case - + +with the C api mapping it should be possible for a PerlModule to +register the filter(s), then use the standard Set{Input,Output}Filter +directives and the add_{input,output}_filter api at request time. + +note: no need to maintain a list of PerlFilters (like PerlModule, +PerlRequire) since the directives trigger modperl_handler_new(), just +like all other Perl*Handlers + +Filters: {get,set,push}_handlers +----------------------- +would be nice for Perl{Input,Output}FilterHandler to work with the +modperl {get,set,push}_handlers api just like other Perl*Handlers + +
diff --git a/2_0_13/todo/docs b/2_0_13/todo/docs new file mode 100644 index 0000000..4c48f8b --- /dev/null +++ b/2_0_13/todo/docs
@@ -0,0 +1 @@ +docs todo is located at modperl-docs/src/docs/2.0/TODO
diff --git a/2_0_13/todo/features_deprecated b/2_0_13/todo/features_deprecated new file mode 100644 index 0000000..18f3624 --- /dev/null +++ b/2_0_13/todo/features_deprecated
@@ -0,0 +1,28 @@ +these features with either: +a) never be in 2.0 +b) only be in #ifdef MP_DEPRECATED +c) be a form that was nothing like 1.xx (e.g. Apache::Leak) +d) split off into something standalone on cpan + +- MaxModPerlRequestsPerChild + +- $r->seqno, $r->sent_header, + $r->query_string, $r->basic_http_header, $r->new_read, + $r->write_client, $r->read_client_block, $r->translate_name + +- $r->content, $r->args in-a-list-context (exist in Apache::compat) + +- $Apache::Server::Starting, $Apache::Server::ReStarting + +- modules: + + Apache::SIG: dead + + Apache::Symbol: unknown + + Apache::Leak: could be made useful + + Apache::RedirectLogFix: dead + + Apache::Include: was just an example + + Apache::Debug: could be make useful + + Apache::FakeRequest: should be built in + + Apache::httpd_conf: dead (to be replaced by new test framework) + + Apache::Symdump: unknown + + Apache::Opcode: was experimental, needs much attention to be + useful
diff --git a/2_0_13/todo/features_maybe b/2_0_13/todo/features_maybe new file mode 100644 index 0000000..85c278e --- /dev/null +++ b/2_0_13/todo/features_maybe
@@ -0,0 +1,203 @@ +######################### +# Nice to have features # +######################### + +* If Apache::SubRequest::DESTROY gets invoked more than once on the + same object (directly and indirectly via object's exit of scope), + memory gets corrupted and some later unrelated requests get affected + badly (segfaults in unrelated areas). So we probably need to do the + same handling as APR::Pool, where we make sure that no matter how + DESTROY is called, it's always called only once, any consequent + calls can be made a NOP or assert. BTW, it's easy to reproduce the + problem, by simply calling $subrequest->DESTROY 3 times or so in a + raw, the server just hangs... + +* 'apachectl configtest' will not test perl modules, unless <perl> + section or PerlLoadModule has happeneded to be loaded (since by + default we start perl in the post-config phase. A possible solution + is to try to detect 'apachectl configtest' and force the interpreter + loading during the config phase, so that configtest will actually + work for mp2 too. there is also an opinion that there is no + problem, and configtest just checks the config file syntax. But the + problem is that users might be mislead and think that it tests + modperl too, and when doing a restart it may fail, even though + configtest said it's OK. + +* PerlPreConnectionHandler is implemented, but the 'void *csd' arg in + the callback is ignored. will require a modification of + modperl_callback_run_handlers to pass yet another optional argument. + + Status: most likely nobody will ever want to use this option, so + don't waste time working on it. + +* Apache::FakeRequest: + since APR can be used outside of httpd, and we can alloc request_rec + and similar structures, it should be possible to bootstrap an + inside-httpd interface and outside-httpd interface. its not really + worthwhile looking at until APR actually installs its *.so or *.a + libraries somewhere apxs can find them. and, there's a bunch of util + functions (e.g. URI stuff) that is supposed to move from httpd into + apr-util. + +* could add support for embedding apache directives into perl + directives values, e.g. interpolating $ServerRoot + + PerlSwitches -I$ServerRoot/lib/perl + +* Since now we have protocol modules, it'd be nice to have a similar + thing to PerlCleanupHandler, which works only for HTTP requests. + It should probably be called PerlConnectionCleanupHandler. + + If we add it we should probably rename PerlCleanupHadndler to + PerlRequestCleanupHandler and keep the old name as a deprecated alias. + + We could also have PerlServerCleanupHandler, but that's exactly what + PerlChildExitHandler does. Consider having ServerCleanup as an alias. + +config features: +---------------- + +- tie %ENV to r->subprocess_env so stores are added to + r->subprocess_env and fetches are looked up in there and elsewhere + (e.g. HTTP_* from r->headers_in). see modperl_env.c, current + implementation is not threadsafe and requires 5.7.2+ + +- make 'PerlSetVar $Foo value' work like 'local $Foo = value' + for the given location + +- allow Perl*Handler's to have arguments in config files + +- allow <Perl></Perl> configuration sections to have read access to internal + configuration structures (would be nice if we could tie a %namespace::) + +- setuid/gid before running any Perl code + +- implement PerlINC (or similar) as a nicer interface for the working + PerlSwitches -Mlib=/home/dev1/lib/perl, to set different @INC for + different virtual hosts. + See the thread: http://marc.theaimsgroup.com/?t=100554858800001&r=1&w=2 + +- a possible implementation of PerlOptions +Inherit, similar to + +Parent but which allows virtual hosts to inherit everything that + was loaded by the main server, at the point of their definition in + the config file. This can make it easier to write configuration + files where there is a common base of modules to be loaded in all + servers. Of course this can be done by putting all these common + modules and code into foo.pl and running it from the base server and + all virtual hosts. + +- PerlModule can be made more efficient using Perl_load_module + + Status: it's possible to implement, but currently there is no way to + prevent from Perl logging the loading error messages to the + console + http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-03/msg00319.html + +perl language features: +---------------------- + +- @ARGV magic, tie to query string + +- sub handler : method ($) {} + call $class->new($r) and pass the returned object as the first and + only arg to the method handler + +- some mod_perlIO/PerlIO type methods for xs modules? (e.g. Apache::Peek) + +- possible to support BEGIN,CHECK,INIT blocks similar to how END is + supported via ModPerl::Global::special_list_{call,clear} + + + +optimization features: +--------------------- + +- copy-on-write SvPVX + +- hook Perl malloc into apr_pool + +- for "compiled handlers" w/ ithreads manage SV allocation via + server-lifetime apr_pool_t + +- "garbage collector" thread to walk padlists looking for certain things + worth releasing. + +- "mip manager" thread to watch # of active interpreters, + cloning/destroying when needed (rather than waiting for a request to + trigger) + +- use subpools per-callback/handler (might trim some memory bloat) + note: creating subpools requires a malloc mutex lock with threaded + mpms + +api: +--- + +- improve the "stacked handlers" implementation, including: + + allow push_handlers to have an additional argument, an array ref, + which will be passed to the handler as arguments, e.g. + $r->push_handlers("PerlHandler", \&some_sub, ['one', 'two', 'etc']); + +- might add an alias for $filter->connection (now we have $filter->c), to be + more intuitive since we have $r->connection. + +modules: +------- + +- core Apache::SubProcess w/ proper CORE::GLOBAL::{fork,exec} support + + currently works only with $] >= 5.007003 (see the + apache/subprocess test) + +- It's possible that we will add: + + #ifdef MP_APACHE_COMPAT + modperl_require_module("Apache::compat"); + #endif + + if MP_APACHE_COMPAT Makefile.PL option is true. But this adds bloat, + so this is just an option to consider. + +- Apache::File->tmpfile now lives only in compat. Consider adding + APR::File->mktemp (apr_file_mktemp) and a perlio layer + defined in terms of apr_file_t to use it. + +- Apache::MethodList was implemented but was not usefull enough. + Thread: http://marc.theaimsgroup.com/?t=109269086600003&r=1&w=2 + Patch: http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=109278475112976&q=p6 + +new modules: +----------- + +- apache.pm: use apache '1.3b3'; + +misc new stuff: +-------------- + +- 'make html' + +- 'make test_report' + +apache features that would be neat for mod_perl: +----------------------------------------------- + +- "autoload" hook for configuration directives + +tools that may help us develop/maintain mp2 +------------------------------------------- +- B::Xref + +- gcov: test code coverage + http://apr.apache.org/coverage/index.html + http://gozer.ectoplasm.org/mod_perl/coverage/report.html + +- valgrind (currently valgrind chokes when running apache, long before + we get to mod_perl). I've heard that we could use some special + #define controls to tell valgrind where to look and where not. + +- gprof + +- lxr + +- tinderbox + +
diff --git a/2_0_13/todo/features_missing b/2_0_13/todo/features_missing new file mode 100644 index 0000000..fee5734 --- /dev/null +++ b/2_0_13/todo/features_missing
@@ -0,0 +1,118 @@ +######################## +# mp1 missing features # +######################## + +### try to get this first post 2.0 release ### + +* mp2 test suite opens many files - quite a few failure reports were + due to the low shell file limit. But at the moment we can't tell + users why this have the problem. Gisle Aas has suggested that we + check whether the shell has a big enough setting for this limit and + either die explaining the situation or try to manually raise the + limit. + + http://thread.gmane.org/gmane.comp.apache.mod-perl/16154 + + once implemented this should be ideally abstracted to be usable by + Apache-Test, and have a hook so each project can specify its own + min files limit, so other projects can benefit too. + +* directive handlers are supported but need some work for 1.x compat + - Apache::CmdParms::{GETC,getline} needs compat mapping, similar to + what Apache::Directive->as_string does, but one char or line at a time + + - Automatic setting of cmd_args in @APACHE_MODULE_DIRECTIVE based on + function prototype + +* $r->child_terminate: + - Apache has no API for this (used to be ap_child_terminate). The + current solution is not ideal. Better trying to get ap_child_terminate + back in the httpd API. + - future ideas for threaded mpms: might consider knocking + off the current PerlInterpreter instead. + +* tied filehandle interface: + -EOF, TELL, SEEK + -READLINE - proper implementation (see comment in Apache::compat) + need to attempt to fix that interface so it'll work with IPC::Open* family + +* It'd be nice to have PAUSE and the clients support packages with + several versions, like mod_perl 1.0 and mod_perl 2.0, since once we + release it any dependency on mod_perl will be resolved as mod_perl + 2.0, when mod_perl 1.0 may be required instead. + owner: stas: talked to autrijus, he will start working on it, but + not sure when. we need to ping him every so often. but + it'll probably won't happen by the time we release 2.0. + +### other, less important things ### + +* Integrate the new perl feature: PL_use_safe_putenv (starting from + perl 5.8.6) + http://public.activestate.com/cgi-bin/perlbrowse?patch=23529 this is + needed to make it possible mod_php and mod_perl run at the same + time. Relevant threads: + http://www.gossamer-threads.com/lists/perl/porters/187753 + http://www.phpbuilder.com/lists/php-install/2003092/0018.php + + at the moment recompiling perl with -DPERL_USE_SAFE_PUTENV may or + may not work + +* $r->last is missing (it was provided explicitly by modperl, it's not + an apache thing) see modperl/src/modules/perl/Apache.xs + +* automate generation of xs/tables/current/apr/FunctionTable.pm + via Apache::ParseSource. This file contains a subset of + functions appearing in ModPerl::FunctionTable that are + needed when building APR.so, and is used when generating + the def/exp files on Win32/AIX. + +* Apache::PerlSections missing features for backwards compatibility: + - $Apache::ReadConfig::DocumentRoot + - Apache::PerlSections->store(filename) + + Report: Philippe M. Chiasson <gozer@cpan.org> + Status: Philippe M. Chiasson <gozer@cpan.org> is working on it + +* PerlOpCodeMask (experimental in 1.xx) + +* die 404 (consider deprecating it) + +* mod_perl::import + - Apache->import: + required for exit/warn overridding + - use mod_perl2 qw(2.0 MethodHandlers Authen Authz [...]); + used to be able to specify what optionnal feature were required + +* Apache::test: tobe a compat stub around new test framework + +* Apache::src: tobe a compat stub around new build framework + +* hooks ordering is not implemented yet + Owner: geoff + +* $r->finfo: + need apr_finfo_t <-> struct stat conversion (might already be there, + haven't looked close enough yet) + +* $r->chdir_file: + not safe for threaded environments. should at least unshift @INC + with dirname $r->filename. consider overriding open() to resolve + relative filenames. + +* size_string() - can we use apr_strfsize ? + +* $r->send_fd: + need to figure out howto map PerlIO <-> apr_file_t + at the moment $r->send_fd is implement in Apache::compat, functions, + but does not have the performance benefits of ap_send_fd() + however, $r->sendfile is a new function that opens the file for you + and calls ap_send_fd() underneath. ap_send_fd() in APR doesn't work + with fd's which aren't files and of unknown length, therefore it cannot + be used for implementing 1.x compatible send_fd. + Solution: send_fd will require the length argument and there will be + no send_fd without the length argument as in mp1 + Owner: stas + +* Apache::Debug: + Possibly work it differently, but certainly add support for dealing with $^M + Report: http://gossamer-threads.com/lists/modperl/modperl/77853
diff --git a/2_0_13/todo/features_new b/2_0_13/todo/features_new new file mode 100644 index 0000000..3cd0096 --- /dev/null +++ b/2_0_13/todo/features_new
@@ -0,0 +1,61 @@ +####################### +# New features in mp2 # +####################### + +* extend add_config to support add_config($multi_line_config). If the + passed argument is not a ref to an array, but a scalar should use + CR?LF to do the line split + +* PerlFooHandler -Bar is a NOOP when 'PerlOptions AutoLoad' is in + effect, whereas it should prevent autloading. + See: + modperl_handler_new in modperl_handler.c + modperl_hash_handlers in modperl_mgv.c + +* filters tie handle/perlio interface + + both input/output filters should provide a tiehandle and/or perlio + interface. + + Perl tiehandle methods include the following, '+' indicates must have, '-' + indicates not possible / doesn't make sense (though might require noop + stubs), '~' indicates would be nice if possible, '?' indicates unsure: + + + TIEHANDLE + + PRINT + + PRINTF + + WRITE + + READLINE + + GETC + + READ + + CLOSE + ? UNTIE + ? DESTROY + + BINMODE (noop) + ? OPEN + ~ EOF + - FILENO + ~ SEEK + ~ TELL + +* maybe functions in xs/maps/(apache|apr)_functions.map + +* Apache->request: + need to deal with subclass objects which are not a request_rec + (e.g. HASH ref) + Owner: gozer + +* Apache::SizeLimit + o Need to work out the details of the implementation of the garbage + collection thread for the threaded mpms as originally suggested by + doug. The issue with threads is that there is no way to know the + thread's size, can we use B::Size and B::TerseSize? + + prefork: + Apache::SizeLimit - done + Apache::GTopLimit - Owner: stas + threaded: + Garbage Collector thread + + => Ideally the tools should work transparently with threaded and + non-threaded mpms, but how?
diff --git a/2_0_13/todo/features_optimization b/2_0_13/todo/features_optimization new file mode 100644 index 0000000..994ccad --- /dev/null +++ b/2_0_13/todo/features_optimization
@@ -0,0 +1,37 @@ +############################################### +# working features but requiring optimization # +############################################### + +* all autogenerated xs methods that return char * are now using + sv_setpv() which always copies the string. See if we somehow can + avoid the copy. If we do so, we need to be careful with method which + take a pool argument, such as: + Apache::ServerUtil + - mpxs_Apache2__ServerUtil_server_root_relative + Apache::URI: + - ap_construct_server + - ap_construct_url + APR::URI + - mpxs_apr_uri_parse + Apache::Util + - ap_ht_time + - escape_path + for which we need to attach the pool object used to create those + strings as a magic. + +* optimize modperl_callback_current_callback_(set|get) to use + numerical equivalents of the phase names, instead of doing expensive + memory allocs and string comparison operations. And only give the + real string in the perl get API. + +* consider using the temp pool for things that are needed only during + the configuration and can be dropped before the actual serving is + started. that pool gets destroyed right after the post-config phase + is over. + +* currently when ithreads-enabled perl is used anon-sub handlers are + always deparsed and non-cached. there are several cases when this + can be optimized. See modperl_handler_new_anon in modperl_handler.c + +* modperl_package_unload() and modperl_xs_dl_*() share some duplicated + logic. The managment of DynaLoaded modules could be somewhat cleaner.
diff --git a/2_0_13/todo/features_registry b/2_0_13/todo/features_registry new file mode 100644 index 0000000..1df0725 --- /dev/null +++ b/2_0_13/todo/features_registry
@@ -0,0 +1,94 @@ +##################### +# Registry Features # +##################### + +- port Apache::PerlRunXS + +- replace the local implementation of finfo() when ported to mod_perl 2.0 + +- $r->chdir_file is not handled/implemented, see todo/api.txt unsafe! + +- $Apache::Server::CWD doesn't exist + +- need to figure out what's happening with + ModPerl::Registry::MarkLine, why it's not on by default? + +- a cousin of convert_script_to_compiled_handler() in 1.x used to have + 'undef &{"$o->[PACKAGE]\::handler"}' to avoid redefine handler() + warnings in case a user has used -w. also see the undef_functions on + the next line. + +- child_terminate is not implemented see + convert_script_to_compiled_handler(). + +- print STDERR is buffered in test handlers, whereas warn() works + normally. select() helps, but STDERR should be unbuffered in first + place. + +- in namespace_from_filename() should test whether a file is a symlink + and if so use readlink() to get the real filename. + +- documentation + +- acl support via 'filetest qw(access)'. It was decided that having + this feature by default will be too expensive, because of the + overhead it adds. The solution was to add a sub-class that will + provide that functionality. It wasn't decided whether it'll be in + the core or should live on CPAN. Also it wasn't decided whether + RegistryCooker should provide the necessary implementation + callbacks. See: + http://marc.theaimsgroup.com/?t=107636627000001&r=1&w=2 + +### optimizations ### + +- currently the default is to strip __DATA__|__END__ and everything + after that, which incurs a little overhead because of the s/// on + the contents of the file. This "feature" wasn't in 1.x, so may + consider to make it optional. + +### nice to have ### + +- Bjarni R. Einarsson <bre@klaki.net> has suggested this Registry hack + http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=98961929702745&w=2 + Message-ID: <20010511221101.A20868@diskordiah.mmedia.is> + +- the closure issue: + there was a suggestion from raptor to use goto() to leave the code + unwrapped in the sub handler, which will solve the closure problem, + but the problem is that once you leave a subroutine with goto() you + cannot return, because you aren't in the sub anymore. + + barrie has suggested a different approach, which requires adding + special tags to the script which help to parse the code, and shuffle + things around without putting subs inside the 'sub handler', but + this requires a lot of code understanding from a user, and if its + gained it's probably easier to fix the script so closure effect + won't happen. However barrie's suggestion can be easily added, by + overriding convert_script_to_compiled_handler(). + +- global variables persistance: could have the cooker option to flush + globals in the autogenerated package at the end of each + request. (not packages use()'d from this package) + +- could also try to privide an optional workaround for the problem + with libs collisions as explained here: + http://perl.apache.org/docs/1.0/guide/porting.html#Name_collisions_with_Modules_and + +- It's a known kludge with mod_perl scripts coming from mod_cgi which + use -M for file mtime comparisons, but are not aware of the fact + that $^T is not getting reset on each request. So may be the cooker + should have an option to reset $^T on each request. + +- develop a cooker() that cooks/modifies a registry package based on + PerlSetVar variables. So for example a user can modify a behavior of + an existing package (stat/donotstat...) and giving it a new name at + the same time. Kinda flag-based inheritance. + +* protect registry classes from bad scripts which try to assassinate $r + Report: http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=106153785129782&w=2 + Status: (stas) i'm not sure whether we really need this feature, + since it's the first time in the last 6 years we had a + problem with bad user code of this kind. let's keep it in + the patches until we have a real need for it. + Priority: very low +
diff --git a/2_0_13/todo/release b/2_0_13/todo/release new file mode 100644 index 0000000..a88bada --- /dev/null +++ b/2_0_13/todo/release
@@ -0,0 +1,57 @@ +################################################## +# Things to be resolved for mod_perl 2.0 release # +################################################## + +-- see also todo/api_status +-- see also todo/release-checklist + +someone has asked to make $r->request_time settable + +------------- + +The following items need more work in order to work with blead-perl: + +http://svn.apache.org/viewcvs?rev=209859&view=rev +perl blead fix: in 5.9.3 HvPMROOT was completely removed, temporary +using Perl_Imodglobal_ptr(thx)))->xmg_magic (which fails on perl_clone +from ithreads, but otherwise works). this must be replaced with a +better solution once we find it. + +http://svn.apache.org/viewcvs?rev=209861&view=rev +blead perl temp fix: some recent change introduced tainting problems, +will remove the workaround once blead perl is fixed + + + + +------------- + +MP_STATIC_EXTS=1 must link all extensions but APR.so. At the moment +the following are not linked: + + APR/Const.so APR/PerlIO.so Apache/Const.so ModPerl/Const.so + +owner: ??? + +note: when testing MP_STATIC_EXTS=1 build we must ensure that there is +no preinstalled mod_perl2. Since if there is a preinstall of a normal +build, MP_STATIC_EXTS=1 will be not properly tested, as the +preinstalled .so modules will be loaded. A potential solution: when +MP_STATIC_EXTS=1 is used change .pm files not to load the .xs +extensions! + +------------- + +When running as root and A-T figures it can't run the test suite +(perms) it'll ask users if she wants to skip the test suite, if this +happens: + + Skip the test suite? [No] yes + Skipping the test suite execution, while returning success status + cd ModPerl-Registry && make test + +she gets to run the registry test suite anyway, since the top level +test suite was successful (needed to make cpan/plus installers +happy). Not sure what's the best solution here. + +---------------
diff --git a/2_0_13/todo/tests_issues b/2_0_13/todo/tests_issues new file mode 100644 index 0000000..07ca7a0 --- /dev/null +++ b/2_0_13/todo/tests_issues
@@ -0,0 +1,25 @@ +###################################### +# test suite issues and improvements # +###################################### + +- As the number of tests grows it takes longer to start the test + suite. Under threaded mpms it can take a very long time on a loaded + machine (10 minutes and more). At the moment we keep on bumping the + startup timeout, but there is always someone with a slower/more + loaded machine, for whom this timeout is too low, and the tests + suite misleadingly fails to start. So may be we must start thinking + to split the existing test suite into several smaller suites (for + example we already have a separate ModPerl-Registry test suite). If + we do perl/ithreads* and any tests definging +Clone/+Parent tests + should definitely be moved out from the main suite, as they cause + the biggest overhead (due to perl_clone). + +- TestDirective::perlloadmodule6 should be the first perlloadmodule + test to run, so we can test how mod_perl starts from vhost (there + was a segfault before). But since other tests define PerlSwitches + TestDirective::perlloadmodule6 must be configured afer them. so if + we introduce new tests suites, this test needs to be moved there + (may be its own test suite or co-existing with other tests which + don't use PerlSwitches and trigger early server startup. + +
diff --git a/2_0_13/todo/tests_wanted b/2_0_13/todo/tests_wanted new file mode 100644 index 0000000..c93a944 --- /dev/null +++ b/2_0_13/todo/tests_wanted
@@ -0,0 +1,17 @@ +################# +# wanted tests # +################# + +- test that we properly set the error-notes tably entry on + HTTP_INTERNAL_SERVER_ERROR (is sub-request check REDIRECT_ERROR_NOTES) + o test with plain handlers + o test with registry (as we set it twice? once in registry and once + more in the handlers?) + + mp1 has some sort of related test in t/net/perl/server_error.pl: + my $note = $r->prev->notes('error-notes') + +- We can put Apache::Scoreboard to a good use for Apache::Test. For + example we can test with it Apache::SizeLimit or + Apache::Watchdog::RunAway, since both kill processes, and we need to + make sure that the process went away.
diff --git a/2_0_13/util/apr_arg_check.pl b/2_0_13/util/apr_arg_check.pl new file mode 100755 index 0000000..301a4fd --- /dev/null +++ b/2_0_13/util/apr_arg_check.pl
@@ -0,0 +1,45 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use lib qw(lib); + +use strict; +use Apache2::FunctionTable (); + +#utility for checking apr_ argument conventions + +my $tx = '_t\s*\*+'; + +for my $entry (@$Apache2::FunctionTable) { + my $name = $entry->{name}; + my $args = $entry->{args}; + next unless @$args and $name =~ /^apr_/; + + my $has_type_arg = 0; + for my $arg (@$args) { + my $type = $arg->{type}; + next unless $type =~ s/$tx$//o; + $has_type_arg = $name =~ /^\Q$type/; + } + next unless $has_type_arg; + + my $i = 0; + for my $arg (@$args) { + $i++; + my $type = $arg->{type}; + $type =~ s/$tx//o; + + if ($name =~ /^\Q$type/) { + last if $i == 1; + } + else { + next; + } + if ($i > 1) { + print "'$arg->{name}' should be the first arg:\n"; + print " $entry->{return_type}\n $name(", + (join ', ', map "$_->{type} $_->{name}", @$args), + ")\n\n"; + } + } +}
diff --git a/2_0_13/util/apr_pool_check.pl b/2_0_13/util/apr_pool_check.pl new file mode 100755 index 0000000..056c8cf --- /dev/null +++ b/2_0_13/util/apr_pool_check.pl
@@ -0,0 +1,56 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +#check which apr_ functions do not have access to a pool + +use lib qw(lib); + +use strict; +use Apache2::SourceTables (); + +my($functions, @nopool); + +#incomplete types (C::Scan only scans *.h, not *.c) we know have an apr_pool_t +my %private = map { $_, 1 } qw{ +apr_dir_t apr_file_t apr_dso_handle_t apr_hash_t apr_hash_index_t apr_lock_t +apr_socket_t apr_pollfd_t apr_threadattr_t apr_thread_t apr_threadkey_t +apr_procattr_t apr_xlate_t apr_dbm_t apr_xml_parser +}; + +for my $entry (@$Apache2::FunctionTable) { + next unless $entry->{name} =~ /^apr_/; + + $functions++; + + unless (grep { find_pool($_->{type}) } @{ $entry->{args} }) { + push @nopool, $entry; + } +} + +my $num_nopool = @nopool; + +print "$num_nopool functions (out of $functions) do not have access to a pool:\n\n"; + +for my $entry (@nopool) { + print "$entry->{return_type} $entry->{name}(", + (join ', ', map "$_->{type} $_->{name}", @{ $entry->{args} }), + ")\n\n"; +} + +sub find_pool { + my $type = shift; + + return 1 if $type =~ /^apr_pool_t/; + + $type =~ s/\s+\*+$//; + $type =~ s/^(const|struct)\s+//g; + + if (my $elts = $Apache2::StructureTable{$type}) { + return 1 if $private{$type}; + + for my $e (@$elts) { + next if $e->{type} =~ /^$type/; + return 1 if find_pool($e->{type}); + } + } +}
diff --git a/2_0_13/util/cvsize.pl b/2_0_13/util/cvsize.pl new file mode 100755 index 0000000..8e6682c --- /dev/null +++ b/2_0_13/util/cvsize.pl
@@ -0,0 +1,32 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +#get an idea of how much space the XS interface will eat +#build/source_scan.pl must be run first +#see pod/modperl_sizeof.pod + +use strict; +use Apache2::FunctionTable (); +use Apache2::StructureTable (); + +use constant sizeofCV => 254; + +my $size = 0; +my $subs = 0; + +for my $entry (@$Apache2::FunctionTable) { + $size += sizeofCV + ((length($entry->{name}) + 1) * 2); + $subs++; +} + +for my $entry (@$Apache2::StructureTable) { + my $elts = $entry->{elts} || []; + next unless @$elts; + + for my $e (@$elts) { + $size += sizeofCV + ((length($e->{name}) + 1) * 2); + $subs++; + } +} + +print "$subs subs, $size estimated bytes\n";
diff --git a/2_0_13/util/getdiff.pl b/2_0_13/util/getdiff.pl new file mode 100755 index 0000000..5b4cbb0 --- /dev/null +++ b/2_0_13/util/getdiff.pl
@@ -0,0 +1,24 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +# this script creates a diff against SVN +# and against /dev/null for all files in ARGV +# and prints it to STDOUT +# +# e.g. +# getdiff.pl t/modules/newtest t/response/TestModules/NewTest.pm \ +# > newtest.patch +# +# the generated patch can be applied with +# patch -p0 < newtest.patch + +# cvs diff +my $o = `svn diff`; + +for (@ARGV) { + $o .= "\n"; + $o .= `diff -u /dev/null $_` +} + +print $o; +
diff --git a/2_0_13/util/methodlookup_check.pl b/2_0_13/util/methodlookup_check.pl new file mode 100755 index 0000000..95da6fd --- /dev/null +++ b/2_0_13/util/methodlookup_check.pl
@@ -0,0 +1,36 @@ +#!/usr/bin/perl +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +# this script checks whether all XS methods are known to ModPerl::MethodLookup + +use strict; +use warnings; + +use lib "lib"; + +use ModPerl::MethodLookup; + +# methods/classes ModPerl::MethodLookup knows about +my %known = (); +for (ModPerl::MethodLookup::avail_methods()) { + my ($modules_hint, @modules) = ModPerl::MethodLookup::lookup_method($_); + $known{$_} = { map {$_ => 1} @modules}; +} + +# real XS methods +my %real = (); +my $in = qx{grep -Ir newXS WrapXS}; +while ($in =~ m{WrapXS/(\w+)/(\w+)/.*?newXS\("(?:.+)::(.+)"}g) { + $real{$3}{"$1\::$2"}++; +} + +# now check what's missing +my @miss = (); +for my $method (sort keys %real) { + for my $module (sort keys %{ $real{$method} }) { + #printf "%-25s %s\n", $method, $module unless $known{$method}{$module}; + push @miss, sprintf "%-25s %s\n", $module, $method unless $known{$method}{$module}; + } +} + +print @miss ? sort(@miss) : "All methods are known by ModPerl::MethodLookup\n";
diff --git a/2_0_13/util/perl_bloat.pl b/2_0_13/util/perl_bloat.pl new file mode 100755 index 0000000..421d393 --- /dev/null +++ b/2_0_13/util/perl_bloat.pl
@@ -0,0 +1,44 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +# perlbloat.pl 'some perlcode' 'more perl code' +# perlbloat.pl Foo/Bar.pm Bar/Tar.pm +# perlbloat.pl Foo::Bar Bar::Tar + +no warnings; + +use GTop (); + +my $gtop = GTop->new; + +my $total = 0; +for (@ARGV) { + + my $code = $_; + file2package($_) if /\S+\.pm$/; + + my $before = $gtop->proc_mem($$)->size; + + if (eval "require $_" ) { + eval { + $_->import; + }; + } + else { + eval $_; + die $@ if $@; + } + + my $after = $gtop->proc_mem($$)->size; + printf "%-30s added %s\n", $_, GTop::size_string($after - $before); + $total += $after - $before; +} + +print "-" x 46, "\n"; +printf "Total added %30s\n", GTop::size_string($total); + +sub file2package { + $_[0] =~ s|/|::|g; + $_[0] =~ s|\.pm$||; +} +
diff --git a/2_0_13/util/sizeof.pl b/2_0_13/util/sizeof.pl new file mode 100644 index 0000000..1a6d3ec --- /dev/null +++ b/2_0_13/util/sizeof.pl
@@ -0,0 +1,62 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +#calculate structure sizes listed in pod/modperl_sizeof.pod via sizeof() + +use strict; + +use ExtUtils::Embed; +use Config; + +my $file = shift || 'pod/modperl_sizeof.pod'; + +open my $pod, $file or die "open $file: $!"; + +FINDSTRUCT: { + while (<$pod>) { + next unless /^\s*(\w+)\s*=\s*\{/; + my $name = $1; + my $size = sizeof($name, $pod); + print "sizeof $name => $size\n"; + redo FINDSTRUCT; + } +} + +sub sizeof { + my($struct, $h) = @_; + + my @elts; + + while (<$h>) { + last if /^\s*\}\;$/; + next unless m:(\w+).*?//\s*(.*):; + push @elts, "sizeof($2) /* $1 */"; + } + + my $name = "perl_sizeof_$struct"; + my $tmpfile = "$name.c"; + open my $fh, '>', $tmpfile or die "open $tmpfile: $!"; + + local $" = " + \n"; + + print $fh <<EOF; +#include <stdio.h> +#define PERLIO_NOT_STDIO 0 +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +#undef fprintf +int main(void) { + int size = @elts; + fprintf(stdout, "%d", size); + return 1; +} +EOF + + my $opts = ccopts(); + system "$Config{cc} -o $name $tmpfile $opts"; + + my $size = `$name`; + + unlink $name, $tmpfile; + + return $size; +}
diff --git a/2_0_13/util/source_stats.pl b/2_0_13/util/source_stats.pl new file mode 100755 index 0000000..fc502b0 --- /dev/null +++ b/2_0_13/util/source_stats.pl
@@ -0,0 +1,41 @@ +#!/usr/bin/perl -w +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- + +use lib qw(lib); + +use strict; +use Apache2::FunctionTable (); +use Apache2::StructureTable (); + +my %stats; + +for my $entry (@$Apache2::FunctionTable) { + unless ($entry->{name} =~ /^(ap|apr)_/) { + #print "found alien function $entry->{name}\n"; + next; + } + + $stats{functions}->{$1}++; +} + +for my $entry (@$Apache2::StructureTable) { + my $elts = $entry->{elts}; + my $type = $entry->{type}; + + my $c = $type =~ /^apr_/ ? "apr" : "ap"; + @$elts = () if $type =~ /^ap_LINK/; + if (@$elts) { + $stats{typedef_structs}->{$c}++; + $stats{struct_members}->{$c} += @$elts; + } + else { + $stats{typedefs}->{$c}++; + } +} + +while (my($name, $tab) = each %stats) { + printf "%d %s\n", $tab->{ap} + $tab->{apr}, $name; + for (qw(apr ap)) { + printf "%6s: %d\n", $_, $tab->{$_}; + } +}
diff --git a/2_0_13/util/xs_check.pl b/2_0_13/util/xs_check.pl new file mode 100644 index 0000000..01ec89b --- /dev/null +++ b/2_0_13/util/xs_check.pl
@@ -0,0 +1,109 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +use lib qw(Apache-Test/lib lib xs/tables/current); + +use strict; +use warnings qw(FATAL all); + +use ModPerl::TypeMap (); +use ModPerl::FunctionMap (); +use ModPerl::StructureMap (); +use ModPerl::WrapXS (); +use ModPerl::MapUtil qw(disabled_reason); + +my %check = ( + types => ModPerl::TypeMap->new, + functions => ModPerl::FunctionMap->new, + structures => ModPerl::StructureMap->new, +); + +my %missing; +while (my($things, $obj) = each %check) { + $missing{$things} = $obj->check; + if (my $missing = $missing{$things}) { + my $n = @$missing; + print "$n $things are not mapped:\n"; + print " $_\n" for sort @$missing; + } + else { + print "all $things are mapped\n"; + } +} + +my %check_exists = ( + functions => $check{functions}, + structure_members => $check{structures}, + types => $check{types}, +); + +while (my($things, $obj) = each %check_exists) { + if (my $missing = $obj->check_exists) { + my $n = @$missing; + print "$n mapped $things do not exist:\n"; + print " $_\n" for sort @$missing; + } + else { + print "all mapped $things exist\n"; + } +} + +my %unmapped = map { $_,1 } @{ $missing{functions} } if $missing{functions}; +my $typemap = $check{types}; +my $function_map = $check{functions}; +my @missing; + +for my $entry (@$Apache2::FunctionTable) { + my $func; + my $name = $entry->{name}; + next if $unmapped{$name}; + next unless $function_map->{map}->{$name}; + next if $func = $typemap->map_function($entry); + push @missing, $name; +} + +if (@missing) { + my $n = @missing; + print "unable to glue $n mapped functions:\n"; + print " $_\n" for sort @missing; +} +else { + print "all mapped functions are glued\n"; +} + +my $stats = ModPerl::WrapXS->new->stats; +my($total_modules, $total_xsubs); + +while (my($module, $n) = each %$stats) { + $total_modules++; + $total_xsubs += $n; +} + +print "$total_modules total modules, ", + "$total_xsubs total xsubs\n"; + +while (my($module, $n) = each %$stats) { + print "$module: $n\n"; +} + +for (qw(functions structure_members)) { + my $disabled = $check_exists{$_}->disabled; + my $total = 0; + for my $names (values %$disabled) { + $total += @$names; + } + print "$total $_ are not wrapped:\n"; + while (my($r, $names) = each %$disabled) { + printf "%4d are %s\n", scalar @$names, disabled_reason($r); + } +} + +if (@ARGV) { + my $key = '!'; + for (qw(functions structure_members)) { + my $disabled = $check_exists{$_}->disabled; + my $names = $disabled->{$key}; + printf "%s $_:\n", disabled_reason($key); + for my $name (sort @$names) { + print " $name\n"; + } + } +}
diff --git a/2_0_13/xs/APR/APR/APR.pm b/2_0_13/xs/APR/APR/APR.pm new file mode 100644 index 0000000..b06a3b6 --- /dev/null +++ b/2_0_13/xs/APR/APR/APR.pm
@@ -0,0 +1,36 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package APR; + +use DynaLoader (); +our $VERSION = '0.009000'; +our @ISA = qw(DynaLoader); + +#dlopen("APR.so", RTDL_GLOBAL); so we only need to link libapr.a once +# XXX: see xs/ModPerl/Const/Const.pm for issues of using 0x01 +use Config (); +use constant DL_GLOBAL => + ( $Config::Config{dlsrc} eq 'dl_dlopen.xs' && $^O ne 'openbsd' ) ? 0x01 : 0x0; +sub dl_load_flags { DL_GLOBAL } + +unless (defined &APR::XSLoader::BOOTSTRAP) { + __PACKAGE__->bootstrap($VERSION); + *APR::XSLoader::BOOTSTRAP = sub () { 1 }; +} + +1; +__END__
diff --git a/2_0_13/xs/APR/APR/APR.xs b/2_0_13/xs/APR/APR/APR.xs new file mode 100644 index 0000000..bf267bc --- /dev/null +++ b/2_0_13/xs/APR/APR/APR.xs
@@ -0,0 +1,74 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +#ifdef MP_HAVE_APR_LIBS +# define APR_initialize apr_initialize +# define APR_terminate apr_terminate +#else +# define APR_initialize() +# define APR_terminate() +#endif + +#ifdef MP_HAVE_APR_LIBS + +/* XXX: APR_initialize doesn't initialize apr_hook_global_pool, needed for + * work outside httpd, so do it manually PR22605 */ +#include "apr_hooks.h" +static void extra_apr_init(pTHX) +{ + if (apr_hook_global_pool == NULL) { + apr_pool_t *global_pool; + apr_status_t rv = apr_pool_create(&global_pool, NULL); + if (rv != APR_SUCCESS) { + PerlIO_printf(PerlIO_stderr(), + "Fatal error: unable to create global pool " + "for use with by the scoreboard"); + } + /* XXX: mutex locking? */ + apr_hook_global_pool = global_pool; + } + { + apr_file_t *stderr_apr_handle; + apr_status_t rv = apr_file_open_stderr(&stderr_apr_handle, + apr_hook_global_pool); + if (rv != APR_SUCCESS) { + PerlIO_printf(PerlIO_stderr(), + "Fatal error: failed to open stderr "); + } + modperl_trace_level_set(stderr_apr_handle, NULL); + } + +} +#else +# define extra_apr_init(aTHX) +#endif + +MODULE = APR PACKAGE = APR + +PROTOTYPES: disable + +BOOT: + file = file; /* -Wall */ + APR_initialize(); + extra_apr_init(aTHX); + +void +END() + + CODE: + APR_terminate();
diff --git a/2_0_13/xs/APR/APR/Makefile.PL b/2_0_13/xs/APR/APR/Makefile.PL new file mode 100644 index 0000000..edbd108 --- /dev/null +++ b/2_0_13/xs/APR/APR/Makefile.PL
@@ -0,0 +1,109 @@ +use strict; +use warnings; + +use lib qw(../lib); +use ModPerl::BuildMM (); +require ModPerl::Code; +use Apache2::Build (); +use Config; +use File::Spec::Functions; + +use constant WIN32 => Apache2::Build::WIN32; +use constant CYGWIN => Apache2::Build::CYGWIN; +use constant SOLARIS => $^O eq 'solaris'; +use constant BUILD_APREXT => Apache2::Build::BUILD_APREXT; + +my %args; + +%args = map { split /=/, $_, 2 } @ARGV; + +$args{NAME} = 'APR'; +$args{VERSION_FROM} = 'APR.pm'; + +my $libs = ''; +$libs = delete $args{LIBS} if $args{LIBS}; + +my $build = ModPerl::BuildMM::build_config(); + +my $ccopts = $build->ccopts; + +# avoid referencing &perl_module outside of mod_perl +$ccopts .= ' -DMP_IN_XS'; + +$args{CCFLAGS} = $ccopts; + +my @apru_link_flags = $build->apru_link_flags; +$libs .= join ' ', @apru_link_flags if @apru_link_flags; + +if (WIN32) { + $libs =~ s{/libpath:}{-L}g; + $libs =~ s{(\S+)\.lib}{-l$1}g; +} + +if (BUILD_APREXT) { + my $mp_apr_lib = $build->mp_apr_lib; + + if (CYGWIN) { + # For Cygwin compatibility, set $mp_apr_lib before the apache libs + $libs = qq{ $mp_apr_lib } . $libs; + } else { + $libs .= qq{ $mp_apr_lib }; + } +} + +if (SOLARIS && $libs) { + # EU::MM sets LD_RUN_PATH (for linking) based on -L options in LIBS. + # LD_RUN_PATH is getting overridden by the specified -R path. + # The -R specified is from the perl config's lddflags. + # Therefore -R has to be added with the appropriate paths rather + # than using LD_RUN_PATH, because it gets overridden. + + # make sure that all -L, -R from libs are moved + # to the beginning of lddflags. + my $extralddflags = join " ", $libs =~ /(-[LR]\S+)/g; + + # -R makes sure that these paths will be used + $extralddflags =~ s{-L(\S+)}{-L$1 -R$1}g; + $args{LDDLFLAGS} = "" unless exists $args{LDDLFLAGS}; + $args{LDDLFLAGS} = join " ", $args{LDDLFLAGS}, $extralddflags, + $build->perl_config('lddlflags'); + + # -R are now copied to LDDFLAGS, but leave -L's in LIBS -- + # EU::MM needs it. + $libs =~ s{-R\S+}{}g; +} + +$args{LIBS} = [$libs] if $libs; + +my $srcdir = '../../../src/modules/perl'; + +# link the following into APR.so so other APR:: modules can be used +# outside of httpd +my @names = ModPerl::Code::src_apr_ext(); + +my(@obj, @clean, %src); +for (@names) { + push @obj, join '.', $_, 'o'; + my $cfile = join '.', $_, 'c'; + push @clean, $cfile; + $src{$cfile} = "$srcdir/$cfile"; +} + +$args{OBJECT} = BUILD_APREXT() ? "APR.o" : "APR.o @obj"; +$args{clean} = { FILES => "@clean" }; + +ModPerl::BuildMM::WriteMakefile(%args); + +# avoid redefined warnings from imported postamble symbol from +# elsewhere in other Makefile.PL files +no warnings 'redefine'; +sub MY::postamble { + my $self = shift; + my $string = $self->ModPerl::BuildMM::MY::postamble; + + $string .= join '', map { + "$_: $src{$_}\n\t\$(CP) $src{$_} .\n"; + } sort keys %src; + + return $string; +}
diff --git a/2_0_13/xs/APR/APR/apr-test b/2_0_13/xs/APR/APR/apr-test new file mode 100644 index 0000000..9c70bd6 --- /dev/null +++ b/2_0_13/xs/APR/APR/apr-test
@@ -0,0 +1,61 @@ +#!perl + +use Test; + +plan tests => 8; + +use blib; +use warnings FATAL => 'all'; +use strict; +use APR (); +use APR::UUID (); +use APR::Pool (); +use APR::Lock (); +use APR::Util (); +use APR::Base64 (); +use APR::Signal (); + +my $status; + +my $uuid = APR::UUID->new->format; + +ok $uuid; + +my $p = APR::Pool->new; + +ok $p; + +my $lock = APR::Lock->new($p, 0, 1, "lock.file"); +$status = $lock->acquire and die APR::strerror($status); +$status = $lock->release and die APR::strerror($status); + +$status = APR::password_validate("one", "two"); +my $str = APR::strerror($status); +ok $str eq "passwords do not match"; + +ok $status; + +my $bytes = APR::generate_random_bytes(10); + +ok length($bytes) == 10; + +my $encoded = APR::Base64::encode($bytes); + +#print "encoded=$encoded\n"; + +ok $encoded; + +my $decoded = APR::Base64::decode($encoded); + +ok $decoded eq $bytes; + +$p->clear; + +for (1..9) { + my $desc = APR::Signal::get_description($_); + #print "$_ => $desc\n"; +} + +ok 1; + +$p->destroy; #XXX
diff --git a/2_0_13/xs/APR/Base64/APR__Base64.h b/2_0_13/xs/APR/Base64/APR__Base64.h new file mode 100644 index 0000000..8ed26f9 --- /dev/null +++ b/2_0_13/xs/APR/Base64/APR__Base64.h
@@ -0,0 +1,64 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* apr_base64_encode_len and apr_base64_encode_binary give length that + * includes the terminating '\0' */ +#define mpxs_APR__Base64_encode_len(len) (apr_base64_encode_len(len) - 1) + +static MP_INLINE void mpxs_apr_base64_encode(pTHX_ SV *sv, SV *arg) +{ + STRLEN len; + int encoded_len; + unsigned char *data = (unsigned char *)SvPV(arg, len); + mpxs_sv_grow(sv, apr_base64_encode_len(len) - 1); + encoded_len = apr_base64_encode_binary(SvPVX(sv), data, len); + mpxs_sv_cur_set(sv, encoded_len - 1); +} + +static MP_INLINE void mpxs_apr_base64_decode(pTHX_ SV *sv, SV *arg) +{ + STRLEN len; + int decoded_len; + char *data = SvPV(arg, len); + mpxs_sv_grow(sv, apr_base64_decode_len(data)); + decoded_len = apr_base64_decode_binary((unsigned char *)SvPVX(sv), data); + mpxs_sv_cur_set(sv, decoded_len); +} + +MP_STATIC XS(MPXS_apr_base64_encode) +{ + dXSARGS; + + mpxs_usage_items_1("data"); + + mpxs_set_targ(mpxs_apr_base64_encode, ST(0)); +} + +MP_STATIC XS(MPXS_apr_base64_decode) +{ + dXSARGS; + + mpxs_usage_items_1("data"); + + mpxs_set_targ(mpxs_apr_base64_decode, ST(0)); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Brigade/APR__Brigade.h b/2_0_13/xs/APR/Brigade/APR__Brigade.h new file mode 100644 index 0000000..15181fd --- /dev/null +++ b/2_0_13/xs/APR/Brigade/APR__Brigade.h
@@ -0,0 +1,180 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +void mpxs_APR__Brigade_cleanup(apr_bucket_brigade *brigade) +{ + /* apr has a broken prototype (passing 'void *' instead of + * 'apr_bucket_brigade *', so use a wrapper here */ + apr_brigade_cleanup(brigade); +} + +static MP_INLINE +SV *mpxs_apr_brigade_create(pTHX_ SV *CLASS, SV *p_sv, + apr_bucket_alloc_t *ba) +{ + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); + apr_bucket_brigade *bb = apr_brigade_create(p, ba); + SV *bb_sv = sv_setref_pv(newSV(0), "APR::Brigade", (void*)bb); + mpxs_add_pool_magic(bb_sv, p_sv); + return bb_sv; +} + +#define get_brigade(brigade, fetch) \ +(fetch(brigade) == APR_BRIGADE_SENTINEL(brigade) ? \ + NULL : fetch(brigade)) + +static MP_INLINE +apr_bucket *mpxs_APR__Brigade_first(apr_bucket_brigade *brigade) +{ + return get_brigade(brigade, APR_BRIGADE_FIRST); +} + +static MP_INLINE +apr_bucket *mpxs_APR__Brigade_last(apr_bucket_brigade *brigade) +{ + return get_brigade(brigade, APR_BRIGADE_LAST); +} + +#define get_bucket(brigade, bucket, fetch) \ +(fetch(bucket) == APR_BRIGADE_SENTINEL(brigade) ? \ + NULL : fetch(bucket)) + +static MP_INLINE +apr_bucket *mpxs_APR__Brigade_next(apr_bucket_brigade *brigade, + apr_bucket *bucket) +{ + return get_bucket(brigade, bucket, APR_BUCKET_NEXT); +} + +static MP_INLINE +apr_bucket *mpxs_APR__Brigade_prev(apr_bucket_brigade *brigade, + apr_bucket *bucket) +{ + return get_bucket(brigade, bucket, APR_BUCKET_PREV); +} + +static MP_INLINE +void mpxs_APR__Brigade_insert_tail(apr_bucket_brigade *brigade, + apr_bucket *bucket) +{ + APR_BRIGADE_INSERT_TAIL(brigade, bucket); +} + +static MP_INLINE +void mpxs_APR__Brigade_insert_head(apr_bucket_brigade *brigade, + apr_bucket *bucket) +{ + APR_BRIGADE_INSERT_HEAD(brigade, bucket); +} + +static MP_INLINE +void mpxs_APR__Brigade_concat(apr_bucket_brigade *a, + apr_bucket_brigade *b) +{ + APR_BRIGADE_CONCAT(a, b); +} + +static MP_INLINE +int mpxs_APR__Brigade_is_empty(apr_bucket_brigade *brigade) +{ + return APR_BRIGADE_EMPTY(brigade); +} + +static MP_INLINE +apr_pool_t *mpxs_APR__Brigade_pool(apr_bucket_brigade *brigade) +{ + /* eesh, it's r->pool, and c->pool, but bb->p + * let's make Perl consistent, otherwise this could be autogenerated + */ + + return brigade->p; +} + +static MP_INLINE +SV *mpxs_APR__Brigade_length(pTHX_ apr_bucket_brigade *bb, + int read_all) +{ + apr_off_t length; + + apr_status_t rv = apr_brigade_length(bb, read_all, &length); + + /* XXX - we're deviating from the API here a bit in order to + * make it more perlish - returning the length instead of + * the return code. maybe that's not such a good idea, though... + */ + if (rv == APR_SUCCESS) { + return newSViv((int)length); + } + + return &PL_sv_undef; +} + +#define mp_xs_sv2_bb mp_xs_sv2_APR__Brigade + +static MP_INLINE +apr_size_t mpxs_APR__Brigade_flatten(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + + apr_bucket_brigade *bb; + apr_size_t wanted; + apr_status_t rc; + SV *buffer; + + mpxs_usage_va_2(bb, buffer, "$bb->flatten($buf, [$wanted])"); + + if (items > 2) { + /* APR::Brigade->flatten($wanted); */ + wanted = SvIV(*MARK); + } + else { + /* APR::Brigade->flatten(); */ + /* can't use pflatten, because we can't realloc() memory + * allocated by pflatten. and we need to append '\0' to it in + * SvPVX. so we copy pflatten's guts here. + */ + apr_off_t actual; + apr_brigade_length(bb, 1, &actual); + wanted = (apr_size_t)actual; + } + + (void)SvUPGRADE(buffer, SVt_PV); + mpxs_sv_grow(buffer, wanted); + + rc = apr_brigade_flatten(bb, SvPVX(buffer), &wanted); + if (!(rc == APR_SUCCESS || rc == APR_EOF)) { + modperl_croak(aTHX_ rc, "APR::Brigade::flatten"); + } + + mpxs_sv_cur_set(buffer, wanted); + SvTAINTED_on(buffer); + + return wanted; +} + +static MP_INLINE +void mpxs_APR__Brigade_destroy(pTHX_ apr_bucket_brigade *bb) +{ + MP_RUN_CROAK(apr_brigade_destroy(bb), "APR::Brigade::destroy"); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Bucket/APR__Bucket.h b/2_0_13/xs/APR/Bucket/APR__Bucket.h new file mode 100644 index 0000000..6c09c75 --- /dev/null +++ b/2_0_13/xs/APR/Bucket/APR__Bucket.h
@@ -0,0 +1,131 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modperl_bucket.h" + +#define mpxs_APR__Bucket_delete apr_bucket_delete +#define mpxs_APR__Bucket_destroy apr_bucket_destroy + +static apr_bucket *mpxs_APR__Bucket_new(pTHX_ SV *classname, apr_bucket_alloc_t *list, + SV *sv, apr_off_t offset, apr_size_t len) +{ + + apr_size_t full_len; + + if (sv == (SV *)NULL) { + sv = newSV(0); + (void)SvUPGRADE(sv, SVt_PV); + } + + (void)SvPV(sv, full_len); + + if (len) { + if (len > full_len - offset) { + Perl_croak(aTHX_ "APR::Bucket::new: the length argument can't be" + " bigger than the total buffer length minus offset"); + } + } + else { + len = full_len - offset; + } + + return modperl_bucket_sv_create(aTHX_ list, sv, offset, len); +} + +static MP_INLINE +apr_size_t mpxs_APR__Bucket_read(pTHX_ + apr_bucket *bucket, + SV *buffer, + apr_read_type_e block) +{ + apr_size_t len; + const char *str; + apr_status_t rc = apr_bucket_read(bucket, &str, &len, block); + + if (!(rc == APR_SUCCESS || rc == APR_EOF)) { + modperl_croak(aTHX_ rc, "APR::Bucket::read"); + } + + if (len) { + sv_setpvn(buffer, str, len); + } + else { + sv_setpvn(buffer, "", 0); + } + + /* must run any set magic */ + SvSETMAGIC(buffer); + + SvTAINTED_on(buffer); + + return len; +} + +static MP_INLINE int mpxs_APR__Bucket_is_eos(apr_bucket *bucket) +{ + return APR_BUCKET_IS_EOS(bucket); +} + +static MP_INLINE int mpxs_APR__Bucket_is_flush(apr_bucket *bucket) +{ + return APR_BUCKET_IS_FLUSH(bucket); +} + +static MP_INLINE void mpxs_APR__Bucket_insert_before(apr_bucket *a, + apr_bucket *b) +{ + APR_BUCKET_INSERT_BEFORE(a, b); +} + +static MP_INLINE void mpxs_APR__Bucket_insert_after(apr_bucket *a, + apr_bucket *b) +{ + APR_BUCKET_INSERT_AFTER(a, b); +} + +static MP_INLINE void mpxs_APR__Bucket_remove(apr_bucket *bucket) +{ + APR_BUCKET_REMOVE(bucket); +} + +static MP_INLINE +apr_status_t mpxs_APR__Bucket_setaside(pTHX_ SV *b_sv, SV *p_sv) +{ + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); + apr_bucket *b = mp_xs_sv2_APR__Bucket(b_sv); + apr_status_t rc = apr_bucket_setaside(b, p); + + /* if users don't bother to check the success, do it on their + * behalf */ + if (GIMME_V == G_VOID && rc != APR_SUCCESS) { + modperl_croak(aTHX_ rc, "APR::Bucket::setaside"); + } + + /* No need to call mpxs_add_pool_magic(b_sv, p_sv); since + * pool_bucket_cleanup is called by apr_bucket_pool_make (called + * by modperl_bucket_sv_setaside) if the pool goes out of scope, + * copying the data to the heap. + */ + + return rc; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/BucketAlloc/APR__BucketAlloc.h b/2_0_13/xs/APR/BucketAlloc/APR__BucketAlloc.h new file mode 100644 index 0000000..bfb2a19 --- /dev/null +++ b/2_0_13/xs/APR/BucketAlloc/APR__BucketAlloc.h
@@ -0,0 +1,36 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modperl_bucket.h" + +#define mpxs_APR__BucketAlloc_destroy apr_bucket_alloc_destroy + +static MP_INLINE +SV *mpxs_APR__BucketAlloc_new(pTHX_ SV *CLASS, SV *p_sv) +{ + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); + apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p); + SV *ba_sv = sv_setref_pv(newSV(0), "APR::BucketAlloc", (void*)ba); + mpxs_add_pool_magic(ba_sv, p_sv); + return ba_sv; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Const/Const.pm b/2_0_13/xs/APR/Const/Const.pm new file mode 100644 index 0000000..cb264f6 --- /dev/null +++ b/2_0_13/xs/APR/Const/Const.pm
@@ -0,0 +1,28 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package APR::Const; + +use ModPerl::Const (); +use APR (); +use XSLoader (); + +our $VERSION = '0.009000'; +our @ISA = qw(ModPerl::Const); + +XSLoader::load(__PACKAGE__, $VERSION); + +1;
diff --git a/2_0_13/xs/APR/Const/Const.xs b/2_0_13/xs/APR/Const/Const.xs new file mode 100644 index 0000000..9d457c3 --- /dev/null +++ b/2_0_13/xs/APR/Const/Const.xs
@@ -0,0 +1,26 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" +#include "modperl_const.h" + +MODULE = APR::Const PACKAGE = APR::Const + +PROTOTYPES: disable + +BOOT: + MP_newModPerlConstXS("APR"); +
diff --git a/2_0_13/xs/APR/Const/Makefile.PL b/2_0_13/xs/APR/Const/Makefile.PL new file mode 100644 index 0000000..c567a34 --- /dev/null +++ b/2_0_13/xs/APR/Const/Makefile.PL
@@ -0,0 +1,15 @@ +use lib qw(../lib); +use ModPerl::BuildMM (); +use Apache2::Build; + +my $build = Apache2::Build->build_config(); +my $ccopts = $build->ccopts; + +# avoid referencing &perl_module outside of mod_perl +$ccopts .= ' -DMP_IN_XS'; + +ModPerl::BuildMM::WriteMakefile( + NAME => 'APR::Const', + VERSION_FROM => 'Const.pm', + CCFLAGS => $ccopts, +);
diff --git a/2_0_13/xs/APR/Error/APR__Error.h b/2_0_13/xs/APR/Error/APR__Error.h new file mode 100644 index 0000000..c7dafd9 --- /dev/null +++ b/2_0_13/xs/APR/Error/APR__Error.h
@@ -0,0 +1,24 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define mpxs_APR__Error_strerror(rc) modperl_error_strerror(aTHX_ rc) + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Error/Error_pm b/2_0_13/xs/APR/Error/Error_pm new file mode 100644 index 0000000..9cb6081 --- /dev/null +++ b/2_0_13/xs/APR/Error/Error_pm
@@ -0,0 +1,69 @@ +require Carp; +require Carp::Heavy; + +use APR::Util (); + +use overload + nomethod => \&fatal, + 'bool' => \&str, + '==' => \&num_cmp, + '!=' => \&num_cmp_not, + '0+' => \&num, + '""' => \&str; + +sub fatal { die __PACKAGE__ . ": Can't handle '$_[3]'" } + +# normally the object is created on the C side, but if you want to +# create one from Perl, you can. just pass a hash with args: +# rc, file, line, func +sub new { + my $class = shift; + my %args = @_; + bless \%args, $class; +} + +# +# - even though most of the time the error id is not useful to the end +# users, developers may need to know it. For example in case of a +# non-english user locale setting, the error string could be +# incomprehensible to a developer, but by having the error id it's +# possible to find the english equivalent +# - the filename and line number are needed because perl doesn't +# provide that info when exception objects are involved +sub str { + return sprintf "%s: (%d) %s at %s line %d", $_[0]->{func}, + $_[0]->{rc}, APR::Error::strerror($_[0]->{rc}), + $_[0]->{file}, $_[0]->{line}; +} + +sub num { $_[0]->{rc} } + +sub num_cmp { $_[0]->{rc} == $_[1] } +sub num_cmp_not { $_[0]->{rc} != $_[1] } + +# skip the wrappers from this package from the long callers trace +$Carp::CarpInternal{+__PACKAGE__}++; + +# XXX: Carp::(confess|cluck) see no calls stack when Perl_croak is +# called with (char *)NULL (which is the way exception objects are +# returned), so we fixup it here (doesn't quite work for croak +# caller). +sub cluck { + if (ref $_[0] eq __PACKAGE__) { + Carp::cluck("$_[0]->{func}: ($_[0]->{rc}) " . + APR::Error::strerror($_[0]->{rc})); + } + else { + &Carp::cluck; + } +} + +sub confess { + if (ref $_[0] eq __PACKAGE__) { + Carp::confess("$_[0]->{func}: ($_[0]->{rc}) " . + APR::Error::strerror($_[0]->{rc})); + } + else { + &Carp::confess; + } +}
diff --git a/2_0_13/xs/APR/Finfo/APR__Finfo.h b/2_0_13/xs/APR/Finfo/APR__Finfo.h new file mode 100644 index 0000000..36843ab --- /dev/null +++ b/2_0_13/xs/APR/Finfo/APR__Finfo.h
@@ -0,0 +1,39 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +SV *mpxs_APR__Finfo_stat(pTHX_ const char *fname, apr_int32_t wanted, + SV *p_sv) +{ + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); + apr_finfo_t *finfo = (apr_finfo_t *)apr_pcalloc(p, sizeof(apr_finfo_t)); + SV *finfo_sv; + + MP_RUN_CROAK(apr_stat(finfo, fname, wanted, p), + "APR::Finfo::stat"); + + finfo_sv = sv_setref_pv(newSV(0), "APR::Finfo", (void*)finfo); + mpxs_add_pool_magic(finfo_sv, p_sv); + + return finfo_sv; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/IpSubnet/APR__IpSubnet.h b/2_0_13/xs/APR/IpSubnet/APR__IpSubnet.h new file mode 100644 index 0000000..c2d6793 --- /dev/null +++ b/2_0_13/xs/APR/IpSubnet/APR__IpSubnet.h
@@ -0,0 +1,37 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +SV *mpxs_apr_ipsubnet_create(pTHX_ SV *classname, SV *p_sv, + const char *ipstr, + const char *mask_or_numbits) +{ + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); + apr_ipsubnet_t *ipsub = NULL; + SV *ipsub_sv; + MP_RUN_CROAK(apr_ipsubnet_create(&ipsub, ipstr, mask_or_numbits, p), + "APR::IpSubnet::new"); + ipsub_sv = sv_setref_pv(newSV(0), "APR::IpSubnet", (void*)ipsub); + mpxs_add_pool_magic(ipsub_sv, p_sv); + return ipsub_sv; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Lock/APR__Lock.h b/2_0_13/xs/APR/Lock/APR__Lock.h new file mode 100644 index 0000000..1054331 --- /dev/null +++ b/2_0_13/xs/APR/Lock/APR__Lock.h
@@ -0,0 +1,22 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Makefile.PL b/2_0_13/xs/APR/Makefile.PL new file mode 100644 index 0000000..1302942 --- /dev/null +++ b/2_0_13/xs/APR/Makefile.PL
@@ -0,0 +1,7 @@ +use lib qw(../lib); +use ModPerl::BuildMM (); + +ModPerl::BuildMM::WriteMakefile( + NAME => "APR_build", + VERSION => '0.01' +);
diff --git a/2_0_13/xs/APR/OS/APR__OS.h b/2_0_13/xs/APR/OS/APR__OS.h new file mode 100644 index 0000000..5cd6f59 --- /dev/null +++ b/2_0_13/xs/APR/OS/APR__OS.h
@@ -0,0 +1,31 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE unsigned long mpxs_APR__OS_current_thread_id(pTHX) +{ +#if APR_HAS_THREADS + return (unsigned long)apr_os_thread_current(); +#else + return 0; +#endif +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/PerlIO/Makefile.PL b/2_0_13/xs/APR/PerlIO/Makefile.PL new file mode 100644 index 0000000..ca102bb --- /dev/null +++ b/2_0_13/xs/APR/PerlIO/Makefile.PL
@@ -0,0 +1,37 @@ +use lib qw(../lib); +use ModPerl::BuildMM (); + +use Config; +use Apache2::Build; +use Apache::TestTrace; +my $build = Apache2::Build->build_config(); + +my $ccopts = $build->ccopts; + +# when uselargefiles is on, -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 +# are needed to get the right 'Off_t', without which perlio compiled +# with Off_t as 'long long int', doesn't quite work with apr_perlio.c +# compiled with Off_t as 'long int' +# +# On the other handl if apr is built without large files support, we +# have binary compatibility problems, if we try to build mod_perl with +# -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 +# +# XXX: it seems that enabling these flags only for apr_perlio/PerlIO +# seems to do the trick +if ($build->has_large_files_conflict) { + $ccopts .= $Config{uselargefiles} + ? ' ' . $Config{ccflags_uselargefiles} + : ''; +} + +# avoid referencing &perl_module outside of mod_perl +$ccopts .= ' -DMP_IN_XS'; + +ModPerl::BuildMM::WriteMakefile( + NAME => 'APR::PerlIO', + VERSION_FROM => 'PerlIO.pm', + CCFLAGS => $ccopts, + OBJECT => 'PerlIO.o modperl_apr_perlio.o' +); +
diff --git a/2_0_13/xs/APR/PerlIO/PerlIO.pm b/2_0_13/xs/APR/PerlIO/PerlIO.pm new file mode 100644 index 0000000..72a6330 --- /dev/null +++ b/2_0_13/xs/APR/PerlIO/PerlIO.pm
@@ -0,0 +1,32 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package APR::PerlIO; + +require 5.006001; + +our $VERSION = '0.009000'; + +# The PerlIO layer is available only since 5.8.0 (5.7.2@13534) +use Config; +use constant PERLIO_LAYERS_ARE_ENABLED => $Config{useperlio} && $] >= 5.007003; + +use APR (); +use APR::XSLoader (); +APR::XSLoader::load __PACKAGE__; + + +1;
diff --git a/2_0_13/xs/APR/PerlIO/PerlIO.xs b/2_0_13/xs/APR/PerlIO/PerlIO.xs new file mode 100644 index 0000000..f833017 --- /dev/null +++ b/2_0_13/xs/APR/PerlIO/PerlIO.xs
@@ -0,0 +1,25 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" +#include "modperl_apr_perlio.h" + +MODULE = APR::PerlIO PACKAGE = APR::PerlIO + +PROTOTYPES: disabled + +BOOT: + modperl_apr_perlio_init(aTHX);
diff --git a/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.c b/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.c new file mode 100644 index 0000000..e8c93a4 --- /dev/null +++ b/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.c
@@ -0,0 +1,633 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modperl_largefiles.h" + +#include "mod_perl.h" +#include "modperl_apr_perlio.h" + +#if defined(PERLIO_LAYERS) && defined(PERLIO_K_MULTIARG) /* 5.7.2+ */ + +/********************************************************************** + * The PerlIO APR layer. + * The PerlIO API is documented in perliol.pod. + **********************************************************************/ + +/* + * APR::PerlIO implements a PerlIO layer using apr_file_io as the core. + */ + +/* + * XXX: Since we cannot snoop on the internal apr_file_io buffer + * currently the IO is not buffered on the Perl side so every read + * requests a char at a time, which is slow. Consider copying the + * relevant code from PerlIOBuf to implement our own buffer, similar + * to what PerlIOBuf does or push :perlio layer on top of this layer + */ + +typedef struct { + struct _PerlIO base; + apr_file_t *file; + apr_pool_t *pool; +} PerlIOAPR; + +static IV PerlIOAPR_pushed(pTHX_ PerlIO *f, const char *mode, + SV *arg, PerlIO_funcs *tab) +{ + IV code = PerlIOBase_pushed(aTHX_ f, mode, arg, tab); + if (*PerlIONext(f)) { + /* XXX: not sure if we can do anything here, but see + * PerlIOUnix_pushed for things that it does + */ + } + return code; +} + +static PerlIO *PerlIOAPR_open(pTHX_ PerlIO_funcs *self, + PerlIO_list_t *layers, IV n, + const char *mode, int fd, int imode, + int perm, PerlIO *f, int narg, SV **args) +{ + SV *arg = (narg > 0) ? *args : PerlIOArg; + PerlIOAPR *st; + const char *path; + apr_int32_t apr_flag; + apr_status_t rc; + SV *sv; + + if (!(SvROK(arg) || SvPOK(arg))) { + return NULL; + } + + /* XXX: why passing only SV* for arg, check this out in PerlIO_push */ + if (!f) { + f = PerlIO_push(aTHX_ PerlIO_allocate(aTHX), self, mode, arg); + } + else { + f = PerlIO_push(aTHX_ f, self, mode, arg); + } + + /* grab the last arg as a filepath */ + path = (const char *)SvPV_nolen(args[narg-2]); + + switch (*mode) { + case 'a': + apr_flag = APR_APPEND | APR_CREATE; + break; + case 'w': + apr_flag = APR_WRITE | APR_CREATE | APR_TRUNCATE; + break; + case 'r': + apr_flag = APR_READ; + break; + default: + Perl_croak(aTHX_ "unknown open mode: %s", mode); + } + + /* APR_BINARY: we always do binary read and PerlIO is supposed + * to handle :crlf if any (by pushing this layer at + * open(). + * APR_BUFFERED: XXX, not sure if it'll be needed if we will push + * :perlio (== PerlIOBuf) layer on top + */ + apr_flag |= APR_BUFFERED | APR_BINARY; + + st = PerlIOSelf(f, PerlIOAPR); + + /* XXX: can't reuse a wrapper mp_xs_sv2_APR__Pool */ + /* XXX: should probably add checks on pool validity in all other callbacks */ + sv = args[narg-1]; + if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG)) { + st->pool = INT2PTR(apr_pool_t *, SvIV((SV*)SvRV(sv))); + } + else { + Perl_croak(aTHX_ "argument is not a blessed reference " + "(expecting an APR::Pool derived object)"); + } + + rc = apr_file_open(&st->file, path, apr_flag, APR_OS_DEFAULT, st->pool); + + MP_TRACE_o(MP_FUNC, "obj=0x%lx, file=0x%lx, name=%s, rc=%d", + (unsigned long)f, (unsigned long)st->file, + path ? path : "(UNKNOWN)", rc); + + if (rc != APR_SUCCESS) { + /* it just so happens that since $! is tied to errno, we get + * it set right via the system call that apr_file_open has + * performed internally, no need to do anything special */ + PerlIO_pop(aTHX_ f); + return NULL; + } + + PerlIOBase(f)->flags |= PERLIO_F_OPEN; + return f; +} + +static IV PerlIOAPR_fileno(pTHX_ PerlIO *f) +{ + /* apr_file_t* is an opaque struct, so fileno is not available. + * -1 in this case indicates that the layer cannot provide fileno + */ + return -1; +} + +static PerlIO *PerlIOAPR_dup(pTHX_ PerlIO *f, PerlIO *o, + CLONE_PARAMS *param, int flags) +{ + apr_status_t rc; + + if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) { + PerlIOAPR *fst = PerlIOSelf(f, PerlIOAPR); + PerlIOAPR *ost = PerlIOSelf(o, PerlIOAPR); + + rc = apr_file_dup(&fst->file, ost->file, ost->pool); + + MP_TRACE_o(MP_FUNC, "obj=0x%lx, " + "file=0x%lx => 0x%lx, rc=%d", + (unsigned long)f, (unsigned long)ost->file, + (unsigned long)fst->file, rc); + + if (rc == APR_SUCCESS) { + fst->pool = ost->pool; + return f; + } + } + + return NULL; +} + +static SSize_t PerlIOAPR_read(pTHX_ PerlIO *f, void *vbuf, Size_t count) +{ + PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR); + apr_status_t rc; + + rc = apr_file_read(st->file, vbuf, &count); + + MP_TRACE_o(MP_FUNC, "%db [%s]", (int)count, + MP_TRACE_STR_TRUNC(st->pool, (char *)vbuf, (int)count)); + + if (rc == APR_EOF) { + PerlIOBase(f)->flags |= PERLIO_F_EOF; + return count; + } + else if (rc != APR_SUCCESS) { + modperl_croak(aTHX_ rc, "APR::PerlIO::read"); + } + + return count; +} + +static SSize_t PerlIOAPR_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count) +{ + PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR); + apr_status_t rc; + + MP_TRACE_o(MP_FUNC, "%db [%s]", (int)count, + MP_TRACE_STR_TRUNC(st->pool, (char *)vbuf, (int)count)); + + rc = apr_file_write(st->file, vbuf, &count); + if (rc == APR_SUCCESS) { + return (SSize_t) count; + } + + PerlIOBase(f)->flags |= PERLIO_F_ERROR; + return (SSize_t) -1; +} + +static IV PerlIOAPR_flush(pTHX_ PerlIO *f) +{ + PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR); + apr_status_t rc; + + rc = apr_file_flush(st->file); + if (rc == APR_SUCCESS) { + return 0; + } + + PerlIOBase(f)->flags |= PERLIO_F_ERROR; + return -1; +} + +static IV PerlIOAPR_seek(pTHX_ PerlIO *f, Off_t offset, int whence) +{ + PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR); + apr_seek_where_t where; + apr_status_t rc; + apr_off_t seek_offset = 0; + +#ifdef MP_LARGE_FILES_CONFLICT + if (offset != 0) { + Perl_croak(aTHX_ "PerlIO::APR::seek with non-zero offset" + "is not supported with Perl built w/ -Duselargefiles" + " and APR w/o largefiles support"); + } +#else + seek_offset = offset; +#endif + + /* Flush the fill buffer */ + if (PerlIO_flush(f) != 0) { + return -1; + } + + switch(whence) { + case 0: + where = APR_SET; + break; + case 1: + where = APR_CUR; + break; + case 2: + where = APR_END; + break; + default: + Perl_croak(aTHX_ "unknown whence mode: %d", whence); + } + + rc = apr_file_seek(st->file, where, &seek_offset); + if (rc == APR_SUCCESS) { + return 0; + } + + return -1; +} + +static Off_t PerlIOAPR_tell(pTHX_ PerlIO *f) +{ + PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR); + apr_off_t offset = 0; + apr_status_t rc; + + rc = apr_file_seek(st->file, APR_CUR, &offset); + if (rc == APR_SUCCESS) { + return (Off_t) offset; + } + + return (Off_t) -1; +} + +static IV PerlIOAPR_close(pTHX_ PerlIO *f) +{ + PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR); + IV code = PerlIOBase_close(aTHX_ f); + apr_status_t rc; + +#ifdef MP_TRACE + const char *new_path = NULL; + apr_os_file_t os_file; + +#ifdef PERL_PHASE_DESTRUCT + if (PL_phase != PERL_PHASE_DESTRUCT) { +#else + if (!PL_dirty) { +#endif + /* if this is called during perl_destruct we are in trouble */ + apr_file_name_get(&new_path, st->file); + } + + rc = apr_os_file_get(&os_file, st->file); + if (rc != APR_SUCCESS) { + Perl_croak(aTHX_ "filedes retrieval failed!"); + } + + MP_TRACE_o(MP_FUNC, "obj=0x%lx, file=0x%lx, fd=%d, name=%s", + (unsigned long)f, (unsigned long)st->file, os_file, + new_path ? new_path : "(UNKNOWN)"); +#endif + +#ifdef PERL_PHASE_DESTRUCT + if (PL_phase == PERL_PHASE_DESTRUCT) { +#else + if (PL_dirty) { +#endif + /* there should not be any PerlIOAPR handles open + * during perl_destruct + */ + Perl_warn(aTHX_ "leaked PerlIOAPR handle 0x%lx", + (unsigned long)f); + return -1; + } + + rc = apr_file_flush(st->file); + if (rc != APR_SUCCESS) { + return -1; + } + + rc = apr_file_close(st->file); + if (rc != APR_SUCCESS) { + return -1; + } + + return code; +} + +#if 0 /* we may use it if the buffering will be done at this layer */ + +static IV PerlIOAPR_fill(pTHX_ PerlIO *f) +{ + PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR); + apr_status_t rc; + SSize_t avail; + Size_t count = st->base.bufsiz; + + if (!st->base.buf) { + PerlIO_get_base(f); /* allocate via vtable */ + } + + MP_TRACE_o(MP_FUNC, "asked to fill %d chars", count); + + rc = apr_file_read(st->file, st->base.ptr, &count); + if (rc != APR_SUCCESS) { + PerlIOBase(f)->flags |= PERLIO_F_ERROR; + return -1; + } + + MP_TRACE_o(MP_FUNC, "got to fill %d chars", count); + + avail = count; /* apr_file_read() sets how many chars were read in count */ + if (avail <= 0) { + if (avail == 0) { + PerlIOBase(f)->flags |= PERLIO_F_EOF; + } + else { + PerlIOBase(f)->flags |= PERLIO_F_ERROR; + } + + return -1; + } + st->base.end = st->base.buf + avail; + + /* indicate that the buffer this layer currently holds unconsumed + data read from layer below. */ + PerlIOBase(f)->flags |= PERLIO_F_RDBUF; + + return 0; +} + +#endif + +static IV PerlIOAPR_eof(pTHX_ PerlIO *f) +{ + PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR); + apr_status_t rc; + + rc = apr_file_eof(st->file); + switch (rc) { + case APR_EOF: + return 1; + default: + return 0; + } + + return -1; +} + +/* 5.8.0 doesn't export PerlIOBase_noop_fail, so we duplicate it here */ +static IV PerlIOAPR_noop_fail(pTHX_ PerlIO *f) +{ + return -1; +} + +static PerlIO_funcs PerlIO_APR = { + sizeof(PerlIO_funcs), + "APR", + sizeof(PerlIOAPR), + PERLIO_K_MULTIARG | PERLIO_K_RAW, + PerlIOAPR_pushed, + PerlIOBase_popped, + PerlIOAPR_open, + PerlIOBase_binmode, /* binmode() is handled by :crlf */ + NULL, /* no getarg needed */ + PerlIOAPR_fileno, + PerlIOAPR_dup, + PerlIOAPR_read, + PerlIOBase_unread, + PerlIOAPR_write, + PerlIOAPR_seek, + PerlIOAPR_tell, + PerlIOAPR_close, + PerlIOAPR_flush, /* flush */ + PerlIOAPR_noop_fail, /* fill */ + PerlIOAPR_eof, + PerlIOBase_error, + PerlIOBase_clearerr, + PerlIOBase_setlinebuf, + NULL, /* get_base */ + NULL, /* get_bufsiz */ + NULL, /* get_ptr */ + NULL, /* get_cnt */ + NULL, /* set_ptrcnt */ +}; + +void modperl_apr_perlio_init(pTHX) +{ + APR_REGISTER_OPTIONAL_FN(modperl_apr_perlio_apr_file_to_PerlIO); + APR_REGISTER_OPTIONAL_FN(modperl_apr_perlio_apr_file_to_glob); + + PerlIO_define_layer(aTHX_ &PerlIO_APR); +} + + +/* ***** End of PerlIOAPR tab ***** */ + + +/* ***** PerlIO <=> apr_file_t helper functions ***** */ + +PerlIO *modperl_apr_perlio_apr_file_to_PerlIO(pTHX_ apr_file_t *file, + apr_pool_t *pool, + modperl_apr_perlio_hook_e type) +{ + char *mode; + const char *layers = ":APR"; + PerlIOAPR *st; + PerlIO *f = PerlIO_allocate(aTHX); + + if (!f) { + Perl_croak(aTHX_ "Failed to allocate PerlIO struct"); + } + + switch (type) { + case MODPERL_APR_PERLIO_HOOK_WRITE: + mode = "w"; + break; + case MODPERL_APR_PERLIO_HOOK_READ: + mode = "r"; + break; + default: + Perl_croak(aTHX_ "unknown MODPERL_APR_PERLIO type: %d", type); + }; + + PerlIO_apply_layers(aTHX_ f, mode, layers); + if (!f) { + Perl_croak(aTHX_ "Failed to apply the ':APR' layer"); + } + + st = PerlIOSelf(f, PerlIOAPR); + +#ifdef MP_TRACE + { + apr_status_t rc; + apr_os_file_t os_file; + + /* convert to the OS representation of file */ + rc = apr_os_file_get(&os_file, file); + if (rc != APR_SUCCESS) { + croak("filedes retrieval failed!"); + } + + MP_TRACE_o(MP_FUNC, "converting to PerlIO fd %d, mode '%s'", + os_file, mode); + } +#endif + + st->pool = pool; + st->file = file; + PerlIOBase(f)->flags |= PERLIO_F_OPEN; + + return f; +} + +static SV *modperl_apr_perlio_PerlIO_to_glob(pTHX_ PerlIO *pio, + modperl_apr_perlio_hook_e type) +{ + SV *retval = modperl_perl_gensym(aTHX_ "APR::PerlIO"); + GV *gv = (GV*)SvRV(retval); + + gv_IOadd(gv); + + switch (type) { + case MODPERL_APR_PERLIO_HOOK_WRITE: + /* if IoIFP() is not assigned to it'll be never closed, see + * Perl_io_close() */ + IoIFP(GvIOp(gv)) = IoOFP(GvIOp(gv)) = pio; + IoFLAGS(GvIOp(gv)) |= IOf_FLUSH; + IoTYPE(GvIOp(gv)) = IoTYPE_WRONLY; + break; + case MODPERL_APR_PERLIO_HOOK_READ: + IoIFP(GvIOp(gv)) = pio; + IoTYPE(GvIOp(gv)) = IoTYPE_RDONLY; + break; + }; + + return sv_2mortal(retval); +} + +SV *modperl_apr_perlio_apr_file_to_glob(pTHX_ apr_file_t *file, + apr_pool_t *pool, + modperl_apr_perlio_hook_e type) +{ + return modperl_apr_perlio_PerlIO_to_glob(aTHX_ + modperl_apr_perlio_apr_file_to_PerlIO(aTHX_ file, pool, type), + type); +} + +#else /* defined(PERLIO_LAYERS) (5.6.x) */ + +#ifdef USE_PERLIO /* 5.6.x + -Duseperlio */ +#define MP_IO_TYPE PerlIO +#else +#define MP_IO_TYPE FILE +#endif + +static MP_IO_TYPE *modperl_apr_perlio_apr_file_to_PerlIO(pTHX_ apr_file_t *file, + modperl_apr_perlio_hook_e type) +{ + MP_IO_TYPE *retval; + char *mode; + int fd; + apr_os_file_t os_file; + apr_status_t rc; + + switch (type) { + case MODPERL_APR_PERLIO_HOOK_WRITE: + mode = "w"; + break; + case MODPERL_APR_PERLIO_HOOK_READ: + mode = "r"; + break; + }; + + /* convert to the OS representation of file */ + rc = apr_os_file_get(&os_file, file); + if (rc != APR_SUCCESS) { + Perl_croak(aTHX_ "filedes retrieval failed!"); + } + + MP_TRACE_o(MP_FUNC, "converting fd %d", os_file); + + /* let's try without the dup, it seems to work fine: + + fd = PerlLIO_dup(os_file); + MP_TRACE_o(MP_FUNC, "fd old: %d, new %d", os_file, fd); + if (!(retval = PerlIO_fdopen(fd, mode))) { + ... + } + + in any case if we later decide to dup, remember to: + + apr_file_close(file); + + after PerlIO_fdopen() or that fh will be leaked + + */ + + if (!(retval = PerlIO_fdopen(os_file, mode))) { + PerlLIO_close(fd); + Perl_croak(aTHX_ "fdopen failed!"); + } + + return retval; +} + +SV *modperl_apr_perlio_apr_file_to_glob(pTHX_ apr_file_t *file, + apr_pool_t *pool, + modperl_apr_perlio_hook_e type) +{ + SV *retval = modperl_perl_gensym(aTHX_ "APR::PerlIO"); + GV *gv = (GV*)SvRV(retval); + + gv_IOadd(gv); + + switch (type) { + case MODPERL_APR_PERLIO_HOOK_WRITE: + IoIFP(GvIOp(gv)) = IoOFP(GvIOp(gv)) = + modperl_apr_perlio_apr_file_to_PerlIO(aTHX_ file, type); + IoFLAGS(GvIOp(gv)) |= IOf_FLUSH; + IoTYPE(GvIOp(gv)) = IoTYPE_WRONLY; + break; + case MODPERL_APR_PERLIO_HOOK_READ: + IoIFP(GvIOp(gv)) = modperl_apr_perlio_apr_file_to_PerlIO(aTHX_ file, + type); + IoTYPE(GvIOp(gv)) = IoTYPE_RDONLY; + break; + }; + + return sv_2mortal(retval); +} + +void modperl_apr_perlio_init(pTHX) +{ + APR_REGISTER_OPTIONAL_FN(modperl_apr_perlio_apr_file_to_glob); +} + +#endif /* PERLIO_LAYERS */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.h b/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.h new file mode 100644 index 0000000..15c853a --- /dev/null +++ b/2_0_13/xs/APR/PerlIO/modperl_apr_perlio.h
@@ -0,0 +1,83 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_APR_PERLIO_H +#define MODPERL_APR_PERLIO_H + +#ifdef PERLIO_LAYERS +#include "perliol.h" +#else +#include "iperlsys.h" +#endif + +#include "apr_portable.h" +#include "apr_file_io.h" +#include "apr_errno.h" + +#ifndef MP_SOURCE_SCAN +#include "apr_optional.h" +#endif + +/* 5.6.0 */ +#ifndef IoTYPE_RDONLY +#define IoTYPE_RDONLY '<' +#endif +#ifndef IoTYPE_WRONLY +#define IoTYPE_WRONLY '>' +#endif + +typedef enum { + MODPERL_APR_PERLIO_HOOK_READ, + MODPERL_APR_PERLIO_HOOK_WRITE +} modperl_apr_perlio_hook_e; + +#ifndef MP_SOURCE_SCAN +void modperl_apr_perlio_init(pTHX); +#endif + +/* The following functions can be used from other .so libs, they just + * need to load APR::PerlIO perl module first + */ +#ifndef MP_SOURCE_SCAN + +#ifdef PERLIO_LAYERS +PerlIO *modperl_apr_perlio_apr_file_to_PerlIO(pTHX_ apr_file_t *file, + apr_pool_t *pool, + modperl_apr_perlio_hook_e type); +APR_DECLARE_OPTIONAL_FN(PerlIO *, + modperl_apr_perlio_apr_file_to_PerlIO, + (pTHX_ apr_file_t *file, apr_pool_t *pool, + modperl_apr_perlio_hook_e type)); +#endif /* PERLIO_LAYERS */ + + +SV *modperl_apr_perlio_apr_file_to_glob(pTHX_ apr_file_t *file, + apr_pool_t *pool, + modperl_apr_perlio_hook_e type); +APR_DECLARE_OPTIONAL_FN(SV *, + modperl_apr_perlio_apr_file_to_glob, + (pTHX_ apr_file_t *file, apr_pool_t *pool, + modperl_apr_perlio_hook_e type)); +#endif /* MP_SOURCE_SCAN */ + +#endif /* MODPERL_APR_PERLIO_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Pool/APR__Pool.h b/2_0_13/xs/APR/Pool/APR__Pool.h new file mode 100644 index 0000000..4a168b3 --- /dev/null +++ b/2_0_13/xs/APR/Pool/APR__Pool.h
@@ -0,0 +1,398 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MP_APR_POOL_NEW "APR::Pool::new" + +typedef struct { + SV *sv; +#ifdef USE_ITHREADS + PerlInterpreter *perl; + modperl_interp_t *interp; +#endif +} mpxs_pool_account_t; + +/* XXX: this implementation has a problem with perl ithreads. if a + * custom pool is allocated, and then a thread is spawned we now have + * two copies of the pool object, each living in a different perl + * interpreter, both pointing to the same memory address of the apr + * pool. + * + * need to write a CLONE class method could properly clone the + * thread's copied object, but it's tricky: + * - it needs to call parent_get() on the copied object and allocate a + * new pool from that parent's pool + * - it needs to reinstall any registered cleanup callbacks (can we do + * that?) may be we can skip those? + */ + +#ifndef MP_SOURCE_SCAN +#ifdef USE_ITHREADS +#include "apr_optional.h" +APR_OPTIONAL_FN_TYPE(modperl_interp_unselect) *modperl_opt_interp_unselect; +APR_OPTIONAL_FN_TYPE(modperl_thx_interp_get) *modperl_opt_thx_interp_get; +#endif +#endif + +#define MP_APR_POOL_SV_HAS_OWNERSHIP(sv) mpxs_pool_is_custom(sv) + +/* before the magic is freed, one needs to carefully detach the + * dependant pool magic added by mpxs_add_pool_magic (most of the time + * it'd be a parent pool), and postpone its destruction, until after + * the child pool is destroyed. Since if we don't do that the + * destruction of the parent pool will destroy the child pool C guts + * and when perl unware of that the rug was pulled under the feet will + * continue destructing the child pool, things will crash + */ +#define MP_APR_POOL_SV_DROPS_OWNERSHIP_RUN(acct) STMT_START { \ + MAGIC *mg = mg_find(acct->sv, PERL_MAGIC_ext); \ + if (mg && mg->mg_obj) { \ + sv_2mortal(mg->mg_obj); \ + mg->mg_obj = (SV *)NULL; \ + mg->mg_flags &= ~MGf_REFCOUNTED; \ + } \ + mg_free(acct->sv); \ + SvIVX(acct->sv) = 0; \ +} STMT_END + +#ifdef USE_ITHREADS + +#define MP_APR_POOL_SV_DROPS_OWNERSHIP(acct) STMT_START { \ + dTHXa(acct->perl); \ + MP_APR_POOL_SV_DROPS_OWNERSHIP_RUN(acct); \ + if (modperl_opt_interp_unselect && acct->interp) { \ + /* this will decrement the interp refcnt until \ + * there are no more references, in which case \ + * the interpreter will be putback into the mip \ + */ \ + MP_TRACE_i(MP_FUNC, "DO: calling interp_unselect(0x%lx)", \ + acct->interp); \ + (void)modperl_opt_interp_unselect(acct->interp); \ + } \ +} STMT_END + +#define MP_APR_POOL_SV_TAKES_OWNERSHIP(acct_sv, pool) STMT_START { \ + mpxs_pool_account_t *acct = apr_palloc(pool, sizeof *acct); \ + acct->sv = acct_sv; \ + acct->perl = aTHX; \ + SvIVX(acct_sv) = PTR2IV(pool); \ + \ + sv_magic(acct_sv, (SV *)NULL, PERL_MAGIC_ext, \ + MP_APR_POOL_NEW, sizeof(MP_APR_POOL_NEW)); \ + \ + apr_pool_cleanup_register(pool, (void *)acct, \ + mpxs_apr_pool_cleanup, \ + apr_pool_cleanup_null); \ + \ + /* make sure interpreter is not putback into the mip \ + * until this cleanup has run. \ + */ \ + if (modperl_opt_thx_interp_get) { \ + if ((acct->interp = modperl_opt_thx_interp_get(aTHX))) { \ + acct->interp->refcnt++; \ + MP_TRACE_i(MP_FUNC, "TO: (0x%lx)->refcnt incremented to %ld", \ + acct->interp, acct->interp->refcnt); \ + } \ + } \ +} STMT_END + +#else /* !USE_ITHREADS */ + +#define MP_APR_POOL_SV_DROPS_OWNERSHIP MP_APR_POOL_SV_DROPS_OWNERSHIP_RUN + +#define MP_APR_POOL_SV_TAKES_OWNERSHIP(acct_sv, pool) STMT_START { \ + mpxs_pool_account_t *acct = apr_palloc(pool, sizeof *acct); \ + acct->sv = acct_sv; \ + SvIVX(acct_sv) = PTR2IV(pool); \ + \ + sv_magic(acct_sv, (SV *)NULL, PERL_MAGIC_ext, \ + MP_APR_POOL_NEW, sizeof(MP_APR_POOL_NEW)); \ + \ + apr_pool_cleanup_register(pool, (void *)acct, \ + mpxs_apr_pool_cleanup, \ + apr_pool_cleanup_null); \ +} STMT_END + +#endif /* USE_ITHREADS */ + + +/* XXX: should we make it a new global tracing category + * MOD_PERL_TRACE=p for tracing pool management? */ +#define MP_POOL_TRACE_DO 0 + +#if MP_POOL_TRACE_DO && defined(MP_TRACE) +#define MP_POOL_TRACE modperl_trace +#else +#define MP_POOL_TRACE if (0) modperl_trace +#endif + +/* invalidate all Perl objects referencing the data sv stored in the + * pool and the sv itself. this is needed when a parent pool triggers + * apr_pool_destroy on its child pools + */ +static MP_INLINE apr_status_t +mpxs_apr_pool_cleanup(void *cleanup_data) +{ + mpxs_pool_account_t *acct = cleanup_data; + MP_APR_POOL_SV_DROPS_OWNERSHIP(acct); + return APR_SUCCESS; +} + +/** + * Create a new pool or subpool. + * @param parent_pool_obj an APR::Pool object or an "APR::Pool" class + * @return a new pool or subpool + */ +static MP_INLINE SV *mpxs_apr_pool_create(pTHX_ SV *parent_pool_obj) +{ + apr_pool_t *parent_pool = mpxs_sv_object_deref(parent_pool_obj, apr_pool_t); + apr_pool_t *child_pool = NULL; + + MP_POOL_TRACE(MP_FUNC, "parent pool 0x%l", (unsigned long)parent_pool); + (void)apr_pool_create(&child_pool, parent_pool); + +#if APR_POOL_DEBUG + /* useful for pools debugging, can grep for APR::Pool::new */ + apr_pool_tag(child_pool, MP_APR_POOL_NEW); +#endif + + /* allocation corruption validation: I saw this happening when the + * same pool was destroyed more than once, should be fixed now, + * but still the check is not redundant */ + if (child_pool == parent_pool) { + Perl_croak(aTHX_ "a newly allocated sub-pool 0x%lx " + "is the same as its parent 0x%lx, aborting", + (unsigned long)child_pool, (unsigned long)parent_pool); + } + +#if APR_POOL_DEBUG + /* child <-> parent <-> ... <-> top ancestry traversal */ + { + apr_pool_t *p = child_pool; + apr_pool_t *pp; + + while ((pp = apr_pool_parent_get(p))) { + MP_POOL_TRACE(MP_FUNC, "parent 0x%lx, child 0x%lx", + (unsigned long)pp, (unsigned long)p); + + if (apr_pool_is_ancestor(pp, p)) { + MP_POOL_TRACE(MP_FUNC, "0x%lx is a subpool of 0x%lx", + (unsigned long)p, (unsigned long)pp); + } + p = pp; + } + } +#endif + + { + SV *rv = sv_setref_pv(newSV(0), "APR::Pool", (void*)child_pool); + SV *sv = SvRV(rv); + + /* Each newly created pool must be destroyed only once. Calling + * apr_pool_destroy will destroy the pool and its children pools, + * however a perl object for a sub-pool will still keep a pointer + * to the pool which was already destroyed. When this object is + * DESTROYed, apr_pool_destroy will be called again. In the best + * case it'll try to destroy a non-existing pool, but in the worst + * case it'll destroy a different valid pool which has been given + * the same memory allocation wrecking havoc. Therefore we must + * ensure that when sub-pools are destroyed via the parent pool, + * their cleanup callbacks will destroy the guts of their perl + * objects, so when those perl objects, pointing to memory + * previously allocated by destroyed sub-pools or re-used already + * by new pools, will get their time to DESTROY, they won't make a + * mess, trying to destroy an already destroyed pool or even worse + * a pool allocate in the place of the old one. + */ + + MP_APR_POOL_SV_TAKES_OWNERSHIP(sv, child_pool); + + MP_POOL_TRACE(MP_FUNC, "sub-pool p: 0x%lx, sv: 0x%lx, rv: 0x%lx", + (unsigned long)child_pool, sv, rv); + + if (parent_pool) { + mpxs_add_pool_magic(rv, parent_pool_obj); + } + + return rv; + } +} + +static MP_INLINE void mpxs_APR__Pool_clear(pTHX_ SV *obj) +{ + apr_pool_t *p = mp_xs_sv2_APR__Pool(obj); + SV *sv = SvRV(obj); + + if (!MP_APR_POOL_SV_HAS_OWNERSHIP(sv)) { + MP_POOL_TRACE(MP_FUNC, "parent pool (0x%lx) is a core pool", + (unsigned long)p); + apr_pool_clear(p); + return; + } + + MP_POOL_TRACE(MP_FUNC, + "parent pool (0x%lx) is a custom pool, sv 0x%lx", + (unsigned long)p, + (unsigned long)sv); + + apr_pool_clear(p); + + /* apr_pool_clear runs & removes the cleanup, so we need to restore + * it. Since clear triggers mpxs_apr_pool_cleanup call, our + * object's guts get nuked too, so we need to restore them too */ + + MP_APR_POOL_SV_TAKES_OWNERSHIP(sv, p); +} + + +typedef struct { + SV *cv; + SV *arg; + apr_pool_t *p; +#ifdef USE_ITHREADS + PerlInterpreter *perl; + modperl_interp_t *interp; +#endif +} mpxs_cleanup_t; + +/** + * callback wrapper for Perl cleanup subroutines + * @param data internal storage + */ + + +static apr_status_t mpxs_cleanup_run(void *data) +{ + int count; + mpxs_cleanup_t *cdata = (mpxs_cleanup_t *)data; +#ifdef USE_ITHREADS + dTHXa(cdata->perl); +#endif + dSP; + + ENTER;SAVETMPS; + PUSHMARK(SP); + if (cdata->arg) { + XPUSHs(cdata->arg); + } + PUTBACK; + + save_gp(PL_errgv, 1); /* local *@ */ + count = call_sv(cdata->cv, G_SCALAR|G_EVAL); + + SPAGAIN; + + if (count == 1) { + (void)POPs; /* the return value is ignored */ + } + + if (SvTRUE(ERRSV)) { + Perl_warn(aTHX_ "APR::Pool: cleanup died: %s", + SvPV_nolen(ERRSV)); + } + + PUTBACK; + FREETMPS;LEAVE; + + SvREFCNT_dec(cdata->cv); + if (cdata->arg) { + SvREFCNT_dec(cdata->arg); + } + +#ifdef USE_ITHREADS + if (cdata->interp && modperl_opt_interp_unselect) { + /* this will decrement the interp refcnt until + * there are no more references, in which case + * the interpreter will be putback into the mip + */ + MP_TRACE_i(MP_FUNC, "calling interp_unselect(0x%lx)", cdata->interp); + (void)modperl_opt_interp_unselect(cdata->interp); + } +#endif + + /* the return value is ignored by apr_pool_destroy anyway */ + return APR_SUCCESS; +} + +/** + * register cleanups to run + * @param p pool with which to associate the cleanup + * @param cv subroutine reference to run + * @param arg optional argument to pass to the subroutine + */ +static MP_INLINE void mpxs_apr_pool_cleanup_register(pTHX_ apr_pool_t *p, + SV *cv, SV *arg) +{ + mpxs_cleanup_t *data = + (mpxs_cleanup_t *)apr_pcalloc(p, sizeof(*data)); + + data->cv = SvREFCNT_inc(cv); + data->arg = arg ? SvREFCNT_inc(arg) : (SV *)NULL; + data->p = p; +#ifdef USE_ITHREADS + data->perl = aTHX; + /* make sure interpreter is not putback into the mip + * until this cleanup has run. + */ + if (modperl_opt_thx_interp_get) { + if ((data->interp = modperl_opt_thx_interp_get(data->perl))) { + data->interp->refcnt++; + MP_TRACE_i(MP_FUNC, "(0x%lx)->refcnt incremented to %ld", + data->interp, data->interp->refcnt); + } + } +#endif + + apr_pool_cleanup_register(p, data, + mpxs_cleanup_run, + apr_pool_cleanup_null); +} + + +static MP_INLINE SV * +mpxs_apr_pool_parent_get(pTHX_ apr_pool_t *child_pool) +{ + apr_pool_t *parent_pool = apr_pool_parent_get(child_pool); + + if (parent_pool) { + return SvREFCNT_inc(mp_xs_APR__Pool_2obj(parent_pool)); + } + else { + MP_POOL_TRACE(MP_FUNC, "pool (0x%lx) has no parents", + (unsigned long)child_pool); + return &PL_sv_undef; + } +} + +/** + * destroy a pool + * @param obj an APR::Pool object + */ +static MP_INLINE void mpxs_apr_pool_DESTROY(pTHX_ SV *obj) +{ + SV *sv = SvRV(obj); + + if (MP_APR_POOL_SV_HAS_OWNERSHIP(sv)) { + apr_pool_t *p = mpxs_sv_object_deref(obj, apr_pool_t); + apr_pool_destroy(p); + } +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/SockAddr/APR__SockAddr.h b/2_0_13/xs/APR/SockAddr/APR__SockAddr.h new file mode 100644 index 0000000..06790d9 --- /dev/null +++ b/2_0_13/xs/APR/SockAddr/APR__SockAddr.h
@@ -0,0 +1,32 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE char * +mpxs_apr_sockaddr_ip_get(pTHX_ apr_sockaddr_t *sockaddr) +{ + char *addr = NULL; + + (void)apr_sockaddr_ip_get(&addr, sockaddr); + + return addr; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Socket/APR__Socket.h b/2_0_13/xs/APR/Socket/APR__Socket.h new file mode 100644 index 0000000..0c2a88e --- /dev/null +++ b/2_0_13/xs/APR/Socket/APR__Socket.h
@@ -0,0 +1,134 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +apr_size_t mpxs_APR__Socket_recv(pTHX_ apr_socket_t *socket, + SV *buffer, + apr_size_t len) +{ + apr_status_t rc; + + mpxs_sv_grow(buffer, len); + rc = apr_socket_recv(socket, SvPVX(buffer), &len); + + if (!(rc == APR_SUCCESS || rc == APR_EOF)) { + modperl_croak(aTHX_ rc, "APR::Socket::recv"); + } + + mpxs_sv_cur_set(buffer, len); + SvTAINTED_on(buffer); + return len; +} + +static MP_INLINE +apr_size_t mpxs_apr_socket_send(pTHX_ apr_socket_t *socket, + SV *sv_buf, SV *sv_len) +{ + apr_size_t buf_len; + char *buffer = SvPV(sv_buf, buf_len); + + if (sv_len) { + if (buf_len < SvIV(sv_len)) { + Perl_croak(aTHX_ "the 3rd arg (%d) is bigger than the " + "length (%d) of the 2nd argument", + (int)SvIV(sv_len), buf_len); + } + buf_len = SvIV(sv_len); + } + + MP_RUN_CROAK(apr_socket_send(socket, buffer, &buf_len), + "APR::Socket::send"); + + return buf_len; +} + +static MP_INLINE +apr_interval_time_t mpxs_apr_socket_timeout_get(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + apr_interval_time_t t; + APR__Socket APR__Socket; + + /* this also magically assings to APR_Socket ;-) */ + mpxs_usage_va_1(APR__Socket, "$socket->timeout_get()"); + + MP_RUN_CROAK(apr_socket_timeout_get(APR__Socket, &t), + "APR::Socket::timeout_get"); + return t; +} + +static MP_INLINE +void mpxs_APR__Socket_timeout_set(pTHX_ apr_socket_t *socket, + apr_interval_time_t t) +{ + MP_RUN_CROAK(apr_socket_timeout_set(socket, t), + "APR::Socket::timeout_set"); +} + + + +static MP_INLINE +apr_int32_t mpxs_APR__Socket_opt_get(pTHX_ apr_socket_t *socket, + apr_int32_t opt) +{ + apr_int32_t val; + MP_RUN_CROAK(apr_socket_opt_get(socket, opt, &val), + "APR::Socket::opt_get"); + return val; +} + +static MP_INLINE +void mpxs_APR__Socket_opt_set(pTHX_ apr_socket_t *socket, apr_int32_t opt, + apr_int32_t val) +{ + MP_RUN_CROAK(apr_socket_opt_set(socket, opt, val), + "APR::Socket::opt_set"); +} + +static MP_INLINE +apr_status_t mpxs_APR__Socket_poll(apr_socket_t *socket, + apr_pool_t *pool, + apr_interval_time_t timeout, + apr_int16_t reqevents) +{ + apr_pollfd_t fd; + apr_int32_t nsds; + + /* what to poll */ + fd.p = pool; + fd.desc_type = APR_POLL_SOCKET; + fd.desc.s = socket; + fd.reqevents = reqevents; + fd.rtnevents = 0; /* XXX: not really necessary to set this */ + + return apr_poll(&fd, 1, &nsds, timeout); +} + +#ifndef WIN32 +static MP_INLINE int mpxs_APR__Socket_fileno(pTHX_ apr_socket_t *socket) +{ + apr_os_sock_t s; + apr_os_sock_get(&s, socket); + return s; +} +#endif + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Status/APR__Status.h b/2_0_13/xs/APR/Status/APR__Status.h new file mode 100644 index 0000000..b741cb2 --- /dev/null +++ b/2_0_13/xs/APR/Status/APR__Status.h
@@ -0,0 +1,32 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_errno.h" + +#define mpxs_APR__Status_is_EAGAIN APR_STATUS_IS_EAGAIN +#define mpxs_APR__Status_is_EACCES APR_STATUS_IS_EACCES +#define mpxs_APR__Status_is_ENOENT APR_STATUS_IS_ENOENT +#define mpxs_APR__Status_is_EOF APR_STATUS_IS_EOF +#define mpxs_APR__Status_is_ECONNABORTED APR_STATUS_IS_ECONNABORTED +#define mpxs_APR__Status_is_ECONNRESET APR_STATUS_IS_ECONNRESET +#define mpxs_APR__Status_is_TIMEUP APR_STATUS_IS_TIMEUP + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/String/APR__String.h b/2_0_13/xs/APR/String/APR__String.h new file mode 100644 index 0000000..a257cdd --- /dev/null +++ b/2_0_13/xs/APR/String/APR__String.h
@@ -0,0 +1,32 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +SV *mpxs_APR__String_strfsize(pTHX_ apr_off_t size) +{ + char buff[5]; + + apr_strfsize(size, buff); + + return newSVpvn(buff, 4); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Table/APR__Table.h b/2_0_13/xs/APR/Table/APR__Table.h new file mode 100644 index 0000000..4ef6c49 --- /dev/null +++ b/2_0_13/xs/APR/Table/APR__Table.h
@@ -0,0 +1,241 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define mpxs_APR__Table_STORE apr_table_set +#define mpxs_APR__Table_DELETE apr_table_unset +#define mpxs_APR__Table_CLEAR apr_table_clear + +#define MPXS_DO_TABLE_N_MAGIC_RETURN(call) \ + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); \ + apr_table_t *t = call; \ + SV *t_sv = modperl_hash_tie(aTHX_ "APR::Table", (SV *)NULL, t); \ + mpxs_add_pool_magic(t_sv, p_sv); \ + return t_sv; + +static MP_INLINE SV *mpxs_APR__Table_make(pTHX_ SV *p_sv, int nelts) +{ + MPXS_DO_TABLE_N_MAGIC_RETURN(apr_table_make(p, nelts)); +} + + +static MP_INLINE SV *mpxs_APR__Table_copy(pTHX_ apr_table_t *base, SV *p_sv) +{ + MPXS_DO_TABLE_N_MAGIC_RETURN(apr_table_copy(p, base)); +} + +static MP_INLINE SV *mpxs_APR__Table_overlay(pTHX_ apr_table_t *base, + apr_table_t *overlay, SV *p_sv) +{ + MPXS_DO_TABLE_N_MAGIC_RETURN(apr_table_overlay(p, overlay, base)); +} + + +typedef struct { + SV *cv; + apr_hash_t *filter; + PerlInterpreter *perl; +} mpxs_table_do_cb_data_t; + +typedef int (*mpxs_apr_table_do_cb_t)(void *, const char *, const char *); + +static int mpxs_apr_table_do_cb(void *data, + const char *key, const char *val) +{ + mpxs_table_do_cb_data_t *tdata = (mpxs_table_do_cb_data_t *)data; + dTHXa(tdata->perl); + dSP; + int rv = 0; + + /* Skip completely if something is wrong */ + if (!(tdata && tdata->cv && key && val)) { + return 0; + } + + /* Skip entries if not in our filter list */ + if (tdata->filter) { + if (!apr_hash_get(tdata->filter, key, APR_HASH_KEY_STRING)) { + return 1; + } + } + + ENTER; + SAVETMPS; + + PUSHMARK(sp); + XPUSHs(sv_2mortal(newSVpv(key,0))); + XPUSHs(sv_2mortal(newSVpv(val,0))); + PUTBACK; + + rv = call_sv(tdata->cv, 0); + SPAGAIN; + rv = (1 == rv) ? POPi : 1; + PUTBACK; + + FREETMPS; + LEAVE; + + /* rv of 0 aborts the traversal */ + return rv; +} + +static MP_INLINE +int mpxs_apr_table_do(pTHX_ I32 items, SV **MARK, SV **SP) +{ + apr_table_t *table; + SV *sub; + mpxs_table_do_cb_data_t tdata; + + mpxs_usage_va_2(table, sub, "$table->do(sub, [@filter])"); + + tdata.cv = sub; + tdata.filter = NULL; +#ifdef USE_ITHREADS + tdata.perl = aTHX; +#endif + + if (items > 2) { + char *filter_entry; + STRLEN len; + + tdata.filter = apr_hash_make(apr_table_elts(table)->pool); + + while (MARK <= SP) { + filter_entry = SvPV(*MARK, len); + apr_hash_set(tdata.filter, filter_entry, len, "1"); + MARK++; + } + } + + /* XXX: would be nice to be able to call apr_table_vdo directly, + * but I don't think it's possible to create/populate something + * that smells like a va_list with our list of filters specs + */ + + apr_table_do(mpxs_apr_table_do_cb, (void *)&tdata, table, NULL); + + /* Free tdata.filter or wait for the pool to go away? */ + + /* XXX: return return value of apr_table_do once we require newer httpd */ + return 1; +} + +static MP_INLINE int mpxs_APR__Table_EXISTS(apr_table_t *t, const char *key) +{ + return (NULL == apr_table_get(t, key)) ? 0 : 1; +} + +/* Note: SvCUR is used as the iterator state counter, why not ;-? */ +#define mpxs_apr_table_iterix(sv) \ +SvCUR(SvRV(sv)) + +#define mpxs_apr_table_nextkey(t, sv) \ + ((apr_table_entry_t *) \ + apr_table_elts(t)->elts)[mpxs_apr_table_iterix(sv)++].key + +static MP_INLINE const char *mpxs_APR__Table_NEXTKEY(pTHX_ SV *tsv, SV *key) +{ + apr_table_t *t; + SV *rv = modperl_hash_tied_object_rv(aTHX_ "APR::Table", tsv); + if (!SvROK(rv)) { + Perl_croak(aTHX_ "Usage: $table->NEXTKEY($key): " + "first argument not an APR::Table object"); + } + + t = INT2PTR(apr_table_t *, SvIVX(SvRV(rv))); + + if (apr_is_empty_table(t)) { + return NULL; + } + + if (key == NULL) { + mpxs_apr_table_iterix(rv) = 0; /* reset iterator index */ + } + + if (mpxs_apr_table_iterix(rv) < apr_table_elts(t)->nelts) { + return mpxs_apr_table_nextkey(t, rv); + } + + mpxs_apr_table_iterix(rv) = 0; + + return NULL; +} + +/* Try to shortcut apr_table_get by fetching the key using the current + * iterator (unless it's inactive or points at different key). + */ +static MP_INLINE const char *mpxs_APR__Table_FETCH(pTHX_ SV *tsv, + const char *key) +{ + SV* rv = modperl_hash_tied_object_rv(aTHX_ "APR::Table", tsv); + const int i = mpxs_apr_table_iterix(rv); + apr_table_t *t = INT2PTR(apr_table_t *, SvIVX(SvRV(rv))); + const apr_array_header_t *arr = apr_table_elts(t); + apr_table_entry_t *elts = (apr_table_entry_t *)arr->elts; + + if (i > 0 && i <= arr->nelts && !strcasecmp(key, elts[i-1].key)) { + return elts[i-1].val; + } + else { + return apr_table_get(t, key); + } +} + + +MP_STATIC XS(MPXS_apr_table_get) +{ + dXSARGS; + + if (items != 2) { + Perl_croak(aTHX_ "Usage: $table->get($key)"); + } + + mpxs_PPCODE({ + APR__Table t = modperl_hash_tied_object(aTHX_ "APR::Table", ST(0)); + const char *key = (const char *)SvPV_nolen(ST(1)); + + if (!t) { + XSRETURN_UNDEF; + } + + if (GIMME_V == G_SCALAR) { + const char *val = apr_table_get(t, key); + + if (val) { + XPUSHs(sv_2mortal(newSVpv((char*)val, 0))); + } + } + else { + const apr_array_header_t *arr = apr_table_elts(t); + apr_table_entry_t *elts = (apr_table_entry_t *)arr->elts; + int i; + + for (i = 0; i < arr->nelts; i++) { + if (!elts[i].key || strcasecmp(elts[i].key, key)) { + continue; + } + XPUSHs(sv_2mortal(newSVpv(elts[i].val,0))); + } + } + }); + +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/ThreadMutex/APR__ThreadMutex.h b/2_0_13/xs/APR/ThreadMutex/APR__ThreadMutex.h new file mode 100644 index 0000000..3f4a395 --- /dev/null +++ b/2_0_13/xs/APR/ThreadMutex/APR__ThreadMutex.h
@@ -0,0 +1,37 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define apr_thread_mutex_DESTROY apr_thread_mutex_destroy + +static MP_INLINE +SV *mpxs_apr_thread_mutex_create(pTHX_ SV *classname, SV *p_sv, + unsigned int flags) +{ + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); + apr_thread_mutex_t *mutex = NULL; + SV *mutex_sv; + (void)apr_thread_mutex_create(&mutex, flags, p); + mutex_sv = sv_setref_pv(newSV(0), "APR::ThreadMutex", (void*)mutex); + mpxs_add_pool_magic(mutex_sv, p_sv); + return mutex_sv; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/ThreadRWLock/APR__ThreadRWLock.h b/2_0_13/xs/APR/ThreadRWLock/APR__ThreadRWLock.h new file mode 100644 index 0000000..a2d4d4b --- /dev/null +++ b/2_0_13/xs/APR/ThreadRWLock/APR__ThreadRWLock.h
@@ -0,0 +1,36 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define apr_thread_rwlock_DESTROY apr_thread_rwlock_destroy + +static MP_INLINE +SV *mpxs_apr_thread_rwlock_create(pTHX_ SV *classname, SV *p_sv) +{ + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); + apr_thread_rwlock_t *rwlock = NULL; + SV *rwlock_sv; + (void)apr_thread_rwlock_create(&rwlock, p); + rwlock_sv = sv_setref_pv(newSV(0), "APR::ThreadRWLock", (void*)rwlock); + mpxs_add_pool_magic(rwlock_sv, p_sv); + return rwlock_sv; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/URI/APR__URI.h b/2_0_13/xs/APR/URI/APR__URI.h new file mode 100644 index 0000000..59589aa --- /dev/null +++ b/2_0_13/xs/APR/URI/APR__URI.h
@@ -0,0 +1,102 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +char *mpxs_apr_uri_unparse(pTHX_ + apr_uri_t *uptr, + unsigned flags) +{ + + /* apr =< 0.9.2-dev segfaults if hostname is set, but scheme is not. + * apr >= 0.9.2 simply uses "", which will force the user to set scheme + * since apr_uri_unparse is protocol-agnostic, it doesn't use + * 'http' as the default fallback anymore. so we use the same solution + */ +#if APR_MAJOR_VERSION == 0 && APR_MINOR_VERSION == 9 && \ + (APR_PATCH_VERSION < 2 || APR_PATCH_VERSION == 2 && defined APR_IS_DEV_VERSION) + if (uptr->hostname && !uptr->scheme) { + uptr->scheme = ""; + } +#endif + + return apr_uri_unparse(((modperl_uri_t *)uptr)->pool, + uptr, flags); +} + +static MP_INLINE +SV *mpxs_apr_uri_parse(pTHX_ SV *classname, SV *p_sv, const char *uri_string) +{ + SV *uri_sv; + apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv); + modperl_uri_t *uri = modperl_uri_new(p); + + (void)apr_uri_parse(p, uri_string, &uri->uri); + + uri_sv = sv_setref_pv(newSV(0), "APR::URI", (void*)uri); + mpxs_add_pool_magic(uri_sv, p_sv); + + return uri_sv; +} + +static MP_INLINE +char *mpxs_APR__URI_port(pTHX_ apr_uri_t *uri, SV *portsv) +{ + char *port_str = uri->port_str; + + if (portsv) { + if (SvOK(portsv)) { + STRLEN len; + char *port = SvPV(portsv, len); + uri->port_str = apr_pstrndup(((modperl_uri_t *)uri)->pool, + port, len); + uri->port = (int)SvIV(portsv); + } + else { + uri->port_str = NULL; + uri->port = 0; + } + } + + return port_str; +} + +static MP_INLINE +SV *mpxs_APR__URI_rpath(pTHX_ apr_uri_t *apr_uri) +{ + modperl_uri_t *uri = (modperl_uri_t *)apr_uri; + + if (uri->path_info) { + int uri_len = strlen(uri->uri.path); + int n = strlen(uri->path_info); + int set = uri_len - n; + if (set > 0) { + return newSVpv(uri->uri.path, set); + } + } + else { + if (uri->uri.path) { + return newSVpv(uri->uri.path, 0); + } + } + return (SV *)NULL; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/UUID/APR__UUID.h b/2_0_13/xs/APR/UUID/APR__UUID.h new file mode 100644 index 0000000..db29a69 --- /dev/null +++ b/2_0_13/xs/APR/UUID/APR__UUID.h
@@ -0,0 +1,58 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define mpxs_apr_uuid_alloc() \ +(apr_uuid_t *)safemalloc(sizeof(apr_uuid_t)) + +static MP_INLINE apr_uuid_t *mpxs_apr_uuid_get(pTHX_ SV *CLASS) +{ + apr_uuid_t *uuid = mpxs_apr_uuid_alloc(); + apr_uuid_get(uuid); + return uuid; +} + +static MP_INLINE void mp_apr_uuid_format(pTHX_ SV *sv, SV *obj) +{ + apr_uuid_t *uuid = mp_xs_sv2_uuid(obj); + mpxs_sv_grow(sv, APR_UUID_FORMATTED_LENGTH); + apr_uuid_format(SvPVX(sv), uuid); + mpxs_sv_cur_set(sv, APR_UUID_FORMATTED_LENGTH); +} + +static MP_INLINE apr_uuid_t *mpxs_apr_uuid_parse(pTHX_ SV *CLASS, char *buf) +{ + apr_uuid_t *uuid = mpxs_apr_uuid_alloc(); + apr_uuid_parse(uuid, buf); + return uuid; +} + +MP_STATIC XS(MPXS_apr_uuid_format) +{ + dXSARGS; + + mpxs_usage_items_1("uuid"); + + mpxs_set_targ(mp_apr_uuid_format, ST(0)); +} + +#define apr_uuid_DESTROY(uuid) safefree(uuid) + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/Util/APR__Util.h b/2_0_13/xs/APR/Util/APR__Util.h new file mode 100644 index 0000000..e51aa7e --- /dev/null +++ b/2_0_13/xs/APR/Util/APR__Util.h
@@ -0,0 +1,28 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE int mpxs_apr_password_validate(pTHX_ const char *passwd, + const char *hash) +{ + return apr_password_validate(passwd, hash) == APR_SUCCESS; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/APR/aprext/Makefile.PL b/2_0_13/xs/APR/aprext/Makefile.PL new file mode 100644 index 0000000..ccf1731 --- /dev/null +++ b/2_0_13/xs/APR/aprext/Makefile.PL
@@ -0,0 +1,60 @@ +use strict; +use warnings; + +use lib qw(../lib); +use ModPerl::BuildMM (); +require ModPerl::Code; +use Apache2::Build (); + +my $build = ModPerl::BuildMM::build_config(); + +my $srcdir = '../../../src/modules/perl'; +my @names = ModPerl::Code::src_apr_ext(); + +my(@obj, @clean, %src); +for (@names) { + push @obj, join '.', $_, 'o'; + my $cfile = join '.', $_, 'c'; + push @clean, $cfile; + $src{$cfile} = "$srcdir/$cfile"; +} + +push @obj, q{modperl_dummy.o}; + +my @skip = qw(dynamic test); +push @skip, q{static} + unless (Apache2::Build::BUILD_APREXT); + +my %args = (NAME => 'lib' . $build->{MP_APR_LIB}, + VERSION_FROM => '../APR/APR.pm', + SKIP => [ @skip ] , + LINKTYPE => 'static', + OBJECT => "@obj", + clean => { FILES => "@clean" }, + ); + +my $ccopts = $build->ccopts; + +# avoid referencing &perl_module outside of mod_perl +$ccopts .= ' -DMP_IN_XS'; + +$args{CCFLAGS} = $ccopts; + +ModPerl::BuildMM::WriteMakefile(%args); + +# avoid redefined warnings from imported postamble symbol from +# elsewhere in other Makefile.PL files +no warnings 'redefine'; +sub MY::postamble { + my $self = shift; + my $string = $self->ModPerl::BuildMM::MY::postamble; + + $string .= join '', map { + "$_: $src{$_}\n\t\$(CP) $src{$_} .\n"; + } sort keys %src; + + # BSD make needs an empty target, even if the target is specified in .PHONY + $string .= "\ndynamic ::\n"; + + return $string; +}
diff --git a/2_0_13/xs/APR/aprext/modperl_dummy.c b/2_0_13/xs/APR/aprext/modperl_dummy.c new file mode 100644 index 0000000..8e936cb --- /dev/null +++ b/2_0_13/xs/APR/aprext/modperl_dummy.c
@@ -0,0 +1,36 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" + +/* FIXME: These functions are called from modperl_trace() in libaprext.lib + * but are normally defined in mod_perl.c which can't be included. + */ + +int modperl_is_running(void) +{ + return 0; +} + +int modperl_threads_started(void) +{ + return 0; +} + +int modperl_threaded_mpm(void) +{ + return 0; +}
diff --git a/2_0_13/xs/Apache2/Access/Apache2__Access.h b/2_0_13/xs/Apache2/Access/Apache2__Access.h new file mode 100644 index 0000000..fe0759e --- /dev/null +++ b/2_0_13/xs/Apache2/Access/Apache2__Access.h
@@ -0,0 +1,175 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE SV *mpxs_ap_requires(pTHX_ request_rec *r) +{ + AV *av; + HV *hv; + register int x; + const apr_array_header_t *reqs_arr = +#if AP_SERVER_MAJORVERSION_NUMBER>2 || AP_SERVER_MINORVERSION_NUMBER>=3 + 0; +#else + ap_requires(r); +#endif + require_line *reqs; + + if (!reqs_arr) { + return &PL_sv_undef; + } + + reqs = (require_line *)reqs_arr->elts; + av = newAV(); + + for (x=0; x < reqs_arr->nelts; x++) { + /* XXX should we do this or let PerlAuthzHandler? */ + if (! (reqs[x].method_mask & (1 << r->method_number))) { + continue; + } + + hv = newHV(); + + (void)hv_store(hv, "method_mask", 11, + newSViv((IV)reqs[x].method_mask), 0); + + (void)hv_store(hv, "requirement", 11, + newSVpv(reqs[x].requirement,0), 0); + + av_push(av, newRV_noinc((SV*)hv)); + } + + return newRV_noinc((SV*)av); +} + +static MP_INLINE +void mpxs_ap_allow_methods(pTHX_ I32 items, SV **MARK, SV **SP) +{ + request_rec *r; + SV *reset; + + mpxs_usage_va_2(r, reset, "$r->allow_methods(reset, ...)"); + + if (SvIV(reset)) { + ap_clear_method_list(r->allowed_methods); + } + + while (MARK <= SP) { + STRLEN n_a; + char *method = SvPV(*MARK, n_a); + ap_method_list_add(r->allowed_methods, method); + MARK++; + } +} + +static MP_INLINE void mpxs_insert_auth_cfg(pTHX_ request_rec *r, + char *directive, + char *val) +{ + const char *errmsg; + AV *config = newAV(); + + av_push(config, Perl_newSVpvf(aTHX_ "%s %s", directive, val)); + + errmsg = + modperl_config_insert_request(aTHX_ r, + newRV_noinc((SV*)config), + OR_AUTHCFG, NULL, + MP_HTTPD_OVERRIDE_OPTS_UNSET); + + if (errmsg) { + Perl_warn(aTHX_ "Can't change %s to '%s'\n", directive, val); + } + + SvREFCNT_dec((SV*)config); +} + +static MP_INLINE +const char *mpxs_Apache2__RequestRec_auth_type(pTHX_ request_rec *r, + char *type) +{ + const char *ret = NULL; + + if (type) { + mpxs_insert_auth_cfg(aTHX_ r, "AuthType", type); + } + + ret = ap_auth_type(r); + if (!ret) { + return "none"; + } + + return ret; +} + +static MP_INLINE +const char *mpxs_Apache2__RequestRec_auth_name(pTHX_ request_rec *r, + char *name) +{ + if (name) { + mpxs_insert_auth_cfg(aTHX_ r, "AuthName", name); + } + + return ap_auth_name(r); +} + +MP_STATIC XS(MPXS_ap_get_basic_auth_pw) +{ + dXSARGS; + request_rec *r; + const char *sent_pw = NULL; + int rc; + + mpxs_usage_items_1("r"); + + mpxs_PPCODE({ + r = mp_xs_sv2_r(ST(0)); + + /* Default auth-type to Basic */ + if (!ap_auth_type(r)) { + mpxs_Apache2__RequestRec_auth_type(aTHX_ r, "Basic"); + } + + rc = ap_get_basic_auth_pw(r, &sent_pw); + + EXTEND(SP, 2); + PUSHs_mortal_iv(rc); + if (rc == OK) { + PUSHs_mortal_pv(sent_pw); + } + else { + PUSHs(&PL_sv_undef); + } + }); +} + +static MP_INLINE +int mpxs_Apache2__RequestRec_allow_override_opts(pTHX_ request_rec *r) +{ +#ifdef MP_HTTPD_HAS_OVERRIDE_OPTS + core_dir_config *cfg = ap_get_module_config(r->per_dir_config, + &core_module); + return cfg->override_opts; +#else + return MP_HTTPD_OVERRIDE_OPTS_DEFAULT; +#endif +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/CmdParms/Apache2__CmdParms.h b/2_0_13/xs/Apache2/CmdParms/Apache2__CmdParms.h new file mode 100644 index 0000000..66497f2 --- /dev/null +++ b/2_0_13/xs/Apache2/CmdParms/Apache2__CmdParms.h
@@ -0,0 +1,55 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modperl_module.h" + +static MP_INLINE +SV *mpxs_Apache2__CmdParms_info(pTHX_ cmd_parms *parms) +{ + const char *data = ((modperl_module_cmd_data_t *)parms->info)->cmd_data; + + if (data) { + return newSVpv(data, 0); + } + + return &PL_sv_undef; +} + +static MP_INLINE +void mpxs_Apache2__CmdParms_add_config(pTHX_ cmd_parms *parms, SV *lines) +{ + const char *errmsg = modperl_config_insert_parms(aTHX_ parms, lines); + if (errmsg) { + Perl_croak(aTHX_ "$parms->add_config() has failed: %s", errmsg); + } +} + +static MP_INLINE +int mpxs_Apache2__CmdParms_override_opts(pTHX_ cmd_parms *parms) +{ +#ifdef MP_HTTPD_HAS_OVERRIDE_OPTS + return parms->override_opts; +#else + return MP_HTTPD_OVERRIDE_OPTS_DEFAULT; +#endif +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/Command/Apache2__Command.h b/2_0_13/xs/Apache2/Command/Apache2__Command.h new file mode 100644 index 0000000..9527d77 --- /dev/null +++ b/2_0_13/xs/Apache2/Command/Apache2__Command.h
@@ -0,0 +1,25 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define mpxs_Apache2__Command_next(cmd) \ +(++cmd, ((cmd && cmd->name) ? cmd : NULL)) + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/Connection/Apache2__Connection.h b/2_0_13/xs/Apache2/Connection/Apache2__Connection.h new file mode 100644 index 0000000..9cdb2cd --- /dev/null +++ b/2_0_13/xs/Apache2/Connection/Apache2__Connection.h
@@ -0,0 +1,49 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* backwards compat for c->keepalive (see ap_mmn.h) */ +#if MODULE_MAGIC_NUMBER < 20020625 +typedef int ap_conn_keepalive_e; +#endif + +static MP_INLINE +apr_socket_t *mpxs_Apache2__Connection_client_socket(pTHX_ conn_rec *c, + apr_socket_t *s) +{ + apr_socket_t *socket = + ap_get_module_config(c->conn_config, &core_module); + + if (s) { + ap_set_module_config(c->conn_config, &core_module, s); + } + + return socket; +} + +static MP_INLINE +const char *mpxs_Apache2__Connection_get_remote_host(pTHX_ conn_rec *c, + int type, + ap_conf_vector_t *dir_config) +{ + return ap_get_remote_host(c, (void *)dir_config, type, NULL); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h b/2_0_13/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h new file mode 100644 index 0000000..40e0c5f --- /dev/null +++ b/2_0_13/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h
@@ -0,0 +1,50 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +SV *mpxs_Apache2__Connection_pnotes(pTHX_ conn_rec *c, SV *key, SV *val) +{ + MP_dCCFG; + + modperl_config_con_init(c, ccfg); + + if (!ccfg) { + return &PL_sv_undef; + } + + return modperl_pnotes(aTHX_ &ccfg->pnotes, key, val, c->pool); +} + +static MP_INLINE +void mpxs_Apache2__Connection_pnotes_kill(pTHX_ conn_rec *c) +{ + MP_dCCFG; + + modperl_config_con_init(c, ccfg); + + if (!ccfg) { + return; + } + + modperl_pnotes_kill(&ccfg->pnotes); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/Const/Const.pm b/2_0_13/xs/Apache2/Const/Const.pm new file mode 100644 index 0000000..05b84c3 --- /dev/null +++ b/2_0_13/xs/Apache2/Const/Const.pm
@@ -0,0 +1,27 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache2::Const; + +use ModPerl::Const (); +use XSLoader (); + +our $VERSION = do { require mod_perl2; $mod_perl2::VERSION }; +our @ISA = qw(ModPerl::Const); + +XSLoader::load(__PACKAGE__, $VERSION); + +1;
diff --git a/2_0_13/xs/Apache2/Const/Const.xs b/2_0_13/xs/Apache2/Const/Const.xs new file mode 100644 index 0000000..5bfc153 --- /dev/null +++ b/2_0_13/xs/Apache2/Const/Const.xs
@@ -0,0 +1,25 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" +#include "modperl_const.h" + +MODULE = Apache2::Const PACKAGE = Apache2::Const + +PROTOTYPES: disable + +BOOT: + MP_newModPerlConstXS("Apache2");
diff --git a/2_0_13/xs/Apache2/Const/Makefile.PL b/2_0_13/xs/Apache2/Const/Makefile.PL new file mode 100644 index 0000000..895bd8e --- /dev/null +++ b/2_0_13/xs/Apache2/Const/Makefile.PL
@@ -0,0 +1,7 @@ +use lib qw(../lib); +use ModPerl::BuildMM (); + +ModPerl::BuildMM::WriteMakefile( + NAME => 'Apache2::Const', + VERSION_FROM => 'Const.pm', +);
diff --git a/2_0_13/xs/Apache2/Directive/Apache2__Directive.h b/2_0_13/xs/Apache2/Directive/Apache2__Directive.h new file mode 100644 index 0000000..2350e31 --- /dev/null +++ b/2_0_13/xs/Apache2/Directive/Apache2__Directive.h
@@ -0,0 +1,204 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define mpxs_Apache2__Directive_conftree() ap_conftree + +/* XXX: this is only useful for <Perl> at the moment */ +static MP_INLINE SV *mpxs_Apache2__Directive_as_string(pTHX_ + ap_directive_t *self) +{ + ap_directive_t *d; + SV *sv = newSVpv("", 0); + + for (d = self->first_child; d; d = d->next) { + sv_catpv(sv, d->directive); + sv_catpv(sv, " "); + sv_catpv(sv, d->args); + sv_catpv(sv, "\n"); + } + + return sv; +} + + +/* Adds an entry to a hash, vivifying hash/array for multiple entries */ +static void hash_insert(pTHX_ HV *hash, const char *key, + int keylen, const char *args, + int argslen, SV *value) +{ + HV *subhash; + AV *args_array; + SV **hash_ent = hv_fetch(hash, key, keylen, 0); + + if (value) { + if (!hash_ent) { + subhash = newHV(); + (void)hv_store(hash, key, keylen, newRV_noinc((SV *)subhash), 0); + } + else { + subhash = (HV *)SvRV(*hash_ent); + } + + (void)hv_store(subhash, args, argslen, value, 0); + } + else { + if (hash_ent) { + if (SvROK(*hash_ent) && (SVt_PVAV == SvTYPE(SvRV(*hash_ent)))) { + args_array = (AV *)SvRV(*hash_ent); + } + else { + args_array = newAV(); + av_push(args_array, newSVsv(*hash_ent)); + (void)hv_store(hash, key, keylen, + newRV_noinc((SV *)args_array), 0); + } + av_push(args_array, newSVpv(args, argslen)); + } + else { + (void)hv_store(hash, key, keylen, newSVpv(args, argslen), 0); + } + } +} + +static MP_INLINE SV *mpxs_Apache2__Directive_as_hash(pTHX_ + ap_directive_t *tree) +{ + const char *directive; + int directive_len; + const char *args; + int args_len; + + HV *hash = newHV(); + SV *subtree; + + while (tree) { + directive = tree->directive; + directive_len = strlen(directive); + args = tree->args; + args_len = strlen(args); + + if (tree->first_child) { + + /* Skip the prefix '<' */ + if ('<' == directive[0]) { + directive++; + directive_len--; + } + + /* Skip the postfix '>' */ + if ('>' == args[args_len-1]) { + args_len--; + } + + subtree = mpxs_Apache2__Directive_as_hash(aTHX_ tree->first_child); + hash_insert(aTHX_ hash, directive, directive_len, + args, args_len, subtree); + } + else { + hash_insert(aTHX_ hash, directive, directive_len, + args, args_len, (SV *)NULL); + } + + tree = tree->next; + } + + return newRV_noinc((SV *)hash); +} + +MP_STATIC XS(MPXS_Apache2__Directive_lookup) +{ + dXSARGS; + + if (items < 2 || items > 3) { + Perl_croak(aTHX_ + "Usage: Apache2::Directive::lookup(self, key, [args])"); + } + + mpxs_PPCODE({ + Apache2__Directive tree; + char *value; + const char *directive; + const char *args; + int args_len; + int directive_len; + + char *key = (char *)SvPV_nolen(ST(1)); + int scalar_context = (G_SCALAR == GIMME_V); + + if (SvROK(ST(0)) && sv_derived_from(ST(0), "Apache2::Directive")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + tree = INT2PTR(Apache2__Directive,tmp); + } + else { + tree = ap_conftree; + } + + if (items < 3) { + value = NULL; + } + else { + value = (char *)SvPV_nolen(ST(2)); + } + + while (tree) { + directive = tree->directive; + directive_len = strlen(directive); + + /* Remove starting '<' for container directives */ + if (directive[0] == '<') { + directive++; + directive_len--; + } + + if (0 == strncasecmp(directive, key, directive_len)) { + + if (value) { + args = tree->args; + args_len = strlen(args); + + /* Skip the postfix '>' */ + if ('>' == args[args_len-1]) { + args_len--; + } + + } + + if ( (!value) || (0 == strncasecmp(args, value, args_len)) ) { + if (tree->first_child) { + XPUSHs(sv_2mortal(mpxs_Apache2__Directive_as_hash( + aTHX_ tree->first_child))); + } + else { + XPUSHs(sv_2mortal(newSVpv(tree->args, 0))); + } + + if (scalar_context) { + break; + } + } + } + + tree = tree->next ? tree->next : NULL; + } + }); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/Filter/Apache2__Filter.h b/2_0_13/xs/Apache2/Filter/Apache2__Filter.h new file mode 100644 index 0000000..bc55137 --- /dev/null +++ b/2_0_13/xs/Apache2/Filter/Apache2__Filter.h
@@ -0,0 +1,376 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define mp_xs_sv2_modperl_filter(sv) \ + ((SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG)) \ + || (Perl_croak(aTHX_ "argument is not a blessed reference"),0) ? \ + modperl_filter_mg_get(aTHX_ sv) : NULL) + +#define mpxs_Apache2__Filter_TIEHANDLE(stashsv, sv) \ + modperl_newSVsv_obj(aTHX_ stashsv, sv) + +#define mpxs_Apache2__Filter_PRINT mpxs_Apache2__Filter_print + +static MP_INLINE apr_size_t mpxs_Apache2__Filter_print(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + modperl_filter_t *modperl_filter; + apr_size_t bytes = 0; + + mpxs_usage_va_1(modperl_filter, "$filter->print(...)"); + + MP_TRACE_f(MP_FUNC, "from %s", + ((modperl_filter_ctx_t *)modperl_filter->f->ctx)->handler->name); + if (modperl_filter->mode == MP_OUTPUT_FILTER_MODE) { + mpxs_write_loop(modperl_output_filter_write, + modperl_filter, "Apache2::Filter::print"); + } + else { + mpxs_write_loop(modperl_input_filter_write, + modperl_filter, "Apache2::Filter::print"); + } + + /* XXX: ap_rflush if $| */ + + return bytes; +} + +static MP_INLINE apr_size_t mpxs_Apache2__Filter_read(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + modperl_filter_t *modperl_filter; + apr_size_t wanted, len=0; + SV *buffer; + + mpxs_usage_va_2(modperl_filter, buffer, "$filter->read(buf, [len])"); + + MP_TRACE_f(MP_FUNC, "from %s", + ((modperl_filter_ctx_t *)modperl_filter->f->ctx)->handler->name); + + if (items > 2) { + wanted = SvIV(*MARK); + } + else { + wanted = MP_IOBUFSIZE; + } + + if (modperl_filter->mode == MP_INPUT_FILTER_MODE) { + /* XXX: if we ever will have a need to change the read + * discipline: (input_mode, block, readbytes) from the filter + * we can provide an accessor method to modify the values + * supplied by the filter chain */ + len = modperl_input_filter_read(aTHX_ modperl_filter, buffer, wanted); + } + else { + len = modperl_output_filter_read(aTHX_ modperl_filter, buffer, wanted); + } + + /* must run any set magic */ + SvSETMAGIC(buffer); + + SvTAINTED_on(buffer); + + return len; +} + +static MP_INLINE U16 *modperl_filter_attributes(pTHX_ SV *package, SV *cvrv) +{ + return modperl_code_attrs(aTHX_ (CV*)SvRV(cvrv)); +} + +#ifdef MP_TRACE +#define trace_attr() \ + MP_TRACE_f(MP_FUNC, "applied %s attribute to %s handler", attribute, \ + HvNAME(stash)) +#else +#define trace_attr() +#endif + +/* we can't eval at this stage, since the package is not compiled yet, + * we are still parsing the source. + */ +#define MODPERL_FILTER_ATTACH_ATTR_CODE(cv, string, len) \ + { \ + char *str; \ + len -= 2; /* s/ \( | \) //x */ \ + string++; /* skip the opening '(' */ \ + Newx(str, len+1, char); \ + Copy(string, str, len+1, char); \ + str[len] = '\0'; /* remove the closing ')' */ \ + sv_magic(cv, (SV *)NULL, '~', NULL, -1); \ + SvMAGIC(cv)->mg_ptr = str; \ + } + + +MP_STATIC XS(MPXS_modperl_filter_attributes) +{ + dXSARGS; + U16 *attrs = modperl_filter_attributes(aTHX_ ST(0), ST(1)); + I32 i; +#ifdef MP_TRACE + HV *stash = gv_stashsv(ST(0), TRUE); +#endif + + for (i=2; i < items; i++) { + STRLEN len; + char *pv = SvPV(ST(i), len); + char *attribute = pv; + + if (strnEQ(pv, "Filter", 6)) { + pv += 6; + } + + switch (*pv) { + case 'C': + if (strEQ(pv, "ConnectionHandler")) { + *attrs |= MP_FILTER_CONNECTION_HANDLER; + trace_attr(); + continue; + } + case 'I': + if (strEQ(pv, "InitHandler")) { + *attrs |= MP_FILTER_INIT_HANDLER; + trace_attr(); + continue; + } + case 'H': + if (strnEQ(pv, "HasInitHandler", 14)) { + STRLEN code_len; + pv += 14; /* skip over the attr name */ + code_len = len - (pv - attribute); + MODPERL_FILTER_ATTACH_ATTR_CODE(SvRV(ST(1)), pv, code_len); + *attrs |= MP_FILTER_HAS_INIT_HANDLER; + trace_attr(); + continue; + } + case 'R': + if (strEQ(pv, "RequestHandler")) { + *attrs |= MP_FILTER_REQUEST_HANDLER; + trace_attr(); + continue; + } + default: + /* XXX: there could be more than one attr to pass through */ + XPUSHs_mortal_pv(attribute); + XSRETURN(1); + } + } + + XSRETURN_EMPTY; +} + +static MP_INLINE SV *mpxs_Apache2__Filter_ctx(pTHX_ + ap_filter_t *filter, + SV *data) +{ + modperl_filter_ctx_t *ctx = (modperl_filter_ctx_t *)(filter->ctx); + + /* XXX: is it possible that the same filter, during a single + * request or connection cycle, will be invoked by different perl + * interpreters? if that happens we are in trouble, if we need to + * return an SV living in a different interpreter. may be there is + * a way to use one of the perl internal functions to clone an SV + * (and it can contain any references) + */ + + if (data != (SV *)NULL) { + if (ctx->data) { + if (SvOK(ctx->data) && SvREFCNT(ctx->data)) { + /* release the previously stored SV so we don't leak + * an SV */ + SvREFCNT_dec(ctx->data); + } + } + +#ifdef USE_ITHREADS + if (!ctx->interp) { + ctx->interp = modperl_thx_interp_get(aTHX); + MP_INTERP_REFCNT_inc(ctx->interp); + } +#endif + ctx->data = SvREFCNT_inc(data); + } + + return ctx->data ? SvREFCNT_inc(ctx->data) : &PL_sv_undef; +} + +static MP_INLINE SV *mpxs_Apache2__Filter_seen_eos(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + modperl_filter_t *modperl_filter; + + if ((items < 1) || (items > 2) || !(mpxs_sv2_obj(modperl_filter, *MARK))) { + Perl_croak(aTHX_ "usage: $filter->seen_eos([$set])"); + } + MARK++; + + if (items == 2) { + modperl_filter->seen_eos = SvTRUE(*MARK) ? 1 : 0; + } + + return modperl_filter->seen_eos ? &PL_sv_yes : &PL_sv_no; +} + +static MP_INLINE +void mpxs_Apache2__RequestRec_add_input_filter(pTHX_ request_rec *r, + SV *callback) +{ + + modperl_filter_runtime_add(aTHX_ r, + r->connection, + MP_FILTER_REQUEST_INPUT_NAME, + MP_INPUT_FILTER_MODE, + ap_add_input_filter, + callback, + "InputFilter"); +} + +static MP_INLINE +void mpxs_Apache2__RequestRec_add_output_filter(pTHX_ request_rec *r, + SV *callback) +{ + + modperl_filter_runtime_add(aTHX_ r, + r->connection, + MP_FILTER_REQUEST_OUTPUT_NAME, + MP_OUTPUT_FILTER_MODE, + ap_add_output_filter, + callback, + "OutputFilter"); +} + +static MP_INLINE +void mpxs_Apache2__Connection_add_input_filter(pTHX_ conn_rec *c, + SV *callback) +{ + + modperl_filter_runtime_add(aTHX_ NULL, + c, + MP_FILTER_CONNECTION_INPUT_NAME, + MP_INPUT_FILTER_MODE, + ap_add_input_filter, + callback, + "InputFilter"); +} + +static MP_INLINE +void mpxs_Apache2__Connection_add_output_filter(pTHX_ conn_rec *c, + SV *callback) +{ + + modperl_filter_runtime_add(aTHX_ NULL, + c, + MP_FILTER_CONNECTION_OUTPUT_NAME, + MP_OUTPUT_FILTER_MODE, + ap_add_output_filter, + callback, + "OutputFilter"); +} + +static MP_INLINE +void mpxs_Apache2__Filter_remove(pTHX_ I32 items, SV **MARK, SV **SP) +{ + modperl_filter_t *modperl_filter; + ap_filter_t *f; + + if (items < 1) { + Perl_croak(aTHX_ "usage: $filter->remove()"); + } + + modperl_filter = mp_xs_sv2_modperl_filter(*MARK); + + /* native filter */ + if (!modperl_filter) { + f = INT2PTR(ap_filter_t *, SvIV(SvRV(*MARK))); + MP_TRACE_f(MP_FUNC, + " %s\n\n\t non-modperl filter removes itself", + f->frec->name); + + /* the filter can reside in only one chain. hence we try to + * remove it from both, the input and output chains, since + * unfortunately we can't tell what kind of filter is that and + * whether the first call was successful + */ + ap_remove_input_filter(f); + ap_remove_output_filter(f); + return; + } + + f = modperl_filter->f; + + MP_TRACE_f(MP_FUNC, " %s\n\n\tfilter removes itself", + ((modperl_filter_ctx_t *)f->ctx)->handler->name); + + if (modperl_filter->mode == MP_INPUT_FILTER_MODE) { + ap_remove_input_filter(f); + } + else { + ap_remove_output_filter(f); + } +} + +static MP_INLINE +apr_status_t mpxs_Apache2__Filter_fflush(pTHX_ ap_filter_t *filter, + apr_bucket_brigade *brigade) +{ + apr_status_t rc = ap_fflush(filter, brigade); + /* if users don't bother to check the success, do it on their + * behalf */ + if (GIMME_V == G_VOID && rc != APR_SUCCESS) { + modperl_croak(aTHX_ rc, "Apache2::Filter::fflush"); + } + + return rc; +} + +static MP_INLINE +apr_status_t mpxs_Apache2__Filter_get_brigade(pTHX_ + ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes) +{ + apr_status_t rc = ap_get_brigade(f, bb, mode, block, readbytes); + /* if users don't bother to check the success, do it on their + * behalf */ + if (GIMME_V == G_VOID && rc != APR_SUCCESS) { + modperl_croak(aTHX_ rc, "Apache2::Filter::get_brigade"); + } + + return rc; +} + +static MP_INLINE +apr_status_t mpxs_Apache2__Filter_pass_brigade(pTHX_ ap_filter_t *f, + apr_bucket_brigade *bb) +{ + apr_status_t rc = ap_pass_brigade(f, bb); + /* if users don't bother to check the success, do it on their + * behalf */ + if (GIMME_V == G_VOID && rc != APR_SUCCESS) { + modperl_croak(aTHX_ rc, "Apache2::Filter::pass_brigade"); + } + + return rc; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/Log/Apache2__Log.h b/2_0_13/xs/Apache2/Log/Apache2__Log.h new file mode 100644 index 0000000..e3c558b --- /dev/null +++ b/2_0_13/xs/Apache2/Log/Apache2__Log.h
@@ -0,0 +1,347 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static void mpxs_Apache2__Log_BOOT(pTHX) +{ + av_push(get_av("Apache2::Log::Request::ISA", TRUE), + newSVpv("Apache2::Log", 12)); + av_push(get_av("Apache2::Log::Server::ISA", TRUE), + newSVpv("Apache2::Log", 12)); +} + +#define croak_inval_obj() \ + Perl_croak(aTHX_ "Argument is not an Apache2::RequestRec " \ + "or Apache2::ServerRec object") + +static void mpxs_ap_log_error(pTHX_ int level, SV *sv, SV *msg) +{ + char *file = NULL; + int line = 0; + char *str; + SV *svstr = (SV *)NULL; + STRLEN n_a; + int lmask = level & APLOG_LEVELMASK; + server_rec *s; + request_rec *r = NULL; + + if (SvROK(sv) && sv_isa(sv, "Apache2::Log::Request")) { + r = INT2PTR(request_rec *, SvObjIV(sv)); + s = r->server; + } + else if (SvROK(sv) && sv_isa(sv, "Apache2::Log::Server")) { + s = INT2PTR(server_rec *, SvObjIV(sv)); + } + else { + s = modperl_global_get_server_rec(); + } + + if ((lmask >= APLOG_DEBUG) && (mp_loglevel(s) >= APLOG_DEBUG)) { + COP *cop = PL_curcop; + file = CopFILE(cop); /* (caller)[1] */ + line = CopLINE(cop); /* (caller)[2] */ + } + + if ((mp_loglevel(s) >= lmask) && + SvROK(msg) && (SvTYPE(SvRV(msg)) == SVt_PVCV)) { + dSP; + ENTER;SAVETMPS; + PUSHMARK(sp); + (void)call_sv(msg, G_SCALAR); + SPAGAIN; + svstr = POPs; + (void)SvREFCNT_inc(svstr); + PUTBACK; + FREETMPS;LEAVE; + str = SvPV(svstr,n_a); + } + else { + str = SvPV(msg,n_a); + } + + if (r) { + ap_log_rerror(file, line, mp_module_index_ level, 0, r, + "%s", str); + } + else { + ap_log_error(file, line, mp_module_index_ level, 0, s, + "%s", str); + } + + if (svstr) { + SvREFCNT_dec(svstr); + } +} + +#define MP_LOG_REQUEST 1 +#define MP_LOG_SERVER 2 + +static SV *mpxs_Apache2__Log_log(pTHX_ SV *sv, int logtype) +{ + SV *svretval; + void *retval; + char *pclass; + + switch (logtype) { + case MP_LOG_REQUEST: + pclass = "Apache2::Log::Request"; + retval = (void *)modperl_sv2request_rec(aTHX_ sv); + break; + case MP_LOG_SERVER: + pclass = "Apache2::Log::Server"; + retval = (void *)modperl_sv2server_rec(aTHX_ sv); + break; + default: + croak_inval_obj(); + }; + + svretval = newSV(0); + sv_setref_pv(svretval, pclass, (void*)retval); + + return svretval; +} + +#define mpxs_Apache2__RequestRec_log(sv) \ + mpxs_Apache2__Log_log(aTHX_ sv, MP_LOG_REQUEST) + +#define mpxs_Apache2__ServerRec_log(sv) \ + mpxs_Apache2__Log_log(aTHX_ sv, MP_LOG_SERVER) + +static MP_INLINE SV *modperl_perl_do_join(pTHX_ SV **mark, SV **sp) +{ + SV *sv = newSV(0); + SV *delim; +#ifdef WIN32 + /* XXX: using PL_sv_no crashes on win32 with 5.6.1 */ + delim = newSVpv("", 0); +#else + delim = SvREFCNT_inc(&PL_sv_no); +#endif + + do_join(sv, delim, mark, sp); + + SvREFCNT_dec(delim); + + return sv; +} + +#define my_do_join(m, s) \ + modperl_perl_do_join(aTHX_ (m), (s)) + +MP_STATIC XS(MPXS_Apache2__Log_dispatch) +{ + dXSARGS; + SV *msgsv; + int level; + char *name = GvNAME(CvGV(cv)); + + if (items < 2) { + Perl_croak(aTHX_ "usage: %s::%s(obj, ...)", + mpxs_cv_name()); + } + + if (items > 2) { + msgsv = my_do_join(MARK+1, SP); + } + else { + msgsv = ST(1); + (void)SvREFCNT_inc(msgsv); + } + + switch (*name) { + case 'e': + if (*(name + 1) == 'r') { + level = APLOG_ERR; + break; + } + level = APLOG_EMERG; + break; + case 'w': + level = APLOG_WARNING; + break; + case 'n': + level = APLOG_NOTICE; + break; + case 'i': + level = APLOG_INFO; + break; + case 'd': + level = APLOG_DEBUG; + break; + case 'a': + level = APLOG_ALERT; + break; + case 'c': + level = APLOG_CRIT; + break; + default: + level = APLOG_ERR; /* should never get here */ + break; + }; + + mpxs_ap_log_error(aTHX_ level, ST(0), msgsv); + + SvREFCNT_dec(msgsv); + + XSRETURN_EMPTY; +} + +MP_STATIC XS(MPXS_Apache2__Log_LOG_MARK) +{ + dXSARGS; + ax = ax; /* -Wall */; + + mpxs_PPCODE({ + COP *cop = PL_curcop; + + if (items) { + Perl_croak(aTHX_ "usage %s::%s()", mpxs_cv_name()); + } + + EXTEND(SP, 2); + PUSHs_mortal_pv(CopFILE(cop)); + PUSHs_mortal_iv(CopLINE(cop)); + }); +} + +MP_STATIC XS(MPXS_Apache2__Log_log_xerror) +{ + dXSARGS; + SV *msgsv = (SV *)NULL; + STRLEN n_a; + request_rec *r = NULL; + server_rec *s = NULL; + char *msgstr; + const char *file; + int line, level; + apr_status_t status; + + if (items < 6) { + Perl_croak(aTHX_ "usage %s::%s(file, line, level, status, ...)", + mpxs_cv_name()); + } + + switch (*(GvNAME(CvGV(cv)) + 4)) { /* 4 == log_ */ + case 'r': + r = modperl_xs_sv2request_rec(aTHX_ ST(0), NULL, cv); + break; + case 's': + s = modperl_sv2server_rec(aTHX_ ST(0)); + break; + default: + croak_inval_obj(); + }; + + file = (const char *)SvPV(ST(1), n_a); + line = (int)SvIV(ST(2)); + level = (int)SvIV(ST(3)); + status = (apr_status_t)SvIV(ST(4)); + + if (items > 6) { + msgsv = my_do_join(MARK+5, SP); + } + else { + msgsv = ST(5); + (void)SvREFCNT_inc(msgsv); + } + + msgstr = SvPV(msgsv, n_a); + + if (r) { + ap_log_rerror(file, line, mp_module_index_ level, status, r, + "%s", msgstr); + } + else { + ap_log_error(file, line, mp_module_index_ level, status, s, + "%s", msgstr); + } + + SvREFCNT_dec(msgsv); + + XSRETURN_EMPTY; +} + +/* + * this function handles: + * $r->log_error + * $s->log_error + * $r->warn + * $s->warn + * Apache2::ServerRec::warn + */ +MP_STATIC XS(MPXS_Apache2__Log_log_error) +{ + dXSARGS; + request_rec *r = NULL; + server_rec *s = NULL; + int i = 0; + char *errstr = NULL; + SV *sv = (SV *)NULL; + STRLEN n_a; + + if (items > 1) { + if (sv_isa(ST(0), "Apache2::ServerRec")) { + s = INT2PTR(server_rec *, SvObjIV(ST(0))); + } + else if ((r = modperl_xs_sv2request_rec(aTHX_ ST(0), + "Apache2::RequestRec", cv))) { + s = r->server; + } + } + + if (s) { + i = 1; + } + else { + request_rec *r = NULL; + (void)modperl_tls_get_request_rec(&r); + if (r) { + s = r->server; + } + else { + s = modperl_global_get_server_rec(); + } + } + + if (items > 1+i) { + sv = my_do_join(MARK+i, SP); /* $sv = join '', @_[1..$#_] */ + errstr = SvPV(sv,n_a); + } + else { + errstr = SvPV(ST(i),n_a); + } + + switch (*GvNAME(CvGV(cv))) { + case 'w': + modperl_log_warn(s, errstr); + break; + default: + modperl_log_error(s, errstr); + break; + } + + if (sv) { + SvREFCNT_dec(sv); + } + + XSRETURN_EMPTY; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/MPM/Apache2__MPM.h b/2_0_13/xs/Apache2/MPM/Apache2__MPM.h new file mode 100644 index 0000000..9ede5f3 --- /dev/null +++ b/2_0_13/xs/Apache2/MPM/Apache2__MPM.h
@@ -0,0 +1,67 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE SV *mpxs_Apache2__MPM_query(pTHX_ SV *self, int query_code) +{ + int mpm_query_info; + + apr_status_t retval = ap_mpm_query(query_code, &mpm_query_info); + + if (retval == APR_SUCCESS) { + return newSViv(mpm_query_info); + } + + return &PL_sv_undef; +} + +static void mpxs_Apache2__MPM_BOOT(pTHX) +{ + /* implement Apache2::MPM->show and Apache2::MPM->is_threaded + * as constant subroutines, since this information will never + * change during an interpreter's lifetime */ + + int mpm_query_info; + + apr_status_t retval = ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_query_info); + + if (retval == APR_SUCCESS) { + MP_TRACE_g(MP_FUNC, "defined Apache2::MPM->is_threaded() as %i", + mpm_query_info); + + newCONSTSUB(PL_defstash, "Apache2::MPM::is_threaded", + newSViv(mpm_query_info)); + } + else { + /* assign false (0) to sub if ap_mpm_query didn't succeed */ + MP_TRACE_g(MP_FUNC, "defined Apache2::MPM->is_threaded() as 0"); + + newCONSTSUB(PL_defstash, "Apache2::MPM::is_threaded", + newSViv(0)); + } + + MP_TRACE_g(MP_FUNC, "defined Apache2::MPM->show() as %s", + ap_show_mpm()); + + newCONSTSUB(PL_defstash, "Apache2::MPM::show", + newSVpv(ap_show_mpm(), 0)); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/Makefile.PL b/2_0_13/xs/Apache2/Makefile.PL new file mode 100644 index 0000000..e662890 --- /dev/null +++ b/2_0_13/xs/Apache2/Makefile.PL
@@ -0,0 +1,7 @@ +use lib qw(../lib); +use ModPerl::BuildMM (); + +ModPerl::BuildMM::WriteMakefile( + NAME => "Apache2_build", + VERSION => '0.01' +);
diff --git a/2_0_13/xs/Apache2/Module/Apache2__Module.h b/2_0_13/xs/Apache2/Module/Apache2__Module.h new file mode 100644 index 0000000..f95b6b6 --- /dev/null +++ b/2_0_13/xs/Apache2/Module/Apache2__Module.h
@@ -0,0 +1,105 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define mpxs_Apache2__Module_top_module() ap_top_module + +static MP_INLINE int mpxs_Apache2__Module_loaded(pTHX_ char *name) +{ + char nameptr[256]; + char *base; + module *modp; + + /* Does the module name have a '.' in it ? */ + if ((base = ap_strchr(name, '.'))) { + int len = base - name; + + memcpy(nameptr, name, len); + memcpy(nameptr + len, ".c\0", 3); + + /* check if module is loaded */ + if (!(modp = ap_find_linked_module(nameptr))) { + return 0; + } + + if (*(base + 1) == 'c') { + return 1; + } + + /* if it ends in '.so', check if it was dynamically loaded */ + if ((strlen(base+1) == 2) && + (*(base + 1) == 's') && (*(base + 2) == 'o') && + modp->dynamic_load_handle) + { + return 1; + } + + return 0; + } + else { + return modperl_perl_module_loaded(aTHX_ name); + } +} + +static MP_INLINE SV *mpxs_Apache2__Module_get_config(pTHX_ + SV *pmodule, + server_rec *s, + ap_conf_vector_t *v) +{ + SV *obj = modperl_module_config_get_obj(aTHX_ pmodule, s, v); + + return SvREFCNT_inc(obj); +} + +static MP_INLINE +int mpxs_Apache2__Module_ap_api_major_version(pTHX_ module *mod) +{ + return mod->version; +} + +static MP_INLINE +int mpxs_Apache2__Module_ap_api_minor_version(pTHX_ module *mod) +{ + return mod->minor_version; +} + +static MP_INLINE void mpxs_Apache2__Module_add(pTHX_ + char *package, + SV *cmds) +{ + const char *error; + server_rec *s; + + if (!(SvROK(cmds) && (SvTYPE(SvRV(cmds)) == SVt_PVAV))) { + Perl_croak(aTHX_ "Usage: Apache2::Module::add(__PACKAGE__, [])"); + } + + s = modperl_global_get_server_rec(); + error = modperl_module_add(s->process->pconf, s, package, cmds); + + if (error) { + Perl_croak(aTHX_ "Apache2::Module::add(%s) failed : %s", + package, error); + } + + return; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/RequestIO/Apache2__RequestIO.h b/2_0_13/xs/Apache2/RequestIO/Apache2__RequestIO.h new file mode 100644 index 0000000..d477597 --- /dev/null +++ b/2_0_13/xs/Apache2/RequestIO/Apache2__RequestIO.h
@@ -0,0 +1,401 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 +/* win32 not happy with &PL_sv_no */ +# define SVNO newSViv(0) +# define SVYES newSViv(1) +#else +# define SVNO &PL_sv_no +# define SVYES &PL_sv_yes +#endif + +#define mpxs_Apache2__RequestRec_TIEHANDLE(stashsv, sv) \ +modperl_newSVsv_obj(aTHX_ stashsv, sv) + +#define mpxs_Apache2__RequestRec_PRINT mpxs_Apache2__RequestRec_print +#define mpxs_Apache2__RequestRec_PRINTF mpxs_ap_rprintf +#define mpxs_Apache2__RequestRec_BINMODE(r) \ + r ? SVYES : SVNO /* noop */ +#define mpxs_Apache2__RequestRec_CLOSE(r) \ + r ? SVYES : SVNO /* noop */ + +#define mpxs_Apache2__RequestRec_UNTIE(r, refcnt) \ + (r && refcnt) ? SVYES : SVNO /* noop */ + +#define mpxs_output_flush(r, rcfg, name) \ + /* if ($|) */ \ + if (IoFLUSH(PL_defoutgv)) { \ + MP_TRACE_o(MP_FUNC, "(flush) %d bytes [%s]", \ + rcfg->wbucket->outcnt, \ + apr_pstrmemdup(rcfg->wbucket->pool, rcfg->wbucket->outbuf, \ + rcfg->wbucket->outcnt)); \ + MP_RUN_CROAK(modperl_wbucket_flush(rcfg->wbucket, TRUE), \ + name); \ + } + +static MP_INLINE apr_size_t mpxs_ap_rvputs(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + modperl_config_req_t *rcfg; + apr_size_t bytes = 0; + request_rec *r; + dMP_TIMES; + + mpxs_usage_va_1(r, "$r->puts(...)"); + + rcfg = modperl_config_req_get(r); + + MP_START_TIMES(); + + MP_CHECK_WBUCKET_INIT("$r->puts"); + mpxs_write_loop(modperl_wbucket_write, rcfg->wbucket, + "Apache2::RequestIO::puts"); + + MP_END_TIMES(); + MP_PRINT_TIMES("r->puts"); + + /* we do not check $| for this method, + * only in the functions called by the tied interface + */ + + return bytes; +} + +static MP_INLINE +SV *mpxs_Apache2__RequestRec_print(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + modperl_config_req_t *rcfg; + request_rec *r; + + /* bytes must be called bytes */ + apr_size_t bytes = 0; + + /* this also magically assings to r ;-) */ + mpxs_usage_va_1(r, "$r->print(...)"); + + rcfg = modperl_config_req_get(r); + + MP_CHECK_WBUCKET_INIT("$r->print"); + mpxs_write_loop(modperl_wbucket_write, rcfg->wbucket, + "Apache2::RequestIO::print"); + + mpxs_output_flush(r, rcfg, "Apache2::RequestIO::print"); + + return bytes ? newSVuv(bytes) : newSVpvn("0E0", 3); +} + +static MP_INLINE +apr_size_t mpxs_ap_rprintf(pTHX_ I32 items, SV **MARK, SV **SP) +{ + modperl_config_req_t *rcfg; + request_rec *r; + apr_size_t bytes = 0; + SV *sv; + + mpxs_usage_va(2, r, "$r->printf($fmt, ...)"); + + rcfg = modperl_config_req_get(r); + + /* Reduce items by 1 since it otherwise includes the + * Apache2::RequestRec object, which shouldn't be included in the + * count of arguments being given to the sprintf() call. + */ + --items; + + /* XXX: we could have an rcfg->sprintf_buffer to reuse this SV + * across requests + */ + sv = sv_newmortal(); + modperl_perl_do_sprintf(aTHX_ sv, items, MARK); + bytes = SvCUR(sv); + + MP_CHECK_WBUCKET_INIT("$r->printf"); + + MP_TRACE_o(MP_FUNC, "%d bytes [%s]", bytes, SvPVX(sv)); + + MP_RUN_CROAK(modperl_wbucket_write(aTHX_ rcfg->wbucket, + SvPVX(sv), &bytes), + "Apache2::RequestIO::printf"); + + mpxs_output_flush(r, rcfg, "Apache2::RequestIO::printf"); + + return bytes; +} + +/* alias */ +#define mpxs_Apache2__RequestRec_WRITE(r, buffer, len, offset) \ + mpxs_Apache2__RequestRec_write(aTHX_ r, buffer, len, offset) + +static MP_INLINE +apr_size_t mpxs_Apache2__RequestRec_write(pTHX_ request_rec *r, + SV *buffer, apr_size_t len, + apr_off_t offset) +{ + apr_size_t wlen; + const char *buf; + STRLEN avail; + MP_dRCFG; + + buf = (const char *)SvPV(buffer, avail); + + if (len == -1) { + wlen = offset ? avail - offset : avail; + } + else { + wlen = len; + } + + MP_CHECK_WBUCKET_INIT("$r->write"); + MP_RUN_CROAK(modperl_wbucket_write(aTHX_ rcfg->wbucket, + buf+offset, &wlen), + "Apache2::RequestIO::write"); + + return wlen; +} + +static MP_INLINE +void mpxs_Apache2__RequestRec_rflush(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + modperl_config_req_t *rcfg; + request_rec *r; + + /* this also magically assings to r ;-) */ + mpxs_usage_va_1(r, "$r->rflush()"); + + rcfg = modperl_config_req_get(r); + + MP_CHECK_WBUCKET_INIT("$r->rflush"); + MP_TRACE_o(MP_FUNC, "%d bytes [%s]", + rcfg->wbucket->outcnt, + apr_pstrmemdup(rcfg->wbucket->pool, rcfg->wbucket->outbuf, + rcfg->wbucket->outcnt)); + MP_RUN_CROAK_RESET_OK(r->server, + modperl_wbucket_flush(rcfg->wbucket, TRUE), + "Apache2::RequestIO::rflush"); +} + +static MP_INLINE long mpxs_ap_get_client_block(pTHX_ request_rec *r, + SV *buffer, int bufsiz) +{ + long nrd = 0; + + mpxs_sv_grow(buffer, bufsiz); + + nrd = ap_get_client_block(r, SvPVX(buffer), bufsiz); + + if (nrd > 0) { + mpxs_sv_cur_set(buffer, nrd); + SvTAINTED_on(buffer); + } + else { + sv_setpvn(buffer, "", 0); + } + + /* must run any set magic */ + SvSETMAGIC(buffer); + + return nrd; +} + +static MP_INLINE +apr_status_t mpxs_setup_client_block(request_rec *r) +{ + if (!r->read_length) { + apr_status_t rc; + + /* only do this once per-request */ + if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "mod_perl: ap_setup_client_block failed: %d", rc); + return rc; + } + } + + return APR_SUCCESS; +} + +#define mpxs_should_client_block(r) \ + (r->read_length || ap_should_client_block(r)) + +#ifndef sv_setpvn_mg +# define sv_setpvn_mg sv_setpvn +#endif + +/* alias */ +#define mpxs_Apache2__RequestRec_READ(r, buffer, len, offset) \ + mpxs_Apache2__RequestRec_read(aTHX_ r, buffer, len, offset) + +static SV *mpxs_Apache2__RequestRec_read(pTHX_ request_rec *r, + SV *buffer, apr_size_t len, + apr_off_t offset) +{ + SSize_t total; + STRLEN blen; + + if (!SvOK(buffer)) { + sv_setpvn_mg(buffer, "", 0); + } + + (void)SvPV_force(buffer, blen); /* make it a valid PV */ + + if (len <= 0) { + Perl_croak(aTHX_ "The LENGTH argument can't be negative"); + } + + /* handle negative offset */ + if (offset < 0) { + if (-offset > (int)blen) Perl_croak(aTHX_ "Offset outside string"); + offset += blen; + } + + mpxs_sv_grow(buffer, len+offset); + + /* need to pad with \0 if offset > size of the buffer */ + if (offset > SvCUR(buffer)) { + Zero(SvEND(buffer), offset - SvCUR(buffer), char); + } + + total = modperl_request_read(aTHX_ r, SvPVX(buffer)+offset, len); + + /* modperl_request_read can return only >=0. So it's safe to do this. */ + /* if total==0 we need to set the buffer length in case it is larger */ + mpxs_sv_cur_set(buffer, offset+total); + + /* must run any set magic */ + SvSETMAGIC(buffer); + + SvTAINTED_on(buffer); + + return newSViv(total); +} + +static MP_INLINE +SV *mpxs_Apache2__RequestRec_GETC(pTHX_ request_rec *r) +{ + char c[1] = "\0"; + + /* XXX: reimplement similar to read() w/o using the deprecated + * client_block interface */ + if (mpxs_setup_client_block(r) == APR_SUCCESS) { + if (mpxs_should_client_block(r)) { + if (ap_get_client_block(r, c, 1) == 1) { + return newSVpvn((char *)&c, 1); + } + } + } + + return &PL_sv_undef; +} + +static MP_INLINE +int mpxs_Apache2__RequestRec_OPEN(pTHX_ SV *self, SV *arg1, SV *arg2) +{ + char *name; + STRLEN len; + SV *arg; + dHANDLE("STDOUT"); + + modperl_io_handle_untie(aTHX_ handle); /* untie *STDOUT */ + + if (arg2 && self) { + arg = newSVsv(arg1); + sv_catsv(arg, arg2); + } + else { + arg = arg1; + } + + name = SvPV(arg, len); + return do_open(handle, name, len, FALSE, O_RDONLY, 0, (PerlIO *)NULL); +} + +static MP_INLINE +int mpxs_Apache2__RequestRec_FILENO(pTHX_ request_rec *r) +{ + dHANDLE("STDOUT"); + return PerlIO_fileno(IoOFP(TIEHANDLE_SV(handle))); +} + +static MP_INLINE +apr_status_t mpxs_Apache2__RequestRec_sendfile(pTHX_ request_rec *r, + const char *filename, + apr_off_t offset, + apr_size_t len) +{ + apr_size_t nbytes; + apr_status_t rc; + apr_file_t *fp; + + rc = apr_file_open(&fp, filename, APR_READ|APR_BINARY, + APR_OS_DEFAULT, r->pool); + + if (rc != APR_SUCCESS) { + if (GIMME_V == G_VOID) { + modperl_croak(aTHX_ rc, + apr_psprintf(r->pool, + "Apache2::RequestIO::sendfile('%s')", + filename)); + } + else { + return rc; + } + } + + if (!len) { + apr_finfo_t finfo; + apr_file_info_get(&finfo, APR_FINFO_SIZE, fp); + len = finfo.size; + if (offset) { + len -= offset; + } + } + + /* flush any buffered modperl output */ + { + modperl_config_req_t *rcfg = modperl_config_req_get(r); + + MP_CHECK_WBUCKET_INIT("$r->rflush"); + if (rcfg->wbucket->outcnt) { + MP_TRACE_o(MP_FUNC, "flushing %d bytes [%s]", + rcfg->wbucket->outcnt, + apr_pstrmemdup(rcfg->wbucket->pool, + rcfg->wbucket->outbuf, + rcfg->wbucket->outcnt)); + MP_RUN_CROAK(modperl_wbucket_flush(rcfg->wbucket, TRUE), + "Apache2::RequestIO::sendfile"); + } + } + + rc = ap_send_fd(fp, r, offset, len, &nbytes); + + /* apr_file_close(fp); */ /* do not do this */ + + if (GIMME_V == G_VOID && rc != APR_SUCCESS) { + modperl_croak(aTHX_ rc, "Apache2::RequestIO::sendfile"); + } + + return rc; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/RequestRec/Apache2__RequestRec.h b/2_0_13/xs/Apache2/RequestRec/Apache2__RequestRec.h new file mode 100644 index 0000000..4a85481 --- /dev/null +++ b/2_0_13/xs/Apache2/RequestRec/Apache2__RequestRec.h
@@ -0,0 +1,155 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +const char *mpxs_Apache2__RequestRec_content_type(pTHX_ request_rec *r, + SV *type) +{ + const char *retval = r->content_type; + + if (type) { + MP_dRCFG; + STRLEN len; + const char *val = SvPV(type, len); + ap_set_content_type(r, apr_pmemdup(r->pool, val, len+1)); + MP_CGI_HEADER_PARSER_OFF(rcfg); + } + + return retval; +} + +static MP_INLINE +SV *mpxs_Apache2__RequestRec_content_languages(pTHX_ request_rec *r, + SV *languages) +{ + SV *retval = modperl_apr_array_header2avrv(aTHX_ + r->content_languages); + if (languages) { + r->content_languages = modperl_avrv2apr_array_header(aTHX_ + r->pool, + languages); + } + return retval; +} + +static MP_INLINE +int mpxs_Apache2__RequestRec_proxyreq(pTHX_ request_rec *r, SV *val) +{ + int retval = r->proxyreq; + + if (!val && !r->proxyreq && + r->parsed_uri.scheme && + !(r->parsed_uri.hostname && + strEQ(r->parsed_uri.scheme, ap_http_scheme(r)) && + ap_matches_request_vhost(r, r->parsed_uri.hostname, + r->parsed_uri.port_str ? + r->parsed_uri.port : + ap_default_port(r)))) + { + retval = r->proxyreq = PROXYREQ_PROXY; + r->uri = r->unparsed_uri; + /* else mod_proxy will segfault */ + r->filename = apr_pstrcat(r->pool, "modperl-proxy:", r->uri, NULL); + } + + if (val) { + r->proxyreq = SvIV(val); + } + + return retval; +} + +static MP_INLINE +SV *mpxs_Apache2__RequestRec_subprocess_env(pTHX_ request_rec *r, + char *key, SV *val) +{ + /* if called in a void context with no arguments, just + * populate %ENV and stop. + */ + if (key == NULL && GIMME_V == G_VOID) { + modperl_env_request_populate(aTHX_ r); + return &PL_sv_undef; + } + + return modperl_table_get_set(aTHX_ r->subprocess_env, + key, val, TRUE); +} + +static MP_INLINE +apr_finfo_t *mpxs_Apache2__RequestRec_finfo(pTHX_ request_rec *r, + apr_finfo_t *finfo) +{ + if (finfo) { + r->finfo = *finfo; + } + + return &r->finfo; +} + +static MP_INLINE +const char *mpxs_Apache2__RequestRec_handler(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + const char *RETVAL; + request_rec *r; + mpxs_usage_va_1(r, "$r->handler([$handler])"); + + RETVAL = (const char *)r->handler; + + if (items == 2) { + if (SvPOK(*MARK)) { + char *new_handler = SvPVX(*MARK); + /* once inside a response phase, one should not try to + * switch response handler types, since they won't take + * any affect */ + if (strEQ(modperl_callback_current_callback_get(), + "PerlResponseHandler")) { + + switch (*new_handler) { + case 'm': + if (strEQ(new_handler, "modperl") && + strEQ(RETVAL, "perl-script")) { + Perl_croak(aTHX_ "Can't switch from 'perl-script' " + "to 'modperl' response handler"); + } + break; + case 'p': + if (strEQ(new_handler, "perl-script") && + strEQ(RETVAL, "modperl")) { + Perl_croak(aTHX_ "Can't switch from 'modperl' " + "to 'perl-script' response handler"); + } + break; + } + } + + r->handler = (const char *)apr_pstrmemdup(r->pool, new_handler, + SvLEN(*MARK)); + } + else { + Perl_croak(aTHX_ "the new_handler argument must be a string"); + } + } + + return RETVAL; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/RequestUtil/Apache2__RequestUtil.h b/2_0_13/xs/Apache2/RequestUtil/Apache2__RequestUtil.h new file mode 100644 index 0000000..4433c88 --- /dev/null +++ b/2_0_13/xs/Apache2/RequestUtil/Apache2__RequestUtil.h
@@ -0,0 +1,421 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +int mpxs_Apache2__RequestRec_push_handlers(pTHX_ request_rec *r, + const char *name, + SV *sv) +{ + return modperl_handler_perl_add_handlers(aTHX_ + r, NULL, r->server, r->pool, + name, sv, + MP_HANDLER_ACTION_PUSH); + +} + +static MP_INLINE +int mpxs_Apache2__RequestRec_set_handlers(pTHX_ request_rec *r, + const char *name, + SV *sv) +{ + return modperl_handler_perl_add_handlers(aTHX_ + r, NULL, r->server, r->pool, + name, sv, + MP_HANDLER_ACTION_SET); +} + +static MP_INLINE +SV *mpxs_Apache2__RequestRec_get_handlers(pTHX_ request_rec *r, + const char *name) +{ + MpAV **handp = + modperl_handler_get_handlers(r, NULL, r->server, + r->pool, name, + MP_HANDLER_ACTION_GET); + + return modperl_handler_perl_get_handlers(aTHX_ handp, r->pool); +} + +/* + * XXX: these three should be part of the apache api + * for protocol module helpers + */ + +static MP_INLINE +SV *mpxs_Apache2__RequestRec_new(pTHX_ SV *classname, + conn_rec *c, + SV *base_pool_sv) +{ + apr_pool_t *p, *base_pool; + request_rec *r; + server_rec *s = c->base_server; + SV *r_sv; + + /* see: httpd-2.0/server/protocol.c:ap_read_request */ + + if (base_pool_sv) { + base_pool = mp_xs_sv2_APR__Pool(base_pool_sv); + } + else { + base_pool = c->pool; + } + + apr_pool_create(&p, base_pool); + r = apr_pcalloc(p, sizeof(request_rec)); + + r->pool = p; + r->connection = c; + r->server = s; + + r->request_time = apr_time_now(); + + r->user = NULL; + r->ap_auth_type = NULL; + + r->allowed_methods = ap_make_method_list(p, 1); + + r->headers_in = apr_table_make(p, 1); + r->subprocess_env = apr_table_make(r->pool, 1); + r->headers_out = apr_table_make(p, 1); + r->err_headers_out = apr_table_make(p, 1); + r->notes = apr_table_make(p, 1); + + r->request_config = ap_create_request_config(p); + + r->proto_output_filters = c->output_filters; + r->output_filters = r->proto_output_filters; + r->proto_input_filters = c->input_filters; + r->input_filters = r->proto_input_filters; + + ap_run_create_request(r); + + r->per_dir_config = s->lookup_defaults; + + r->sent_bodyct = 0; + r->read_length = 0; + r->read_body = REQUEST_NO_BODY; + r->status = HTTP_OK; + r->the_request = "UNKNOWN"; + + r->hostname = s->server_hostname; + + r->method = "GET"; + r->method_number = M_GET; + r->uri = "/"; + r->filename = (char *)ap_server_root_relative(p, r->uri); + + r->assbackwards = 1; + r->protocol = "UNKNOWN"; + + r_sv = sv_setref_pv(newSV(0), "Apache2::RequestRec", (void*)r); + + if (base_pool_sv) { + mpxs_add_pool_magic(r_sv, base_pool_sv); + } + + return r_sv; +} + +static MP_INLINE +request_rec *mpxs_Apache2__RequestUtil_request(pTHX_ SV *classname, SV *svr) +{ + /* ignore classname */ + return modperl_global_request(aTHX_ svr); +} + +static MP_INLINE +int mpxs_Apache2__RequestRec_location_merge(request_rec *r, + char *location) +{ + apr_pool_t *p = r->pool; + server_rec *s = r->server; + core_server_config *sconf = ap_get_module_config(s->module_config, + &core_module); + ap_conf_vector_t **sec = (ap_conf_vector_t **)sconf->sec_url->elts; + int num_sec = sconf->sec_url->nelts; + int i; + + for (i=0; i<num_sec; i++) { + core_dir_config *entry = + (core_dir_config *)ap_get_module_config(sec[i], + &core_module); + + if (strEQ(entry->d, location)) { + r->per_dir_config = + ap_merge_per_dir_configs(p, s->lookup_defaults, sec[i]); + return 1; + } + } + + return 0; +} + +static MP_INLINE +void mpxs_Apache2__RequestRec_set_basic_credentials(request_rec *r, + char *username, + char *password) +{ + char encoded[1024]; + int elen; + char *auth_value, *auth_cat; + + auth_cat = apr_pstrcat(r->pool, + username, ":", password, NULL); + elen = apr_base64_encode(encoded, auth_cat, strlen(auth_cat)); + encoded[elen] = '\0'; + + auth_value = apr_pstrcat(r->pool, "Basic ", encoded, NULL); + apr_table_setn(r->headers_in, "Authorization", auth_value); +} + + +static MP_INLINE +int mpxs_Apache2__RequestRec_no_cache(pTHX_ request_rec *r, SV *flag) +{ + int retval = r->no_cache; + + if (flag) { + r->no_cache = (int)SvIV(flag); + } + + if (r->no_cache) { + apr_table_setn(r->headers_out, "Pragma", "no-cache"); + apr_table_setn(r->headers_out, "Cache-control", "no-cache"); + } + else if (flag) { /* only unset if $r->no_cache(0) */ + apr_table_unset(r->headers_out, "Pragma"); + apr_table_unset(r->headers_out, "Cache-control"); + } + + return retval; +} + +static MP_INLINE +SV *mpxs_Apache2__RequestRec_pnotes(pTHX_ request_rec *r, SV *key, SV *val) +{ + MP_dRCFG; + + if (!rcfg) { + return &PL_sv_undef; + } + + return modperl_pnotes(aTHX_ &rcfg->pnotes, key, val, r->pool); +} + +static MP_INLINE +void mpxs_Apache2__RequestRec_pnotes_kill(pTHX_ request_rec *r) +{ + MP_dRCFG; + + if (!rcfg) { + return; + } + + modperl_pnotes_kill(&rcfg->pnotes); +} + +#define mpxs_Apache2__RequestRec_dir_config(r, key, sv_val) \ + modperl_dir_config(aTHX_ r, r->server, key, sv_val) + +#define mpxs_Apache2__RequestRec_slurp_filename(r, tainted) \ + modperl_slurp_filename(aTHX_ r, tainted) + +static MP_INLINE +char *mpxs_Apache2__RequestRec_location(request_rec *r) +{ + MP_dDCFG; + + return dcfg->location; +} + +typedef struct { + PerlInterpreter *perl; + SV *sv; +} sv_str_header_t; + +static int sv_str_header(void *arg, const char *k, const char *v) +{ + sv_str_header_t *svh = (sv_str_header_t *)arg; + dTHXa(svh->perl); + Perl_sv_catpvf(aTHX_ svh->sv, "%s: %s\n", k, v); + return 1; +} + +static MP_INLINE +SV *mpxs_Apache2__RequestRec_as_string(pTHX_ request_rec *r) +{ + sv_str_header_t svh; +#ifdef USE_ITHREADS + svh.perl = aTHX; +#endif + + svh.sv = newSVpv(r->the_request, 0); + + sv_catpvn(svh.sv, "\n", 1); + + apr_table_do((int (*) (void *, const char *, const char *)) + sv_str_header, (void *) &svh, r->headers_in, NULL); + + Perl_sv_catpvf(aTHX_ svh.sv, "\n%s %s\n", r->protocol, r->status_line); + + apr_table_do((int (*) (void *, const char *, const char *)) + sv_str_header, (void *) &svh, r->headers_out, NULL); + apr_table_do((int (*) (void *, const char *, const char *)) + sv_str_header, (void *) &svh, r->err_headers_out, NULL); + + sv_catpvn(svh.sv, "\n", 1); + + return svh.sv; +} + +static MP_INLINE +int mpxs_Apache2__RequestRec_is_perl_option_enabled(pTHX_ request_rec *r, + const char *name) +{ + return modperl_config_is_perl_option_enabled(aTHX_ r, r->server, name); +} + +static MP_INLINE +void mpxs_Apache2__RequestRec_add_config(pTHX_ request_rec *r, SV *lines, + int override, char *path, + int override_options) +{ + const char *errmsg = modperl_config_insert_request(aTHX_ r, lines, + override, path, + override_options); + if (errmsg) { + Perl_croak(aTHX_ "$r->add_config() has failed: %s", errmsg); + } +} + +/* in order to ensure that s->document_root doesn't get corrupted by + * modperl users setting its value, restore the original value at the + * end of each request */ +struct mp_docroot_info { + const char **docroot; + const char *original; +}; + +static apr_status_t restore_docroot(void *data) +{ + struct mp_docroot_info *di = (struct mp_docroot_info *)data; + *di->docroot = di->original; + return APR_SUCCESS; +} + +static MP_INLINE +const char *mpxs_Apache2__RequestRec_document_root(pTHX_ request_rec *r, + SV *new_root) +{ + const char *retval = ap_document_root(r); + + if (new_root) { + struct mp_docroot_info *di; + core_server_config *conf; + MP_CROAK_IF_THREADS_STARTED("setting $r->document_root"); + conf = ap_get_module_config(r->server->module_config, + &core_module); + di = apr_palloc(r->pool, sizeof *di); + di->docroot = &conf->ap_document_root; + di->original = conf->ap_document_root; + apr_pool_cleanup_register(r->pool, di, restore_docroot, + restore_docroot); + + conf->ap_document_root = apr_pstrdup(r->pool, SvPV_nolen(new_root)); + } + + return retval; +} + +static apr_status_t child_terminate(void *data) { + apr_pool_t *pool = (apr_pool_t *)data; + + /* On the first pass, re-register so we end up last */ + if (data) { + apr_pool_cleanup_register(pool, NULL, child_terminate, + apr_pool_cleanup_null); + } + else { + exit(0); + } + return APR_SUCCESS; +} + +static MP_INLINE +void mpxs_Apache2__RequestRec_child_terminate(pTHX_ request_rec *r) +{ + MP_CROAK_IF_THREADED_MPM("$r->child_terminate") + apr_pool_cleanup_register(r->pool, r->pool, child_terminate, + apr_pool_cleanup_null); +} + + + +static MP_INLINE +apr_status_t mpxs_ap_register_auth_provider(pTHX_ I32 items, SV **MARK, SV **SP) +{ + apr_pool_t *pool; + const char *provider_group; + const char *provider_name; + const char *provider_version; + SV *callback1; + SV *callback2 = NULL; + int type; + + if (items != 7) + Perl_croak(aTHX_ "pool, provider_group, provider_name, " + "provider_version, callback1, callback2, type"); + + if (SvROK(*MARK) && sv_derived_from(*MARK, "APR::Pool")) { + IV tmp = SvIV((SV*)SvRV(*MARK)); + if (tmp == 0) { + Perl_croak(aTHX_ "invalid pool object (already destroyed?)"); + } + pool = INT2PTR(APR__Pool, tmp); + } + else { + Perl_croak(aTHX_ SvROK(*MARK) ? + "pool is not of type APR::Pool" : + "pool is not a blessed reference"); + } + + MARK++; + provider_group = (const char *)SvPV_nolen(*MARK); + MARK++; + provider_name = (const char *)SvPV_nolen(*MARK); + MARK++; + provider_version = (const char *)SvPV_nolen(*MARK); + MARK++; + callback1 = newSVsv(*MARK); + MARK++; + callback2 = NULL; + if (SvROK(*MARK)) { + callback2 = newSVsv(*MARK); + } + MARK++; + type = (int)SvIV(*MARK); + + return modperl_register_auth_provider(pool, provider_group, provider_name, + provider_version, callback1, + callback2, type); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/Response/Apache2__Response.h b/2_0_13/xs/Apache2/Response/Apache2__Response.h new file mode 100644 index 0000000..6bd03be --- /dev/null +++ b/2_0_13/xs/Apache2/Response/Apache2__Response.h
@@ -0,0 +1,48 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* XXX: this should probably named $r->cgi_header_parse + * and send_cgi_header an alias in Apache2::compat + */ +#define mpxs_Apache2__RequestRec_send_cgi_header(r, sv) \ +{ \ + MP_dRCFG; \ + STRLEN len; \ + const char *bodytext; \ + MP_CGI_HEADER_PARSER_OFF(rcfg); \ + SvPV_force(sv, len); \ + modperl_cgi_header_parse(r, SvPVX(sv), (apr_size_t*)&len, &bodytext); \ + if (len) {\ + MP_CHECK_WBUCKET_INIT("$r->send_cgi_header"); \ + modperl_wbucket_write(aTHX_ rcfg->wbucket, bodytext, &len); \ + } \ +} + +static MP_INLINE void +mpxs_Apache2__RequestRec_set_last_modified(request_rec *r, apr_time_t mtime) +{ + if (mtime) { + ap_update_mtime(r, mtime); + } + ap_set_last_modified(r); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/ServerRec/Apache2__ServerRec.h b/2_0_13/xs/Apache2/ServerRec/Apache2__ServerRec.h new file mode 100644 index 0000000..91d944a --- /dev/null +++ b/2_0_13/xs/Apache2/ServerRec/Apache2__ServerRec.h
@@ -0,0 +1,32 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if AP_SERVER_MAJORVERSION_NUMBER>2 || AP_SERVER_MINORVERSION_NUMBER>=3 +#define loglevel log.level + +static MP_INLINE +int mpxs_Apache2__ServerRec_is_virtual(pTHX_ server_rec *s, SV *val) +{ + int retval = s->is_virtual; + + if (val) { + s->is_virtual = SvIV(val); + } + + return retval; +} + +#endif
diff --git a/2_0_13/xs/Apache2/ServerRec/ServerRec_pm b/2_0_13/xs/Apache2/ServerRec/ServerRec_pm new file mode 100644 index 0000000..5a606cc --- /dev/null +++ b/2_0_13/xs/Apache2/ServerRec/ServerRec_pm
@@ -0,0 +1,4 @@ +use Exporter (); +use Apache2::Log (); # Apache2::ServerRec::loads warn +@Apache2::ServerRec::EXPORT_OK = qw(warn); +*Apache2::ServerRec::import = \&Exporter::import;
diff --git a/2_0_13/xs/Apache2/ServerUtil/Apache2__ServerUtil.h b/2_0_13/xs/Apache2/ServerUtil/Apache2__ServerUtil.h new file mode 100644 index 0000000..f52ed0a --- /dev/null +++ b/2_0_13/xs/Apache2/ServerUtil/Apache2__ServerUtil.h
@@ -0,0 +1,227 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) +#include "unixd.h" +#endif + +#define mpxs_Apache2__ServerUtil_restart_count modperl_restart_count + +#define mpxs_Apache2__ServerRec_method_register(s, methname) \ + ap_method_register(s->process->pconf, methname); + +#define mpxs_Apache2__ServerRec_add_version_component(s, component) \ + ap_add_version_component(s->process->pconf, component); + +/* XXX: the mpxs_cleanup_t and mpxs_cleanup_run are almost dups with + * code in APR__Pool.h (minus interpr member which is not used + * here. They should be moved to modperl_common_util - the problem is + * modperl_interp_t *, which can't live in modperl_common_* since it + * creates a dependency on mod_perl. A possible solution is to use + * void * for that slot and cast it to modperl_interp_t * when used + */ + +typedef struct { + SV *cv; + SV *arg; + apr_pool_t *p; +#ifdef USE_ITHREADS + PerlInterpreter *perl; +#endif +} mpxs_cleanup2_t; + +/** + * callback wrapper for Perl cleanup subroutines + * @param data internal storage + */ +static apr_status_t mpxs_cleanup_run(void *data) +{ + int count; + mpxs_cleanup2_t *cdata = (mpxs_cleanup2_t *)data; +#ifdef USE_ITHREADS + dTHXa(cdata->perl); +#endif + dSP; +#ifdef USE_ITHREADS + PERL_SET_CONTEXT(aTHX); +#endif + + ENTER;SAVETMPS; + PUSHMARK(SP); + if (cdata->arg) { + XPUSHs(cdata->arg); + } + PUTBACK; + + save_gp(PL_errgv, 1); /* local *@ */ + count = call_sv(cdata->cv, G_SCALAR|G_EVAL); + + SPAGAIN; + + if (count == 1) { + (void)POPs; /* the return value is ignored */ + } + + if (SvTRUE(ERRSV)) { + Perl_warn(aTHX_ "Apache2::ServerUtil: cleanup died: %s", + SvPV_nolen(ERRSV)); + } + + PUTBACK; + FREETMPS;LEAVE; + + SvREFCNT_dec(cdata->cv); + if (cdata->arg) { + SvREFCNT_dec(cdata->arg); + } + + /* the return value is ignored by apr_pool_destroy anyway */ + return APR_SUCCESS; +} + +/* this cleanups registered by this function are run only by the + * parent interpreter */ +static MP_INLINE +void mpxs_Apache2__ServerUtil_server_shutdown_cleanup_register(pTHX_ SV *cv, + SV *arg) +{ + mpxs_cleanup2_t *data; + apr_pool_t *p; + + MP_CROAK_IF_POST_POST_CONFIG_PHASE("server_shutdown_cleanup_register"); + + p = modperl_server_user_pool(); + /* must use modperl_server_user_pool here to make sure that it's run + * before parent perl is destroyed */ + data = (mpxs_cleanup2_t *)apr_pcalloc(p, sizeof(*data)); + data->cv = SvREFCNT_inc(cv); + data->arg = arg ? SvREFCNT_inc(arg) : (SV *)NULL; + data->p = p; +#ifdef USE_ITHREADS + data->perl = aTHX; +#endif /* USE_ITHREADS */ + + apr_pool_cleanup_register(p, data, mpxs_cleanup_run, + apr_pool_cleanup_null); +} + +static MP_INLINE +int mpxs_Apache2__ServerRec_push_handlers(pTHX_ server_rec *s, + const char *name, + SV *sv) +{ + return modperl_handler_perl_add_handlers(aTHX_ + NULL, NULL, s, + s->process->pconf, + name, sv, + MP_HANDLER_ACTION_PUSH); + +} + +static MP_INLINE +int mpxs_Apache2__ServerRec_set_handlers(pTHX_ server_rec *s, + const char *name, + SV *sv) +{ + return modperl_handler_perl_add_handlers(aTHX_ + NULL, NULL, s, + s->process->pconf, + name, sv, + MP_HANDLER_ACTION_SET); +} + +static MP_INLINE +SV *mpxs_Apache2__ServerRec_get_handlers(pTHX_ server_rec *s, + const char *name) +{ + MpAV **handp = + modperl_handler_get_handlers(NULL, NULL, s, + s->process->pconf, name, + MP_HANDLER_ACTION_GET); + + return modperl_handler_perl_get_handlers(aTHX_ handp, + s->process->pconf); +} + +#define mpxs_Apache2__ServerRec_dir_config(s, key, sv_val) \ + modperl_dir_config(aTHX_ NULL, s, key, sv_val) + +#define mpxs_Apache2__ServerUtil_server(classname) modperl_global_get_server_rec() + +#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) +#define mpxs_Apache2__ServerUtil_user_id(classname) ap_unixd_config.user_id +#define mpxs_Apache2__ServerUtil_group_id(classname) ap_unixd_config.group_id +#else +#define mpxs_Apache2__ServerUtil_user_id(classname) 0 +#define mpxs_Apache2__ServerUtil_group_id(classname) 0 +#endif + +static MP_INLINE +int mpxs_Apache2__ServerRec_is_perl_option_enabled(pTHX_ server_rec *s, + const char *name) +{ + return modperl_config_is_perl_option_enabled(aTHX_ NULL, s, name); +} + + +static MP_INLINE +void mpxs_Apache2__ServerRec_add_config(pTHX_ server_rec *s, SV *lines) +{ + const char *errmsg; + + MP_CROAK_IF_POST_POST_CONFIG_PHASE("$s->add_config"); + + errmsg = modperl_config_insert_server(aTHX_ s, lines); + if (errmsg) { + Perl_croak(aTHX_ "$s->add_config() has failed: %s", errmsg); + } +} + +#define mpxs_Apache2__ServerRec_get_server_banner \ + ap_get_server_banner() +#define mpxs_Apache2__ServerRec_get_server_description \ + ap_get_server_description() +#define mpxs_Apache2__ServerRec_get_server_version \ + ap_get_server_version() + +static void mpxs_Apache2__ServerUtil_BOOT(pTHX) +{ + newCONSTSUB(PL_defstash, "Apache2::ServerUtil::server_root", + newSVpv(ap_server_root, 0)); + + newCONSTSUB(PL_defstash, "Apache2::ServerUtil::get_server_built", + newSVpv(ap_get_server_built(), 0)); +} + +#if AP_SERVER_MAJORVERSION_NUMBER>2 || \ + (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER>=3) +static MP_INLINE +int mpxs_Apache2__ServerRec_loglevel(pTHX_ server_rec *s, int loglevel) +{ + if (loglevel) { + s->log.level = loglevel; + } + + return s->log.level; +} +#endif + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/SubProcess/Apache2__SubProcess.h b/2_0_13/xs/Apache2/SubProcess/Apache2__SubProcess.h new file mode 100644 index 0000000..4db7d4a --- /dev/null +++ b/2_0_13/xs/Apache2/SubProcess/Apache2__SubProcess.h
@@ -0,0 +1,225 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "../../APR/PerlIO/modperl_apr_perlio.h" + +#ifndef MP_SOURCE_SCAN +#include "apr_optional.h" + +static APR_OPTIONAL_FN_TYPE(modperl_apr_perlio_apr_file_to_glob) *apr_file_to_glob; +#endif + +/* XXX: probably needs a lot more error checkings */ + +typedef struct { + apr_int32_t in_pipe; + apr_int32_t out_pipe; + apr_int32_t err_pipe; + apr_cmdtype_e cmd_type; +} exec_info; + +#undef FAILED /* win32 defines a macro with this name */ +#define FAILED(command) ((rc = command) != APR_SUCCESS) + +#define SET_TIMEOUT(fp) \ + apr_file_pipe_timeout_set(fp, \ + (int)(apr_time_from_sec(r->server->timeout))) + +static int modperl_spawn_proc_prog(pTHX_ + request_rec *r, + const char *command, + const char ***argv, + apr_file_t **script_in, + apr_file_t **script_out, + apr_file_t **script_err) +{ + exec_info e_info; + apr_pool_t *p; + const char * const *env; + + apr_procattr_t *procattr; + apr_proc_t *procnew; + apr_status_t rc = APR_SUCCESS; + + e_info.in_pipe = APR_CHILD_BLOCK; + e_info.out_pipe = APR_CHILD_BLOCK; + e_info.err_pipe = APR_CHILD_BLOCK; + e_info.cmd_type = APR_PROGRAM; + + p = r->main ? r->main->pool : r->pool; + + *script_out = *script_in = *script_err = NULL; + + env = (const char * const *)ap_create_environment(p, r->subprocess_env); + + if (FAILED(apr_procattr_create(&procattr, p)) || + FAILED(apr_procattr_io_set(procattr, e_info.in_pipe, + e_info.out_pipe, e_info.err_pipe)) || + FAILED(apr_procattr_dir_set(procattr, + ap_make_dirstr_parent(r->pool, + r->filename))) || + FAILED(apr_procattr_cmdtype_set(procattr, e_info.cmd_type))) + { + /* Something bad happened, tell the world. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, + "couldn't set child process attributes: %s", + r->filename); + return rc; + } + + procnew = apr_pcalloc(p, sizeof(*procnew)); + if (FAILED(ap_os_create_privileged_process(r, procnew, command, + *argv, env, procattr, p))) + { + /* Bad things happened. Everyone should have cleaned up. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, + "couldn't create child process: %d: %s", + rc, r->filename); + return rc; + } + + apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); + + if (!(*script_in = procnew->in)) { + Perl_croak(aTHX_ "broken program-in stream"); + return APR_EBADF; + } + SET_TIMEOUT(*script_in); + + if (!(*script_out = procnew->out)) { + Perl_croak(aTHX_ "broken program-out stream"); + return APR_EBADF; + } + SET_TIMEOUT(*script_out); + + if (!(*script_err = procnew->err)) { + Perl_croak(aTHX_ "broken program-err stream"); + return APR_EBADF; + } + SET_TIMEOUT(*script_err); + + return rc; +} + +#define PUSH_FILE_GLOB(fp, type) \ + PUSHs(apr_file_to_glob(aTHX_ fp, r->pool, type)) + +#define PUSH_FILE_GLOB_READ(fp) \ + PUSH_FILE_GLOB(fp, MODPERL_APR_PERLIO_HOOK_READ) + +#define PUSH_FILE_GLOB_WRITE(fp) \ + PUSH_FILE_GLOB(fp, MODPERL_APR_PERLIO_HOOK_WRITE) + +#define CLOSE_SCRIPT_STD(stream) \ + rc = apr_file_close(stream); \ + if (rc != APR_SUCCESS) { \ + XSRETURN_UNDEF; \ + } + +MP_STATIC XS(MPXS_modperl_spawn_proc_prog) +{ + dXSARGS; + const char *usage = "Usage: spawn_proc_prog($r, $command, [\\@argv])"; + + if (items < 2) { + Perl_croak(aTHX_ "%s", usage); + } + + SP -= items; + { + apr_file_t *script_in, *script_out, *script_err; + apr_status_t rc; + const char **argv; + int i=0; + AV *av_argv = (AV *)NULL; + I32 len=-1, av_items=0; + request_rec *r = modperl_xs_sv2request_rec(aTHX_ ST(0), NULL, cv); + const char *command = (const char *)SvPV_nolen(ST(1)); + + if (items == 3) { + if (SvROK(ST(2)) && SvTYPE(SvRV(ST(2))) == SVt_PVAV) { + av_argv = (AV*)SvRV(ST(2)); + len = AvFILLp(av_argv); + av_items = len+1; + } + else { + Perl_croak(aTHX_ "%s", usage); + } + } + + /* ap_os_create_privileged_process expects ARGV as char + * **argv, with terminating NULL and the program itself as a + * first item. + */ + argv = apr_palloc(r->pool, (av_items + 2) * sizeof(char *)); + argv[0] = command; + if (av_argv) { + for (i = 0; i <= len; i++) { + argv[i+1] = (const char *)SvPV_nolen(AvARRAY(av_argv)[i]); + } + } + argv[i+1] = NULL; +#if 0 + for (i=0; i<=len+2; i++) { + Perl_warn(aTHX_ "arg: %d %s\n", + i, argv[i] ? argv[i] : "NULL"); + } +#endif + rc = modperl_spawn_proc_prog(aTHX_ r, command, &argv, + &script_in, &script_out, + &script_err); + + if (rc == APR_SUCCESS) { + /* XXX: apr_file_to_glob should be set once in the BOOT: section */ + apr_file_to_glob = + APR_RETRIEVE_OPTIONAL_FN(modperl_apr_perlio_apr_file_to_glob); + + if (GIMME_V == G_VOID) { + CLOSE_SCRIPT_STD(script_in); + CLOSE_SCRIPT_STD(script_out); + CLOSE_SCRIPT_STD(script_err); + XSRETURN_EMPTY; + } + else if (GIMME_V == G_SCALAR) { + /* XXX: need to do lots of error checking before + * putting the object on the stack + */ + EXTEND(SP, 1); + PUSH_FILE_GLOB_READ(script_out); + CLOSE_SCRIPT_STD(script_in); + CLOSE_SCRIPT_STD(script_err); + } + else { + EXTEND(SP, 3); + PUSH_FILE_GLOB_WRITE(script_in); + PUSH_FILE_GLOB_READ(script_out); + PUSH_FILE_GLOB_READ(script_err); + } + } + else { + XSRETURN_UNDEF; + } + } + + PUTBACK; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/SubProcess/SubProcess_pm b/2_0_13/xs/Apache2/SubProcess/SubProcess_pm new file mode 100644 index 0000000..92da457 --- /dev/null +++ b/2_0_13/xs/Apache2/SubProcess/SubProcess_pm
@@ -0,0 +1 @@ +use APR::PerlIO ();
diff --git a/2_0_13/xs/Apache2/SubRequest/Apache2__SubRequest.h b/2_0_13/xs/Apache2/SubRequest/Apache2__SubRequest.h new file mode 100644 index 0000000..debfa70 --- /dev/null +++ b/2_0_13/xs/Apache2/SubRequest/Apache2__SubRequest.h
@@ -0,0 +1,40 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE int mpxs_ap_run_sub_req(pTHX_ request_rec *r) +{ + /* need to flush main request output buffer if any + * before running any subrequests, else we get subrequest + * output before anything already written in the main request + */ + + if (r->main) { + modperl_config_req_t *rcfg = modperl_config_req_get(r->main); + if (rcfg->wbucket) { + MP_RUN_CROAK(modperl_wbucket_flush(rcfg->wbucket, FALSE), + "Apache2::SubRequest::run"); + } + } + + return ap_run_sub_req(r); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/URI/Apache2__URI.h b/2_0_13/xs/Apache2/URI/Apache2__URI.h new file mode 100644 index 0000000..5c33c26 --- /dev/null +++ b/2_0_13/xs/Apache2/URI/Apache2__URI.h
@@ -0,0 +1,47 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +apr_uri_t *mpxs_Apache2__RequestRec_parsed_uri(request_rec *r) +{ + modperl_uri_t *uri = modperl_uri_new(r->pool); + + uri->uri = r->parsed_uri; + uri->path_info = r->path_info; + + return (apr_uri_t *)uri; +} + +static MP_INLINE char *mpxs_ap_unescape_url(pTHX_ SV *url) +{ + int status; + STRLEN n_a; + + (void)SvPV_force(url, n_a); + + if ((status = ap_unescape_url(SvPVX(url))) == OK) { + SvCUR_set(url, strlen(SvPVX(url))); + } + + return SvPVX(url); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Apache2/Util/Apache2__Util.h b/2_0_13/xs/Apache2/Util/Apache2__Util.h new file mode 100644 index 0000000..19220d0 --- /dev/null +++ b/2_0_13/xs/Apache2/Util/Apache2__Util.h
@@ -0,0 +1,25 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define TIME_NOW apr_time_now() +#define DEFAULT_TIME_FORMAT "%a, %d %b %Y %H:%M:%S %Z" + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/Makefile.PL b/2_0_13/xs/Makefile.PL new file mode 100644 index 0000000..d82becc --- /dev/null +++ b/2_0_13/xs/Makefile.PL
@@ -0,0 +1,7 @@ +use lib qw(../lib); +use ModPerl::BuildMM (); + +ModPerl::BuildMM::WriteMakefile( + NAME => "ModPerl::XS", + VERSION => '0.01' +);
diff --git a/2_0_13/xs/ModPerl/Const/Const.pm b/2_0_13/xs/ModPerl/Const/Const.pm new file mode 100644 index 0000000..2b9632d --- /dev/null +++ b/2_0_13/xs/ModPerl/Const/Const.pm
@@ -0,0 +1,56 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package ModPerl::Const; + +use DynaLoader (); + +our $VERSION = do { require mod_perl2; $mod_perl2::VERSION }; +our @ISA = qw(DynaLoader); + +#dlopen("Const.so", RTDL_GLOBAL); +#XXX: dl_dlopen.xs check isn't portable; works for hpux +# - on aix this is dl_aix.xs, and depending on release, RTDL_GLOBAL is +# available or not, e.g. 4.3 doesn't have it in the headers, while +# 5.1 does have it +# - from looking at ext/DynaLoader/dl_*.xs when 0x01 is used when it's +# not supported perl issues a warning and passes the right flag to dlopen +# - currently (patchlevel 18958) dl_aix.xs always issues a warning +# even when RTDL_GLOBAL is available, patch submitted to p5p +use Config (); +use constant DL_GLOBAL => + ( $Config::Config{dlsrc} eq 'dl_dlopen.xs' && $^O ne 'openbsd' ) ? 0x01 : 0x0; +sub dl_load_flags { DL_GLOBAL } + +#only bootstrap for use outside of mod_perl +unless (defined &ModPerl::Const::compile) { + __PACKAGE__->bootstrap($VERSION); +} + +sub import { + my $class = shift; + my $arg; + + if ($_[0] and $_[0] =~ /^-compile/) { + $arg = shift; #just compile the constants subs, export nothing + } + + $arg ||= scalar caller; #compile and export into caller's namespace + + $class->compile($arg, @_ ? @_ : ':common'); +} + +1;
diff --git a/2_0_13/xs/ModPerl/Const/Const.xs b/2_0_13/xs/ModPerl/Const/Const.xs new file mode 100644 index 0000000..85b0a32 --- /dev/null +++ b/2_0_13/xs/ModPerl/Const/Const.xs
@@ -0,0 +1,47 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mod_perl.h" +#include "modperl_const.h" + +#ifndef WIN32 +/* FIXME: To define extern perl_module to something so Const.so can be + * loaded later. Without this code, loading Const.so fails with + * undefined_symbol: perl_module. (Windows does not need this since it + * explicitly links against mod_perl.lib anyway.) + */ +module AP_MODULE_DECLARE_DATA perl_module = { + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + NULL, /* table of config file commands */ + NULL, /* register hooks */ +}; +#endif + +MODULE = ModPerl::Const PACKAGE = ModPerl::Const + +PROTOTYPES: disable + +BOOT: +#XXX: +#currently used just for {APR,Apache}/Const.{so,dll} to lookup +#XS_modperl_const_compile +#linking is fun. +newXS("ModPerl::Const::compile", XS_modperl_const_compile, __FILE__); +
diff --git a/2_0_13/xs/ModPerl/Const/Makefile.PL b/2_0_13/xs/ModPerl/Const/Makefile.PL new file mode 100644 index 0000000..a7a1838 --- /dev/null +++ b/2_0_13/xs/ModPerl/Const/Makefile.PL
@@ -0,0 +1,32 @@ +use lib qw(../lib); +use ModPerl::BuildMM (); + +my $srcdir = '../../../src/modules/perl'; +#link these two into Const.so so constants can be used outside of httpd +my @names = map { "modperl_$_" } qw(const constants); +my(@obj, @clean, %src); + +for (@names) { + push @obj, join '.', $_, 'o'; + my $cfile = join '.', $_, 'c'; + push @clean, $cfile; + $src{$cfile} = "$srcdir/$cfile"; +} + +ModPerl::BuildMM::WriteMakefile( + NAME => 'ModPerl::Const', + VERSION_FROM => 'Const.pm', + OBJECT => "Const.o @obj", + clean => { FILES => "@clean" }, +); + +sub MY::postamble { + my $self = shift; + my $string = $self->ModPerl::BuildMM::MY::postamble; + + $string .= join '', map { + "$_: $src{$_}\n\t\$(CP) $src{$_} .\n"; + } sort keys %src; + + return $string; +}
diff --git a/2_0_13/xs/ModPerl/Global/ModPerl__Global.h b/2_0_13/xs/ModPerl/Global/ModPerl__Global.h new file mode 100644 index 0000000..0d76ceb --- /dev/null +++ b/2_0_13/xs/ModPerl/Global/ModPerl__Global.h
@@ -0,0 +1,69 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +typedef void (*mpxs_special_list_do_t)(pTHX_ modperl_modglobal_key_t *, + const char *, I32); + +static int mpxs_special_list_do(pTHX_ const char *name, + SV *package, + mpxs_special_list_do_t func) +{ + STRLEN packlen; + char *packname; + modperl_modglobal_key_t *gkey = modperl_modglobal_lookup(aTHX_ name); + + if (!gkey) { + return FALSE; + } + + packname = SvPV(package, packlen); + + func(aTHX_ gkey, packname, packlen); + + return TRUE; +} + +static +MP_INLINE int mpxs_ModPerl__Global_special_list_call(pTHX_ const char *name, + SV *package) +{ + return mpxs_special_list_do(aTHX_ name, package, + modperl_perl_global_avcv_call); +} + +static +MP_INLINE int mpxs_ModPerl__Global_special_list_clear(pTHX_ const char *name, + SV *package) +{ + return mpxs_special_list_do(aTHX_ name, package, + modperl_perl_global_avcv_clear); +} + +static +MP_INLINE int mpxs_ModPerl__Global_special_list_register(pTHX_ + const char *name, + SV *package) +{ + return mpxs_special_list_do(aTHX_ name, package, + modperl_perl_global_avcv_register); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/ModPerl/Interpreter/ModPerl__Interpreter.h b/2_0_13/xs/ModPerl/Interpreter/ModPerl__Interpreter.h new file mode 100644 index 0000000..c3f735e --- /dev/null +++ b/2_0_13/xs/ModPerl/Interpreter/ModPerl__Interpreter.h
@@ -0,0 +1,28 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static MP_INLINE +modperl_interp_t *mpxs_ModPerl__Interpreter_current(pTHX_ SV *class) +{ + return modperl_thx_interp_get(aTHX); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/ModPerl/Makefile.PL b/2_0_13/xs/ModPerl/Makefile.PL new file mode 100644 index 0000000..1e7f50e --- /dev/null +++ b/2_0_13/xs/ModPerl/Makefile.PL
@@ -0,0 +1,7 @@ +use lib qw(../lib); +use ModPerl::BuildMM (); + +ModPerl::BuildMM::WriteMakefile( + NAME => "ModPerl", + VERSION => '0.01' +);
diff --git a/2_0_13/xs/ModPerl/Util/ModPerl__Util.h b/2_0_13/xs/ModPerl/Util/ModPerl__Util.h new file mode 100644 index 0000000..3e09070 --- /dev/null +++ b/2_0_13/xs/ModPerl/Util/ModPerl__Util.h
@@ -0,0 +1,49 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef USE_ITHREADS +#define mpxs_ModPerl__Util_current_perl_id() \ + Perl_newSVpvf(aTHX_ "0x%lx", (unsigned long)aTHX) +#else +#define mpxs_ModPerl__Util_current_perl_id() \ + Perl_newSVpvf(aTHX_ "0x%lx", (unsigned long)0) +#endif + +static MP_INLINE void mpxs_ModPerl__Util_untaint(pTHX_ I32 items, + SV **MARK, SV **SP) +{ + if (!PL_tainting) { + return; + } + while (MARK <= SP) { + sv_untaint(*MARK++); + } +} + +#define mpxs_ModPerl__Util_current_callback \ + modperl_callback_current_callback_get + +#define mpxs_ModPerl__Util_unload_package_xs(pkg) \ + modperl_package_unload(aTHX_ pkg) + +/* ModPerl::Util::exit lives in mod_perl.so, see modperl_perl.c */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/ModPerl/Util/Util_pm b/2_0_13/xs/ModPerl/Util/Util_pm new file mode 100644 index 0000000..365661e --- /dev/null +++ b/2_0_13/xs/ModPerl/Util/Util_pm
@@ -0,0 +1,63 @@ +#Extra stuff + +our $DEFAULT_UNLOAD_METHOD ||= "unload_package_pp"; + +sub unload_package { + goto &$DEFAULT_UNLOAD_METHOD; +} + +sub unload_package_pp { + my $package = shift; + no strict 'refs'; + my $tab = \%{ $package . '::' }; + + # below we assign to a symbol first before undef'ing it, to avoid + # nuking aliases. If we undef directly we may undef not only the + # alias but the original function as well + + for (keys %$tab) { + #Skip sub stashes + next if /::$/; + + my $fullname = join '::', $package, $_; + # code/hash/array/scalar might be imported make sure the gv + # does not point elsewhere before undefing each + if (%$fullname) { + *{$fullname} = {}; + undef %$fullname; + } + if (@$fullname) { + *{$fullname} = []; + undef @$fullname; + } + if ($$fullname) { + my $tmp; # argh, no such thing as an anonymous scalar + *{$fullname} = \$tmp; + undef $$fullname; + } + if (defined &$fullname) { + no warnings; + local $^W = 0; + if (defined(my $p = prototype $fullname)) { + *{$fullname} = eval "sub ($p) {}"; + } + else { + *{$fullname} = sub {}; + } + undef &$fullname; + } + if (*{$fullname}{IO}) { + local $@; + eval { + if (fileno $fullname) { + close $fullname; + } + }; + } + } + + #Wipe from %INC + $package =~ s[::][/]g; + $package .= '.pm'; + delete $INC{$package}; +}
diff --git a/2_0_13/xs/maps/apache2_functions.map b/2_0_13/xs/maps/apache2_functions.map new file mode 100644 index 0000000..1503ec7 --- /dev/null +++ b/2_0_13/xs/maps/apache2_functions.map
@@ -0,0 +1,568 @@ +########## Apache functions ########## + +#keywords: +# MODULE = the module name +# e.g. Apache2::Connection -> Apache2/Connection.{pm,xs} +# +# PACKAGE = the package name functions belong to, defaults to MODULE +# value of 'guess' indicates that package name should be +# guessed based on first argument found that maps to a Perl class +# fallsback on the prefix (ap_ -> Apache2, apr_ -> APR) +# +# PREFIX = prefix to be stripped +# defaults to PACKAGE, converted to C name convention, e.g. +# APR::Base64 -> apr_base64_ +# if the converted prefix does not match, defaults to ap_ or apr_ + +#format of entries: +# C function name | dispatch function name | argspec | Perl alias + +# dispatch function name defaults to C function name +# if the dispatch name is just a prefix (mpxs_, MPXS_) +# the C function name is appended to it +# the return type can be specified before the C function name, +# defaults to return_type in {Apache2,ModPerl}::FunctionTable + +# the argspec defaults to arguments in {Apache2,ModPerl}::FunctionTable +# argument types can be specified to override those in the FunctionTable +# default values can be specified, e.g. arg=default_value +# argspec of '...' indicates passthru, calling the function with +# (aTHX_ I32 items, SP **sp, SV **MARK) + +# the alias will be created in the current PACKAGE + +# function names that do not begin with /^\w/ are skipped +# for details see: %ModPerl::MapUtil::disabled_map +# in lib/ModPerl/MapUtil.pm + +MODULE=Apache2::RequestUtil + ap_get_status_line +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 + ap_register_auth_provider | mpxs_ | ... +#_end_ + +MODULE=Apache2::RequestUtil PACKAGE=guess + ap_psignature | | r, prefix +>ap_finalize_request_protocol +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } < 2003000 + ap_default_type +#_end_ + ap_get_server_name + ap_get_server_port +!ap_content_type_tolower + ap_is_initial_req +>ap_method_registry_init +>ap_process_request_internal +?ap_get_mime_headers +>ap_rgetline_core +?ap_get_request_note +?ap_register_request_note +~ap_set_content_type + +#MODULE=Apache2::RequestConfig +~ap_document_root + ap_get_limit_req_body +?ap_get_limit_xml_body +>ap_core_translate + +>MODULE=Apache2::Core + ap_basic_http_header + ap_http_filter + ap_send_http_options + ap_send_http_trace + ap_response_code_string + ap_add_file_conf + ap_add_per_dir_conf + ap_add_per_url_conf + ap_limit_section + ap_setup_make_content_type + +>MODULE=Apache2::Listen + ap_set_listenbacklog + ap_set_listener + ap_set_send_buffer_size + ap_setup_listeners + +MODULE=Apache2::SubRequest PACKAGE=Apache2::RequestRec +?ap_sub_req_output_filter +>ap_set_sub_req_protocol +-ap_finalize_sub_req_protocol + ap_internal_redirect | | r, new_uri + ap_internal_redirect_handler | | r, new_uri + ap_internal_fast_redirect | | r, sub_req + ap_sub_req_lookup_dirent | | r, finfo, subtype=AP_SUBREQ_NO_ARGS, next_filter=NULL | lookup_dirent + +subrequest_rec *:ap_sub_req_lookup_file | | \ + r, new_file, next_filter=r->proto_output_filters | lookup_file + +subrequest_rec *:ap_sub_req_lookup_uri | | \ + r, new_uri, next_filter=r->proto_output_filters | lookup_uri + +subrequest_rec *:ap_sub_req_method_uri | | \ + r, method, new_uri, next_filter=r->proto_output_filters | lookup_method_uri + +PACKAGE=Apache2::SubRequest ISA=Apache2::RequestRec + ap_destroy_sub_req | | r | DESTROY + ap_run_sub_req | mpxs_ | | run + +MODULE=Apache2::RequestIO PACKAGE=Apache2::RequestRec + ap_discard_request_body +!ap_getline + ap_get_client_block | mpxs_ | r, SV *:buffer, bufsiz + ap_setup_client_block | | r, read_policy=REQUEST_CHUNKED_ERROR + ap_should_client_block +PREFIX=ap_r +~ap_rwrite + ap_rprintf | mpxs_ | ... +!ap_rputc +~ap_rputs + ap_rvputs | mpxs_ | ... | puts +-ap_vrprintf + +MODULE=Apache2::Response PACKAGE=guess + ap_make_etag | | r, force_weak=0 + ap_set_content_length | | r, length=r->finfo.csize + ap_set_etag + ap_meets_conditions + ap_rationalize_mtime + ap_update_mtime | | r, dependency_mtime=0 + ap_send_error_response +~ap_send_fd + ap_send_mmap | | r, mm, offset, length + ap_set_keepalive +-ap_set_last_modified + ap_custom_response + +MODULE=Apache2::Access PACKAGE=Apache2::RequestRec + ap_allow_methods | mpxs_ | ... + ap_allow_options + ap_allow_overrides +!ap_allow_standard_methods + ap_get_remote_logname + SV *:ap_requires | mpxs_ + ap_satisfies + +#MODULE=Apache2::Auth + mpxs_Apache2__RequestRec_auth_name | | r, name=NULL + mpxs_Apache2__RequestRec_auth_type | | r, type=NULL + ap_get_basic_auth_pw | MPXS_ | r + ap_note_auth_failure + ap_note_basic_auth_failure + ap_note_digest_auth_failure + ap_some_auth_required + +!MODULE=Apache2::ScriptUtil PACKAGE=guess + ap_add_cgi_vars + ap_add_common_vars + ap_create_environment + ap_find_path_info +-ap_scan_script_header_err +-ap_scan_script_header_err_core +-ap_scan_script_header_err_strs +-ap_scan_script_header_err_brigade + +MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerRec BOOT=1 +~ap_method_register + int:DEFINE_method_register | | server_rec *:s, const char *:methname +~add_version_component + void:DEFINE_add_version_component | | server_rec *:s, const char *:component +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 + mpxs_Apache2__ServerRec_loglevel | | server_rec *:s, loglevel=0 +#_end_ + +MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerUtil + ap_exists_config_define + ap_server_root_relative | | p, fname="" + ap_get_server_banner + ap_get_server_description + ap_get_server_version + +MODULE=Apache2::ServerUtil PACKAGE=guess + ap_error_log2stderr +?ap_replace_stderr_log + +#MODULE=Apache2::ServerConfig +#XXX: thought this might be useful +#however it is not exported on win32 +!ap_get_local_host +~ap_get_server_built +~ap_server_root + + +MODULE=Apache2::Connection PACKAGE=guess +#XXX: thought this might be useful for protocol modules +#however it is not exported on win32 +!ap_read_request +>ap_update_vhost_given_ip + mpxs_Apache2__Connection_get_remote_host | | c, type=REMOTE_NAME, dir_config=NULL + +MODULE=Apache2::Log PACKAGE=guess +?ap_log_assert +~ap_log_error +-ap_log_perror +~ap_log_rerror +>ap_open_stderr_log +>ap_open_logs + +PACKAGE=Apache2::Log PREFIX=ap_ + ap_log_pid + +MODULE=Apache2::Module + module *:DEFINE_top_module +-ap_add_loaded_module +-ap_add_module +-ap_add_named_module + ap_find_linked_module +-ap_find_module_name +ap_remove_loaded_module +-ap_remove_module +>ap_single_module_configure +>ap_setup_prelinked_modules +>ap_show_directives +>ap_show_modules +>ap_register_hooks + mpxs_Apache2__Module_loaded + mpxs_Apache2__Module_add + #ap_get_module_config + mpxs_Apache2__Module_get_config | | pmodule, s, v=NULL + mpxs_Apache2__Module_ap_api_major_version + mpxs_Apache2__Module_ap_api_minor_version + +MODULE=Apache2::Directive + ap_directive_t *:DEFINE_conftree +!ap_add_node +!ap_build_config +!ap_build_cont_config +!ap_walk_config +>ap_process_config_tree + +MODULE=Apache2::Filter PACKAGE=guess +~ap_add_output_filter +~ap_add_input_filter +-ap_add_input_filter_handle +-ap_get_input_filter_handle +-ap_add_output_filter_handle +-ap_get_output_filter_handle +>ap_add_ouput_filters_by_type +~ap_get_brigade + mpxs_Apache2__Filter_get_brigade | | \ + f, bb, mode=AP_MODE_READBYTES, \ + block=APR_BLOCK_READ, \ + readbytes=8192 +~ap_pass_brigade + mpxs_Apache2__Filter_pass_brigade +!ap_register_input_filter +!ap_register_output_filter +-ap_remove_output_filter +-ap_remove_input_filter +!ap_save_brigade + ap_filter_flush +~ap_fflush + mpxs_Apache2__Filter_fflush +-ap_fputstrs +#int:DEFINE_ap_fputs | | \ +# ap_filter_t *:f, apr_bucket_brigade *:bb, const char *:str +-ap_fprintf +>ap_byterange_filter +>ap_http_header_filter +>ap_content_length_filter +>ap_old_write_filter + +!MODULE=Apache2::Bucket + ap_bucket_error_create + ap_bucket_error_make + +!MODULE=Apache2::Base64 + ap_pbase64decode + ap_pbase64encode + +!MODULE=Apache2::ConfigFile + ap_cfg_closefile + ap_cfg_getc + ap_cfg_getline + ap_pcfg_open_custom + ap_pcfg_openfile +>ap_read_config +>ap_merge_per_dir_configs +>ap_create_conn_config +>ap_parse_htaccess +>ap_process_resource_config + +MODULE=Apache2::Command + command_rec *:DEFINE_next | | command_rec *:cmd +-ap_soak_end_container +-ap_set_int_slot +-ap_set_file_slot +-ap_set_flag_slot +-ap_set_string_slot +-ap_set_string_slot_lower +-ap_set_deprecated + +MODULE=Apache2::Util + ap_ht_time | | p, t=TIME_NOW, fmt=DEFAULT_TIME_FORMAT, gmt=1 +!ap_rfc1413 +!ap_escape_html | | s, p + #escape_uri + ap_os_escape_path | | path, p, partial=TRUE | escape_path +!ap_explode_recent_gmt +!ap_explode_recent_localtime +!ap_recent_ctime +!ap_recent_rfc822_date + +MODULE=Apache2::URI PACKAGE=guess + ap_parse_uri + ap_construct_url | | r, uri=r->uri, p=r->pool + ap_construct_server | | r, hostname=ap_get_server_name(r), \ + port=ap_get_server_port(r), p=r->pool +PACKAGE=Apache2::URI + char *:ap_unescape_url | mpxs_ | SV *:url + +PACKAGE=Apache2::RequestRec + mpxs_Apache2__RequestRec_parsed_uri + +!MODULE=Apache2::StringUtil PACKAGE=guess + ap_count_dirs + ap_escape_path_segment + ap_escape_quotes + ap_escape_shell_cmd + ap_field_noparam + ap_find_last_token + ap_find_list_item + ap_find_token + ap_get_list_item + ap_size_list_item + ap_getparents + ap_get_token +-ap_getword +-ap_getword_conf +-ap_getword_conf_nc +-ap_getword_nc +-ap_getword_nulls +-ap_getword_nulls_nc +-ap_getword_white +-ap_getword_white_nc +-ap_ind +-ap_rind + ap_is_directory + ap_is_matchexp + ap_is_rdirectory + ap_is_url + ap_make_dirstr_parent + ap_make_dirstr_prefix + ap_make_full_path + ap_no2slash + ap_os_is_path_absolute + ap_resolve_env +-ap_strcasecmp_match +-ap_strcasestr +-ap_strcmp_match + ap_stripprefix +-ap_str_tolower + +!MODULE=Apache2::MethodList + ap_clear_method_list +-ap_copy_method_list + ap_make_method_list + ap_method_in_list + ap_method_list_add + ap_method_list_do + ap_method_list_remove + ap_method_list_vdo + ap_method_name_of + ap_method_number_of + +!MODULE=Apache2::PipedLog + ap_close_piped_log + ap_open_piped_log + +!MODULE=Apache2::Scoreboard + ap_exists_scoreboard_image +-ap_update_child_status +-ap_time_process_request +-ap_create_scoreboard + ap_cleanup_scoreboard + ap_increment_counts + ap_calc_scoreboard_size + ap_create_sb_handle + ap_get_scoreboard_global + ap_get_scoreboard_process + ap_get_scoreboard_worker +>ap_init_scoreboard +>ap_reopen_scoreboard + ap_update_child_status_from_indexes + +!MODULE=Apache2::Hooks + ap_location_walk + ap_directory_walk + ap_file_walk + ap_hook_access_checker + ap_hook_auth_checker + ap_hook_check_user_id + ap_hook_child_init +>ap_hook_create_connection +>ap_hook_get_create_connection + ap_hook_default_port + ap_hook_fixups + ap_hook_handler + ap_hook_header_parser + ap_hook_http_method + ap_hook_insert_filter + ap_hook_log_transaction + ap_hook_open_logs + ap_hook_optional_fn_retrieve + ap_hook_post_config + ap_hook_post_read_request + ap_hook_pre_config + ap_hook_pre_connection + ap_hook_process_connection + ap_hook_translate_name + ap_hook_type_checker +!ap_hook_quick_handler + ap_hook_map_to_storage + ap_hook_create_request + ap_hook_error_log +>ap_hook_pre_mpm +-ap_hook_get_suexec_identity +-ap_hook_get_access_checker +-ap_hook_get_auth_checker +-ap_hook_get_check_user_id +-ap_hook_get_child_init +-ap_hook_get_create_request +-ap_hook_get_default_port +-ap_hook_get_error_log +-ap_hook_get_fixups +-ap_hook_get_get_mgmt_items +-ap_hook_get_get_suexec_identity +-ap_hook_get_handler +-ap_hook_get_header_parser +-ap_hook_get_http_method +-ap_hook_get_insert_filter +-ap_hook_get_log_transaction +-ap_hook_get_map_to_storage +-ap_hook_get_mgmt_items +-ap_hook_get_open_logs +-ap_hook_get_optional_fn_retrieve +-ap_hook_get_post_config +-ap_hook_get_post_read_request +-ap_hook_get_pre_config +-ap_hook_get_pre_connection +-ap_hook_get_pre_mpm +-ap_hook_get_process_connection +-ap_hook_get_quick_handler +-ap_hook_get_translate_name +-ap_hook_get_type_checker + +MODULE=Apache2::HookRun PACKAGE=guess +-ap_run_get_suexec_identity +-ap_run_optional_fn_retrieve +>ap_run_pre_config +>ap_run_open_logs +>ap_run_post_config +>ap_run_insert_filter +>ap_run_child_init +?ap_run_default_port +?ap_run_http_method +>ap_run_create_connection +>ap_run_pre_connection +>ap_run_process_connection + ap_run_post_read_request + ap_run_translate_name + ap_run_header_parser + ap_run_access_checker + ap_run_check_user_id + ap_run_auth_checker + ap_run_type_checker + ap_run_fixups + ap_run_handler + ap_run_log_transaction +>ap_run_rewrite_args +?ap_run_create_request +>ap_run_error_log +>ap_run_get_mgmt_items + ap_run_map_to_storage +>ap_run_pre_mpm +!ap_run_quick_handler + ap_invoke_handler + ap_die | | r, type + +!MODULE=Apache2::MD5 + ap_md5 + ap_md5_binary + ap_md5contextTo64 + ap_md5digest + +-MODULE=Apache2::Regexp + ap_pregcomp + ap_pregfree + ap_pregsub + ap_regerror + ap_regexec + +!MODULE=Apache2::VHost +-ap_set_name_virtual_host +-ap_fini_vhost_config +-ap_init_vhost_config + ap_matches_request_vhost + ap_parse_vhost_addrs +-ap_update_vhost_from_headers +-ap_fixup_virtual_hosts + +!MODULE=Apache2::HTTPCore +>ap_process_request +>ap_make_content_type +>ap_core_reorder_directories +>ap_index_of_response + +!MODULE=Apache2::XML + ap_xml_parse_input + +MODULE=Apache2::MPM PACKAGE=Apache2::MPM BOOT=1 +~ap_mpm_query +~ap_show_mpm +>ap_mpm_run +?ap_os_create_privileged_process +?ap_wait_or_timeout +?ap_graceful_stop_signalled +?ap_process_child_status +?ap_reclaim_child_processes +?ap_sock_disable_nagle +?ap_gname2id +?ap_uname2id +?ap_lingering_close +?ap_mpm_pod_check +?ap_mpm_pod_close +?ap_mpm_pod_killpg +?ap_mpm_pod_open +?ap_mpm_pod_signal +?ap_mpm_set_accept_lock_mech +?ap_mpm_set_coredumpdir +?ap_mpm_set_lockfile +?ap_mpm_set_max_requests +?ap_mpm_set_pidfile +?ap_mpm_set_scoreboard +?ap_listen_pre_config + +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 +MODULE=Apache2::Provider + ap_register_provider +#_end_
diff --git a/2_0_13/xs/maps/apache2_structures.map b/2_0_13/xs/maps/apache2_structures.map new file mode 100644 index 0000000..c9ff850 --- /dev/null +++ b/2_0_13/xs/maps/apache2_structures.map
@@ -0,0 +1,336 @@ +########## Apache structures ########## + +# for mapping see %ModPerl::MapUtil::disabled_map in +# lib/ModPerl/MapUtil.pm +# the mapping happens in lib/ModPerl/StructureMap.pm: sub parse +# '<' => 'auto-generated but gives only a read-only access' +# '&' => 'RDWR accessor to a char* field, supporting undef arg' +# '$' => 'RONLY accessor, with WRITE accessor before child_init' +# '%' => like $, but makes sure that for the write accessor the +# original perl scalar can change or go away w/o affecting +# the object +# my %disabled_map = ( +# '!' => 'disabled or not yet implemented', +# '~' => 'implemented but not auto-generated', +# '-' => 'likely never be available to Perl', +# '>' => '"private" to apache', +# '?' => 'unclassified', +# ); + +IGNORE: ap_LINK_ ap_filter_func ap_bucket_error ap_listen_rec core_net_rec + +<request_rec> +< pool +< connection +< server +< next +< prev +< main + the_request + assbackwards +~ proxyreq +< header_only +< protocol +< proto_num + hostname +< request_time + status_line + status + method + method_number + allowed + allowed_xmethods + allowed_methods +> sent_bodyct + bytes_sent + mtime +> chunked +> range +> clength +- remaining +> read_length +> read_body +> read_chunked +> expecting_100 + headers_in + headers_out + err_headers_out +~ subprocess_env + notes +~ content_type +~ handler + content_encoding +~ content_languages +> vlist_validator + user + ap_auth_type +~ no_cache + no_local_copy +< unparsed_uri + uri + filename +- canonical_filename + path_info + args +~ finfo +~ parsed_uri + used_path_info +< per_dir_config +< request_config +! htaccess + output_filters + input_filters + proto_output_filters + proto_input_filters +? eos_sent +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 +< useragent_addr + useragent_ip +#_end_ +</request_rec> + +<server_rec> +< process +< next +- defn_name +- defn_line_number +% server_admin +% server_hostname +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 +% server_scheme +#_end_ +$ port +% error_fname +$ error_log +$ loglevel +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 +~ is_virtual +#_else_ +< is_virtual +#_end_ +< module_config +< lookup_defaults +< addrs +$ timeout +$ keep_alive_timeout +$ keep_alive_max +$ keep_alive +% path +- pathlen +% names +% wild_names +$ limit_req_line +$ limit_req_fieldsize +$ limit_req_fields +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 + context +#_end_ +</server_rec> + +<conn_rec> +< pool +< base_server +> vhost_lookup_data +< local_addr +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 +< client_addr + client_ip +#_end_ +< local_ip +< local_host +< remote_addr + remote_ip +< remote_host +- remote_logname +< aborted + keepalive +? double_reverse + keepalives +< id +< conn_config + notes + input_filters + output_filters +< sbh +< bucket_alloc +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 +< log +< log_id +#_end_ +</conn_rec> + +!<server_addr_rec> + next + host_addr + host_port + virthost +</server_addr_rec> + +<module> +~ version +~ minor_version +< module_index +< name +! dynamic_load_handle +< next +> magic +- rewrite_args +> create_dir_config +> merge_dir_config +> create_server_config +> merge_server_config +< cmds +> register_hooks +</module> + +<process_rec> +< pool +< pconf +- argc +! argv +< short_name +</process_rec> + +<command_rec> +< name +! func +! cmd_data +< req_override +< args_how +< errmsg +</command_rec> + +<ap_filter_rec_t> +< name +- filter_func +! ftype +- next +</ap_filter_rec_t> + +<ap_filter_t> +< frec +~ ctx + next + r + c +</ap_filter_t> + +!<ap_method_list_t> + method_mask + method_list +</ap_method_list_t> + +<ap_directive_t> +< directive +< args +< next +< first_child +< parent +! data +< filename +< line_num +</ap_directive_t> + +!<ap_configfile_t> + getch + getstr + close + param + name + line_number +</ap_configfile_t> + +!<ap_unix_identity_t> + uid + gid + userdir +</ap_unix_identity_t> + +!<unixd_config_rec> + user_name + user_id + group_id + suexec_enabled +</unixd_config_rec> + +!<htaccess_result> + dir + override + htaccess + next +</htaccess_result> + +!<piped_log> + p + fds + program + pid +</piped_log> + +<cmd_parms> +- info +< override +! limited +! limited_xmethods +! xlimited +! config_file +< directive +< pool +< temp_pool +< server +< path +< cmd +< context +! err_directive +- override_opts +</cmd_parms> + +!<ap_mgmt_item_t> + description + name + vtype + v +</ap_mgmt_item_t> + +!<ap_mgmt_value> + s_value + i_value + h_value +</ap_mgmt_value> + +!<ap_pod_t> + pod_in + pod_out + p + sa +</ap_pod_t>
diff --git a/2_0_13/xs/maps/apache2_types.map b/2_0_13/xs/maps/apache2_types.map new file mode 100644 index 0000000..156a919 --- /dev/null +++ b/2_0_13/xs/maps/apache2_types.map
@@ -0,0 +1,93 @@ +########## Apache types ########## + +struct server_rec | Apache2::ServerRec +struct server_addr_rec | Apache2::ServerAddr +struct conn_rec | Apache2::Connection +struct request_rec | Apache2::RequestRec +struct subrequest_rec | Apache2::SubRequest +struct process_rec | Apache2::Process +struct ap_method_list_t | Apache2::MethodList +struct piped_log | Apache2::PipedLog + +struct module | Apache2::Module +struct module_struct | Apache2::Module + +ap_conn_keepalive_e | IV + +#config stuff +struct command_rec | Apache2::Command +enum cmd_how | IV +cmd_func | UNDEFINED +struct cmd_parms | Apache2::CmdParms +struct ap_configfile_t | Apache2::ConfigFile +struct htaccess_result | UNDEFINED +struct ap_directive_t | Apache2::Directive +struct ap_conf_vector_t | Apache2::ConfVector + +#system-ish stuff +ap_mgmt_type_e | IV +ap_mgmt_value | UNDEFINED +ap_scoreboard_e | IV +struct process_score | UNDEFINED +struct worker_score | UNDEFINED +struct ap_pod_t | UNDEFINED +ap_unix_identity_t | UNDEFINED + +#filters +struct ap_filter_t | Apache2::Filter +struct ap_filter_rec_t | Apache2::FilterRec +ap_filter_type | Apache2::FilterType +ap_filter_func | UNDEFINED +ap_out_filter_func | UNDEFINED +ap_in_filter_func | UNDEFINED +ap_input_mode_t | IV + +########## Standard types ########## + +int | IV +int * | PTR +unsigned int | UV +signed int | IV +long | IV +long int | IV +unsigned long | UV +unsigned | UV +double | NV + +char * | PV +const char * | PV +const char ** | UNDEFINED +char const * | PV +unsigned char * | PV +const unsigned char * | PV +char ** | UNDEFINED +char *** | UNDEFINED +const char * const * | UNDEFINED + +char | CHAR +const char | CHAR +const unsigned char | U_CHAR +unsigned char | U_CHAR + +void * | PTR +void ** | UNDEFINED +const void * | PTR +const void ** | UNDEFINED +void | VOID + +... | UNDEFINED #varargs +va_list | UNDEFINED + +########## Misc types ########## + +time_t | NV +uid_t | IV +gid_t | IV +pid_t | IV +size_t | IV +size_t * | UNDEFINED + +struct regex_t +regmatch_t +struct pthread_mutex_t +struct iovec | NOTIMPL
diff --git a/2_0_13/xs/maps/apr_functions.map b/2_0_13/xs/maps/apr_functions.map new file mode 100644 index 0000000..b4f6182 --- /dev/null +++ b/2_0_13/xs/maps/apr_functions.map
@@ -0,0 +1,664 @@ +########## APR Functions ########## + +# for mapping see %ModPerl::MapUtil::disabled_map in +# lib/ModPerl/MapUtil.pm + +!MODULE=APR::Poll + apr_poll_socket_add + apr_poll_socket_clear + apr_poll_data_get + apr_poll_revents_get + apr_poll_socket_mask + apr_poll + apr_poll_socket_remove + apr_poll_data_set + apr_poll_setup + +!MODULE=APR::Time +-apr_ctime + apr_implode_time +-apr_time_now +-apr_sleep + apr_rfc822_date + apr_strftime + apr_time_exp_gmt_get + apr_time_ansi_put + apr_time_exp_get + apr_time_exp_gmt + apr_time_exp_lt + apr_time_exp_tz + +MODULE=APR::Date +-apr_date_checkmask + apr_date_parse_http + apr_date_parse_rfc + +!MODULE=APR::Array + apr_array_append + apr_array_cat + apr_array_pstrcat + apr_array_copy + apr_array_copy_hdr + apr_array_make + apr_array_push + +MODULE=APR::Socket + apr_socket_bind +!apr_socket_accept + apr_socket_listen + apr_socket_connect +~apr_socket_recv + mpxs_APR__Socket_recv + apr_socket_recvfrom + apr_socket_send | mpxs_ | sock, SV *:buf, SV *:len=(SV *)NULL + apr_socket_sendto +!apr_socket_shutdown +-apr_socket_inherit_set +-apr_socket_inherit_unset +#_if_ $^O !~ /mswin/i + mpxs_APR__Socket_fileno | | apr_socket_t *:socket +#_end_ + +MODULE=APR::Socket + apr_socket_close +!apr_socket_create +!apr_socket_addr_get +!apr_socket_data_get +!apr_socket_data_set +~apr_socket_opt_get + mpxs_APR__Socket_opt_get +~apr_socket_opt_set + mpxs_APR__Socket_opt_set + apr_socket_timeout_get | mpxs_ | ... +~apr_socket_timeout_set + mpxs_APR__Socket_timeout_set +-apr_socket_sendfile +-apr_socket_sendv +!apr_socket_from_file + mpxs_APR__Socket_poll + +MODULE=APR::SockAddr +!apr_sockaddr_info_get + char *:apr_sockaddr_ip_get | mpxs_ | sockaddr + apr_sockaddr_equal + +MODULE=APR::Brigade + SV *:apr_brigade_create | mpxs_ | SV *:CLASS, SV *:p_sv, list | new +~apr_brigade_destroy + mpxs_APR__Brigade_destroy +!apr_brigade_partition +!apr_brigade_printf +-apr_brigade_putstrs + apr_brigade_split +-apr_brigade_to_iovec +-apr_brigade_vprintf +-apr_brigade_vputstrs +~apr_brigade_length +!apr_brigade_write +!apr_brigade_puts +-apr_brigade_putc +~ apr_brigade_cleanup + mpxs_APR__Brigade_cleanup +~apr_brigade_flatten +~apr_brigade_pflatten +?apr_brigade_split_line + mpxs_APR__Brigade_first #APR_BRIGADE_FIRST + mpxs_APR__Brigade_last #APR_BRIGADE_LAST + mpxs_APR__Brigade_prev #APR_BUCKET_PREV + mpxs_APR__Brigade_next #APR_BUCKET_NEXT + mpxs_APR__Brigade_insert_tail #APR_BRIGADE_INSERT_TAIL + mpxs_APR__Brigade_insert_head #APR_BRIGADE_INSERT_HEAD + mpxs_APR__Brigade_concat #APR_BRIGADE_CONCAT + mpxs_APR__Brigade_is_empty #APR_BRIGADE_EMPTY + mpxs_APR__Brigade_length | | bb, read_all=1 + mpxs_APR__Brigade_flatten | | ... + mpxs_APR__Brigade_pool + +MODULE=APR::Bucket + mpxs_APR__Bucket_is_flush #APR_BUCKET_IS_FLUSH + mpxs_APR__Bucket_is_eos #APR_BUCKET_IS_EOS + mpxs_APR__Bucket_insert_after #APR_BUCKET_INSERT_AFTER + mpxs_APR__Bucket_insert_before #APR_BUCKET_INSERT_AFTER + mpxs_APR__Bucket_remove #APR_BUCKET_REMOVE + #apr_bucket_read + mpxs_APR__Bucket_read | | bucket, buffer, block=APR_BLOCK_READ + #modperl_bucket_sv_create + mpxs_APR__Bucket_new | | classname, list, sv, offset=0, len=0 + void:DEFINE_destroy | | apr_bucket:bucket + void:DEFINE_delete | | apr_bucket:bucket +~apr_bucket_setaside + mpxs_APR__Bucket_setaside +>apr_bucket_free +!apr_bucket_copy_notimpl +!apr_bucket_shared_copy + apr_bucket_eos_create +!apr_bucket_file_create +!apr_bucket_file_enable_mmap + apr_bucket_flush_create +!apr_bucket_heap_create +!apr_bucket_immortal_create +!apr_bucket_mmap_create +!apr_bucket_pipe_create +!apr_bucket_pool_create +!apr_bucket_socket_create +!apr_bucket_transient_create +!apr_bucket_shared_destroy +!apr_bucket_eos_make +!apr_bucket_file_make +!apr_bucket_flush_make +!apr_bucket_heap_make +!apr_bucket_immortal_make +!apr_bucket_mmap_make +!apr_bucket_pipe_make +!apr_bucket_pool_make +!apr_bucket_shared_make +!apr_bucket_socket_make +!apr_bucket_transient_make +!apr_bucket_setaside_notimpl +!apr_bucket_split_notimpl +!apr_bucket_shared_split +!apr_bucket_simple_split +!apr_bucket_simple_copy +!apr_bucket_destroy_noop +!apr_bucket_setaside_noop + +MODULE=APR::BucketAlloc +>apr_bucket_alloc +~apr_bucket_alloc_create + mpxs_APR__BucketAlloc_new + void:DEFINE_destroy | | apr_bucket_alloc_t *:ba + +MODULE=APR::Pool +-apr_pool_num_bytes | | p, recurse=0 #only available with -DAPR_POOL_DEBUG + apr_pool_cleanup_for_exec +~apr_pool_clear +mpxs_APR__Pool_clear +>apr_pool_clear_debug +~apr_pool_destroy + DEFINE_destroy | mpxs_apr_pool_DESTROY | SV *:obj + DEFINE_DESTROY | mpxs_apr_pool_DESTROY | SV *:obj +>apr_pool_destroy_debug + SV *:DEFINE_new | mpxs_apr_pool_create | SV *:parent_pool_obj +-apr_pool_create_ex +>apr_pool_create_ex_debug +!apr_pool_userdata_get +!apr_pool_userdata_set +-apr_pool_userdata_setn +!apr_pool_cleanup_kill +!apr_pool_cleanup_run +-apr_pool_cleanup_null + apr_pool_cleanup_register | mpxs_ | p, SV *:cv, SV *:arg=(SV *)NULL +!apr_pool_note_subprocess +-apr_palloc +>apr_palloc_debug +>apr_pcalloc_debug +-apr_pcalloc +-apr_pmemdup +!apr_pool_child_cleanup_set +!apr_pool_abort_get + SV *:apr_pool_parent_get | mpxs_ + apr_pool_is_ancestor +-apr_pool_abort_set +>apr_pool_initialize +>apr_pool_terminate + apr_pool_tag + +-MODULE=APR::Allocator + apr_allocator_alloc + apr_allocator_create + apr_allocator_destroy + apr_allocator_free + apr_allocator_mutex_get + apr_allocator_owner_get + apr_allocator_mutex_set + apr_allocator_owner_set + +-MODULE=APR::Atomic + apr_atomic_add + apr_atomic_cas + apr_atomic_dec + apr_atomic_inc + apr_atomic_init + apr_atomic_set + +!MODULE=APR::GlobalMutex + apr_global_mutex_child_init + apr_global_mutex_create + apr_global_mutex_destroy + apr_global_mutex_lock + apr_global_mutex_pool_get + apr_global_mutex_trylock + apr_global_mutex_unlock + +MODULE=APR::ThreadMutex PREFIX=apr_thread_mutex_ + SV *:apr_thread_mutex_create | mpxs_ | \ + SV *:classname, SV *:p_sv, flags=APR_THREAD_MUTEX_DEFAULT | new + void:apr_thread_mutex_destroy | | | apr_thread_mutex_DESTROY + apr_thread_mutex_lock + apr_thread_mutex_trylock + apr_thread_mutex_unlock + apr_thread_mutex_pool_get + +!MODULE=APR::ProcMutex + apr_proc_mutex_child_init + apr_proc_mutex_create + apr_proc_mutex_destroy + apr_proc_mutex_lock + apr_proc_mutex_pool_get + apr_proc_mutex_trylock + apr_proc_mutex_unlock + +MODULE=APR::Table + apr_table_clear +~apr_table_copy + mpxs_APR__Table_copy +~apr_table_make + mpxs_APR__Table_make + apr_table_overlap +~apr_table_overlay + mpxs_APR__Table_overlay + apr_table_compress + apr_table_add +-apr_table_addn + apr_table_do | mpxs_ | ... + apr_table_get | MPXS_ | ... + apr_table_merge +-apr_table_mergen + apr_table_set +-apr_table_setn + apr_table_unset +-apr_table_vdo + void:DEFINE_STORE | | apr_table_t *:t, const char *:key, const char *:value + void:DEFINE_DELETE | | apr_table_t *:t, const char *:key + void:DEFINE_CLEAR | | apr_table_t *:t + const char *:DEFINE_FIRSTKEY | mpxs_APR__Table_NEXTKEY | SV *:tsv, SV *:key=(SV *)NULL + mpxs_APR__Table_NEXTKEY | | SV *:tsv, SV *:key=&PL_sv_undef + mpxs_APR__Table_FETCH + mpxs_APR__Table_EXISTS + +!MODULE=APR::File +-apr_file_append +-apr_file_attrs_set +-apr_file_copy +-apr_file_dup2 + apr_file_mktemp +-apr_file_open +-apr_file_close +-apr_file_namedpipe_create + apr_file_pipe_create +-apr_file_dup +-apr_file_flush +-apr_file_eof +-apr_file_gets +-apr_file_printf +-apr_file_write_full +-apr_file_read_full +-apr_file_getc +-apr_file_ungetc +-apr_file_putc +-apr_file_puts +-apr_file_read +-apr_file_write +-apr_file_writev +-apr_file_seek + apr_file_data_get + apr_file_info_get + apr_file_name_get + apr_file_pool_get + apr_file_pipe_timeout_get + apr_file_pipe_timeout_set + apr_file_lock + apr_file_unlock + apr_file_open_stderr + apr_file_open_stdout +-apr_file_remove +-apr_file_rename + apr_file_data_set + apr_file_perms_set +-apr_file_flags_get +-apr_file_open_stdin +-apr_file_set_inherit +-apr_file_unset_inherit +-apr_file_trunc + apr_filepath_get + apr_filepath_merge + apr_filepath_root + apr_filepath_set + +MODULE=APR::Finfo +-apr_lstat +~apr_stat + mpxs_APR__Finfo_stat + +!MODULE=APR::String + apr_collapse_spaces +-apr_cpystrn + apr_fnmatch + apr_fnmatch_test +-apr_psprintf +-apr_pstrcat +-apr_pstrcatv +-apr_pstrdup +-apr_pstrndup +-apr_pstrmemdup +-apr_pvsprintf + apr_strnatcasecmp + apr_strnatcmp +-apr_tokenize_to_argv +-apr_strtok +-apr_itoa +-apr_ltoa +-apr_off_t_toa + +MODULE=APR::String + SV *:apr_strfsize | mpxs_APR__String_strfsize | size | format_size + +!MODULE=APR::StrMatch + apr_strmatch_precompile + +!MODULE=APR::ProcAttr + apr_procattr_create + apr_procattr_child_err_set + apr_procattr_child_in_set + apr_procattr_child_out_set + apr_procattr_cmdtype_set + apr_procattr_detach_set + apr_procattr_dir_set + apr_procattr_io_set + apr_procattr_limit_set + +!MODULE=APR::Proc + apr_proc_create + apr_proc_fork + apr_proc_kill + apr_proc_wait + apr_proc_detach +-apr_proc_other_child_read +-apr_proc_other_child_register +-apr_proc_other_child_unregister +-apr_proc_other_child_check +-apr_proc_wait_all_procs + +-MODULE=APR::Thread + apr_thread_create + apr_thread_data_get + apr_thread_data_set + apr_thread_detach + apr_thread_exit + apr_thread_join + apr_thread_once + apr_thread_once_init + apr_thread_pool_get + apr_thread_yield + +-MODULE=APR::ThreadCond + apr_thread_cond_broadcast + apr_thread_cond_create + apr_thread_cond_destroy + apr_thread_cond_signal + apr_thread_cond_wait + apr_thread_cond_pool_get + apr_thread_cond_timedwait + +MODULE=APR::ThreadRWLock PREFIX=apr_thread_rwlock_ + SV *:apr_thread_rwlock_create | mpxs_ | SV *:classname, SV *:p_sv | new + void:apr_thread_rwlock_destroy | | | apr_thread_rwlock_DESTROY + apr_thread_rwlock_rdlock + apr_thread_rwlock_tryrdlock + apr_thread_rwlock_trywrlock + apr_thread_rwlock_unlock + apr_thread_rwlock_wrlock + apr_thread_rwlock_pool_get + +-MODULE=APR::ThreadKey + apr_threadkey_data_get + apr_threadkey_data_set + apr_threadkey_private_get + apr_threadkey_private_set + apr_threadkey_private_create + apr_threadkey_private_delete + +-MODULE=APR::ThreadAttr + apr_threadattr_create + apr_threadattr_detach_set + apr_threadattr_detach_get + +!MODULE=APR::Version + apr_version + apr_version_string + +-MODULE=APR::DBM + apr_dbm_close + apr_dbm_delete + apr_dbm_exists + apr_dbm_fetch + apr_dbm_firstkey + apr_dbm_freedatum + apr_dbm_geterror + apr_dbm_get_usednames + apr_dbm_get_usednames_ex + apr_dbm_nextkey + apr_dbm_open + apr_dbm_open_ex + apr_dbm_store + +-MODULE=APR::SDBM + apr_sdbm_close + apr_sdbm_delete + apr_sdbm_fetch + apr_sdbm_firstkey + apr_sdbm_lock + apr_sdbm_nextkey + apr_sdbm_open + apr_sdbm_rdonly + apr_sdbm_store + apr_sdbm_unlock + +-MODULE=APR::Dir + apr_dir_close + apr_dir_open + apr_dir_read + apr_dir_rewind + apr_dir_make + apr_dir_remove + +!MODULE=APR::DSO + apr_dso_error + apr_dso_load + apr_dso_sym + apr_dso_unload + +MODULE=APR::Util + apr_filepath_name_get + apr_password_get + int:apr_password_validate | mpxs_ +-apr_snprintf +-apr_vformatter +-apr_vsnprintf +# only available if APR_HAS_RANDOM +-apr_generate_random_bytes + +MODULE=APR::Error +~apr_strerror + char *:DEFINE_strerror | | apr_status_t:rc + +!MODULE=APR::General +-apr_app_initialize +-apr_initialize +-apr_terminate +-apr_terminate2 + +MODULE=APR::Signal +-apr_signal +#not available on all platforms +!apr_signal_description_get +-apr_signal_init +-apr_setup_signal_thread +!apr_signal_thread + +MODULE=APR::UUID + apr_uuid_format | MPXS_ | uuid + apr_uuid_t *:apr_uuid_get | mpxs_ | SV *:CLASS | new + apr_uuid_t *:apr_uuid_parse | mpxs_ | SV *:CLASS,char *:buf | parse + apr_uuid_DESTROY | | uuid + +!MODULE=APR::Hook + apr_hook_deregister_all + apr_hook_sort_register +-apr_register_optional_fn + apr_hook_debug_show + apr_hook_sort_all + apr_optional_hook_add + apr_optional_hook_get + +!MODULE=APR::User + apr_gid_name_get + apr_uid_homepath_get + apr_uid_name_get + apr_uid_get + apr_gid_get + apr_uid_current + +!MODULE=APR::NetLib +-apr_gethostname +!apr_getnameinfo +-apr_getservbyname +!apr_parse_addr_port + +MODULE=APR::IpSubnet + SV *:apr_ipsubnet_create | mpxs_ | \ + SV *:CLASS, SV *:p_sv, ipstr, mask_or_numbits=NULL | new + apr_ipsubnet_test + +!MODULE=APR::Getopt + apr_getopt + apr_getopt_long + apr_getopt_init + +!MODULE=APR::Shm + apr_shm_create + apr_shm_destroy + apr_shm_attach + apr_shm_detach + apr_shm_baseaddr_get + apr_shm_size_get + apr_shm_pool_get + +!MODULE=APR::Hash + apr_hash_copy + apr_hash_count + apr_hash_first + apr_hash_get + apr_hash_merge + apr_hash_next + apr_hash_set + apr_hash_this + apr_hash_make + apr_hash_overlay + apr_hash_pool_get + +!MODULE=APR::MD5 + apr_md5 + apr_md5_encode + apr_md5_final + apr_md5_init + apr_md5_set_xlate + apr_md5_update + +!MODULE=APR::MD4 + apr_md4 + apr_md4_final + apr_md4_init + apr_md4_set_xlate + apr_md4_update + +!MODULE=APR::SHA1 + apr_sha1_base64 + apr_sha1_final + apr_sha1_init + apr_sha1_update + apr_sha1_update_binary + +MODULE=APR::Base64 + apr_base64_decode | MPXS_ | coded_src + apr_base64_encode | MPXS_ | plain_src + int:DEFINE_encode_len | | int:len +-apr_base64_decode_len +-apr_base64_encode_binary +-apr_base64_decode_binary + +MODULE=APR::URI +!apr_uri_parse_hostinfo + SV *:apr_uri_parse | mpxs_ | SV *:classname, SV *:p_sv, uri | parse + apr_uri_unparse | mpxs_ | \ + uptr, flags=APR_URI_UNP_OMITPASSWORD | unparse + #special case to set both uri->port and uri->port_str + mpxs_APR__URI_port | | uri, portsv=(SV *)NULL + mpxs_APR__URI_rpath + apr_uri_port_of_scheme + +!MODULE=Apache2::XML + apr_text_append + apr_xml_parser_create + apr_xml_parser_feed + apr_xml_parser_done + apr_xml_parser_geterror + apr_xml_to_text + apr_xml_empty_elem + apr_xml_quote_string + apr_xml_quote_elem + apr_xml_insert_uri + apr_xml_parse_file + +!MODULE=APR::Mmap + apr_mmap_create + apr_mmap_delete + apr_mmap_offset + apr_mmap_dup + +!MODULE=APR::Xlate + apr_xlate_close + apr_xlate_conv_buffer + apr_xlate_conv_byte + apr_xlate_get_sb + apr_xlate_open + +MODULE=APR::OS + mpxs_APR__OS_current_thread_id +-apr_os_dir_get +-apr_os_exp_time_get +-apr_os_file_get +-apr_os_imp_time_get +#_if_ $^O !~ /mswin/i +~apr_os_sock_get +#_else_ +-apr_os_sock_get +#_end_ +-apr_os_thread_get +-apr_os_threadkey_get +-apr_os_sock_make +-apr_os_dir_put +-apr_os_exp_time_put +-apr_os_file_put +-apr_os_imp_time_put +-apr_os_sock_put +-apr_os_thread_put +-apr_os_threadkey_put +-apr_os_dso_handle_get +-apr_os_dso_handle_put +~apr_os_thread_current +-apr_os_thread_equal +-apr_os_global_mutex_get +-apr_os_proc_mutex_get +-apr_os_proc_mutex_put +-apr_os_shm_get +-apr_os_shm_put + +MODULE=APR::Status PREFIX=mpxs_APR__STATUS_ + int:DEFINE_is_EAGAIN | | apr_status_t:rc + int:DEFINE_is_EACCES | | apr_status_t:rc + int:DEFINE_is_ENOENT | | apr_status_t:rc + int:DEFINE_is_EOF | | apr_status_t:rc + int:DEFINE_is_ECONNABORTED | | apr_status_t:rc + int:DEFINE_is_ECONNRESET | | apr_status_t:rc + int:DEFINE_is_TIMEUP | | apr_status_t:rc
diff --git a/2_0_13/xs/maps/apr_structures.map b/2_0_13/xs/maps/apr_structures.map new file mode 100644 index 0000000..970ce68 --- /dev/null +++ b/2_0_13/xs/maps/apr_structures.map
@@ -0,0 +1,189 @@ +########## APR structures ########## + +# for mapping see %ModPerl::MapUtil::disabled_map in +# lib/ModPerl/MapUtil.pm + +IGNORE: apr_pool_t apr_os_ apr_vformatter_buff_t apr_pool_t \ +apr_table_t apr_in_addr_t apr_bucket_ apr_md5_ctx_t apr_sha1_ctx_t \ +apr_md4_ctx_t apr_sdbm_datum_t apr_memnode_t \ +apr_uuid_t apr_datum_t apr_mmap_t apr_hdtr_t apr_ipsubnet_t \ +apr_strmatch_pattern apr_version_t + +#buckets + +<apr_bucket_type_t> +< name +- num_func +- destroy +- read +- setaside +- split +- copy +</apr_bucket_type_t> + +<apr_bucket> +> link +< type +< length +< start +< data +> free +> list +</apr_bucket> + +<apr_bucket_brigade> +~ pool +> list +< bucket_alloc +</apr_bucket_brigade> + +<apr_finfo_t> +- pool +< valid +< protection +< filetype +< user +< group +< inode +< device +< nlink +< size +< csize +< atime +< mtime +< ctime +< fname +< name +- filehand +</apr_finfo_t> + +<apr_sockaddr_t> +- pool +- hostname +- servname +< port +- sa +- salen +- ipaddr_len +- addr_str_len +- ipaddr_ptr +- next +- family +</apr_sockaddr_t> + +!<apr_proc_t> + pid + in + out + err +</apr_proc_t> + +!<apr_time_exp_t> + tm_usec + tm_sec + tm_min + tm_hour + tm_mday + tm_mon + tm_year + tm_wday + tm_yday + tm_isdst + tm_gmtoff +</apr_time_exp_t> + +#generic data structures + +!<apr_array_header_t> +> pool +> elt_size + nelts +> nalloc + elts +</apr_array_header_t> + +!<apr_table_entry_t> + key + val +> key_checksum +</apr_table_entry_t> + +#getopt + +!<apr_getopt_t> +- cont +- errfn + errarg + ind +- opt +- reset + argc + argv +- place +- interleave +- skip_start +- skip_end +</apr_getopt_t> + +!<apr_getopt_option_t> + name +- optch +- has_arg + description +</apr_getopt_option_t> + +#XML + +!<apr_xml_elem> + name + ns + lang + first_cdata + following_cdata + parent + next + first_child + attr + last_child + ns_scope + priv +</apr_xml_elem> + +<apr_xml_doc> + root + namespaces +</apr_xml_doc> + +<apr_text_header> + first + last +</apr_text_header> + +<apr_xml_attr> + name + ns + value + next +</apr_xml_attr> + +<apr_text> + text + next +</apr_text> + +<apr_uri_t> +& scheme + hostinfo +& user +& password +& hostname +- port_str +& path +& query +& fragment + hostent +~ port +- is_initialized +- dns_looked_up +- dns_resolved +</apr_uri_t>
diff --git a/2_0_13/xs/maps/apr_types.map b/2_0_13/xs/maps/apr_types.map new file mode 100644 index 0000000..0508609 --- /dev/null +++ b/2_0_13/xs/maps/apr_types.map
@@ -0,0 +1,149 @@ +########## APR types ########## + +struct apr_xlate_t | UNDEFINED +struct apr_pool_t | APR::Pool +apr_abortfunc_t | UNDEFINED + +#socket stuff +struct apr_sockaddr_t | APR::SockAddr +apr_os_sock_info_t | APR::SockInfo +struct apr_os_sock_t | UNDEFINED +struct apr_in_addr_t | APR::InAddr +apr_port_t | IV +struct apr_socket_t | APR::Socket +struct sockaddr | UNDEFINED +struct hostent | UNDEFINED +apr_shutdown_how_e | UNDEFINED +apr_interface_e | UNDEFINED + +struct apr_ipsubnet_t | APR::IpSubnet + +#bucket stuff +struct apr_bucket | APR::Bucket +struct apr_bucket_brigade | APR::Brigade +struct apr_bucket_alloc_t | APR::BucketAlloc +apr_brigade_flush | UNDEFINED +struct apr_bucket_type_t | APR::BucketType +apr_read_type_e | IV +apr_bucket_file | UNDEFINED +apr_bucket_pool | UNDEFINED +apr_bucket_heap | UNDEFINED +apr_bucket_mmap | UNDEFINED +apr_bucket_refcount | UNDEFINED +apr_bucket_list | UNDEFINED +#apr_bucket_simple | UNDEFINED +#apr_bucket_shared | UNDEFINED + +#uri +struct apr_uri_t | APR::URI + +#uuid +struct apr_uuid_t | APR::UUID + +#crypto stuff +struct apr_md5_ctx_t | APR::MD5 +struct apr_md4_ctx_t | UNDEFINED +struct apr_sha1_ctx_t | APR::SHA1 + +#getopt +struct apr_getopt_t | APR::Getopt +struct apr_getopt_option_t | APR::GetoptOption + +#dso +struct apr_dso_handle_t | UNDEFINED +struct apr_dso_handle_sym_t | UNDEFINED +struct apr_os_dso_handle_t | UNDEFINED + +#file stuff +struct apr_file_t | UNDEFINED +struct apr_os_file_t | UNDEFINED +struct apr_dir_t | UNDEFINED +struct apr_os_dir_t | UNDEFINED +apr_seek_where_t | UNDEFINED +struct apr_pollfd_t | UNDEFINED +apr_fileperms_t | IV +struct apr_finfo_t | APR::Finfo +apr_filetype_e | IV +apr_dev_t | NV +apr_ino_t | IV + +#process stuff +struct apr_proc_t | APR::Process +struct apr_procattr_t | UNDEFINED +enum kill_conditions +apr_os_proc_t | UNDEFINED +apr_cmdtype_e | UNDEFINED +apr_wait_how_e | UNDEFINED +apr_other_child_rec_t | UNDEFINED + +#time stuff +struct apr_time_exp_t | APR::ExplodedTime +struct apr_os_exp_time_t | UNDEFINED +struct apr_os_imp_time_t | NOTIMPL + +#data structure stuff +struct apr_array_header_t | APR::ArrayHeader +struct apr_table_t | APR::Table +apr_table_entry_t | APR::TableEntry +struct apr_hash_t | APR::Hash +apr_hash_index_t | APR::HashIndex + +#lock stuff +apr_locktype_e | IV +apr_lockmech_e | IV + +#thread stuff +struct apr_threadkey_t | UNDEFINED +struct apr_os_threadkey_t | UNDEFINED +typedef apr_os_thread_t | UNDEFINED +struct apr_thread_t | UNDEFINED +apr_thread_start_t | UNDEFINED +struct apr_threadattr_t | UNDEFINED +struct apr_thread_mutex_t | APR::ThreadMutex +struct apr_thread_once_t | UNDEFINED +struct apr_thread_cond_t | UNDEFINED +struct apr_thread_rwlock_t | APR::ThreadRWLock + +#signal stuff +apr_signum_t | UNDEFINED +apr_sigfunc_t | UNDEFINED + +#shared memory stuff +struct apr_mmap_t | APR::Mmap + +#xml stuff +struct apr_text | UNDEFINED +struct apr_text_header | UNDEFINED +struct apr_xml_elem | UNDEFINED +struct apr_xml_doc | UNDEFINED +struct apr_xml_attr | UNDEFINED +struct apr_xml_ns_scope | UNDEFINED +struct apr_xml_parser | UNDEFINED + +#integer stuff +apr_int16_t | IV +apr_int32_t | IV +apr_int64_t | NV +apr_uint16_t | IV +apr_uint32_t | IV +apr_uint64_t | NV +apr_socklen_t | IV +apr_ssize_t | IV +apr_size_t | UV +apr_time_t | NV +apr_interval_time_t | NV +apr_gid_t | IV +apr_uid_t | IV +apr_off_t | IV +apr_byte_t | CHAR +apr_status_t | IV #dualvar? + +#misc stuff +apr_hdtr_t | NOTIMPL #sendfile +apr_vformatter_buff_t | NOTIMPL + +#dbm stuff +apr_datum_t | NOTIMPL #sdbm +struct apr_dbm_t | NOTIMPL #sdbm +struct apr_sdbm_t | NOTIMPL +struct apr_sdbm_datum_t| NOTIMPL
diff --git a/2_0_13/xs/maps/modperl_functions.map b/2_0_13/xs/maps/modperl_functions.map new file mode 100644 index 0000000..66047aa --- /dev/null +++ b/2_0_13/xs/maps/modperl_functions.map
@@ -0,0 +1,183 @@ +########## mod_perl specific functions ########## + +# for mapping see %ModPerl::MapUtil::disabled_map in +# lib/ModPerl/MapUtil.pm + +MODULE=ModPerl::Util + mpxs_ModPerl__Util_untaint | | ... + SV *:DEFINE_current_perl_id + char *:DEFINE_current_callback + DEFINE_unload_package_xs | | const char *:package + +MODULE=ModPerl::Global + mpxs_ModPerl__Global_special_list_call + mpxs_ModPerl__Global_special_list_clear + mpxs_ModPerl__Global_special_list_register + +MODULE=Apache2::RequestRec PACKAGE=Apache2::RequestRec + mpxs_Apache2__RequestRec_content_type | | r, type=(SV *)NULL + mpxs_Apache2__RequestRec_proxyreq | | r, val=(SV *)NULL + mpxs_Apache2__RequestRec_subprocess_env | | r, key=NULL, val=(SV *)NULL + mpxs_Apache2__RequestRec_finfo | | r, finfo=NULL + mpxs_Apache2__RequestRec_handler | | ... + mpxs_Apache2__RequestRec_content_languages | | r, languages=(SV *)NULL + +#_if_ do { \ + Apache2::Build->build_config \ + ->httpd_version =~ /^(\d+)\.(\d+)\.(\d+)/ \ + ? ($1*1000+$2)*1000+$3 \ + : die "Cannot get httpd version"; \ + } > 2003000 +MODULE=Apache2::ServerRec PACKAGE=Apache2::ServerRec + mpxs_Apache2__ServerRec_is_virtual | | server_rec *:s, val=(SV *)NULL +#_end_ + +MODULE=Apache2::RequestUtil PACKAGE=guess + mpxs_Apache2__RequestRec_push_handlers + mpxs_Apache2__RequestRec_set_handlers + mpxs_Apache2__RequestRec_get_handlers + mpxs_Apache2__RequestRec_is_perl_option_enabled + mpxs_Apache2__RequestRec_location + mpxs_Apache2__RequestRec_as_string + mpxs_Apache2__RequestRec_pnotes | | r, key=(SV *)NULL, val=(SV *)NULL + mpxs_Apache2__RequestRec_pnotes_kill | | r + mpxs_Apache2__RequestRec_add_config | | r, lines, override=MP_HTTPD_OVERRIDE_HTACCESS, path=NULL, override_options=MP_HTTPD_OVERRIDE_OPTS_UNSET + mpxs_Apache2__RequestRec_document_root | | r, new_root=(SV *)NULL + mpxs_Apache2__RequestRec_child_terminate + + #protocol module helpers + mpxs_Apache2__RequestRec_location_merge + mpxs_Apache2__RequestRec_set_basic_credentials + mpxs_Apache2__RequestRec_no_cache | | r, flag=(SV *)NULL + +PACKAGE=Apache2::RequestRec + mpxs_Apache2__RequestRec_new | | classname, c, base_pool_sv=(SV *)NULL + SV *:DEFINE_dir_config | | request_rec *:r, char *:key=NULL, SV *:sv_val=(SV *)NULL + SV *:DEFINE_slurp_filename | | request_rec *:r, int:tainted=1 + +MODULE=Apache2::RequestUtil PACKAGE=Apache2::RequestUtil + mpxs_Apache2__RequestUtil_request | | classname, svr=(SV *)NULL + +MODULE=Apache2::RequestIO PACKAGE=Apache2::RequestRec + SV *:DEFINE_TIEHANDLE | | SV *:stashsv, SV *:sv=(SV *)NULL + SV *:DEFINE_PRINT | | ... + apr_size_t:DEFINE_PRINTF | | ... + SV *:DEFINE_BINMODE | | request_rec *:r + SV *:DEFINE_CLOSE | | request_rec *:r + SV *:DEFINE_UNTIE | | request_rec *:r, int:refcnt + mpxs_Apache2__RequestRec_sendfile | | r, filename=r->filename, offset=0, len=0 + mpxs_Apache2__RequestRec_read | | r, buffer, len, offset=0 + SV *:DEFINE_READ | | request_rec *:r, SV *:buffer, apr_size_t:len, apr_off_t:offset=0 + mpxs_Apache2__RequestRec_write | | r, buffer, len=-1, offset=0 + mpxs_Apache2__RequestRec_print | | ... + apr_size_t:DEFINE_WRITE | | \ + request_rec *:r, SV *:buffer, apr_size_t:len=-1, apr_off_t:offset=0 + mpxs_Apache2__RequestRec_rflush | | ... + mpxs_Apache2__RequestRec_GETC + mpxs_Apache2__RequestRec_OPEN | | SV *:self, SV *:arg1, SV *:arg2=(SV *)NULL + mpxs_Apache2__RequestRec_FILENO + +MODULE=Apache2::Response PACKAGE=Apache2::RequestRec +DEFINE_send_cgi_header | | request_rec *:r, SV *:buffer + mpxs_Apache2__RequestRec_set_last_modified | | r, mtime=0 + + +MODULE=Apache2::ServerUtil PACKAGE=guess + mpxs_Apache2__ServerRec_push_handlers + mpxs_Apache2__ServerRec_set_handlers + mpxs_Apache2__ServerRec_get_handlers + mpxs_Apache2__ServerRec_is_perl_option_enabled + mpxs_Apache2__ServerRec_add_config + +MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerRec + SV *:DEFINE_dir_config | | server_rec *:s, char *:key=NULL, SV *:sv_val=(SV *)NULL + +MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerUtil + mpxs_Apache2__ServerUtil_server_shutdown_cleanup_register | | cv, arg=(SV *)NULL + int:DEFINE_restart_count + +MODULE=Apache2::ServerUtil PACKAGE=Apache2::ServerUtil + server_rec *:DEFINE_server | | SV *:classname=(SV *)NULL + uid_t:DEFINE_user_id | | SV *:classname=(SV *)NULL + gid_t:DEFINE_group_id | | SV *:classname=(SV *)NULL + +MODULE=Apache2::Connection + mpxs_Apache2__Connection_client_socket | | c, s=NULL + +MODULE=Apache2::ConnectionUtil PACKAGE=guess + mpxs_Apache2__Connection_pnotes | | c, key=(SV *)NULL, val=(SV *)NULL + mpxs_Apache2__Connection_pnotes_kill | | c + +MODULE=Apache2::Filter + modperl_filter_attributes | MPXS_ | ... | MODIFY_CODE_ATTRIBUTES + + mpxs_Apache2__Filter_print | | ... + mpxs_Apache2__Filter_read | | ... + mpxs_Apache2__Filter_seen_eos | | ... + mpxs_Apache2__Filter_ctx | | filter, data=(SV *)NULL + mpxs_Apache2__Filter_remove | | ... + + SV *:DEFINE_TIEHANDLE | | SV *:stashsv, SV *:sv=(SV *)NULL + apr_size_t:DEFINE_PRINT | | ... + +MODULE=Apache2::Filter PACKAGE=Apache2::RequestRec + mpxs_Apache2__RequestRec_add_input_filter + mpxs_Apache2__RequestRec_add_output_filter + +MODULE=Apache2::Filter PACKAGE=Apache2::Connection + mpxs_Apache2__Connection_add_input_filter + mpxs_Apache2__Connection_add_output_filter + +MODULE=Apache2::Log PACKAGE=Apache2::Log BOOT=1 + +DEFINE_error | MPXS_Apache2__Log_dispatch | ... +DEFINE_emerg | MPXS_Apache2__Log_dispatch | ... +DEFINE_alert | MPXS_Apache2__Log_dispatch | ... +DEFINE_warn | MPXS_Apache2__Log_dispatch | ... +DEFINE_notice | MPXS_Apache2__Log_dispatch | ... +DEFINE_info | MPXS_Apache2__Log_dispatch | ... +DEFINE_debug | MPXS_Apache2__Log_dispatch | ... +DEFINE_crit | MPXS_Apache2__Log_dispatch | ... +DEFINE_LOG_MARK | MPXS_Apache2__Log_LOG_MARK | ... + +PACKAGE=Apache2::RequestRec +SV *:DEFINE_log | | SV *:obj +DEFINE_log_rerror | MPXS_Apache2__Log_log_xerror | ... +DEFINE_log_error | MPXS_Apache2__Log_log_error | ... +DEFINE_warn | MPXS_Apache2__Log_log_error | ... +DEFINE_log_reason | modperl_log_reason | request_rec *:r, char *:msg, char *:file=r->uri + +PACKAGE=Apache2::ServerRec +SV *:DEFINE_log | | SV *:obj +DEFINE_log_serror | MPXS_Apache2__Log_log_xerror | ... +DEFINE_log_error | MPXS_Apache2__Log_log_error | ... +DEFINE_warn | MPXS_Apache2__Log_log_error | ... + +MODULE=Apache2::SubProcess PACKAGE=Apache2::RequestRec + # ap_subprocess_ won't work + modperl_spawn_proc_prog | MPXS_ | ... | spawn_proc_prog + +MODULE=Apache2::Directive + mpxs_Apache2__Directive_as_string + mpxs_Apache2__Directive_as_hash + DEFINE_lookup | MPXS_Apache2__Directive_lookup | ... + +MODULE=Apache2::CmdParms + ap_check_cmd_context + ap_method_is_limited + mpxs_Apache2__CmdParms_info + mpxs_Apache2__CmdParms_add_config + mpxs_Apache2__CmdParms_override_opts + +MODULE=Apache2::MPM PACKAGE=Apache2::MPM BOOT=1 + mpxs_Apache2__MPM_query + +MODULE=Apache2::Access PACKAGE=guess + mpxs_Apache2__RequestRec_allow_override_opts + +#_if_ do {use Apache2::Build; Apache2::Build::PERL_HAS_ITHREADS} + +MODULE=ModPerl::Interpreter + mpxs_ModPerl__Interpreter_current | | class=Nullsv + +#_end_
diff --git a/2_0_13/xs/maps/modperl_structures.map b/2_0_13/xs/maps/modperl_structures.map new file mode 100644 index 0000000..9157ee3 --- /dev/null +++ b/2_0_13/xs/maps/modperl_structures.map
@@ -0,0 +1,44 @@ +########## ModPerl structures ########## + +# for mapping see %ModPerl::MapUtil::disabled_map in +# lib/ModPerl/MapUtil.pm + +#_if_ do {use Apache2::Build; Apache2::Build::PERL_HAS_ITHREADS} + +<modperl_interp_t> +< mip +< perl +< num_requests +< flags +- ccfg +< refcnt +- tid +</modperl_interp_t> + +<modperl_interp_pool_t> +< server +< tipool +< parent +</modperl_interp_pool_t> + +<modperl_tipool_t> +- tiplock +- available +- idle +- busy +< in_use +< size +- data +< cfg +- func +</modperl_tipool_t> + +<modperl_tipool_config_t> +< start +< min_spare +< max_spare +< max +< max_requests +</modperl_tipool_config_t> + +#_end_
diff --git a/2_0_13/xs/maps/modperl_types.map b/2_0_13/xs/maps/modperl_types.map new file mode 100644 index 0000000..b251940 --- /dev/null +++ b/2_0_13/xs/maps/modperl_types.map
@@ -0,0 +1,24 @@ +########## mod_perl types ########## + +struct modperl_filter_t | Apache2::OutputFilter + +#_if_ do {use Apache2::Build; Apache2::Build::PERL_HAS_ITHREADS} + +struct modperl_interp_t | ModPerl::Interpreter +struct modperl_interp_pool_t | ModPerl::InterpPool +struct modperl_tipool_t | ModPerl::TiPool +struct modperl_tipool_config_t | ModPerl::TiPoolConfig +PerlInterpreter * | IV + +#_end_ + +########## Perl types ########## + +SV * | SV +I32 | IV +I32 * | IV +U16 | UV +U16 * | UV +U32 | UV +U32 * | UV +
diff --git a/2_0_13/xs/modperl_xs_util.h b/2_0_13/xs/modperl_xs_util.h new file mode 100644 index 0000000..749352e --- /dev/null +++ b/2_0_13/xs/modperl_xs_util.h
@@ -0,0 +1,167 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODPERL_XS_H +#define MODPERL_XS_H + +/* XXX: should be part of generation */ +#undef mp_xs_sv2_r /* defined in modperl_xs_sv_convert.h */ +#define mp_xs_sv2_r(sv) modperl_sv2request_rec(aTHX_ sv) + +#undef mp_xs_sv2_APR__Table +#define mp_xs_sv2_APR__Table(sv) \ + (apr_table_t *)modperl_hash_tied_object(aTHX_ "APR::Table", sv) + +#define mpxs_Apache2__RequestRec_pool(r) r->pool +#define mpxs_Apache2__Connection_pool(c) c->pool +#define mpxs_Apache2__URI_pool(u) ((modperl_uri_t *)u)->pool +#define mpxs_APR__URI_pool(u) ((modperl_uri_t *)u)->pool + +#ifndef dAX +# define dAX I32 ax = mark - PL_stack_base + 1 +#endif + +#ifndef dITEMS +# define dITEMS I32 items = SP - MARK +#endif + +#define mpxs_PPCODE(code) STMT_START { \ + SP -= items; \ + code; \ + PUTBACK; \ +} STMT_END + +#define PUSHs_mortal_iv(iv) PUSHs(sv_2mortal(newSViv(iv))) +#define PUSHs_mortal_pv(pv) PUSHs(sv_2mortal(newSVpv((char *)pv,0))) + +#define XPUSHs_mortal_iv(iv) EXTEND(SP, 1); PUSHs_mortal_iv(iv) +#define XPUSHs_mortal_pv(pv) EXTEND(SP, 1); PUSHs_mortal_pv(pv) + +/* XXX: replace the old mpxs_sv_ macros with MP_Sv macros */ + +#define mpxs_sv_grow(sv, len) MP_SvGROW(sv, len) + +#define mpxs_sv_cur_set(sv, len) MP_SvCUR_set(sv, len) + +#define mpxs_set_targ(func, arg) \ + STMT_START { \ + dXSTARG; \ + XSprePUSH; \ + func(aTHX_ TARG, arg); \ + PUSHTARG; \ + XSRETURN(1); \ +} STMT_END + +#define mpxs_cv_name() \ + HvNAME(GvSTASH(CvGV(cv))), GvNAME(CvGV(cv)) + +#define mpxs_sv_is_object(sv) \ + (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG)) + +#define mpxs_sv_object_deref(sv, type) \ + (mpxs_sv_is_object(sv) ? \ + INT2PTR(type *, SvIVX((SV*)SvRV(sv))) : NULL) + +#define mpxs_sv2_obj(obj, sv) \ + (obj = mp_xs_sv2_##obj(sv)) + +#define mpxs_usage_items_1(arg) \ + if (items != 1) { \ + Perl_croak(aTHX_ "usage: %s::%s(%s)", \ + mpxs_cv_name(), arg); \ + } + +#define mpxs_usage_va(i, obj, msg) \ + if ((items < i) || !(mpxs_sv2_obj(obj, *MARK))) { \ + Perl_croak(aTHX_ "usage: %s", msg); \ + } \ + MARK++ + +#define mpxs_usage_va_1(obj, msg) mpxs_usage_va(1, obj, msg) + +#define mpxs_usage_va_2(obj, arg, msg) \ + mpxs_usage_va(2, obj, msg); \ + arg = *MARK++ + +#define mpxs_write_loop(func, obj, name) \ + while (MARK <= SP) { \ + apr_size_t wlen; \ + char *buf = SvPV(*MARK, wlen); \ + MP_TRACE_o(MP_FUNC, "%d bytes [%s]", wlen, buf); \ + MP_RUN_CROAK(func(aTHX_ obj, buf, &wlen), name); \ + bytes += wlen; \ + MARK++; \ + } + +/* custom pool objects created by modperl users (not internal like + * r->pool) are marked by magic in SvRV(obj) + */ +#define mpxs_pool_is_custom(pool) (mg_find(pool, PERL_MAGIC_ext) != NULL) + +/* several methods need to ensure that the pool that they take as an + * object doesn't go out of scope before the object that they return, + * since if this happens, the data contained in the later object + * becomes corrupted. this macro is used in various xs files where + * it's needed */ +#if ((PERL_REVISION == 5) && (PERL_VERSION >= 8)) + /* sometimes the added magic is the second one (e.g. in case when + * the object is generated by modperl_hash_tie, so under 5.8+ + * need to use sv_magicext, since sv_magicext does only one magic + * of the same type at 5.8+ */ +#define mpxs_add_pool_magic_doit(obj, pool_obj) \ + sv_magicext(SvRV(obj), pool_obj, PERL_MAGIC_ext, NULL, (char *)NULL, -1) +#else +#define mpxs_add_pool_magic_doit(obj, pool_obj) \ + sv_magic(SvRV(obj), pool_obj, PERL_MAGIC_ext, (char *)NULL, -1) +#endif + +/* add dependency magic only for custom pools. there are all kind of + * complications when more than one magic of the same type(in this + * case PERL_MAGIC_ext is added), luckily most of the PERL_MAGIC_ext + * magic used by modperl-core, uses (SV *)NULL as mg->mg_obj, therefore + * the following code tries to workaround the multiple magic issue, by + * simply hanging the pool object into the unused slot, incrementing + * its refcnt just like sv_magic does internally. In case we ever hit + * magic which already has mg->mg_obj taken we will deal with that, + * for now we just croak in such a case. + */ +#define mpxs_add_pool_magic(obj, pool_obj) \ + if (mpxs_pool_is_custom(SvRV(pool_obj))) { \ + MAGIC *mg = mg_find(SvRV(obj), PERL_MAGIC_ext); \ + if (mg) { \ + if (mg->mg_obj == (SV *)NULL) { \ + mg->mg_obj = SvREFCNT_inc(SvRV(pool_obj)); \ + mg->mg_flags |= MGf_REFCOUNTED; \ + } \ + else { \ + Perl_croak(aTHX_ "Fixme: don't know how to " \ + "handle magic w/ occupied mg->mg_obj"); \ + } \ + } \ + else { \ + mpxs_add_pool_magic_doit(obj, SvRV(pool_obj)); \ + } \ + } + + +#endif /* MODPERL_XS_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */
diff --git a/2_0_13/xs/tables/current/APR/FunctionTable.pm b/2_0_13/xs/tables/current/APR/FunctionTable.pm new file mode 100644 index 0000000..6e3b404 --- /dev/null +++ b/2_0_13/xs/tables/current/APR/FunctionTable.pm
@@ -0,0 +1,229 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package APR::FunctionTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: this file was manually generated on +# ! Tue Jun 22 22:00:00 2004 +# ! It contains a subset of functions appearing in +# ! ModPerl::FunctionTable used to build APR.so +# ! Eventually this will be autogenerated by +# ! Apache::ParseSource +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$APR::FunctionTable = [ + { + 'return_type' => 'void', + 'name' => 'modperl_trace', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'func' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace_level_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'logfile' + }, + { + 'type' => 'const char *', + 'name' => 'level' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace_logfile_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'logfile_new' + } + ] + }, + { + 'return_type' => 'unsigned long', + 'name' => 'modperl_debug_level', + 'args' => [] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_hash_tie', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + }, + { + 'type' => 'void *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_hash_tied_object', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_sv_setref_uv', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'rv' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'UV', + 'name' => 'uv' + } + ] + }, + { + 'return_type' => 'modperl_uri_t *', + 'name' => 'modperl_uri_new', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_gensym', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'pack' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_error_strerror', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_croak', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + }, + { + 'type' => 'const char*', + 'name' => 'func' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_interp_unselect', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'modperl_bucket_sv_create', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, +]; + +1;
diff --git a/2_0_13/xs/tables/current/Apache2/ConstantsTable.pm b/2_0_13/xs/tables/current/Apache2/ConstantsTable.pm new file mode 100644 index 0000000..9ea2d43 --- /dev/null +++ b/2_0_13/xs/tables/current/Apache2/ConstantsTable.pm
@@ -0,0 +1,474 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package Apache2::ConstantsTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by Apache2::ParseSource/0.02 +# ! Mon May 23 14:15:32 2005 +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$Apache2::ConstantsTable = { + 'ModPerl' => { + 'common' => [ + 'MODPERL_RC_EXIT' + ] + }, + 'Apache2::Const' => { + 'types' => [ + 'DIR_MAGIC_TYPE' + ], + 'satisfy' => [ + 'SATISFY_ALL', + 'SATISFY_ANY', + 'SATISFY_NOSPEC' + ], + 'remotehost' => [ + 'REMOTE_HOST', + 'REMOTE_NAME', + 'REMOTE_NOLOOKUP', + 'REMOTE_DOUBLE_REV' + ], + 'platform' => [ + 'LF', + 'CR', + 'CRLF' + ], + 'override' => [ + 'OR_NONE', + 'OR_LIMIT', + 'OR_OPTIONS', + 'OR_FILEINFO', + 'OR_AUTHCFG', + 'OR_INDEXES', + 'OR_UNSET', + 'ACCESS_CONF', + 'RSRC_CONF', + 'EXEC_ON_READ', + 'OR_ALL' + ], + 'options' => [ + 'OPT_NONE', + 'OPT_INDEXES', + 'OPT_INCLUDES', + 'OPT_SYM_LINKS', + 'OPT_EXECCGI', + 'OPT_UNSET', + 'OPT_INCNOEXEC', + 'OPT_SYM_OWNER', + 'OPT_MULTI', + 'OPT_ALL' + ], + 'mpmq' => [ + 'AP_MPMQ_NOT_SUPPORTED', + 'AP_MPMQ_STATIC', + 'AP_MPMQ_DYNAMIC', + 'AP_MPMQ_STARTING', + 'AP_MPMQ_RUNNING', + 'AP_MPMQ_STOPPING', + 'AP_MPMQ_MAX_DAEMON_USED', + 'AP_MPMQ_IS_THREADED', + 'AP_MPMQ_IS_FORKED', + 'AP_MPMQ_HARD_LIMIT_DAEMONS', + 'AP_MPMQ_HARD_LIMIT_THREADS', + 'AP_MPMQ_MAX_THREADS', + 'AP_MPMQ_MIN_SPARE_DAEMONS', + 'AP_MPMQ_MIN_SPARE_THREADS', + 'AP_MPMQ_MAX_SPARE_DAEMONS', + 'AP_MPMQ_MAX_SPARE_THREADS', + 'AP_MPMQ_MAX_REQUESTS_DAEMON', + 'AP_MPMQ_MAX_DAEMONS', + 'AP_MPMQ_MPM_STATE' + ], + 'methods' => [ + 'M_GET', + 'M_PUT', + 'M_POST', + 'M_DELETE', + 'M_CONNECT', + 'M_OPTIONS', + 'M_TRACE', + 'M_PATCH', + 'M_PROPFIND', + 'M_PROPPATCH', + 'M_MKCOL', + 'M_COPY', + 'M_MOVE', + 'M_LOCK', + 'M_UNLOCK', + 'M_VERSION_CONTROL', + 'M_CHECKOUT', + 'M_UNCHECKOUT', + 'M_CHECKIN', + 'M_UPDATE', + 'M_LABEL', + 'M_REPORT', + 'M_MKWORKSPACE', + 'M_MKACTIVITY', + 'M_BASELINE_CONTROL', + 'M_MERGE', + 'M_INVALID', + 'METHODS' + ], + 'log' => [ + 'APLOG_EMERG', + 'APLOG_ALERT', + 'APLOG_CRIT', + 'APLOG_ERR', + 'APLOG_WARNING', + 'APLOG_NOTICE', + 'APLOG_INFO', + 'APLOG_DEBUG', + 'APLOG_LEVELMASK', + 'APLOG_TOCLIENT', + 'APLOG_STARTUP' + ], + 'input_mode' => [ + 'AP_MODE_READBYTES', + 'AP_MODE_GETLINE', + 'AP_MODE_EATCRLF', + 'AP_MODE_SPECULATIVE', + 'AP_MODE_EXHAUSTIVE', + 'AP_MODE_INIT' + ], + 'http' => [ + 'HTTP_CONTINUE', + 'HTTP_SWITCHING_PROTOCOLS', + 'HTTP_PROCESSING', + 'HTTP_OK', + 'HTTP_CREATED', + 'HTTP_ACCEPTED', + 'HTTP_NON_AUTHORITATIVE', + 'HTTP_NO_CONTENT', + 'HTTP_RESET_CONTENT', + 'HTTP_PARTIAL_CONTENT', + 'HTTP_MULTI_STATUS', + 'HTTP_MULTIPLE_CHOICES', + 'HTTP_MOVED_PERMANENTLY', + 'HTTP_MOVED_TEMPORARILY', + 'HTTP_SEE_OTHER', + 'HTTP_NOT_MODIFIED', + 'HTTP_USE_PROXY', + 'HTTP_TEMPORARY_REDIRECT', + 'HTTP_BAD_REQUEST', + 'HTTP_UNAUTHORIZED', + 'HTTP_PAYMENT_REQUIRED', + 'HTTP_FORBIDDEN', + 'HTTP_NOT_FOUND', + 'HTTP_METHOD_NOT_ALLOWED', + 'HTTP_NOT_ACCEPTABLE', + 'HTTP_PROXY_AUTHENTICATION_REQUIRED', + 'HTTP_REQUEST_TIME_OUT', + 'HTTP_CONFLICT', + 'HTTP_GONE', + 'HTTP_LENGTH_REQUIRED', + 'HTTP_PRECONDITION_FAILED', + 'HTTP_REQUEST_ENTITY_TOO_LARGE', + 'HTTP_REQUEST_URI_TOO_LARGE', + 'HTTP_UNSUPPORTED_MEDIA_TYPE', + 'HTTP_RANGE_NOT_SATISFIABLE', + 'HTTP_EXPECTATION_FAILED', + 'HTTP_UNPROCESSABLE_ENTITY', + 'HTTP_LOCKED', + 'HTTP_FAILED_DEPENDENCY', + 'HTTP_UPGRADE_REQUIRED', + 'HTTP_INTERNAL_SERVER_ERROR', + 'HTTP_NOT_IMPLEMENTED', + 'HTTP_BAD_GATEWAY', + 'HTTP_SERVICE_UNAVAILABLE', + 'HTTP_GATEWAY_TIME_OUT', + 'HTTP_VARIANT_ALSO_VARIES', + 'HTTP_INSUFFICIENT_STORAGE', + 'HTTP_NOT_EXTENDED' + ], + 'filter_type' => [ + 'AP_FTYPE_RESOURCE', + 'AP_FTYPE_CONTENT_SET', + 'AP_FTYPE_PROTOCOL', + 'AP_FTYPE_TRANSCODE', + 'AP_FTYPE_CONNECTION', + 'AP_FTYPE_NETWORK' + ], + 'context' => [ + 'NOT_IN_VIRTUALHOST', + 'NOT_IN_LIMIT', + 'NOT_IN_DIRECTORY', + 'NOT_IN_LOCATION', + 'NOT_IN_FILES', + 'NOT_IN_DIR_LOC_FILE', + 'GLOBAL_ONLY' + ], + 'conn_keepalive' => [ + 'AP_CONN_UNKNOWN', + 'AP_CONN_CLOSE', + 'AP_CONN_KEEPALIVE' + ], + 'config' => [ + 'DECLINE_CMD' + ], + 'common' => [ + 'DECLINED', + 'DONE', + 'OK', + 'NOT_FOUND', + 'FORBIDDEN', + 'AUTH_REQUIRED', + 'SERVER_ERROR', + 'REDIRECT' + ], + 'cmd_how' => [ + 'RAW_ARGS', + 'TAKE1', + 'TAKE2', + 'ITERATE', + 'ITERATE2', + 'FLAG', + 'NO_ARGS', + 'TAKE12', + 'TAKE3', + 'TAKE23', + 'TAKE123', + 'TAKE13' + ], + 'proxy' => [ + 'PROXYREQ_REVERSE', + 'PROXYREQ_NONE', + 'PROXYREQ_PROXY', + 'PROXYREQ_RESPONSE', + ], + }, + 'APR::Const' => { + 'uri' => [ + 'APR_URI_FTP_DEFAULT_PORT', + 'APR_URI_SSH_DEFAULT_PORT', + 'APR_URI_TELNET_DEFAULT_PORT', + 'APR_URI_GOPHER_DEFAULT_PORT', + 'APR_URI_HTTP_DEFAULT_PORT', + 'APR_URI_POP_DEFAULT_PORT', + 'APR_URI_NNTP_DEFAULT_PORT', + 'APR_URI_IMAP_DEFAULT_PORT', + 'APR_URI_PROSPERO_DEFAULT_PORT', + 'APR_URI_WAIS_DEFAULT_PORT', + 'APR_URI_LDAP_DEFAULT_PORT', + 'APR_URI_HTTPS_DEFAULT_PORT', + 'APR_URI_RTSP_DEFAULT_PORT', + 'APR_URI_SNEWS_DEFAULT_PORT', + 'APR_URI_ACAP_DEFAULT_PORT', + 'APR_URI_NFS_DEFAULT_PORT', + 'APR_URI_TIP_DEFAULT_PORT', + 'APR_URI_SIP_DEFAULT_PORT', + 'APR_URI_UNP_OMITSITEPART', + 'APR_URI_UNP_OMITUSER', + 'APR_URI_UNP_OMITPASSWORD', + 'APR_URI_UNP_OMITUSERINFO', + 'APR_URI_UNP_REVEALPASSWORD', + 'APR_URI_UNP_OMITPATHINFO', + 'APR_URI_UNP_OMITQUERY' + ], + 'table' => [ + 'APR_OVERLAP_TABLES_SET', + 'APR_OVERLAP_TABLES_MERGE' + ], + 'status' => [ + 'APR_TIMEUP' + ], + 'socket' => [ + 'APR_SO_LINGER', + 'APR_SO_KEEPALIVE', + 'APR_SO_DEBUG', + 'APR_SO_NONBLOCK', + 'APR_SO_REUSEADDR', + 'APR_SO_SNDBUF', + 'APR_SO_RCVBUF', + 'APR_SO_DISCONNECTED' + ], + 'shutdown_how' => [ + 'APR_SHUTDOWN_READ', + 'APR_SHUTDOWN_WRITE', + 'APR_SHUTDOWN_READWRITE' + ], + 'read_type' => [ + 'APR_BLOCK_READ', + 'APR_NONBLOCK_READ' + ], + 'poll' => [ + 'APR_POLLIN', + 'APR_POLLPRI', + 'APR_POLLOUT', + 'APR_POLLERR', + 'APR_POLLHUP', + 'APR_POLLNVAL' + ], + 'lockmech' => [ + 'APR_LOCK_FCNTL', + 'APR_LOCK_FLOCK', + 'APR_LOCK_SYSVSEM', + 'APR_LOCK_PROC_PTHREAD', + 'APR_LOCK_POSIXSEM', + 'APR_LOCK_DEFAULT' + ], + 'limit' => [ + 'APR_LIMIT_CPU', + 'APR_LIMIT_MEM', + 'APR_LIMIT_NPROC', + 'APR_LIMIT_NOFILE' + ], + 'hook' => [ + 'APR_HOOK_REALLY_FIRST', + 'APR_HOOK_FIRST', + 'APR_HOOK_MIDDLE', + 'APR_HOOK_LAST', + 'APR_HOOK_REALLY_LAST' + ], + 'fprot' => [ + 'APR_FPROT_USETID', + 'APR_FPROT_UREAD', + 'APR_FPROT_UWRITE', + 'APR_FPROT_UEXECUTE', + 'APR_FPROT_GSETID', + 'APR_FPROT_GREAD', + 'APR_FPROT_GWRITE', + 'APR_FPROT_GEXECUTE', + 'APR_FPROT_WSTICKY', + 'APR_FPROT_WREAD', + 'APR_FPROT_WWRITE', + 'APR_FPROT_WEXECUTE', + 'APR_FPROT_OS_DEFAULT' + ], + 'fopen' => [ + 'APR_FOPEN_READ', + 'APR_FOPEN_WRITE', + 'APR_FOPEN_CREATE', + 'APR_FOPEN_APPEND', + 'APR_FOPEN_TRUNCATE', + 'APR_FOPEN_BINARY', + 'APR_FOPEN_EXCL', + 'APR_FOPEN_BUFFERED', + 'APR_FOPEN_DELONCLOSE', + 'APR_FOPEN_XTHREAD', + 'APR_FOPEN_SHARELOCK', + 'APR_FOPEN_NOCLEANUP', + 'APR_FOPEN_SENDFILE_ENABLED', + 'APR_FOPEN_LARGEFILE' + ], + 'flock' => [ + 'APR_FLOCK_SHARED', + 'APR_FLOCK_EXCLUSIVE', + 'APR_FLOCK_TYPEMASK', + 'APR_FLOCK_NONBLOCK' + ], + 'finfo' => [ + 'APR_FINFO_LINK', + 'APR_FINFO_MTIME', + 'APR_FINFO_CTIME', + 'APR_FINFO_ATIME', + 'APR_FINFO_SIZE', + 'APR_FINFO_CSIZE', + 'APR_FINFO_DEV', + 'APR_FINFO_INODE', + 'APR_FINFO_NLINK', + 'APR_FINFO_TYPE', + 'APR_FINFO_USER', + 'APR_FINFO_GROUP', + 'APR_FINFO_UPROT', + 'APR_FINFO_GPROT', + 'APR_FINFO_WPROT', + 'APR_FINFO_ICASE', + 'APR_FINFO_NAME', + 'APR_FINFO_MIN', + 'APR_FINFO_IDENT', + 'APR_FINFO_OWNER', + 'APR_FINFO_PROT', + 'APR_FINFO_NORM', + 'APR_FINFO_DIRENT' + ], + 'filetype' => [ + 'APR_FILETYPE_NOFILE', + 'APR_FILETYPE_REG', + 'APR_FILETYPE_DIR', + 'APR_FILETYPE_CHR', + 'APR_FILETYPE_BLK', + 'APR_FILETYPE_PIPE', + 'APR_FILETYPE_LNK', + 'APR_FILETYPE_SOCK', + 'APR_FILETYPE_UNKFILE' + ], + 'filepath' => [ + 'APR_FILEPATH_NOTABOVEROOT', + 'APR_FILEPATH_SECUREROOTTEST', + 'APR_FILEPATH_SECUREROOT', + 'APR_FILEPATH_NOTRELATIVE', + 'APR_FILEPATH_NOTABSOLUTE', + 'APR_FILEPATH_NATIVE', + 'APR_FILEPATH_TRUENAME', + 'APR_FILEPATH_ENCODING_UNKNOWN', + 'APR_FILEPATH_ENCODING_LOCALE', + 'APR_FILEPATH_ENCODING_UTF8' + ], + 'error' => [ + 'APR_ENOSTAT', + 'APR_ENOPOOL', + 'APR_EBADDATE', + 'APR_EINVALSOCK', + 'APR_ENOPROC', + 'APR_ENOTIME', + 'APR_ENODIR', + 'APR_ENOLOCK', + 'APR_ENOPOLL', + 'APR_ENOSOCKET', + 'APR_ENOTHREAD', + 'APR_ENOTHDKEY', + 'APR_EGENERAL', + 'APR_ENOSHMAVAIL', + 'APR_EBADIP', + 'APR_EBADMASK', + 'APR_EDSOOPEN', + 'APR_EABSOLUTE', + 'APR_ERELATIVE', + 'APR_EINCOMPLETE', + 'APR_EABOVEROOT', + 'APR_EBADPATH', + 'APR_EPATHWILD', + 'APR_ESYMNOTFOUND', + 'APR_EPROC_UNKNOWN', + 'APR_EOF', + 'APR_EINIT', + 'APR_ENOTIMPL', + 'APR_EMISMATCH', + 'APR_EBUSY', + 'APR_EACCES', + 'APR_EEXIST', + 'APR_ENAMETOOLONG', + 'APR_ENOENT', + 'APR_ENOTDIR', + 'APR_ENOSPC', + 'APR_ENOMEM', + 'APR_EMFILE', + 'APR_ENFILE', + 'APR_EBADF', + 'APR_EINVAL', + 'APR_ESPIPE', + 'APR_EAGAIN', + 'APR_EINTR', + 'APR_ENOTSOCK', + 'APR_ECONNREFUSED', + 'APR_EINPROGRESS', + 'APR_ECONNABORTED', + 'APR_ECONNRESET', + 'APR_ETIMEDOUT', + 'APR_EHOSTUNREACH', + 'APR_ENETUNREACH', + 'APR_EFTYPE', + 'APR_EPIPE', + 'APR_EXDEV', + 'APR_ENOTEMPTY', + 'APR_EXCL', + 'APR_END' + ], + 'common' => [ + 'APR_SUCCESS' + ], + } +}; + + +1;
diff --git a/2_0_13/xs/tables/current/Apache2/FunctionTable.pm b/2_0_13/xs/tables/current/Apache2/FunctionTable.pm new file mode 100644 index 0000000..dd06d45 --- /dev/null +++ b/2_0_13/xs/tables/current/Apache2/FunctionTable.pm
@@ -0,0 +1,15034 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package Apache2::FunctionTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by Apache2::ParseSource/0.02 +# ! Mon May 23 14:15:40 2005 +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$Apache2::FunctionTable = [ + { + 'return_type' => 'void', + 'name' => 'ap_add_file_conf', + 'args' => [ + { + 'type' => 'core_dir_config *', + 'name' => 'conf' + }, + { + 'type' => 'void *', + 'name' => 'url_config' + } + ] + }, + { + 'return_type' => 'ap_filter_t *', + 'name' => 'ap_add_input_filter', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'ap_filter_t *', + 'name' => 'ap_add_input_filter_handle', + 'args' => [ + { + 'type' => 'ap_filter_rec_t *', + 'name' => 'f' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_loaded_module', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'mod' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_module', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_add_named_module', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ap_directive_t *', + 'name' => 'ap_add_node', + 'args' => [ + { + 'type' => 'ap_directive_t **', + 'name' => 'parent' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'current' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'toadd' + }, + { + 'type' => 'int', + 'name' => 'child' + } + ] + }, + { + 'return_type' => 'ap_filter_t *', + 'name' => 'ap_add_output_filter', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'ap_filter_t *', + 'name' => 'ap_add_output_filter_handle', + 'args' => [ + { + 'type' => 'ap_filter_rec_t *', + 'name' => 'f' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_output_filters_by_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_per_dir_conf', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'void *', + 'name' => 'dir_config' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_per_url_conf', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'void *', + 'name' => 'url_config' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_version_component', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'const char *', + 'name' => 'component' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_allow_methods', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'reset' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_allow_options', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_allow_overrides', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_allow_standard_methods', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'reset' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_auth_name', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_auth_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_basic_http_header', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_eoc_create', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_eoc_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_error_create', + 'args' => [ + { + 'type' => 'int', + 'name' => 'error' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_error_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'int', + 'name' => 'error' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_build_config', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'conf_pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'conftree' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_build_cont_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'current' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'curr_parent' + }, + { + 'type' => 'char *', + 'name' => 'orig_directive' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_byterange_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_calc_scoreboard_size', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_cfg_closefile', + 'args' => [ + { + 'type' => 'ap_configfile_t *', + 'name' => 'cfp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_cfg_getc', + 'args' => [ + { + 'type' => 'ap_configfile_t *', + 'name' => 'cfp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_cfg_getline', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'size_t', + 'name' => 'bufsize' + }, + { + 'type' => 'ap_configfile_t *', + 'name' => 'cfp' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_check_cmd_context', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'unsigned', + 'name' => 'forbidden' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cleanup_scoreboard', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'd' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_clear_method_list', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'l' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_close_piped_log', + 'args' => [ + { + 'type' => 'piped_log *', + 'name' => 'pl' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_construct_server', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_construct_url', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'uri' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_content_length_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'arg0' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_content_type_tolower', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_copy_method_list', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'dest' + }, + { + 'type' => 'ap_method_list_t *', + 'name' => 'src' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_core_reorder_directories', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'arg0' + }, + { + 'type' => 'server_rec *', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_core_translate', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_count_dirs', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + } + ] + }, + { + 'return_type' => 'ap_conf_vector_t*', + 'name' => 'ap_create_conn_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ap_conf_vector_t *', + 'name' => 'ap_create_per_dir_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ap_conf_vector_t*', + 'name' => 'ap_create_request_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_create_sb_handle', + 'args' => [ + { + 'type' => 'ap_sb_handle_t **', + 'name' => 'new_sbh' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'child_num' + }, + { + 'type' => 'int', + 'name' => 'thread_num' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_create_scoreboard', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_scoreboard_e', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_custom_response', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'const char *', + 'name' => 'string' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_default_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_destroy_sub_req', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_die', + 'args' => [ + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_directory_walk', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_discard_request_body', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_document_root', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_error_log2stderr', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'ap_escape_errorlog_item', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'dest' + }, + { + 'type' => 'const char *', + 'name' => 'source' + }, + { + 'type' => 'apr_size_t', + 'name' => 'buflen' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_html', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_logitem', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_path_segment', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_quotes', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'instring' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_shell_cmd', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_exists_config_define', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_exists_scoreboard_image', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_explode_recent_gmt', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'tm' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_explode_recent_localtime', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'tm' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fatal_signal_child_setup', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fatal_signal_setup', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fflush', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_field_noparam', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'intype' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_file_walk', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_filter_flush', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_finalize_request_protocol', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_finalize_sub_req_protocol', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'sub_r' + } + ] + }, + { + 'return_type' => 'const command_rec *', + 'name' => 'ap_find_command', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'const command_rec *', + 'name' => 'cmds' + } + ] + }, + { + 'return_type' => 'const command_rec *', + 'name' => 'ap_find_command_in_modules', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'cmd_name' + }, + { + 'type' => 'module **', + 'name' => 'mod' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_find_last_token', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'line' + }, + { + 'type' => 'const char *', + 'name' => 'tok' + } + ] + }, + { + 'return_type' => 'module *', + 'name' => 'ap_find_linked_module', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_find_list_item', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'line' + }, + { + 'type' => 'const char *', + 'name' => 'tok' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_find_module_name', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_find_token', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'line' + }, + { + 'type' => 'const char *', + 'name' => 'tok' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_fini_vhost_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 'main_server' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_fixup_virtual_hosts', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 'main_server' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_flush_conn', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fprintf', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fputstrs', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_get_basic_auth_pw', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char **', + 'name' => 'pw' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_get_brigade', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bucket' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'long', + 'name' => 'ap_get_client_block', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bufsiz' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_get_input_filter_handle', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'apr_off_t', + 'name' => 'ap_get_limit_req_body', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'size_t', + 'name' => 'ap_get_limit_xml_body', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_get_list_item', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'field' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_get_local_host', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_get_mime_headers', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_get_mime_headers_core', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_get_module_config', + 'args' => [ + { + 'type' => 'const ap_conf_vector_t *', + 'name' => 'cv' + }, + { + 'type' => 'const module *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_get_output_filter_handle', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_remote_host', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'conn' + }, + { + 'type' => 'void *', + 'name' => 'dir_config' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'int *', + 'name' => 'str_is_ip' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_remote_logname', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void **', + 'name' => 'ap_get_request_note', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_size_t', + 'name' => 'note_num' + } + ] + }, + { + 'return_type' => 'global_score *', + 'name' => 'ap_get_scoreboard_global', + 'args' => [] + }, + { + 'return_type' => 'process_score *', + 'name' => 'ap_get_scoreboard_process', + 'args' => [ + { + 'type' => 'int', + 'name' => 'x' + } + ] + }, + { + 'return_type' => 'worker_score *', + 'name' => 'ap_get_scoreboard_worker', + 'args' => [ + { + 'type' => 'int', + 'name' => 'x' + }, + { + 'type' => 'int', + 'name' => 'y' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_built', + 'args' => [] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_name', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_port_t', + 'name' => 'ap_get_server_port', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_version', + 'args' => [] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_description', + 'args' => [] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_banner', + 'args' => [] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_status_line', + 'args' => [ + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_get_token', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'accept_line' + }, + { + 'type' => 'int', + 'name' => 'accept_white' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_getline', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'n' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'fold' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_getparents', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'line' + }, + { + 'type' => 'char', + 'name' => 'stop' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_conf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'line' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_conf_nc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'line' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_nc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'line' + }, + { + 'type' => 'char', + 'name' => 'stop' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_nulls', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'line' + }, + { + 'type' => 'char', + 'name' => 'stop' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_nulls_nc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'line' + }, + { + 'type' => 'char', + 'name' => 'stop' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_white', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'line' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_white_nc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'line' + } + ] + }, + { + 'return_type' => 'gid_t', + 'name' => 'ap_gname2id', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_graceful_stop_signalled', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_access_checker', + 'args' => [ + { + 'type' => 'ap_HOOK_access_checker_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_auth_checker', + 'args' => [ + { + 'type' => 'ap_HOOK_auth_checker_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_check_user_id', + 'args' => [ + { + 'type' => 'ap_HOOK_check_user_id_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_child_init', + 'args' => [ + { + 'type' => 'ap_HOOK_child_init_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_create_connection', + 'args' => [ + { + 'type' => 'ap_HOOK_create_connection_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_create_request', + 'args' => [ + { + 'type' => 'ap_HOOK_create_request_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_default_port', + 'args' => [ + { + 'type' => 'ap_HOOK_default_port_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_error_log', + 'args' => [ + { + 'type' => 'ap_HOOK_error_log_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_fixups', + 'args' => [ + { + 'type' => 'ap_HOOK_fixups_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_access_checker', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_auth_checker', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_check_user_id', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_child_init', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_create_connection', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_create_request', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_default_port', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_error_log', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_fixups', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_get_mgmt_items', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_get_suexec_identity', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_handler', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_header_parser', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_http_method', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_insert_error_filter', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_insert_filter', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_log_transaction', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_map_to_storage', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_get_mgmt_items', + 'args' => [ + { + 'type' => 'ap_HOOK_get_mgmt_items_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_open_logs', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_optional_fn_retrieve', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_post_config', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_post_read_request', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_pre_config', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_pre_connection', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_pre_mpm', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_process_connection', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_quick_handler', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_status_hook', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_get_suexec_identity', + 'args' => [ + { + 'type' => 'ap_HOOK_get_suexec_identity_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_translate_name', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_type_checker', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_handler', + 'args' => [ + { + 'type' => 'ap_HOOK_handler_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_header_parser', + 'args' => [ + { + 'type' => 'ap_HOOK_header_parser_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_http_method', + 'args' => [ + { + 'type' => 'ap_HOOK_http_method_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_insert_error_filter', + 'args' => [ + { + 'type' => 'ap_HOOK_insert_error_filter_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_insert_filter', + 'args' => [ + { + 'type' => 'ap_HOOK_insert_filter_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_log_transaction', + 'args' => [ + { + 'type' => 'ap_HOOK_log_transaction_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_map_to_storage', + 'args' => [ + { + 'type' => 'ap_HOOK_map_to_storage_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_open_logs', + 'args' => [ + { + 'type' => 'ap_HOOK_open_logs_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_optional_fn_retrieve', + 'args' => [ + { + 'type' => 'ap_HOOK_optional_fn_retrieve_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_post_config', + 'args' => [ + { + 'type' => 'ap_HOOK_post_config_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_post_read_request', + 'args' => [ + { + 'type' => 'ap_HOOK_post_read_request_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_pre_config', + 'args' => [ + { + 'type' => 'ap_HOOK_pre_config_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_pre_connection', + 'args' => [ + { + 'type' => 'ap_HOOK_pre_connection_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_pre_mpm', + 'args' => [ + { + 'type' => 'ap_HOOK_pre_mpm_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_process_connection', + 'args' => [ + { + 'type' => 'ap_HOOK_process_connection_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_quick_handler', + 'args' => [ + { + 'type' => 'ap_HOOK_quick_handler_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_status_hook', + 'args' => [ + { + 'type' => 'ap_HOOK_status_hook_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_translate_name', + 'args' => [ + { + 'type' => 'ap_HOOK_translate_name_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_type_checker', + 'args' => [ + { + 'type' => 'ap_HOOK_type_checker_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_ht_time', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'int', + 'name' => 'gmt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_http_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_http_header_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_increment_counts', + 'args' => [ + { + 'type' => 'ap_sb_handle_t *', + 'name' => 'sbh' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_ind', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'char', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_index_of_response', + 'args' => [ + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_init_scoreboard', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'shared_score' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_init_vhost_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_init_virtual_host', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'server_rec *', + 'name' => 'main_server' + }, + { + 'type' => 'server_rec **', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_internal_fast_redirect', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'sub_req' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_internal_redirect', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'new_uri' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_internal_redirect_handler', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'new_uri' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_invoke_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_directory', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_initial_req', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_matchexp', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_rdirectory', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_recursion_limit_exceeded', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_url', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'u' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_limit_section', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_lingering_close', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_listen_pre_config', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_location_walk', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_assert', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szExp' + }, + { + 'type' => 'const char *', + 'name' => 'szFile' + }, + { + 'type' => 'int', + 'name' => 'nLine' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_error', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'const server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg6' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_perror', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg6' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_pid', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_rerror', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg6' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_lookup_provider', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_name' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_make_content_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_make_dirstr_parent', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_make_dirstr_prefix', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'd' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_make_etag', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'force_weak' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_make_full_path', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'const char *', + 'name' => 'dir' + }, + { + 'type' => 'const char *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'ap_method_list_t *', + 'name' => 'ap_make_method_list', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'nelts' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_matches_request_vhost', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'host' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_md5', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'string' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_md5_binary', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'buf' + }, + { + 'type' => 'int', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_md5contextTo64', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_md5digest', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'infile' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_meets_conditions', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'ap_conf_vector_t*', + 'name' => 'ap_merge_per_dir_configs', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'base' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'new_conf' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_method_in_list', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'l' + }, + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_method_is_limited', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_method_list_add', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'l' + }, + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_method_list_do', + 'args' => [ + { + 'type' => 'int (*comp) (void *urec, const char *mname, int mnum)', + 'name' => 'arg0' + }, + { + 'type' => 'void *', + 'name' => 'rec' + }, + { + 'type' => 'const ap_method_list_t *', + 'name' => 'ml' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_method_list_remove', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'l' + }, + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_method_list_vdo', + 'args' => [ + { + 'type' => 'int (*comp) (void *urec, const char *mname, int mnum)', + 'name' => 'arg0' + }, + { + 'type' => 'void *', + 'name' => 'rec' + }, + { + 'type' => 'const ap_method_list_t *', + 'name' => 'ml' + }, + { + 'type' => 'va_list', + 'name' => 'vp' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_method_name_of', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'methnum' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_method_number_of', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_method_register', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'methname' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_method_registry_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_pod_check', + 'args' => [ + { + 'type' => 'ap_pod_t *', + 'name' => 'pod' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_pod_close', + 'args' => [ + { + 'type' => 'ap_pod_t *', + 'name' => 'pod' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_mpm_pod_killpg', + 'args' => [ + { + 'type' => 'ap_pod_t *', + 'name' => 'pod' + }, + { + 'type' => 'int', + 'name' => 'num' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_pod_open', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_pod_t **', + 'name' => 'pod' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_pod_signal', + 'args' => [ + { + 'type' => 'ap_pod_t *', + 'name' => 'pod' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_query', + 'args' => [ + { + 'type' => 'int', + 'name' => 'query_code' + }, + { + 'type' => 'int *', + 'name' => 'result' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_mpm_rewrite_args', + 'args' => [ + { + 'type' => 'process_rec *', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_mpm_run', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'server_rec *', + 'name' => 'server_conf' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_accept_lock_mech', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_coredumpdir', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_lockfile', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_max_mem_free', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_max_requests', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_pidfile', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_scoreboard', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_no2slash', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_note_auth_failure', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_note_basic_auth_failure', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_note_digest_auth_failure', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_old_write_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_open_logs', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's_main' + } + ] + }, + { + 'return_type' => 'piped_log *', + 'name' => 'ap_open_piped_log', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'program' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_open_stderr_log', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_os_create_privileged_process', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_proc_t *', + 'name' => 'newproc' + }, + { + 'type' => 'const char *', + 'name' => 'progname' + }, + { + 'type' => 'const char * const *', + 'name' => 'args' + }, + { + 'type' => 'const char * const *', + 'name' => 'env' + }, + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_os_escape_path', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'partial' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_os_is_path_absolute', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'dir' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_parse_htaccess', + 'args' => [ + { + 'type' => 'ap_conf_vector_t **', + 'name' => 'result' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'const char *', + 'name' => 'access_name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_parse_uri', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'uri' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_parse_vhost_addrs', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_pass_brigade', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_pbase64decode', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'bufcoded' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_pbase64encode', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char *', + 'name' => 'string' + } + ] + }, + { + 'return_type' => 'ap_configfile_t *', + 'name' => 'ap_pcfg_open_custom', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'descr' + }, + { + 'type' => 'void *', + 'name' => 'param' + }, + { + 'type' => 'int(*getc_func)(void*)', + 'name' => 'arg3' + }, + { + 'type' => 'void *(*gets_func) (void *buf, size_t bufsiz, void *param)', + 'name' => 'arg4' + }, + { + 'type' => 'int(*close_func)(void *param)', + 'name' => 'arg5' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_pcfg_openfile', + 'args' => [ + { + 'type' => 'ap_configfile_t **', + 'name' => 'ret_cfg' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'ap_pcw_srv_cb_t', + 'name' => 'srv_cb' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_default_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_directory_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'core_server_config *', + 'name' => 'sconf' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_files_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'core_dir_config *', + 'name' => 'dconf' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_location_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'core_server_config *', + 'name' => 'sconf' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_server_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_srv_cb_t', + 'name' => 'srv_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'regex_t *', + 'name' => 'ap_pregcomp', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'pattern' + }, + { + 'type' => 'int', + 'name' => 'cflags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pregfree', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'regex_t *', + 'name' => 'reg' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_pregsub', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'input' + }, + { + 'type' => 'const char *', + 'name' => 'source' + }, + { + 'type' => 'size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'regmatch_t', + 'name' => 'pmatch' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_process_child_status', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'pid' + }, + { + 'type' => 'apr_exit_why_e', + 'name' => 'why' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_process_config_tree', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'conftree' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_process_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'void *', + 'name' => 'csd' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_process_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_process_request_internal', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_process_resource_config', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'conftree' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_psignature', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'prefix' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_time_t', + 'name' => 'ap_rationalize_mtime', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + } + ] + }, + { + 'return_type' => 'server_rec *', + 'name' => 'ap_read_config', + 'args' => [ + { + 'type' => 'process_rec *', + 'name' => 'process' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'const char *', + 'name' => 'config_name' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'conftree' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_read_pid', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'pid_t *', + 'name' => 'mypid' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_read_request', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_recent_ctime', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_recent_rfc822_date', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_reclaim_child_processes', + 'args' => [ + { + 'type' => 'int', + 'name' => 'terminate' + } + ] + }, + { + 'return_type' => 'size_t', + 'name' => 'ap_regerror', + 'args' => [ + { + 'type' => 'int', + 'name' => 'errcode' + }, + { + 'type' => 'const regex_t *', + 'name' => 'preg' + }, + { + 'type' => 'char *', + 'name' => 'errbuf' + }, + { + 'type' => 'size_t', + 'name' => 'errbuf_size' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_regexec', + 'args' => [ + { + 'type' => 'regex_t *', + 'name' => 'preg' + }, + { + 'type' => 'const char *', + 'name' => 'string' + }, + { + 'type' => 'size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'regmatch_t', + 'name' => 'pmatch' + }, + { + 'type' => 'int', + 'name' => 'eflags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_register_extra_mpm_process', + 'args' => [ + { + 'type' => 'pid_t', + 'name' => 'pid' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_register_hooks', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_register_input_filter', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_in_filter_func', + 'name' => 'filter_func' + }, + { + 'type' => 'ap_init_filter_func', + 'name' => 'filter_init' + }, + { + 'type' => 'ap_filter_type', + 'name' => 'ftype' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_register_output_filter', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_out_filter_func', + 'name' => 'filter_func' + }, + { + 'type' => 'ap_init_filter_func', + 'name' => 'filter_init' + }, + { + 'type' => 'ap_filter_type', + 'name' => 'ftype' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_register_provider', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_name' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + }, + { + 'type' => 'const void *', + 'name' => 'provider' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'ap_register_request_note', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_input_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_loaded_module', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'mod' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_module', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_output_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_reopen_scoreboard', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_shm_t **', + 'name' => 'shm' + }, + { + 'type' => 'int', + 'name' => 'detached' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_replace_stderr_log', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'const apr_array_header_t *', + 'name' => 'ap_requires', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_resolve_env', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'word' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_response_code_string', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'error_index' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_rfc1413', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'conn' + }, + { + 'type' => 'server_rec *', + 'name' => 'srv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rflush', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_rgetline_core', + 'args' => [ + { + 'type' => 'char **', + 'name' => 's' + }, + { + 'type' => 'apr_size_t', + 'name' => 'n' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'read' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'fold' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rind', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'char', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rprintf', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rputc', + 'args' => [ + { + 'type' => 'int', + 'name' => 'c' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rputs', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_access_checker', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_auth_checker', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_check_user_id', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_child_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pchild' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'conn_rec *', + 'name' => 'ap_run_create_connection', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'csd' + }, + { + 'type' => 'long', + 'name' => 'conn_id' + }, + { + 'type' => 'void *', + 'name' => 'sbh' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'alloc' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_create_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_port_t', + 'name' => 'ap_run_default_port', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_error_log', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'const server_rec *', + 'name' => 's' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'errstr' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_fixups', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_get_mgmt_items', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'val' + }, + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + } + ] + }, + { + 'return_type' => 'ap_unix_identity_t *', + 'name' => 'ap_run_get_suexec_identity', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_header_parser', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_run_http_method', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_insert_error_filter', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_insert_filter', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_log_transaction', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_map_to_storage', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_open_logs', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_optional_fn_retrieve', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_post_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_post_read_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_pre_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_pre_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'void *', + 'name' => 'csd' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_pre_mpm', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_scoreboard_e', + 'name' => 'sb_type' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_process_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_quick_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'lookup_uri' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_rewrite_args', + 'args' => [ + { + 'type' => 'process_rec *', + 'name' => 'process' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_status_hook', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_sub_req', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_translate_name', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_type_checker', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rvputs', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => '...', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rwrite', + 'args' => [ + { + 'type' => 'const void *', + 'name' => 'buf' + }, + { + 'type' => 'int', + 'name' => 'nbyte' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_satisfies', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_save_brigade', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade **', + 'name' => 'save_to' + }, + { + 'type' => 'apr_bucket_brigade **', + 'name' => 'b' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_send_error_response', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'recursive_error' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_send_fd', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fd' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_send_http_options', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_send_http_trace', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'size_t', + 'name' => 'ap_send_mmap', + 'args' => [ + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'size_t', + 'name' => 'offset' + }, + { + 'type' => 'size_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_server_root_relative', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_set_config_vectors', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'section_vector' + }, + { + 'type' => 'const char *section', + 'name' => 'arg2' + }, + { + 'type' => 'module *', + 'name' => 'mod' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_content_length', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_off_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_content_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'ct' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_deprecated', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_etag', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_file_slot', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_flag_slot', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'int', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_int_slot', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_set_keepalive', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_last_modified', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_listenbacklog', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_listener', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'ips' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_module_config', + 'args' => [ + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'cv' + }, + { + 'type' => 'const module *', + 'name' => 'm' + }, + { + 'type' => 'void *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_name_virtual_host', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_send_buffer_size', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_string_slot', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_string_slot_lower', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_sub_req_protocol', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'rnew' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_setup_client_block', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'read_policy' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_setup_listeners', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_setup_make_content_type', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_setup_prelinked_modules', + 'args' => [ + { + 'type' => 'process_rec *', + 'name' => 'process' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_should_client_block', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_show_directives', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_show_modules', + 'args' => [] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_show_mpm', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_signal_server', + 'args' => [ + { + 'type' => 'int *', + 'name' => 'arg0' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_single_module_configure', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'module *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_size_list_item', + 'args' => [ + { + 'type' => 'const char **', + 'name' => 'field' + }, + { + 'type' => 'int *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_soak_end_container', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'char *', + 'name' => 'directive' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_some_auth_required', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_str_tolower', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_strcasecmp_match', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'const char *', + 'name' => 'expected' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_strcasestr', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 's1' + }, + { + 'type' => 'const char *', + 'name' => 's2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_strchr', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_strchr_c', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_strcmp_match', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'const char *', + 'name' => 'expected' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_stripprefix', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'bigstring' + }, + { + 'type' => 'const char *', + 'name' => 'prefix' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_strrchr', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_strrchr_c', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_strstr', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_strstr_c', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_sub_req_lookup_dirent', + 'args' => [ + { + 'type' => 'const apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'subtype' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next_filter' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_sub_req_lookup_file', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'new_file' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next_filter' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_sub_req_lookup_uri', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'new_uri' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next_filter' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_sub_req_method_uri', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'method' + }, + { + 'type' => 'const char *', + 'name' => 'new_uri' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next_filter' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_sub_req_output_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_time_process_request', + 'args' => [ + { + 'type' => 'ap_sb_handle_t *', + 'name' => 'sbh' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'uid_t', + 'name' => 'ap_uname2id', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unescape_url', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unescape_url_keep2f', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unregister_extra_mpm_process', + 'args' => [ + { + 'type' => 'pid_t', + 'name' => 'pid' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_update_child_status', + 'args' => [ + { + 'type' => 'ap_sb_handle_t *', + 'name' => 'sbh' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_update_child_status_from_indexes', + 'args' => [ + { + 'type' => 'int', + 'name' => 'child_num' + }, + { + 'type' => 'int', + 'name' => 'thread_num' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_update_mtime', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_time_t', + 'name' => 'dependency_mtime' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_update_vhost_from_headers', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_update_vhost_given_ip', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'conn' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_vrprintf', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'va_list', + 'name' => 'vlist' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_wait_or_timeout', + 'args' => [ + { + 'type' => 'apr_exit_why_e *', + 'name' => 'status' + }, + { + 'type' => 'int *', + 'name' => 'exitcode' + }, + { + 'type' => 'apr_proc_t *', + 'name' => 'ret' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_walk_config', + 'args' => [ + { + 'type' => 'ap_directive_t *', + 'name' => 'conftree' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'section_vector' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_xml_parse_input', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_xml_doc **', + 'name' => 'pdoc' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_accept', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'new_sock' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'connection_pool' + } + ] + }, + { + 'return_type' => 'apr_memnode_t *', + 'name' => 'apr_allocator_alloc', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_allocator_create', + 'args' => [ + { + 'type' => 'apr_allocator_t **', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_destroy', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_free', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_memnode_t *', + 'name' => 'memnode' + } + ] + }, + { + 'return_type' => 'apr_thread_mutex_t *', + 'name' => 'apr_allocator_get_mutex', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_allocator_get_owner', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_max_free_set', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'apr_thread_mutex_t *', + 'name' => 'apr_allocator_mutex_get', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_mutex_set', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_allocator_owner_get', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_owner_set', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_set_max_free', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_set_mutex', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_set_owner', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_app_initialize', + 'args' => [ + { + 'type' => 'int *', + 'name' => 'argc' + }, + { + 'type' => 'char const * const * *', + 'name' => 'argv' + }, + { + 'type' => 'char const * const * *', + 'name' => 'env' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_array_append', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'first' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'second' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_array_cat', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'dst' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'src' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_array_copy', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_array_copy_hdr', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_array_make', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'nelts' + }, + { + 'type' => 'int', + 'name' => 'elt_size' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_array_pop', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_array_pstrcat', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'arr' + }, + { + 'type' => 'const char', + 'name' => 'sep' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_array_push', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'apr_int64_t', + 'name' => 'apr_atoi64', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_atomic_add', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_atomic_cas', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + }, + { + 'type' => 'long', + 'name' => 'with' + }, + { + 'type' => 'long', + 'name' => 'cmp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_atomic_dec', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_atomic_inc', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_atomic_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_atomic_set', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_decode', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'plain_dst' + }, + { + 'type' => 'const char *', + 'name' => 'coded_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_decode_binary', + 'args' => [ + { + 'type' => 'unsigned char *', + 'name' => 'plain_dst' + }, + { + 'type' => 'const char *', + 'name' => 'coded_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_decode_len', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'coded_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_encode', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'coded_dst' + }, + { + 'type' => 'const char *', + 'name' => 'plain_src' + }, + { + 'type' => 'int', + 'name' => 'len_plain_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_encode_binary', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'coded_dst' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'plain_src' + }, + { + 'type' => 'int', + 'name' => 'len_plain_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_encode_len', + 'args' => [ + { + 'type' => 'int', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bind', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_bucket_brigade *', + 'name' => 'apr_brigade_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_destroy', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_flatten', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'char *', + 'name' => 'c' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_length', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'int', + 'name' => 'read_all' + }, + { + 'type' => 'apr_off_t *', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_partition', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_off_t', + 'name' => 'point' + }, + { + 'type' => 'apr_bucket **', + 'name' => 'after_point' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_pflatten', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'char **', + 'name' => 'c' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_printf', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg4' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_putc', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_puts', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_putstrs', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_bucket_brigade *', + 'name' => 'apr_brigade_split', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'e' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_split_line', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bbOut' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bbIn' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'maxbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_to_iovec', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'int *', + 'name' => 'nvec' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_vprintf', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'va_list', + 'name' => 'va' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_vputstrs', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'va_list', + 'name' => 'va' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_write', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_writev', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nvec' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_bucket_alloc', + 'args' => [ + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket_alloc_t *', + 'name' => 'apr_bucket_alloc_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_bucket_alloc_t *', + 'name' => 'apr_bucket_alloc_create_ex', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_bucket_alloc_destroy', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_copy_notimpl', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'e' + }, + { + 'type' => 'apr_bucket **', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_bucket_destroy_noop', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_eos_create', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_eos_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_file_create', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fd' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_file_enable_mmap', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'int', + 'name' => 'enabled' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_file_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'fd' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_flush_create', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_flush_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_bucket_free', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'block' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_heap_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + }, + { + 'type' => 'void (*free_func)(void *data)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_heap_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + }, + { + 'type' => 'void (*free_func)(void *data)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_immortal_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_immortal_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_mmap_create', + 'args' => [ + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_mmap_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_pipe_create', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thispipe' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_pipe_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thispipe' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_pool_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_pool_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_setaside_noop', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'data' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_setaside_notimpl', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'data' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_shared_copy', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket **', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_bucket_shared_destroy', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_shared_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_shared_split', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_size_t', + 'name' => 'point' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_simple_copy', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket **', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_simple_split', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_size_t', + 'name' => 'point' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_socket_create', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thissock' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_socket_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'thissock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_split_notimpl', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'data' + }, + { + 'type' => 'apr_size_t', + 'name' => 'point' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_transient_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_transient_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_collapse_spaces', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'dest' + }, + { + 'type' => 'const char *', + 'name' => 'src' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_connect', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_cpystrn', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'dst' + }, + { + 'type' => 'const char *', + 'name' => 'src' + }, + { + 'type' => 'apr_size_t', + 'name' => 'dst_size' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_ctime', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_current_userid', + 'args' => [ + { + 'type' => 'apr_uid_t *', + 'name' => 'userid' + }, + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_date_checkmask', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'mask' + } + ] + }, + { + 'return_type' => 'apr_time_t', + 'name' => 'apr_date_parse_http', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'date' + } + ] + }, + { + 'return_type' => 'apr_time_t', + 'name' => 'apr_date_parse_rfc', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'date' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_dbm_close', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_delete', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbm_exists', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_fetch', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'key' + }, + { + 'type' => 'apr_datum_t *', + 'name' => 'pvalue' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_firstkey', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t *', + 'name' => 'pkey' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_dbm_freedatum', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_dbm_get_usednames', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'pathname' + }, + { + 'type' => 'const char **', + 'name' => 'used1' + }, + { + 'type' => 'const char **', + 'name' => 'used2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_get_usednames_ex', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'pathname' + }, + { + 'type' => 'const char **', + 'name' => 'used1' + }, + { + 'type' => 'const char **', + 'name' => 'used2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_dbm_geterror', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'int *', + 'name' => 'errcode' + }, + { + 'type' => 'char *', + 'name' => 'errbuf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'errbufsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_nextkey', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t *', + 'name' => 'pkey' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_open', + 'args' => [ + { + 'type' => 'apr_dbm_t **', + 'name' => 'dbm' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cntxt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_open_ex', + 'args' => [ + { + 'type' => 'apr_dbm_t **', + 'name' => 'dbm' + }, + { + 'type' => 'const char*', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cntxt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_store', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'key' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'value' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_close', + 'args' => [ + { + 'type' => 'apr_dir_t *', + 'name' => 'thedir' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_make', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_make_recursive', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_open', + 'args' => [ + { + 'type' => 'apr_dir_t **', + 'name' => 'new_dir' + }, + { + 'type' => 'const char *', + 'name' => 'dirname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_read', + 'args' => [ + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'apr_dir_t *', + 'name' => 'thedir' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_remove', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_rewind', + 'args' => [ + { + 'type' => 'apr_dir_t *', + 'name' => 'thedir' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_dso_error', + 'args' => [ + { + 'type' => 'apr_dso_handle_t *', + 'name' => 'dso' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bufsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dso_load', + 'args' => [ + { + 'type' => 'apr_dso_handle_t **', + 'name' => 'res_handle' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dso_sym', + 'args' => [ + { + 'type' => 'apr_dso_handle_sym_t *', + 'name' => 'ressym' + }, + { + 'type' => 'apr_dso_handle_t *', + 'name' => 'handle' + }, + { + 'type' => 'const char *', + 'name' => 'symname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dso_unload', + 'args' => [ + { + 'type' => 'apr_dso_handle_t *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_dynamic_fn_register', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'apr_opt_fn_t *', + 'name' => 'pfn' + } + ] + }, + { + 'return_type' => 'apr_opt_fn_t *', + 'name' => 'apr_dynamic_fn_retrieve', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_env_delete', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'envvar' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_env_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'value' + }, + { + 'type' => 'const char *', + 'name' => 'envvar' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_env_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'envvar' + }, + { + 'type' => 'const char *', + 'name' => 'value' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_explode_localtime', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_t', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_explode_time', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_t', + 'name' => 'input' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'offs' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_append', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'from_path' + }, + { + 'type' => 'const char *', + 'name' => 'to_path' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_attrs_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_fileattrs_t', + 'name' => 'attributes' + }, + { + 'type' => 'apr_fileattrs_t', + 'name' => 'attr_mask' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_close', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_copy', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'from_path' + }, + { + 'type' => 'const char *', + 'name' => 'to_path' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_data_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_data_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'file' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_dup', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'new_file' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'old_file' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_dup2', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'new_file' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'old_file' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_eof', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fptr' + } + ] + }, + { + 'return_type' => 'apr_int32_t', + 'name' => 'apr_file_flags_get', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_flush', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_getc', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'ch' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_gets', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'str' + }, + { + 'type' => 'int', + 'name' => 'len' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_info_get', + 'args' => [ + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_inherit_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_inherit_unset', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_lock', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_mktemp', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'fp' + }, + { + 'type' => 'char *', + 'name' => 'templ' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_mtime_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_name_get', + 'args' => [ + { + 'type' => 'const char **', + 'name' => 'new_path' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_namedpipe_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'newf' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flag' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_stderr', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_stdin', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_stdout', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_perms_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perms' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_pipe_create', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'in' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'out' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_pipe_timeout_get', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thepipe' + }, + { + 'type' => 'apr_interval_time_t *', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_pipe_timeout_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thepipe' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_file_pool_get', + 'args' => [ + { + 'type' => 'const apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_file_printf', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fptr' + }, + { + 'type' => 'const char *', + 'name' => 'format' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_putc', + 'args' => [ + { + 'type' => 'char', + 'name' => 'ch' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_puts', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_read', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_read_full', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbytes' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'bytes_read' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_remove', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_rename', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'from_path' + }, + { + 'type' => 'const char *', + 'name' => 'to_path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_seek', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'apr_seek_where_t', + 'name' => 'where' + }, + { + 'type' => 'apr_off_t *', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_file_set_inherit', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_setaside', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'new_file' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'old_file' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_trunc', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fp' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_ungetc', + 'args' => [ + { + 'type' => 'char', + 'name' => 'ch' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_unlock', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_file_unset_inherit', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_write', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'const void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_write_full', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'const void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbytes' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'bytes_written' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_writev', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nvec' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_filename_of_pathname', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pathname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_encoding', + 'args' => [ + { + 'type' => 'int *', + 'name' => 'style' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'path' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_list_merge', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'liststr' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'pathelts' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_list_split', + 'args' => [ + { + 'type' => 'apr_array_header_t **', + 'name' => 'pathelts' + }, + { + 'type' => 'const char *', + 'name' => 'liststr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_merge', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'newpath' + }, + { + 'type' => 'const char *', + 'name' => 'rootpath' + }, + { + 'type' => 'const char *', + 'name' => 'addpath' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_filepath_name_get', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pathname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_root', + 'args' => [ + { + 'type' => 'const char **', + 'name' => 'rootpath' + }, + { + 'type' => 'const char **', + 'name' => 'filepath' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_fnmatch', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pattern' + }, + { + 'type' => 'const char *', + 'name' => 'strings' + }, + { + 'type' => 'int', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_fnmatch_test', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pattern' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_generate_random_bytes', + 'args' => [ + { + 'type' => 'unsigned char *', + 'name' => 'buf' + }, + { + 'type' => 'int', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_get_groupid', + 'args' => [ + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'const char *', + 'name' => 'groupname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_get_groupname', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'groupname' + }, + { + 'type' => 'apr_gid_t', + 'name' => 'groupid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_get_home_directory', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'dirname' + }, + { + 'type' => 'const char *', + 'name' => 'username' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_get_userid', + 'args' => [ + { + 'type' => 'apr_uid_t *', + 'name' => 'userid' + }, + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'const char *', + 'name' => 'username' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_get_username', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'username' + }, + { + 'type' => 'apr_uid_t', + 'name' => 'userid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_gethostname', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'int', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getnameinfo', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'hostname' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getopt', + 'args' => [ + { + 'type' => 'apr_getopt_t *', + 'name' => 'os' + }, + { + 'type' => 'const char *', + 'name' => 'opts' + }, + { + 'type' => 'char *', + 'name' => 'option_ch' + }, + { + 'type' => 'const char **', + 'name' => 'option_arg' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getopt_init', + 'args' => [ + { + 'type' => 'apr_getopt_t **', + 'name' => 'os' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + }, + { + 'type' => 'int', + 'name' => 'argc' + }, + { + 'type' => 'const char * const *', + 'name' => 'argv' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getopt_long', + 'args' => [ + { + 'type' => 'apr_getopt_t *', + 'name' => 'os' + }, + { + 'type' => 'const apr_getopt_option_t *', + 'name' => 'opts' + }, + { + 'type' => 'int *', + 'name' => 'option_ch' + }, + { + 'type' => 'const char **', + 'name' => 'option_arg' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getservbyname', + 'args' => [ + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + }, + { + 'type' => 'const char *', + 'name' => 'servname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getsocketopt', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + }, + { + 'type' => 'apr_int32_t *', + 'name' => 'on' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_gid_get', + 'args' => [ + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'const char *', + 'name' => 'groupname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_gid_name_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'groupname' + }, + { + 'type' => 'apr_gid_t', + 'name' => 'groupid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_child_init', + 'args' => [ + { + 'type' => 'apr_global_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_create', + 'args' => [ + { + 'type' => 'apr_global_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_lockmech_e', + 'name' => 'mech' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_destroy', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_lock', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_global_mutex_pool_get', + 'args' => [ + { + 'type' => 'const apr_global_mutex_t *', + 'name' => 'theglobal_mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_trylock', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_unlock', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_group_name_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'groupname' + }, + { + 'type' => 'apr_gid_t', + 'name' => 'groupid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_copy', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'h' + } + ] + }, + { + 'return_type' => 'unsigned int', + 'name' => 'apr_hash_count', + 'args' => [ + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + } + ] + }, + { + 'return_type' => 'apr_hash_index_t *', + 'name' => 'apr_hash_first', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_hash_get', + 'args' => [ + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + }, + { + 'type' => 'const void *', + 'name' => 'key' + }, + { + 'type' => 'apr_ssize_t', + 'name' => 'klen' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_make', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'h1' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'h2' + }, + { + 'type' => 'void * (*merger)(apr_pool_t *p, const void *key, apr_ssize_t klen, const void *h1_val, const void *h2_val, const void *data)', + 'name' => 'arg3' + }, + { + 'type' => 'const void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_hash_index_t *', + 'name' => 'apr_hash_next', + 'args' => [ + { + 'type' => 'apr_hash_index_t *', + 'name' => 'hi' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_overlay', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'overlay' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'base' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_hash_pool_get', + 'args' => [ + { + 'type' => 'const apr_hash_t *', + 'name' => 'thehash' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hash_set', + 'args' => [ + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + }, + { + 'type' => 'const void *', + 'name' => 'key' + }, + { + 'type' => 'apr_ssize_t', + 'name' => 'klen' + }, + { + 'type' => 'const void *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hash_this', + 'args' => [ + { + 'type' => 'apr_hash_index_t *', + 'name' => 'hi' + }, + { + 'type' => 'const void **', + 'name' => 'key' + }, + { + 'type' => 'apr_ssize_t *', + 'name' => 'klen' + }, + { + 'type' => 'void **', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hook_debug_show', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hook_deregister_all', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hook_sort_all', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hook_sort_register', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szHookName' + }, + { + 'type' => 'apr_array_header_t **', + 'name' => 'aHooks' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_implode_gmt', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_initialize', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_ipsubnet_create', + 'args' => [ + { + 'type' => 'apr_ipsubnet_t **', + 'name' => 'ipsub' + }, + { + 'type' => 'const char *', + 'name' => 'ipstr' + }, + { + 'type' => 'const char *', + 'name' => 'mask_or_numbits' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ipsubnet_test', + 'args' => [ + { + 'type' => 'apr_ipsubnet_t *', + 'name' => 'ipsub' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_is_empty_array', + 'args' => [ + { + 'type' => 'const apr_array_header_t *', + 'name' => 'a' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_is_empty_table', + 'args' => [ + { + 'type' => 'const apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_is_fnmatch', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pattern' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_itoa', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_listen', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'backlog' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_lstat', + 'args' => [ + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_ltoa', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'long', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'input' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4_final', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'apr_md4_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4_init', + 'args' => [ + { + 'type' => 'apr_md4_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4_set_xlate', + 'args' => [ + { + 'type' => 'apr_md4_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'apr_xlate_t *', + 'name' => 'xlate' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4_update', + 'args' => [ + { + 'type' => 'apr_md4_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'input' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'const void *', + 'name' => 'input' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_encode', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'password' + }, + { + 'type' => 'const char *', + 'name' => 'salt' + }, + { + 'type' => 'char *', + 'name' => 'result' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_final', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_init', + 'args' => [ + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_set_xlate', + 'args' => [ + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'apr_xlate_t *', + 'name' => 'xlate' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_update', + 'args' => [ + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'const void *', + 'name' => 'input' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mmap_create', + 'args' => [ + { + 'type' => 'apr_mmap_t **', + 'name' => 'newmmap' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flag' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cntxt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mmap_delete', + 'args' => [ + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mmap_dup', + 'args' => [ + { + 'type' => 'apr_mmap_t **', + 'name' => 'new_mmap' + }, + { + 'type' => 'apr_mmap_t *', + 'name' => 'old_mmap' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'transfer_ownership' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mmap_offset', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'addr' + }, + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_off_t_toa', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_off_t', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_optional_hook_add', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'void (*pfn)(void)', + 'name' => 'arg1' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_optional_hook_get', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_os_default_encoding', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_dir_get', + 'args' => [ + { + 'type' => 'apr_os_dir_t **', + 'name' => 'thedir' + }, + { + 'type' => 'apr_dir_t *', + 'name' => 'dir' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_dir_put', + 'args' => [ + { + 'type' => 'apr_dir_t **', + 'name' => 'dir' + }, + { + 'type' => 'apr_os_dir_t *', + 'name' => 'thedir' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_dso_handle_get', + 'args' => [ + { + 'type' => 'apr_os_dso_handle_t *', + 'name' => 'dso' + }, + { + 'type' => 'apr_dso_handle_t *', + 'name' => 'aprdso' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_dso_handle_put', + 'args' => [ + { + 'type' => 'apr_dso_handle_t **', + 'name' => 'dso' + }, + { + 'type' => 'apr_os_dso_handle_t', + 'name' => 'thedso' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_exp_time_get', + 'args' => [ + { + 'type' => 'apr_os_exp_time_t **', + 'name' => 'ostime' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'aprtime' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_exp_time_put', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'aprtime' + }, + { + 'type' => 'apr_os_exp_time_t **', + 'name' => 'ostime' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_file_get', + 'args' => [ + { + 'type' => 'apr_os_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_file_put', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'file' + }, + { + 'type' => 'apr_os_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_global_mutex_get', + 'args' => [ + { + 'type' => 'apr_os_global_mutex_t *', + 'name' => 'ospmutex' + }, + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'pmutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_imp_time_get', + 'args' => [ + { + 'type' => 'apr_os_imp_time_t **', + 'name' => 'ostime' + }, + { + 'type' => 'apr_time_t *', + 'name' => 'aprtime' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_imp_time_put', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'aprtime' + }, + { + 'type' => 'apr_os_imp_time_t **', + 'name' => 'ostime' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_os_locale_encoding', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_pipe_put', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'file' + }, + { + 'type' => 'apr_os_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_pipe_put_ex', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'file' + }, + { + 'type' => 'apr_os_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'int', + 'name' => 'register_cleanup' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_proc_mutex_get', + 'args' => [ + { + 'type' => 'apr_os_proc_mutex_t *', + 'name' => 'ospmutex' + }, + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'pmutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_proc_mutex_put', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t **', + 'name' => 'pmutex' + }, + { + 'type' => 'apr_os_proc_mutex_t *', + 'name' => 'ospmutex' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_shm_get', + 'args' => [ + { + 'type' => 'apr_os_shm_t *', + 'name' => 'osshm' + }, + { + 'type' => 'apr_shm_t *', + 'name' => 'shm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_shm_put', + 'args' => [ + { + 'type' => 'apr_shm_t **', + 'name' => 'shm' + }, + { + 'type' => 'apr_os_shm_t *', + 'name' => 'osshm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_sock_get', + 'args' => [ + { + 'type' => 'apr_os_sock_t *', + 'name' => 'thesock' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_sock_make', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'apr_sock' + }, + { + 'type' => 'apr_os_sock_info_t *', + 'name' => 'os_sock_info' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_sock_put', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'sock' + }, + { + 'type' => 'apr_os_sock_t *', + 'name' => 'thesock' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_os_thread_t', + 'name' => 'apr_os_thread_current', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'apr_os_thread_equal', + 'args' => [ + { + 'type' => 'apr_os_thread_t', + 'name' => 'tid1' + }, + { + 'type' => 'apr_os_thread_t', + 'name' => 'tid2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_thread_get', + 'args' => [ + { + 'type' => 'apr_os_thread_t **', + 'name' => 'thethd' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_thread_put', + 'args' => [ + { + 'type' => 'apr_thread_t **', + 'name' => 'thd' + }, + { + 'type' => 'apr_os_thread_t *', + 'name' => 'thethd' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_threadkey_get', + 'args' => [ + { + 'type' => 'apr_os_threadkey_t *', + 'name' => 'thekey' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_threadkey_put', + 'args' => [ + { + 'type' => 'apr_threadkey_t **', + 'name' => 'key' + }, + { + 'type' => 'apr_os_threadkey_t *', + 'name' => 'thekey' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_palloc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_palloc_debug', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_parse_addr_port', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'addr' + }, + { + 'type' => 'char **', + 'name' => 'scope_id' + }, + { + 'type' => 'apr_port_t *', + 'name' => 'port' + }, + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_password_get', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'prompt' + }, + { + 'type' => 'char *', + 'name' => 'pwbuf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'bufsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_password_validate', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'passwd' + }, + { + 'type' => 'const char *', + 'name' => 'hash' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_pcalloc_debug', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_pmemdup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'm' + }, + { + 'type' => 'apr_size_t', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_poll', + 'args' => [ + { + 'type' => 'apr_pollfd_t *', + 'name' => 'aprset' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'numsock' + }, + { + 'type' => 'apr_int32_t *', + 'name' => 'nsds' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_poll_revents_get', + 'args' => [ + { + 'type' => 'apr_int16_t *', + 'name' => 'event' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_pollfd_t *', + 'name' => 'aprset' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_poll_setup', + 'args' => [ + { + 'type' => 'apr_pollfd_t **', + 'name' => 'new_poll' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'num' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_poll_socket_add', + 'args' => [ + { + 'type' => 'apr_pollfd_t *', + 'name' => 'aprset' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'event' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_poll_socket_clear', + 'args' => [ + { + 'type' => 'apr_pollfd_t *', + 'name' => 'aprset' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'events' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_poll_socket_mask', + 'args' => [ + { + 'type' => 'apr_pollfd_t *', + 'name' => 'aprset' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'events' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_poll_socket_remove', + 'args' => [ + { + 'type' => 'apr_pollfd_t *', + 'name' => 'aprset' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_add', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + }, + { + 'type' => 'const apr_pollfd_t *', + 'name' => 'descriptor' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_create', + 'args' => [ + { + 'type' => 'apr_pollset_t **', + 'name' => 'pollset' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'size' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_destroy', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_poll', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_int32_t *', + 'name' => 'num' + }, + { + 'type' => 'const apr_pollfd_t **', + 'name' => 'descriptors' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_remove', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + }, + { + 'type' => 'const apr_pollfd_t *', + 'name' => 'descriptor' + } + ] + }, + { + 'return_type' => 'apr_abortfunc_t', + 'name' => 'apr_pool_abort_get', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_abort_set', + 'args' => [ + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abortfunc' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_allocator_t *', + 'name' => 'apr_pool_allocator_get', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_child_cleanup_set', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*plain_cleanup)(void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_status_t (*child_cleanup)(void *)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_cleanup_for_exec', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_cleanup_kill', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_cleanup_null', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_cleanup_register', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*plain_cleanup)(void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_status_t (*child_cleanup)(void *)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_cleanup_run', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_clear', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_clear_debug', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_create_ex', + 'args' => [ + { + 'type' => 'apr_pool_t **', + 'name' => 'newpool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'parent' + }, + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abort_fn' + }, + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_create_ex_debug', + 'args' => [ + { + 'type' => 'apr_pool_t **', + 'name' => 'newpool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'parent' + }, + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abort_fn' + }, + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_destroy', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_destroy_debug', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'apr_abortfunc_t', + 'name' => 'apr_pool_get_abort', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_pool_get_parent', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_initialize', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'apr_pool_is_ancestor', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_note_subprocess', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'apr_kill_conditions_e', + 'name' => 'how' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_pool_parent_get', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_set_abort', + 'args' => [ + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abortfunc' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_tag', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'tag' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_terminate', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_userdata_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_userdata_set', + 'args' => [ + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_userdata_setn', + 'args' => [ + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_create', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'new_proc' + }, + { + 'type' => 'const char *', + 'name' => 'progname' + }, + { + 'type' => 'const char * const *', + 'name' => 'args' + }, + { + 'type' => 'const char * const *', + 'name' => 'env' + }, + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_detach', + 'args' => [ + { + 'type' => 'int', + 'name' => 'daemonize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_fork', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_kill', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int', + 'name' => 'sig' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_child_init', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_create', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_lockmech_e', + 'name' => 'mech' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_proc_mutex_defname', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_destroy', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_lock', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_proc_mutex_lockfile', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_proc_mutex_name', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_proc_mutex_pool_get', + 'args' => [ + { + 'type' => 'const apr_proc_mutex_t *', + 'name' => 'theproc_mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_trylock', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_unlock', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_other_child_alert', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int', + 'name' => 'reason' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_check', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_other_child_read', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_refresh', + 'args' => [ + { + 'type' => 'apr_other_child_rec_t *', + 'name' => 'ocr' + }, + { + 'type' => 'int', + 'name' => 'reason' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_refresh_all', + 'args' => [ + { + 'type' => 'int', + 'name' => 'reason' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_register', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'void (*maintenance) (int reason, void *, int status)', + 'name' => 'arg1' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'write_fd' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_unregister', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_wait', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int *', + 'name' => 'exitcode' + }, + { + 'type' => 'apr_exit_why_e *', + 'name' => 'exitwhy' + }, + { + 'type' => 'apr_wait_how_e', + 'name' => 'waithow' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_wait_all_procs', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int *', + 'name' => 'exitcode' + }, + { + 'type' => 'apr_exit_why_e *', + 'name' => 'exitwhy' + }, + { + 'type' => 'apr_wait_how_e', + 'name' => 'waithow' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_child_err_set', + 'args' => [ + { + 'type' => 'struct apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'child_err' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'parent_err' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_child_errfn_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_child_errfn_t *', + 'name' => 'errfn' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_child_in_set', + 'args' => [ + { + 'type' => 'struct apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'child_in' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'parent_in' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_child_out_set', + 'args' => [ + { + 'type' => 'struct apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'child_out' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'parent_out' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_cmdtype_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_cmdtype_e', + 'name' => 'cmd' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_create', + 'args' => [ + { + 'type' => 'apr_procattr_t **', + 'name' => 'new_attr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_detach_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'detach' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_dir_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'const char *', + 'name' => 'dir' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_error_check_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'chk' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_io_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'in' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'out' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'err' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_limit_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'what' + }, + { + 'type' => 'struct rlimit *', + 'name' => 'limit' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_psprintf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrcat', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => '...', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrcatv', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nvec' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrdup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrmemdup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'apr_size_t', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrndup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'apr_size_t', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pvsprintf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'va_list', + 'name' => 'ap' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_create', + 'args' => [ + { + 'type' => 'apr_queue_t **', + 'name' => 'queue' + }, + { + 'type' => 'unsigned int', + 'name' => 'queue_capacity' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_interrupt_all', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_pop', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + }, + { + 'type' => 'void **', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_push', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'unsigned int', + 'name' => 'apr_queue_size', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_term', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_trypop', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + }, + { + 'type' => 'void **', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_trypush', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_recv', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_recvfrom', + 'args' => [ + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'from' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_register_optional_fn', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'apr_opt_fn_t *', + 'name' => 'pfn' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_acquire', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + }, + { + 'type' => 'void **', + 'name' => 'resource' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_create', + 'args' => [ + { + 'type' => 'apr_reslist_t **', + 'name' => 'reslist' + }, + { + 'type' => 'int', + 'name' => 'min' + }, + { + 'type' => 'int', + 'name' => 'smax' + }, + { + 'type' => 'int', + 'name' => 'hmax' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'ttl' + }, + { + 'type' => 'apr_reslist_constructor', + 'name' => 'con' + }, + { + 'type' => 'apr_reslist_destructor', + 'name' => 'de' + }, + { + 'type' => 'void *', + 'name' => 'params' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_destroy', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_release', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + }, + { + 'type' => 'void *', + 'name' => 'resource' + } + ] + }, + { + 'return_type' => 'apr_opt_fn_t *', + 'name' => 'apr_retrieve_optional_fn', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_rfc822_date', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_close', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_delete', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'const apr_sdbm_datum_t', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_fetch', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'apr_sdbm_datum_t *', + 'name' => 'value' + }, + { + 'type' => 'apr_sdbm_datum_t', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_firstkey', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'apr_sdbm_datum_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_lock', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_nextkey', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'apr_sdbm_datum_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_open', + 'args' => [ + { + 'type' => 'apr_sdbm_t **', + 'name' => 'db' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_sdbm_rdonly', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_store', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'apr_sdbm_datum_t', + 'name' => 'key' + }, + { + 'type' => 'apr_sdbm_datum_t', + 'name' => 'value' + }, + { + 'type' => 'int', + 'name' => 'opt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_unlock', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_send', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sendfile', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + }, + { + 'type' => 'apr_hdtr_t *', + 'name' => 'hdtr' + }, + { + 'type' => 'apr_off_t *', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sendto', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'where' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sendv', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'nvec' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_setsocketopt', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'on' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_setup_signal_thread', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_base64', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'clear' + }, + { + 'type' => 'int', + 'name' => 'len' + }, + { + 'type' => 'char *', + 'name' => 'out' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_final', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'apr_sha1_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_init', + 'args' => [ + { + 'type' => 'apr_sha1_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_update', + 'args' => [ + { + 'type' => 'apr_sha1_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'const char *', + 'name' => 'input' + }, + { + 'type' => 'unsigned int', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_update_binary', + 'args' => [ + { + 'type' => 'apr_sha1_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'input' + }, + { + 'type' => 'unsigned int', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_attach', + 'args' => [ + { + 'type' => 'apr_shm_t **', + 'name' => 'm' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_shm_baseaddr_get', + 'args' => [ + { + 'type' => 'const apr_shm_t *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_create', + 'args' => [ + { + 'type' => 'apr_shm_t **', + 'name' => 'm' + }, + { + 'type' => 'apr_size_t', + 'name' => 'reqsize' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_destroy', + 'args' => [ + { + 'type' => 'apr_shm_t *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_detach', + 'args' => [ + { + 'type' => 'apr_shm_t *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_shm_pool_get', + 'args' => [ + { + 'type' => 'const apr_shm_t *', + 'name' => 'theshm' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_shm_size_get', + 'args' => [ + { + 'type' => 'const apr_shm_t *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_show_hook', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shutdown', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + }, + { + 'type' => 'apr_shutdown_how_e', + 'name' => 'how' + } + ] + }, + { + 'return_type' => 'apr_sigfunc_t *', + 'name' => 'apr_signal', + 'args' => [ + { + 'type' => 'int', + 'name' => 'signo' + }, + { + 'type' => 'apr_sigfunc_t * func', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_signal_description_get', + 'args' => [ + { + 'type' => 'int', + 'name' => 'signum' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_signal_get_description', + 'args' => [ + { + 'type' => 'int', + 'name' => 'signum' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_signal_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pglobal' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_signal_thread', + 'args' => [ + { + 'type' => 'int(*signal_handler)(int signum)', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sleep', + 'args' => [ + { + 'type' => 'apr_interval_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_snprintf', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'const char *', + 'name' => 'format' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_sockaddr_equal', + 'args' => [ + { + 'type' => 'const apr_sockaddr_t *', + 'name' => 'addr1' + }, + { + 'type' => 'const apr_sockaddr_t *', + 'name' => 'addr2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sockaddr_info_get', + 'args' => [ + { + 'type' => 'apr_sockaddr_t **', + 'name' => 'sa' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'family' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sockaddr_ip_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'addr' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sockaddr_ip_set', + 'args' => [ + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + }, + { + 'type' => 'const char *', + 'name' => 'addr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sockaddr_port_get', + 'args' => [ + { + 'type' => 'apr_port_t *', + 'name' => 'port' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sockaddr_port_set', + 'args' => [ + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_accept', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'new_sock' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'connection_pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_addr_get', + 'args' => [ + { + 'type' => 'apr_sockaddr_t **', + 'name' => 'sa' + }, + { + 'type' => 'apr_interface_e', + 'name' => 'which' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_atmark', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'int *', + 'name' => 'atmark' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_bind', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_close', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_connect', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_create', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'new_sock' + }, + { + 'type' => 'int', + 'name' => 'family' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_create_ex', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'new_sock' + }, + { + 'type' => 'int', + 'name' => 'family' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'int', + 'name' => 'protocol' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_data_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_data_set', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup)(void*)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_from_file', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'newsock' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_inherit_set', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_inherit_unset', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_listen', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'backlog' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_opt_get', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + }, + { + 'type' => 'apr_int32_t *', + 'name' => 'on' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_opt_set', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'on' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_protocol_get', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'int *', + 'name' => 'protocol' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_recv', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_recvfrom', + 'args' => [ + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'from' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_send', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_sendfile', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + }, + { + 'type' => 'apr_hdtr_t *', + 'name' => 'hdtr' + }, + { + 'type' => 'apr_off_t *', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_sendto', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'where' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_sendv', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'nvec' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_socket_set_inherit', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'skt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_shutdown', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + }, + { + 'type' => 'apr_shutdown_how_e', + 'name' => 'how' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_timeout_get', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_interval_time_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_timeout_set', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_socket_unset_inherit', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'skt' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sort_hooks', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_stat', + 'args' => [ + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_strerror', + 'args' => [ + { + 'type' => 'apr_status_t', + 'name' => 'statcode' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bufsize' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_strfsize', + 'args' => [ + { + 'type' => 'apr_off_t', + 'name' => 'size' + }, + { + 'type' => 'char *', + 'name' => 'buf' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_strftime', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'retsize' + }, + { + 'type' => 'apr_size_t', + 'name' => 'max' + }, + { + 'type' => 'const char *', + 'name' => 'format' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'tm' + } + ] + }, + { + 'return_type' => 'const apr_strmatch_pattern *', + 'name' => 'apr_strmatch_precompile', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'case_sensitive' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_strnatcasecmp', + 'args' => [ + { + 'type' => 'char const *', + 'name' => 'a' + }, + { + 'type' => 'char const *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_strnatcmp', + 'args' => [ + { + 'type' => 'char const *', + 'name' => 'a' + }, + { + 'type' => 'char const *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_int64_t', + 'name' => 'apr_strtoi64', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'char **', + 'name' => 'end' + }, + { + 'type' => 'int', + 'name' => 'base' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_strtok', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'str' + }, + { + 'type' => 'const char *', + 'name' => 'sep' + }, + { + 'type' => 'char **', + 'name' => 'last' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_add', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_addn', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_clear', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_compress', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'unsigned', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_table_t *', + 'name' => 'apr_table_copy', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_table_do', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'comp' + }, + { + 'type' => 'void *', + 'name' => 'rec' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 't' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'const apr_array_header_t *', + 'name' => 'apr_table_elts', + 'args' => [ + { + 'type' => 'const apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_table_get', + 'args' => [ + { + 'type' => 'const apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_table_t *', + 'name' => 'apr_table_make', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'nelts' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_merge', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_mergen', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_overlap', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 'a' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 'b' + }, + { + 'type' => 'unsigned', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_table_t *', + 'name' => 'apr_table_overlay', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 'overlay' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 'base' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_set', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_setn', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_unset', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_table_vdo', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'comp' + }, + { + 'type' => 'void *', + 'name' => 'rec' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'va_list', + 'name' => 'vp' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_temp_dir_get', + 'args' => [ + { + 'type' => 'const char **', + 'name' => 'temp_dir' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_terminate', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_terminate2', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_text_append', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_text_header *', + 'name' => 'hdr' + }, + { + 'type' => 'const char *', + 'name' => 'text' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_broadcast', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_create', + 'args' => [ + { + 'type' => 'apr_thread_cond_t **', + 'name' => 'cond' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_destroy', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_thread_cond_pool_get', + 'args' => [ + { + 'type' => 'const apr_thread_cond_t *', + 'name' => 'thethread_cond' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_signal', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_timedwait', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_wait', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_create', + 'args' => [ + { + 'type' => 'apr_thread_t **', + 'name' => 'new_thread' + }, + { + 'type' => 'apr_threadattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_thread_start_t func', + 'name' => 'arg2' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_data_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'thread' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_data_set', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup) (void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'thread' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_detach', + 'args' => [ + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_exit', + 'args' => [ + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + }, + { + 'type' => 'apr_status_t', + 'name' => 'retval' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_join', + 'args' => [ + { + 'type' => 'apr_status_t *', + 'name' => 'retval' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_create', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'unsigned int', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_destroy', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_lock', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_thread_mutex_pool_get', + 'args' => [ + { + 'type' => 'const apr_thread_mutex_t *', + 'name' => 'thethread_mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_trylock', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_unlock', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_once', + 'args' => [ + { + 'type' => 'apr_thread_once_t *', + 'name' => 'control' + }, + { + 'type' => 'void (*func)(void)', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_once_init', + 'args' => [ + { + 'type' => 'apr_thread_once_t **', + 'name' => 'control' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_thread_pool_get', + 'args' => [ + { + 'type' => 'const apr_thread_t *', + 'name' => 'thethread' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_create', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t **', + 'name' => 'rwlock' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_destroy', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_thread_rwlock_pool_get', + 'args' => [ + { + 'type' => 'const apr_thread_rwlock_t *', + 'name' => 'thethread_rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_rdlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_tryrdlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_trywrlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_unlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_wrlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_thread_yield', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadattr_create', + 'args' => [ + { + 'type' => 'apr_threadattr_t **', + 'name' => 'new_attr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadattr_detach_get', + 'args' => [ + { + 'type' => 'apr_threadattr_t *', + 'name' => 'attr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadattr_detach_set', + 'args' => [ + { + 'type' => 'apr_threadattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'on' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_data_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'threadkey' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_data_set', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup) (void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'threadkey' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_private_create', + 'args' => [ + { + 'type' => 'apr_threadkey_t **', + 'name' => 'key' + }, + { + 'type' => 'void (*dest)(void *)', + 'name' => 'arg1' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_private_delete', + 'args' => [ + { + 'type' => 'apr_threadkey_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_private_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'new_mem' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_private_set', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'priv' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_ansi_put', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'result' + }, + { + 'type' => 'time_t', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_time_clock_hires', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_get', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_gmt', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_t', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_gmt_get', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_lt', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_t', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_tz', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_t', + 'name' => 'input' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'offs' + } + ] + }, + { + 'return_type' => 'apr_time_t', + 'name' => 'apr_time_now', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_tokenize_to_argv', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'arg_str' + }, + { + 'type' => 'char ***', + 'name' => 'argv_out' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'token_context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uid_current', + 'args' => [ + { + 'type' => 'apr_uid_t *', + 'name' => 'userid' + }, + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uid_get', + 'args' => [ + { + 'type' => 'apr_uid_t *', + 'name' => 'userid' + }, + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'const char *', + 'name' => 'username' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uid_homepath_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'dirname' + }, + { + 'type' => 'const char *', + 'name' => 'username' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uid_name_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'username' + }, + { + 'type' => 'apr_uid_t', + 'name' => 'userid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_port_t', + 'name' => 'apr_uri_default_port_for_scheme', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'scheme_str' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_uri_parse', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'uri' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'uptr' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_uri_parse_hostinfo', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'hostinfo' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'uptr' + } + ] + }, + { + 'return_type' => 'apr_port_t', + 'name' => 'apr_uri_port_of_scheme', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'scheme_str' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_uri_unparse', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_uri_t *', + 'name' => 'uptr' + }, + { + 'type' => 'unsigned', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_uuid_format', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'const apr_uuid_t *', + 'name' => 'uuid' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_uuid_get', + 'args' => [ + { + 'type' => 'apr_uuid_t *', + 'name' => 'uuid' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uuid_parse', + 'args' => [ + { + 'type' => 'apr_uuid_t *', + 'name' => 'uuid' + }, + { + 'type' => 'const char *', + 'name' => 'uuid_str' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_version', + 'args' => [ + { + 'type' => 'apr_version_t *', + 'name' => 'pvsn' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_version_string', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'apr_vformatter', + 'args' => [ + { + 'type' => 'int (*flush_func)(apr_vformatter_buff_t *b)', + 'name' => 'arg0' + }, + { + 'type' => 'apr_vformatter_buff_t *', + 'name' => 'c' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'va_list', + 'name' => 'ap' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_vsnprintf', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'const char *', + 'name' => 'format' + }, + { + 'type' => 'va_list', + 'name' => 'ap' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_wait_for_io_or_timeout', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'for_read' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_close', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_conv_buffer', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + }, + { + 'type' => 'const char *', + 'name' => 'inbuf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'inbytes_left' + }, + { + 'type' => 'char *', + 'name' => 'outbuf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'outbytes_left' + } + ] + }, + { + 'return_type' => 'apr_int32_t', + 'name' => 'apr_xlate_conv_byte', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + }, + { + 'type' => 'unsigned char', + 'name' => 'inchar' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_get_sb', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + }, + { + 'type' => 'int *', + 'name' => 'onoff' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_open', + 'args' => [ + { + 'type' => 'apr_xlate_t **', + 'name' => 'convset' + }, + { + 'type' => 'const char *', + 'name' => 'topage' + }, + { + 'type' => 'const char *', + 'name' => 'frompage' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_sb_get', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + }, + { + 'type' => 'int *', + 'name' => 'onoff' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_xml_empty_elem', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_xml_elem *', + 'name' => 'elem' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_xml_insert_uri', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'uri_array' + }, + { + 'type' => 'const char *', + 'name' => 'uri' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xml_parse_file', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_xml_parser **', + 'name' => 'parser' + }, + { + 'type' => 'apr_xml_doc **', + 'name' => 'ppdoc' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'xmlfd' + }, + { + 'type' => 'apr_size_t', + 'name' => 'buffer_length' + } + ] + }, + { + 'return_type' => 'apr_xml_parser *', + 'name' => 'apr_xml_parser_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xml_parser_done', + 'args' => [ + { + 'type' => 'apr_xml_parser *', + 'name' => 'parser' + }, + { + 'type' => 'apr_xml_doc **', + 'name' => 'pdoc' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xml_parser_feed', + 'args' => [ + { + 'type' => 'apr_xml_parser *', + 'name' => 'parser' + }, + { + 'type' => 'const char *', + 'name' => 'data' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_xml_parser_geterror', + 'args' => [ + { + 'type' => 'apr_xml_parser *', + 'name' => 'parser' + }, + { + 'type' => 'char *', + 'name' => 'errbuf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'errbufsize' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_xml_quote_elem', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'elem' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_xml_quote_string', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'quotes' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_xml_to_text', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_xml_elem *', + 'name' => 'elem' + }, + { + 'type' => 'int', + 'name' => 'style' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'namespaces' + }, + { + 'type' => 'int *', + 'name' => 'ns_map' + }, + { + 'type' => 'const char **', + 'name' => 'pbuf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'psize' + } + ] + } +]; + + +1;
diff --git a/2_0_13/xs/tables/current/Apache2/StructureTable.pm b/2_0_13/xs/tables/current/Apache2/StructureTable.pm new file mode 100644 index 0000000..80dd06c --- /dev/null +++ b/2_0_13/xs/tables/current/Apache2/StructureTable.pm
@@ -0,0 +1,3461 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package Apache2::StructureTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by Apache::ParseSource/0.02 +# ! Fri Dec 10 14:14:10 2004 +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$Apache2::StructureTable = [ + { + 'type' => 'ap_HOOK_access_checker_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_auth_checker_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_check_user_id_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_child_init_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_create_connection_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_create_request_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_default_port_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_error_log_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_fixups_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_get_mgmt_items_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_get_suexec_identity_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_handler_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_header_parser_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_http_method_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_insert_error_filter_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_insert_filter_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_log_transaction_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_map_to_storage_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_open_logs_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_optional_fn_retrieve_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_post_config_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_post_read_request_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_pre_config_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_pre_connection_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_pre_mpm_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_process_connection_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_quick_handler_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_status_hook_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_translate_name_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_type_checker_t', + 'elts' => [] + }, + { + 'type' => 'ap_LINK_access_checker_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_access_checker_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_auth_checker_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_auth_checker_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_check_user_id_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_check_user_id_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_child_init_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_child_init_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_create_connection_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_create_connection_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_create_request_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_create_request_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_default_port_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_default_port_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_error_log_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_error_log_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_fixups_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_fixups_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_get_mgmt_items_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_get_mgmt_items_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_get_suexec_identity_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_get_suexec_identity_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_handler_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_handler_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_header_parser_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_header_parser_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_http_method_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_http_method_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_insert_error_filter_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_insert_error_filter_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_insert_filter_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_insert_filter_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_log_transaction_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_log_transaction_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_map_to_storage_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_map_to_storage_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_open_logs_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_open_logs_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_optional_fn_retrieve_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_optional_fn_retrieve_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_post_config_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_post_config_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_post_read_request_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_post_read_request_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_pre_config_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_pre_config_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_pre_connection_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_pre_connection_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_pre_mpm_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_pre_mpm_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_process_connection_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_process_connection_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_quick_handler_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_quick_handler_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_status_hook_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_status_hook_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_translate_name_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_translate_name_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_type_checker_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_type_checker_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_bucket_error', + 'elts' => [ + { + 'type' => 'apr_bucket_refcount', + 'name' => 'refcount' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'const char *', + 'name' => 'data' + } + ] + }, + { + 'type' => 'ap_conf_vector_t', + 'elts' => [] + }, + { + 'type' => 'ap_configfile_t', + 'elts' => [ + { + 'type' => 'int(*) (void *param)', + 'name' => 'getch' + }, + { + 'type' => 'void *(*) (void *buf, size_t bufsiz, void *param)', + 'name' => 'getstr' + }, + { + 'type' => 'int(*) (void *param)', + 'name' => 'close' + }, + { + 'type' => 'void *', + 'name' => 'param' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'unsigned', + 'name' => 'line_number' + } + ] + }, + { + 'type' => 'ap_conn_keepalive_e', + 'elts' => [] + }, + { + 'type' => 'ap_directive_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'directive' + }, + { + 'type' => 'const char *', + 'name' => 'args' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'next' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'first_child' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'parent' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'int', + 'name' => 'line_num' + } + ] + }, + { + 'type' => 'ap_filter_func', + 'elts' => [ + { + 'type' => 'ap_out_filter_func', + 'name' => 'out_func' + }, + { + 'type' => 'ap_in_filter_func', + 'name' => 'in_func' + } + ] + }, + { + 'type' => 'ap_filter_rec_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_filter_func', + 'name' => 'filter_func' + }, + { + 'type' => 'ap_init_filter_func', + 'name' => 'filter_init_func' + }, + { + 'type' => 'ap_filter_type', + 'name' => 'ftype' + }, + { + 'type' => 'ap_filter_rec_t *', + 'name' => 'next' + } + ] + }, + { + 'type' => 'ap_filter_t', + 'elts' => [ + { + 'type' => 'ap_filter_rec_t *', + 'name' => 'frec' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'type' => 'ap_filter_type', + 'elts' => [] + }, + { + 'type' => 'ap_generation_t', + 'elts' => [] + }, + { + 'type' => 'ap_in_filter_func', + 'elts' => [] + }, + { + 'type' => 'ap_init_filter_func', + 'elts' => [] + }, + { + 'type' => 'ap_input_mode_t', + 'elts' => [] + }, + { + 'type' => 'ap_listen_rec', + 'elts' => [ + { + 'type' => 'ap_listen_rec *', + 'name' => 'next' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sd' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'bind_addr' + }, + { + 'type' => 'accept_function', + 'name' => 'accept_func' + }, + { + 'type' => 'int', + 'name' => 'active' + } + ] + }, + { + 'type' => 'ap_method_list_t', + 'elts' => [ + { + 'type' => 'apr_int64_t', + 'name' => 'method_mask' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'method_list' + } + ] + }, + { + 'type' => 'ap_mgmt_item_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'description' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_mgmt_type_e', + 'name' => 'vtype' + }, + { + 'type' => 'ap_mgmt_value', + 'name' => 'v' + } + ] + }, + { + 'type' => 'ap_mgmt_type_e', + 'elts' => [] + }, + { + 'type' => 'ap_mgmt_value', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 's_value' + }, + { + 'type' => 'long', + 'name' => 'i_value' + }, + { + 'type' => 'apr_hash_t *', + 'name' => 'h_value' + } + ] + }, + { + 'type' => 'ap_out_filter_func', + 'elts' => [] + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'elts' => [] + }, + { + 'type' => 'ap_pcw_srv_cb_t', + 'elts' => [] + }, + { + 'type' => 'ap_pod_t', + 'elts' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'pod_in' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'pod_out' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'type' => 'ap_sb_handle_t', + 'elts' => [] + }, + { + 'type' => 'ap_scoreboard_e', + 'elts' => [] + }, + { + 'type' => 'ap_unix_identity_t', + 'elts' => [ + { + 'type' => 'uid_t', + 'name' => 'uid' + }, + { + 'type' => 'gid_t', + 'name' => 'gid' + }, + { + 'type' => 'int', + 'name' => 'userdir' + } + ] + }, + { + 'type' => 'apr_OFN_ap_logio_add_bytes_out_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_signal_server_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_modperl_interp_unselect_t', + 'elts' => [] + }, + { + 'type' => 'apr_abortfunc_t', + 'elts' => [] + }, + { + 'type' => 'apr_allocator_t', + 'elts' => [] + }, + { + 'type' => 'apr_array_header_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'int', + 'name' => 'elt_size' + }, + { + 'type' => 'int', + 'name' => 'nelts' + }, + { + 'type' => 'int', + 'name' => 'nalloc' + }, + { + 'type' => 'char *', + 'name' => 'elts' + } + ] + }, + { + 'type' => 'apr_brigade_flush', + 'elts' => [] + }, + { + 'type' => 'apr_bucket', + 'elts' => [ + { + 'type' => '_ANON 53', + 'name' => 'link' + }, + { + 'type' => 'const apr_bucket_type_t *', + 'name' => 'type' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'void(*)(void *e)', + 'name' => 'free' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'type' => 'apr_bucket_alloc_t', + 'elts' => [] + }, + { + 'type' => 'apr_bucket_brigade', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_bucket_list', + 'name' => 'list' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'bucket_alloc' + } + ] + }, + { + 'type' => 'apr_bucket_file', + 'elts' => [ + { + 'type' => 'apr_bucket_refcount', + 'name' => 'refcount' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'fd' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'readpool' + }, + { + 'type' => 'int', + 'name' => 'can_mmap' + } + ] + }, + { + 'type' => 'apr_bucket_heap', + 'elts' => [ + { + 'type' => 'apr_bucket_refcount', + 'name' => 'refcount' + }, + { + 'type' => 'char *', + 'name' => 'base' + }, + { + 'type' => 'apr_size_t', + 'name' => 'alloc_len' + }, + { + 'type' => 'void(*)(void *data)', + 'name' => 'free_func' + } + ] + }, + { + 'type' => 'apr_bucket_mmap', + 'elts' => [ + { + 'type' => 'apr_bucket_refcount', + 'name' => 'refcount' + }, + { + 'type' => 'apr_mmap_t *', + 'name' => 'mmap' + } + ] + }, + { + 'type' => 'apr_bucket_pool', + 'elts' => [ + { + 'type' => 'apr_bucket_heap', + 'name' => 'heap' + }, + { + 'type' => 'const char *', + 'name' => 'base' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'type' => 'apr_bucket_refcount', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'refcount' + } + ] + }, + { + 'type' => 'apr_bucket_structs', + 'elts' => [] + }, + { + 'type' => 'apr_bucket_type_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'num_func' + }, + { + 'type' => 'int', + 'name' => 'is_metadata' + }, + { + 'type' => 'void(*)(void *data)', + 'name' => 'destroy' + }, + { + 'type' => 'apr_status_t(*)(apr_bucket *b, const char **str, apr_size_t *len, + apr_read_type_e block)', + 'name' => 'read' + }, + { + 'type' => 'apr_status_t(*)(apr_bucket *e, apr_pool_t *pool)', + 'name' => 'setaside' + }, + { + 'type' => 'apr_status_t(*)(apr_bucket *e, apr_size_t point)', + 'name' => 'split' + }, + { + 'type' => 'apr_status_t(*)(apr_bucket *e, apr_bucket **c)', + 'name' => 'copy' + } + ] + }, + { + 'type' => 'apr_byte_t', + 'elts' => [] + }, + { + 'type' => 'apr_child_errfn_t', + 'elts' => [] + }, + { + 'type' => 'apr_cmdtype_e', + 'elts' => [] + }, + { + 'type' => 'apr_datatype_e', + 'elts' => [] + }, + { + 'type' => 'apr_datum_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'dptr' + }, + { + 'type' => 'apr_size_t', + 'name' => 'dsize' + } + ] + }, + { + 'type' => 'apr_dbm_t', + 'elts' => [] + }, + { + 'type' => 'apr_descriptor', + 'elts' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 's' + } + ] + }, + { + 'type' => 'apr_dev_t', + 'elts' => [] + }, + { + 'type' => 'apr_dir_t', + 'elts' => [] + }, + { + 'type' => 'apr_dso_handle_sym_t', + 'elts' => [] + }, + { + 'type' => 'apr_dso_handle_t', + 'elts' => [] + }, + { + 'type' => 'apr_exit_why_e', + 'elts' => [] + }, + { + 'type' => 'apr_file_t', + 'elts' => [] + }, + { + 'type' => 'apr_fileattrs_t', + 'elts' => [] + }, + { + 'type' => 'apr_fileperms_t', + 'elts' => [] + }, + { + 'type' => 'apr_filetype_e', + 'elts' => [] + }, + { + 'type' => 'apr_finfo_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'valid' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'protection' + }, + { + 'type' => 'apr_filetype_e', + 'name' => 'filetype' + }, + { + 'type' => 'apr_uid_t', + 'name' => 'user' + }, + { + 'type' => 'apr_gid_t', + 'name' => 'group' + }, + { + 'type' => 'apr_ino_t', + 'name' => 'inode' + }, + { + 'type' => 'apr_dev_t', + 'name' => 'device' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'nlink' + }, + { + 'type' => 'apr_off_t', + 'name' => 'size' + }, + { + 'type' => 'apr_off_t', + 'name' => 'csize' + }, + { + 'type' => 'apr_time_t', + 'name' => 'atime' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + }, + { + 'type' => 'apr_time_t', + 'name' => 'ctime' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'filehand' + } + ] + }, + { + 'type' => 'apr_getopt_err_fn_t', + 'elts' => [] + }, + { + 'type' => 'apr_getopt_option_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'optch' + }, + { + 'type' => 'int', + 'name' => 'has_arg' + }, + { + 'type' => 'const char *', + 'name' => 'description' + } + ] + }, + { + 'type' => 'apr_getopt_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + }, + { + 'type' => 'apr_getopt_err_fn_t *', + 'name' => 'errfn' + }, + { + 'type' => 'void *', + 'name' => 'errarg' + }, + { + 'type' => 'int', + 'name' => 'ind' + }, + { + 'type' => 'int', + 'name' => 'opt' + }, + { + 'type' => 'int', + 'name' => 'reset' + }, + { + 'type' => 'int', + 'name' => 'argc' + }, + { + 'type' => 'const char **', + 'name' => 'argv' + }, + { + 'type' => 'char const *', + 'name' => 'place' + }, + { + 'type' => 'int', + 'name' => 'interleave' + }, + { + 'type' => 'int', + 'name' => 'skip_start' + }, + { + 'type' => 'int', + 'name' => 'skip_end' + } + ] + }, + { + 'type' => 'apr_gid_t', + 'elts' => [] + }, + { + 'type' => 'apr_global_mutex_t', + 'elts' => [] + }, + { + 'type' => 'apr_hash_index_t', + 'elts' => [] + }, + { + 'type' => 'apr_hash_t', + 'elts' => [] + }, + { + 'type' => 'apr_hdtr_t', + 'elts' => [ + { + 'type' => 'iovec *', + 'name' => 'headers' + }, + { + 'type' => 'int', + 'name' => 'numheaders' + }, + { + 'type' => 'iovec *', + 'name' => 'trailers' + }, + { + 'type' => 'int', + 'name' => 'numtrailers' + } + ] + }, + { + 'type' => 'apr_in_addr_t', + 'elts' => [ + { + 'type' => 'in_addr_t', + 'name' => 's_addr' + } + ] + }, + { + 'type' => 'apr_ino_t', + 'elts' => [] + }, + { + 'type' => 'apr_int16_t', + 'elts' => [] + }, + { + 'type' => 'apr_int32_t', + 'elts' => [] + }, + { + 'type' => 'apr_int64_t', + 'elts' => [] + }, + { + 'type' => 'apr_interface_e', + 'elts' => [] + }, + { + 'type' => 'apr_interval_time_t', + 'elts' => [] + }, + { + 'type' => 'apr_ipsubnet_t', + 'elts' => [] + }, + { + 'type' => 'apr_kill_conditions_e', + 'elts' => [] + }, + { + 'type' => 'apr_lockmech_e', + 'elts' => [] + }, + { + 'type' => 'apr_md4_ctx_t', + 'elts' => [ + { + 'type' => 'apr_uint32_t[4]', + 'name' => 'state' + }, + { + 'type' => 'apr_uint32_t[2]', + 'name' => 'count' + }, + { + 'type' => 'unsigned char[64]', + 'name' => 'buffer' + }, + { + 'type' => 'apr_xlate_t *', + 'name' => 'xlate' + } + ] + }, + { + 'type' => 'apr_md5_ctx_t', + 'elts' => [ + { + 'type' => 'apr_uint32_t[4]', + 'name' => 'state' + }, + { + 'type' => 'apr_uint32_t[2]', + 'name' => 'count' + }, + { + 'type' => 'unsigned char[64]', + 'name' => 'buffer' + }, + { + 'type' => 'apr_xlate_t *', + 'name' => 'xlate' + } + ] + }, + { + 'type' => 'apr_memnode_t', + 'elts' => [ + { + 'type' => 'apr_memnode_t *', + 'name' => 'next' + }, + { + 'type' => 'apr_memnode_t **', + 'name' => 'ref' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'index' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'free_index' + }, + { + 'type' => 'char *', + 'name' => 'first_avail' + }, + { + 'type' => 'char *', + 'name' => 'endp' + } + ] + }, + { + 'type' => 'apr_mmap_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'cntxt' + }, + { + 'type' => 'void *', + 'name' => 'mm' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'int', + 'name' => 'unused' + }, + { + 'type' => '_ANON 51', + 'name' => 'link' + } + ] + }, + { + 'type' => 'apr_off_t', + 'elts' => [] + }, + { + 'type' => 'apr_opt_fn_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_dir_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_dso_handle_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_exp_time_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'tm_sec' + }, + { + 'type' => 'int', + 'name' => 'tm_min' + }, + { + 'type' => 'int', + 'name' => 'tm_hour' + }, + { + 'type' => 'int', + 'name' => 'tm_mday' + }, + { + 'type' => 'int', + 'name' => 'tm_mon' + }, + { + 'type' => 'int', + 'name' => 'tm_year' + }, + { + 'type' => 'int', + 'name' => 'tm_wday' + }, + { + 'type' => 'int', + 'name' => 'tm_yday' + }, + { + 'type' => 'int', + 'name' => 'tm_isdst' + }, + { + 'type' => 'long int', + 'name' => 'tm_gmtoff' + }, + { + 'type' => '__const char *', + 'name' => 'tm_zone' + } + ] + }, + { + 'type' => 'apr_os_file_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_global_mutex_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'proc_mutex' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'thread_mutex' + } + ] + }, + { + 'type' => 'apr_os_imp_time_t', + 'elts' => [ + { + 'type' => '__time_t', + 'name' => 'tv_sec' + }, + { + 'type' => '__suseconds_t', + 'name' => 'tv_usec' + } + ] + }, + { + 'type' => 'apr_os_proc_mutex_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'crossproc' + }, + { + 'type' => 'pthread_mutex_t *', + 'name' => 'pthread_interproc' + }, + { + 'type' => 'pthread_mutex_t *', + 'name' => 'intraproc' + } + ] + }, + { + 'type' => 'apr_os_proc_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_shm_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_sock_info_t', + 'elts' => [ + { + 'type' => 'apr_os_sock_t *', + 'name' => 'os_sock' + }, + { + 'type' => 'sockaddr *', + 'name' => 'local' + }, + { + 'type' => 'sockaddr *', + 'name' => 'remote' + }, + { + 'type' => 'int', + 'name' => 'family' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'type' => 'apr_os_sock_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_thread_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_threadkey_t', + 'elts' => [] + }, + { + 'type' => 'apr_other_child_rec_t', + 'elts' => [] + }, + { + 'type' => 'apr_pollfd_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_datatype_e', + 'name' => 'desc_type' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'reqevents' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'rtnevents' + }, + { + 'type' => 'apr_descriptor', + 'name' => 'desc' + }, + { + 'type' => 'void *', + 'name' => 'client_data' + } + ] + }, + { + 'type' => 'apr_pollset_t', + 'elts' => [] + }, + { + 'type' => 'apr_pool_t', + 'elts' => [] + }, + { + 'type' => 'apr_port_t', + 'elts' => [] + }, + { + 'type' => 'apr_proc_mutex_t', + 'elts' => [] + }, + { + 'type' => 'apr_proc_t', + 'elts' => [ + { + 'type' => 'pid_t', + 'name' => 'pid' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'in' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'out' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'err' + } + ] + }, + { + 'type' => 'apr_procattr_t', + 'elts' => [] + }, + { + 'type' => 'apr_queue_t', + 'elts' => [] + }, + { + 'type' => 'apr_read_type_e', + 'elts' => [] + }, + { + 'type' => 'apr_reslist_constructor', + 'elts' => [] + }, + { + 'type' => 'apr_reslist_destructor', + 'elts' => [] + }, + { + 'type' => 'apr_reslist_t', + 'elts' => [] + }, + { + 'type' => 'apr_sdbm_datum_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'dptr' + }, + { + 'type' => 'int', + 'name' => 'dsize' + } + ] + }, + { + 'type' => 'apr_sdbm_t', + 'elts' => [] + }, + { + 'type' => 'apr_seek_where_t', + 'elts' => [] + }, + { + 'type' => 'apr_sha1_ctx_t', + 'elts' => [ + { + 'type' => 'apr_uint32_t[5]', + 'name' => 'digest' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'count_lo' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'count_hi' + }, + { + 'type' => 'apr_uint32_t[16]', + 'name' => 'data' + }, + { + 'type' => 'int', + 'name' => 'local' + } + ] + }, + { + 'type' => 'apr_shm_t', + 'elts' => [] + }, + { + 'type' => 'apr_short_interval_time_t', + 'elts' => [] + }, + { + 'type' => 'apr_shutdown_how_e', + 'elts' => [] + }, + { + 'type' => 'apr_sigfunc_t', + 'elts' => [] + }, + { + 'type' => 'apr_signum_t', + 'elts' => [] + }, + { + 'type' => 'apr_size_t', + 'elts' => [] + }, + { + 'type' => 'apr_sockaddr_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'char *', + 'name' => 'hostname' + }, + { + 'type' => 'char *', + 'name' => 'servname' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'family' + }, + { + 'type' => 'union _ANON 1', + 'name' => 'sa' + }, + { + 'type' => 'apr_socklen_t', + 'name' => 'salen' + }, + { + 'type' => 'int', + 'name' => 'ipaddr_len' + }, + { + 'type' => 'int', + 'name' => 'addr_str_len' + }, + { + 'type' => 'void *', + 'name' => 'ipaddr_ptr' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'next' + } + ] + }, + { + 'type' => 'apr_socket_t', + 'elts' => [] + }, + { + 'type' => 'apr_socklen_t', + 'elts' => [] + }, + { + 'type' => 'apr_ssize_t', + 'elts' => [] + }, + { + 'type' => 'apr_status_t', + 'elts' => [] + }, + { + 'type' => 'apr_strmatch_pattern', + 'elts' => [ + { + 'type' => 'const char *(*)(const apr_strmatch_pattern *this_pattern, + const char *s, apr_size_t slen)', + 'name' => 'compare' + }, + { + 'type' => 'const char *', + 'name' => 'pattern' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'void *', + 'name' => 'context' + } + ] + }, + { + 'type' => 'apr_table_entry_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'char *', + 'name' => 'val' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'key_checksum' + } + ] + }, + { + 'type' => 'apr_table_t', + 'elts' => [] + }, + { + 'type' => 'apr_text', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'text' + }, + { + 'type' => 'apr_text *', + 'name' => 'next' + } + ] + }, + { + 'type' => 'apr_text_header', + 'elts' => [ + { + 'type' => 'apr_text *', + 'name' => 'first' + }, + { + 'type' => 'apr_text *', + 'name' => 'last' + } + ] + }, + { + 'type' => 'apr_thread_cond_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_mutex_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_once_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_rwlock_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_start_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_t', + 'elts' => [] + }, + { + 'type' => 'apr_threadattr_t', + 'elts' => [] + }, + { + 'type' => 'apr_threadkey_t', + 'elts' => [] + }, + { + 'type' => 'apr_time_exp_t', + 'elts' => [ + { + 'type' => 'apr_int32_t', + 'name' => 'tm_usec' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_sec' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_min' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_hour' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_mday' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_mon' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_year' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_wday' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_yday' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_isdst' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_gmtoff' + } + ] + }, + { + 'type' => 'apr_time_t', + 'elts' => [] + }, + { + 'type' => 'apr_uid_t', + 'elts' => [] + }, + { + 'type' => 'apr_uint16_t', + 'elts' => [] + }, + { + 'type' => 'apr_uint32_t', + 'elts' => [] + }, + { + 'type' => 'apr_uint64_t', + 'elts' => [] + }, + { + 'type' => 'apr_uri_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'scheme' + }, + { + 'type' => 'char *', + 'name' => 'hostinfo' + }, + { + 'type' => 'char *', + 'name' => 'user' + }, + { + 'type' => 'char *', + 'name' => 'password' + }, + { + 'type' => 'char *', + 'name' => 'hostname' + }, + { + 'type' => 'char *', + 'name' => 'port_str' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'char *', + 'name' => 'query' + }, + { + 'type' => 'char *', + 'name' => 'fragment' + }, + { + 'type' => 'hostent *', + 'name' => 'hostent' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'unsigned', + 'name' => 'is_initialized' + }, + { + 'type' => 'unsigned', + 'name' => 'dns_looked_up' + }, + { + 'type' => 'unsigned', + 'name' => 'dns_resolved' + } + ] + }, + { + 'type' => 'apr_uuid_t', + 'elts' => [ + { + 'type' => 'unsigned char[16]', + 'name' => 'data' + } + ] + }, + { + 'type' => 'apr_version_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'major' + }, + { + 'type' => 'int', + 'name' => 'minor' + }, + { + 'type' => 'int', + 'name' => 'patch' + }, + { + 'type' => 'int', + 'name' => 'is_dev' + } + ] + }, + { + 'type' => 'apr_vformatter_buff_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'curpos' + }, + { + 'type' => 'char *', + 'name' => 'endpos' + } + ] + }, + { + 'type' => 'apr_wait_how_e', + 'elts' => [] + }, + { + 'type' => 'apr_xlate_t', + 'elts' => [] + }, + { + 'type' => 'apr_xml_attr', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'ns' + }, + { + 'type' => 'const char *', + 'name' => 'value' + }, + { + 'type' => 'apr_xml_attr *', + 'name' => 'next' + } + ] + }, + { + 'type' => 'apr_xml_doc', + 'elts' => [ + { + 'type' => 'apr_xml_elem *', + 'name' => 'root' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'namespaces' + } + ] + }, + { + 'type' => 'apr_xml_elem', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'ns' + }, + { + 'type' => 'const char *', + 'name' => 'lang' + }, + { + 'type' => 'apr_text_header', + 'name' => 'first_cdata' + }, + { + 'type' => 'apr_text_header', + 'name' => 'following_cdata' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'parent' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'next' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'first_child' + }, + { + 'type' => 'apr_xml_attr *', + 'name' => 'attr' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'last_child' + }, + { + 'type' => 'apr_xml_ns_scope *', + 'name' => 'ns_scope' + }, + { + 'type' => 'void *', + 'name' => 'priv' + } + ] + }, + { + 'type' => 'apr_xml_parser', + 'elts' => [] + }, + { + 'type' => 'cmd_func', + 'elts' => [] + }, + { + 'type' => 'cmd_parms', + 'elts' => [ + { + 'type' => 'void *', + 'name' => 'info' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'apr_int64_t', + 'name' => 'limited' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'limited_xmethods' + }, + { + 'type' => 'ap_method_list_t *', + 'name' => 'xlimited' + }, + { + 'type' => 'ap_configfile_t *', + 'name' => 'config_file' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'directive' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'const command_rec *', + 'name' => 'cmd' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'context' + }, + { + 'type' => 'const ap_directive_t *', + 'name' => 'err_directive' + } + ] + }, + { + 'type' => 'command_rec', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'cmd_func', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'cmd_data' + }, + { + 'type' => 'int', + 'name' => 'req_override' + }, + { + 'type' => 'enum cmd_how', + 'name' => 'args_how' + }, + { + 'type' => 'const char *', + 'name' => 'errmsg' + } + ] + }, + { + 'type' => 'conn_rec', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'server_rec *', + 'name' => 'base_server' + }, + { + 'type' => 'void *', + 'name' => 'vhost_lookup_data' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'local_addr' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'remote_addr' + }, + { + 'type' => 'char *', + 'name' => 'remote_ip' + }, + { + 'type' => 'char *', + 'name' => 'remote_host' + }, + { + 'type' => 'char *', + 'name' => 'remote_logname' + }, + { + 'type' => 'unsigned', + 'name' => 'aborted' + }, + { + 'type' => 'ap_conn_keepalive_e', + 'name' => 'keepalive' + }, + { + 'type' => 'signed int', + 'name' => 'double_reverse' + }, + { + 'type' => 'int', + 'name' => 'keepalives' + }, + { + 'type' => 'char *', + 'name' => 'local_ip' + }, + { + 'type' => 'char *', + 'name' => 'local_host' + }, + { + 'type' => 'long', + 'name' => 'id' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'conn_config' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'notes' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'input_filters' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'output_filters' + }, + { + 'type' => 'void *', + 'name' => 'sbh' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'bucket_alloc' + } + ] + }, + { + 'type' => 'core_net_rec', + 'elts' => [] + }, + { + 'type' => 'htaccess_result', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'dir' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'htaccess' + }, + { + 'type' => 'const struct htaccess_result *', + 'name' => 'next' + } + ] + }, + { + 'type' => 'modperl_uri_t', + 'elts' => [ + { + 'type' => 'apr_uri_t', + 'name' => 'uri' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'char *', + 'name' => 'path_info' + } + ] + }, + { + 'type' => 'module', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'version' + }, + { + 'type' => 'int', + 'name' => 'minor_version' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'void *', + 'name' => 'dynamic_load_handle' + }, + { + 'type' => 'module_struct *', + 'name' => 'next' + }, + { + 'type' => 'unsigned long', + 'name' => 'magic' + }, + { + 'type' => 'void(*) (process_rec *process)', + 'name' => 'rewrite_args' + }, + { + 'type' => 'void *(*) (apr_pool_t *p, char *dir)', + 'name' => 'create_dir_config' + }, + { + 'type' => 'void *(*) (apr_pool_t *p, void *base_conf, void *new_conf)', + 'name' => 'merge_dir_config' + }, + { + 'type' => 'void *(*) (apr_pool_t *p, server_rec *s)', + 'name' => 'create_server_config' + }, + { + 'type' => 'void *(*) (apr_pool_t *p, void *base_conf, + void *new_conf)', + 'name' => 'merge_server_config' + }, + { + 'type' => 'const command_rec *', + 'name' => 'cmds' + }, + { + 'type' => 'void(*) (apr_pool_t *p)', + 'name' => 'register_hooks' + } + ] + }, + { + 'type' => 'piped_log', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_file_t *[2]', + 'name' => 'fds' + }, + { + 'type' => 'char *', + 'name' => 'program' + }, + { + 'type' => 'apr_proc_t *', + 'name' => 'pid' + } + ] + }, + { + 'type' => 'process_rec', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'int', + 'name' => 'argc' + }, + { + 'type' => 'const char * const *', + 'name' => 'argv' + }, + { + 'type' => 'const char *', + 'name' => 'short_name' + } + ] + }, + { + 'type' => 'request_rec', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'conn_rec *', + 'name' => 'connection' + }, + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'request_rec *', + 'name' => 'next' + }, + { + 'type' => 'request_rec *', + 'name' => 'prev' + }, + { + 'type' => 'request_rec *', + 'name' => 'main' + }, + { + 'type' => 'char *', + 'name' => 'the_request' + }, + { + 'type' => 'int', + 'name' => 'assbackwards' + }, + { + 'type' => 'int', + 'name' => 'proxyreq' + }, + { + 'type' => 'int', + 'name' => 'header_only' + }, + { + 'type' => 'char *', + 'name' => 'protocol' + }, + { + 'type' => 'int', + 'name' => 'proto_num' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'apr_time_t', + 'name' => 'request_time' + }, + { + 'type' => 'const char *', + 'name' => 'status_line' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'const char *', + 'name' => 'method' + }, + { + 'type' => 'int', + 'name' => 'method_number' + }, + { + 'type' => 'apr_int64_t', + 'name' => 'allowed' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'allowed_xmethods' + }, + { + 'type' => 'ap_method_list_t *', + 'name' => 'allowed_methods' + }, + { + 'type' => 'apr_off_t', + 'name' => 'sent_bodyct' + }, + { + 'type' => 'apr_off_t', + 'name' => 'bytes_sent' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + }, + { + 'type' => 'int', + 'name' => 'chunked' + }, + { + 'type' => 'const char *', + 'name' => 'range' + }, + { + 'type' => 'apr_off_t', + 'name' => 'clength' + }, + { + 'type' => 'apr_off_t', + 'name' => 'remaining' + }, + { + 'type' => 'apr_off_t', + 'name' => 'read_length' + }, + { + 'type' => 'int', + 'name' => 'read_body' + }, + { + 'type' => 'int', + 'name' => 'read_chunked' + }, + { + 'type' => 'unsigned', + 'name' => 'expecting_100' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'headers_in' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'headers_out' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'err_headers_out' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'subprocess_env' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'notes' + }, + { + 'type' => 'const char *', + 'name' => 'content_type' + }, + { + 'type' => 'const char *', + 'name' => 'handler' + }, + { + 'type' => 'const char *', + 'name' => 'content_encoding' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'content_languages' + }, + { + 'type' => 'char *', + 'name' => 'vlist_validator' + }, + { + 'type' => 'char *', + 'name' => 'user' + }, + { + 'type' => 'char *', + 'name' => 'ap_auth_type' + }, + { + 'type' => 'int', + 'name' => 'no_cache' + }, + { + 'type' => 'int', + 'name' => 'no_local_copy' + }, + { + 'type' => 'char *', + 'name' => 'unparsed_uri' + }, + { + 'type' => 'char *', + 'name' => 'uri' + }, + { + 'type' => 'char *', + 'name' => 'filename' + }, + { + 'type' => 'char *', + 'name' => 'canonical_filename' + }, + { + 'type' => 'char *', + 'name' => 'path_info' + }, + { + 'type' => 'char *', + 'name' => 'args' + }, + { + 'type' => 'apr_finfo_t', + 'name' => 'finfo' + }, + { + 'type' => 'apr_uri_t', + 'name' => 'parsed_uri' + }, + { + 'type' => 'int', + 'name' => 'used_path_info' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'per_dir_config' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'request_config' + }, + { + 'type' => 'const struct htaccess_result *', + 'name' => 'htaccess' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'output_filters' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'input_filters' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'proto_output_filters' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'proto_input_filters' + }, + { + 'type' => 'int', + 'name' => 'eos_sent' + } + ] + }, + { + 'type' => 'server_addr_rec', + 'elts' => [ + { + 'type' => 'server_addr_rec *', + 'name' => 'next' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'host_addr' + }, + { + 'type' => 'apr_port_t', + 'name' => 'host_port' + }, + { + 'type' => 'char *', + 'name' => 'virthost' + } + ] + }, + { + 'type' => 'server_rec', + 'elts' => [ + { + 'type' => 'process_rec *', + 'name' => 'process' + }, + { + 'type' => 'server_rec *', + 'name' => 'next' + }, + { + 'type' => 'const char *', + 'name' => 'defn_name' + }, + { + 'type' => 'unsigned', + 'name' => 'defn_line_number' + }, + { + 'type' => 'char *', + 'name' => 'server_admin' + }, + { + 'type' => 'char *', + 'name' => 'server_hostname' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'char *', + 'name' => 'error_fname' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'error_log' + }, + { + 'type' => 'int', + 'name' => 'loglevel' + }, + { + 'type' => 'int', + 'name' => 'is_virtual' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'module_config' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'lookup_defaults' + }, + { + 'type' => 'server_addr_rec *', + 'name' => 'addrs' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'keep_alive_timeout' + }, + { + 'type' => 'int', + 'name' => 'keep_alive_max' + }, + { + 'type' => 'int', + 'name' => 'keep_alive' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'pathlen' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'names' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'wild_names' + }, + { + 'type' => 'int', + 'name' => 'limit_req_line' + }, + { + 'type' => 'int', + 'name' => 'limit_req_fieldsize' + }, + { + 'type' => 'int', + 'name' => 'limit_req_fields' + } + ] + }, + { + 'type' => 'subrequest_rec', + 'elts' => [] + }, + { + 'type' => 'unixd_config_rec', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'user_name' + }, + { + 'type' => 'uid_t', + 'name' => 'user_id' + }, + { + 'type' => 'gid_t', + 'name' => 'group_id' + }, + { + 'type' => 'int', + 'name' => 'suexec_enabled' + } + ] + }, + { + 'type' => 'modperl_interp_t', + 'elts' => [ + { + 'type' => 'modperl_interp_pool_t *', + 'name' => 'mip' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + }, + { + 'type' => 'int', + 'name' => 'num_requests' + }, + { + 'type' => 'U8', + 'name' => 'flags' + }, + { + 'type' => 'modperl_config_con_t *', + 'name' => 'ccfg' + }, + { + 'type' => 'int', + 'name' => 'refcnt' + }, + { + 'type' => 'unsigned long', + 'name' => 'tid' + } + ] + }, + { + 'type' => 'modperl_interp_pool_t', + 'elts' => [ + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'modperl_tipool_config_t *', + 'name' => 'tipool_cfg' + }, + { + 'type' => 'modperl_interp_t *', + 'name' => 'parent' + } + ] + }, + { + 'type' => 'modperl_tipool_t', + 'elts' => [ + { + 'type' => 'perl_mutex', + 'name' => 'tiplock' + }, + { + 'type' => 'perl_cond', + 'name' => 'available' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'idle' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'busy' + }, + { + 'type' => 'int', + 'name' => 'in_use' + }, + { + 'type' => 'int', + 'name' => 'size' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'modperl_tipool_config_t *', + 'name' => 'cfg' + }, + { + 'type' => 'modperl_tipool_vtbl_t *', + 'name' => 'func' + } + ] + }, + { + 'type' => 'modperl_tipool_config_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'start' + }, + { + 'type' => 'int', + 'name' => 'min_spare' + }, + { + 'type' => 'int', + 'name' => 'max_spare' + }, + { + 'type' => 'int', + 'name' => 'max' + }, + { + 'type' => 'int', + 'name' => 'max_requests' + } + ] + } +]; + + +1;
diff --git a/2_0_13/xs/tables/current/ModPerl/FunctionTable.pm b/2_0_13/xs/tables/current/ModPerl/FunctionTable.pm new file mode 100644 index 0000000..e5b47ce --- /dev/null +++ b/2_0_13/xs/tables/current/ModPerl/FunctionTable.pm
@@ -0,0 +1,8296 @@ +# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*- +package ModPerl::FunctionTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by ModPerl::ParseSource/0.01 +# ! Mon May 23 14:15:47 2005 +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$ModPerl::FunctionTable = [ + { + 'return_type' => 'int', + 'name' => 'modperl_access_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_apr_array_header2avrv', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'array' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_authen_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_authz_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'modperl_avrv2apr_array_header', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'SV *', + 'name' => 'avrv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_brigade_dump', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'modperl_bucket_sv_create', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'handler' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'AV *', + 'name' => 'args' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_connection', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_files', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_per_dir', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_per_srv', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_pre_connection', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'void *', + 'name' => 'csd' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_callback_process', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_run_handlers', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_cgi_header_parse', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + }, + { + 'type' => 'const char **', + 'name' => 'body' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_child_init_handler', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'modperl_cleanup_data_t *', + 'name' => 'modperl_cleanup_data_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_END', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_access_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_add_var', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg1' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_authen_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_authz_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_child_exit_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_child_init_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_cleanup_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_config_requires', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_fixup_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_header_parser_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_init_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_input_filter_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_max', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_max_requests', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_max_spare', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_min_spare', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_start', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_load_module', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_log_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_map_to_storage_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_modules', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_open_logs_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_options', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_output_filter_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_pass_env', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_perl', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_perldo', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_pod', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_pod_cut', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_post_config_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_post_config_requires', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_post_read_request_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_pre_connection_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_process_connection_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_cmd_push_filter_handlers', + 'args' => [ + { + 'type' => 'MpAV **', + 'name' => 'handlers' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_cmd_push_handlers', + 'args' => [ + { + 'type' => 'MpAV **', + 'name' => 'handlers' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_requires', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_response_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_set_env', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg1' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_set_input_filter', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_set_output_filter', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_set_var', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg1' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_switches', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_trace', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_trans_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_type_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'U16 *', + 'name' => 'modperl_code_attrs', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'CV *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_config_apply_PerlModule', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_config_apply_PerlPostConfigRequire', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_config_apply_PerlRequire', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_config_dir_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char *', + 'name' => 'dir' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_config_dir_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'basev' + }, + { + 'type' => 'void *', + 'name' => 'addv' + } + ] + }, + { + 'return_type' => 'modperl_config_dir_t *', + 'name' => 'modperl_config_dir_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_config_insert', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptmp' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'override_options' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'conf' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_config_insert_parms', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_config_insert_request', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'override_options' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_config_insert_server', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_config_is_perl_option_enabled', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_config_req_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'modperl_config_req_t *', + 'name' => 'modperl_config_req_new', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'modperl_config_con_t *', + 'name' => 'modperl_config_con_new', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_config_request_cleanup', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'char **', + 'name' => 'modperl_config_srv_argv_init', + 'args' => [ + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'int *', + 'name' => 'argc' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_config_srv_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_config_srv_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'basev' + }, + { + 'type' => 'void *', + 'name' => 'addv' + } + ] + }, + { + 'return_type' => 'modperl_config_srv_t *', + 'name' => 'modperl_config_srv_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_const_compile', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char **', + 'name' => 'modperl_constants_group_lookup_apache2_const', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char **', + 'name' => 'modperl_constants_group_lookup_apr_const', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char **', + 'name' => 'modperl_constants_group_lookup_modperl', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_constants_lookup_apache2_const', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_constants_lookup_apr_const', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_constants_lookup_modperl', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_croak', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + }, + { + 'type' => 'const char*', + 'name' => 'func' + } + ] + }, + { + 'return_type' => 'unsigned long', + 'name' => 'modperl_debug_level', + 'args' => [] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_dir_config', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'sv_val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_clear', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_configure_request_dir', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_configure_request_srv', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_configure_server', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_default_populate', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_hash_keys', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_hv_store', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_init', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_request_populate', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_request_tie', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_request_unpopulate', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_request_untie', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_sync_dir_env_hash2table', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_config_dir_t *', + 'name' => 'dcfg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_sync_srv_env_hash2table', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_unload', + 'args' => [] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_error_strerror', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_errsv', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_errsv_prepend', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'pat' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_file2package', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'U32 *', + 'name' => 'modperl_filter_attributes', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'SV *', + 'name' => 'package' + }, + { + 'type' => 'SV *', + 'name' => 'cvrv' + } + ] + }, + { + 'return_type' => 'modperl_filter_t *', + 'name' => 'modperl_filter_mg_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'obj' + } + ] + }, + { + 'return_type' => 'modperl_filter_t *', + 'name' => 'modperl_filter_new', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'modperl_filter_mode_e', + 'name' => 'mode' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'input_mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_filter_resolve_init_handler', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'handler' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_filter_runtime_add', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'modperl_filter_mode_e', + 'name' => 'mode' + }, + { + 'type' => 'modperl_filter_add_t', + 'name' => 'addfunc' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + }, + { + 'type' => 'const char *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_fixup_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'U32', + 'name' => 'modperl_flags_lookup_dir', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'U32', + 'name' => 'modperl_flags_lookup_srv', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_get_perl_module_config', + 'args' => [ + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_anon_cnt_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_global_anon_cnt_next', + 'args' => [] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_global_get', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'modperl_global_get_pconf', + 'args' => [] + }, + { + 'return_type' => 'server_rec *', + 'name' => 'modperl_global_get_server_rec', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_init', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_init_pconf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_init_server_rec', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec * server_rec', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_lock', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_lock_pconf', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_lock_server_rec', + 'args' => [] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'modperl_global_request', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'svr' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_request_cfg_set', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_request_obj_set', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'svr' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_request_set', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_set', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_set_pconf', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_set_server_rec', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_unlock', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_unlock_pconf', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_unlock_server_rec', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_handler_anon_add', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'anon' + }, + { + 'type' => 'CV *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'CV *', + 'name' => 'modperl_handler_anon_get', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'anon' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_handler_anon_init', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'modperl_mgv_t *', + 'name' => 'modperl_handler_anon_next', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'MpAV *', + 'name' => 'modperl_handler_array_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'MpAV *', + 'name' => 'base_a' + }, + { + 'type' => 'MpAV *', + 'name' => 'add_a' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_connection', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_files', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_per_dir', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_per_srv', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_pre_connection', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_process', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'modperl_handler_t *', + 'name' => 'modperl_handler_dup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'h' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_equal', + 'args' => [ + { + 'type' => 'modperl_handler_t *', + 'name' => 'h1' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'h2' + } + ] + }, + { + 'return_type' => 'MpAV **', + 'name' => 'modperl_handler_get_handlers', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'modperl_handler_action_e', + 'name' => 'action' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_lookup', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'MpAV **', + 'name' => 'modperl_handler_lookup_handlers', + 'args' => [ + { + 'type' => 'modperl_config_dir_t *', + 'name' => 'dcfg' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'modperl_config_req_t *', + 'name' => 'rcfg' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'modperl_handler_action_e', + 'name' => 'action' + }, + { + 'type' => 'const char **', + 'name' => 'desc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_handler_make_args', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'AV **', + 'name' => 'avp' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_name', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_handler_t *', + 'name' => 'handler' + } + ] + }, + { + 'return_type' => 'modperl_handler_t *', + 'name' => 'modperl_handler_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'modperl_handler_t *', + 'name' => 'modperl_handler_new_from_sv', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_perl_add_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'modperl_handler_action_e', + 'name' => 'action' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_handler_perl_get_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'MpAV **', + 'name' => 'handp' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_push_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'MpAV *', + 'name' => 'handlers' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_resolve', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_handler_t **', + 'name' => 'handp' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_hash_seed_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_hash_seed_set', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_hash_tie', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + }, + { + 'type' => 'void *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_hash_tied_object', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_hash_tied_object_rv', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_header_parser_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_hook_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_hook_pre_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_init', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_init_globals', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_init_vhost', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 'base_server' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_input_filter_add_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_input_filter_add_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_input_filter_flush', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_input_filter_handler', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'input_mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'modperl_input_filter_read', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'wanted' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_input_filter_write', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_interp_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_clone_init', + 'args' => [ + { + 'type' => 'modperl_interp_t *', + 'name' => 'interp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_destroy', + 'args' => [ + { + 'type' => 'modperl_interp_t *', + 'name' => 'interp' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_get', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_init', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_mip_walk', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'current_perl' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'parent_perl' + }, + { + 'type' => 'modperl_interp_pool_t *', + 'name' => 'mip' + }, + { + 'type' => 'modperl_interp_mip_walker_t', + 'name' => 'walker' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_mip_walk_servers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'current_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 'base_server' + }, + { + 'type' => 'modperl_interp_mip_walker_t', + 'name' => 'walker' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_new', + 'args' => [ + { + 'type' => 'modperl_interp_pool_t *', + 'name' => 'mip' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_interp_pool_destroy', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_pool_get', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_pool_select', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_pool_set', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_interp_t *', + 'name' => 'interp' + }, + { + 'type' => 'int', + 'name' => 'cleanup' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_select', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_interp_unselect', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_apache_init', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_handle_tie', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + }, + { + 'type' => 'char *', + 'name' => 'classname' + }, + { + 'type' => 'void *', + 'name' => 'ptr' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_io_handle_tied', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + }, + { + 'type' => 'char *', + 'name' => 'classname' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_handle_untie', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_io_perlio_override_stdin', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_io_perlio_override_stdout', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_perlio_restore_stdin', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_perlio_restore_stdout', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_io_tie_stdin', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_io_tie_stdout', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_is_running', + 'args' => [] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_append', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'new_list' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_first', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_last', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_new', + 'args' => [] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_prepend', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'new_list' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_remove', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'rlist' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_remove_data', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'modperl_list_t **', + 'name' => 'listp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_log_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_map_to_storage_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_mgv_append', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_mgv_as_string', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'modperl_mgv_t *', + 'name' => 'modperl_mgv_compile', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_mgv_equal', + 'args' => [ + { + 'type' => 'modperl_mgv_t *', + 'name' => 'mgv1' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'mgv2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_mgv_hash_handlers', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'modperl_mgv_t *', + 'name' => 'modperl_mgv_last', + 'args' => [ + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_mgv_last_name', + 'args' => [ + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_mgv_lookup', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_mgv_lookup_autoload', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'modperl_mgv_t *', + 'name' => 'modperl_mgv_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_mgv_require_module', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_mgv_resolve', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'handler' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'logfailure' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_modglobal_hash_keys', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'modperl_modglobal_key_t *', + 'name' => 'modperl_modglobal_lookup', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_module_add', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'mod_cmds' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_module_config_get_obj', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'pmodule' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'v' + } + ] + }, + { + 'return_type' => 'PTR_TBL_t *', + 'name' => 'modperl_module_config_table_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'int', + 'name' => 'create' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_module_config_table_set', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'table' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_newSVsv_obj', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'stashsv' + }, + { + 'type' => 'SV *', + 'name' => 'obj' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_open_logs_handler', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'modperl_options_t *', + 'name' => 'modperl_options_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_options_t *', + 'name' => 'base' + }, + { + 'type' => 'modperl_options_t *new', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'modperl_options_t *', + 'name' => 'modperl_options_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_options_set', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_options_t *', + 'name' => 'o' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_output_filter_add_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_output_filter_add_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_output_filter_flush', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_output_filter_handler', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'modperl_output_filter_read', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'wanted' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_output_filter_write', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_package_unload', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_av_push_elts_ref', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'AV *', + 'name' => 'dst' + }, + { + 'type' => 'AV *', + 'name' => 'src' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_call_endav', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_call_list', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'AV *', + 'name' => 'subs' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_core_global_init', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_destruct', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_perl_destruct_level', + 'args' => [] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_do_join', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_do_sprintf', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'I32', + 'name' => 'len' + }, + { + 'type' => 'SV **', + 'name' => 'sarg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_exit', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_gensym', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'pack' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_avcv_call', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_modglobal_key_t *', + 'name' => 'gkey' + }, + { + 'type' => 'const char *', + 'name' => 'package' + }, + { + 'type' => 'I32', + 'name' => 'packlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_avcv_clear', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_modglobal_key_t *', + 'name' => 'gkey' + }, + { + 'type' => 'const char *', + 'name' => 'package' + }, + { + 'type' => 'I32', + 'name' => 'packlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_avcv_register', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_modglobal_key_t *', + 'name' => 'gkey' + }, + { + 'type' => 'const char *', + 'name' => 'package' + }, + { + 'type' => 'I32', + 'name' => 'packlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_request_restore', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_request_save', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'HE *', + 'name' => 'modperl_perl_hv_fetch_he', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'HV *', + 'name' => 'hv' + }, + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'I32', + 'name' => 'klen' + }, + { + 'type' => 'U32', + 'name' => 'hash' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_init_ids_server', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_perl_module_loaded', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_pp_set', + 'args' => [ + { + 'type' => 'modperl_perl_opcode_e', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_pp_set_all', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_pp_unset', + 'args' => [ + { + 'type' => 'modperl_perl_opcode_e', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_pp_unset_all', + 'args' => [] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_sv_setref_uv', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'rv' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'UV', + 'name' => 'uv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_pnotes', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'HV **', + 'name' => 'pnotes' + }, + { + 'type' => 'SV *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'val' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_pnotes_kill', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'cl_data' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_post_config_handler', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_post_post_config_phase', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_post_read_request_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_pre_connection_handler', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'void *', + 'name' => 'csd' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_process_connection_handler', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_ptr2obj', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'classname' + }, + { + 'type' => 'void *', + 'name' => 'ptr' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_register_handler_hooks', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_register_hooks', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ssize_t', + 'name' => 'modperl_request_read', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_require_file', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'pv' + }, + { + 'type' => 'int', + 'name' => 'logfailure' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_require_module', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'pv' + }, + { + 'type' => 'int', + 'name' => 'logfailure' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_response_finish', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_response_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_response_handler_cgi', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_response_init', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_restart_count', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_restart_count_inc', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 'base_server' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_run', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_run_filter', + 'args' => [ + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_server_desc', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'modperl_server_pool', + 'args' => [] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'modperl_server_user_pool', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_set_perl_module_config', + 'args' => [ + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'cv' + }, + { + 'type' => 'void *', + 'name' => 'cfg' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_slurp_filename', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'tainted' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_spawn_proc_prog', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'command' + }, + { + 'type' => 'const char ***', + 'name' => 'argv' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'script_in' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'script_out' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'script_err' + } + ] + }, + { + 'return_type' => 'PerlInterpreter *', + 'name' => 'modperl_startup', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_str_toupper', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'modperl_sv2request_rec', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'server_rec *', + 'name' => 'modperl_sv2server_rec', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_clear', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + } + ] + }, + { + 'return_type' => 'PTR_TBL_t *', + 'name' => 'modperl_svptr_table_clone', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'proto_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'source' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_delete', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + }, + { + 'type' => 'void *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_destroy', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_svptr_table_fetch', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + }, + { + 'type' => 'void *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_free', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + } + ] + }, + { + 'return_type' => 'PTR_TBL_t *', + 'name' => 'modperl_svptr_table_new', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_split', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_store', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + }, + { + 'type' => 'void *', + 'name' => 'oldv' + }, + { + 'type' => 'void *', + 'name' => 'newv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_sys_dlclose', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_sys_is_dir', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_table_get_set', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'table' + }, + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'sv_val' + }, + { + 'type' => 'int', + 'name' => 'do_taint' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_threaded_mpm', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_threads_started', + 'args' => [] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_thx_interp_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'thx', + }, + ], + }, + { + 'return_type' => 'void', + 'name' => 'modperl_thx_interp_set', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'thx', + }, + { + 'type' => 'modperl_interp_t *', + 'name' => 'interp', + }, + ], + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_add', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_destroy', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_init', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + } + ] + }, + { + 'return_type' => 'modperl_tipool_t *', + 'name' => 'modperl_tipool_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_tipool_config_t *', + 'name' => 'cfg' + }, + { + 'type' => 'void *', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_tipool_pop', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_putback', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'listp' + }, + { + 'type' => 'int', + 'name' => 'num_requests' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_putback_data', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'int', + 'name' => 'num_requests' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_remove', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'listp' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_tls_t **', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_create_request_rec', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_get', + 'args' => [ + { + 'type' => 'modperl_tls_t *', + 'name' => 'key' + }, + { + 'type' => 'void **', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_get_request_rec', + 'args' => [ + { + 'type' => 'request_rec * *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tls_reset_cleanup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_tls_t *', + 'name' => 'key' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tls_reset_cleanup_request_rec', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'request_rec *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_set', + 'args' => [ + { + 'type' => 'modperl_tls_t *', + 'name' => 'key' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_set_request_rec', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'func' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace_level_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'logfile' + }, + { + 'type' => 'const char *', + 'name' => 'level' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace_logfile_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'logfile_new' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_trans_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_type_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'modperl_uri_t *', + 'name' => 'modperl_uri_new', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_wbucket_flush', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_wbucket_t *', + 'name' => 'b' + }, + { + 'type' => 'int', + 'name' => 'add_flush_bucket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_wbucket_pass', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_wbucket_t *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'int', + 'name' => 'add_flush_bucket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_wbucket_write', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_wbucket_t *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'wlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_xs_dl_handles_clear', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_xs_dl_handles_close', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'handles' + } + ] + }, + { + 'return_type' => 'void **', + 'name' => 'modperl_xs_dl_handles_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'modperl_xs_sv2request_rec', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'char *', + 'name' => 'classname' + }, + { + 'type' => 'CV *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_cleanup', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_concat', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_destroy', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Brigade_first', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_APR__Brigade_flatten', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_insert_head', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_insert_tail', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Brigade_is_empty', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Brigade_last', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Brigade_length', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'int', + 'name' => 'read_all' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Brigade_next', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'mpxs_APR__Brigade_pool', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Brigade_prev', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__BucketAlloc_new', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'CLASS' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Bucket_insert_after', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Bucket_insert_before', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Bucket_is_eos', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Bucket_is_flush', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Bucket_new', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_APR__Bucket_read', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Bucket_remove', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_APR__Bucket_setaside', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'b_sv' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Finfo_stat', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'U32', + 'name' => 'mpxs_APR__OS_current_thread_id', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Pool_clear', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'obj' + } + ] + }, + { + 'return_type' => 'apr_int32_t', + 'name' => 'mpxs_APR__Socket_opt_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Socket_opt_set', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_APR__Socket_poll', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'reqevents' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_APR__Socket_recv', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Socket_timeout_set', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Socket_fileno', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__String_strfsize', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_off_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Table_EXISTS', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_APR__Table_FETCH', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + }, + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_APR__Table_NEXTKEY', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + }, + { + 'type' => 'SV *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Table_copy', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'base' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Table_make', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'int', + 'name' => 'nelts' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Table_overlay', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'base' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'overlay' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'mpxs_APR__URI_port', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'uri' + }, + { + 'type' => 'SV *', + 'name' => 'portsv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__URI_rpath', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'apr_uri' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__CmdParms_add_config', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__CmdParms_info', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__CmdParms_override_opts', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Connection_add_input_filter', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Connection_add_output_filter', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + } + ] + }, + { + 'return_type' => 'apr_socket_t *', + 'name' => 'mpxs_Apache2__Connection_client_socket', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__Connection_get_remote_host', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'dir_config' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Connection_pnotes', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'SV *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Connection_pnotes_kill', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Directive_as_hash', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'tree' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Directive_as_string', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'self' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Filter_ctx', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'SV *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_Apache2__Filter_fflush', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_Apache2__Filter_get_brigade', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_Apache2__Filter_pass_brigade', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_Apache2__Filter_print', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_Apache2__Filter_read', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Filter_remove', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Filter_seen_eos', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Log_BOOT', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Log_log', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'int', + 'name' => 'logtype' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__MPM_BOOT', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__MPM_query', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'self' + }, + { + 'type' => 'int', + 'name' => 'query_code' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Module_add', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'package' + }, + { + 'type' => 'SV *', + 'name' => 'cmds' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__Module_ap_api_major_version', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'module *', + 'name' => 'mod' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__Module_ap_api_minor_version', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'module *', + 'name' => 'mod' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Module_get_config', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'pmodule' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'v' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__Module_loaded', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_FILENO', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_GETC', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_OPEN', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'self' + }, + { + 'type' => 'SV *', + 'name' => 'arg1' + }, + { + 'type' => 'SV *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_add_config', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'override_options' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_add_input_filter', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_add_output_filter', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_allow_override_opts', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_as_string', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_auth_name', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_auth_type', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_child_terminate', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_content_languages', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'languages' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_content_type', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_document_root', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'new_root' + } + ] + }, + { + 'return_type' => 'apr_finfo_t *', + 'name' => 'mpxs_Apache2__RequestRec_finfo', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_get_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_handler', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_is_perl_option_enabled', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'mpxs_Apache2__RequestRec_location', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_location_merge', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'location' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_new', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'SV *', + 'name' => 'base_pool_sv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_no_cache', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'flag' + } + ] + }, + { + 'return_type' => 'apr_uri_t *', + 'name' => 'mpxs_Apache2__RequestRec_parsed_uri', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_pnotes', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_pnotes_kill', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_print', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_proxyreq', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_push_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_read', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_rflush', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_Apache2__RequestRec_sendfile', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_set_basic_credentials', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'username' + }, + { + 'type' => 'char *', + 'name' => 'password' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_set_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => '', + 'name' => 'mpxs_Apache2__RequestRec_set_last_modified', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_subprocess_env', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_Apache2__RequestRec_write', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'mpxs_Apache2__RequestUtil_request', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'svr' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__ServerRec_add_config', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__ServerRec_get_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__ServerRec_is_perl_option_enabled', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__ServerRec_push_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__ServerRec_set_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__ServerUtil_BOOT', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__ServerUtil_server_shutdown_cleanup_register', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'cv' + }, + { + 'type' => 'SV *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_ModPerl__Global_special_list_call', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_ModPerl__Global_special_list_clear', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_ModPerl__Global_special_list_register', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_ModPerl__Util_untaint', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_ap_allow_methods', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'long', + 'name' => 'mpxs_ap_get_client_block', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'int', + 'name' => 'bufsiz' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_ap_log_error', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'SV *', + 'name' => 'msg' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_ap_requires', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_ap_rprintf', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_ap_run_sub_req', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_ap_rvputs', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'mpxs_ap_unescape_url', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_apr_base64_decode', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'SV *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_apr_base64_encode', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'SV *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_brigade_create', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'CLASS' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'ba' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_ipsubnet_create', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'const char *', + 'name' => 'ipstr' + }, + { + 'type' => 'const char *', + 'name' => 'mask_or_numbits' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_apr_password_validate', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'passwd' + }, + { + 'type' => 'const char *', + 'name' => 'hash' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_apr_pool_DESTROY', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'obj' + } + ] + }, + { + 'return_type' => '', + 'name' => 'mpxs_apr_pool_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'cleanup_data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_apr_pool_cleanup_register', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'SV *', + 'name' => 'cv' + }, + { + 'type' => 'SV *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_pool_create', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'parent_pool_obj' + } + ] + }, + { + 'return_type' => '', + 'name' => 'mpxs_apr_pool_parent_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'child_pool' + } + ] + }, + { + 'return_type' => '', + 'name' => 'mpxs_apr_sockaddr_ip_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_apr_socket_send', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'SV *', + 'name' => 'sv_buf' + }, + { + 'type' => 'SV *', + 'name' => 'sv_len' + } + ] + }, + { + 'return_type' => 'apr_interval_time_t', + 'name' => 'mpxs_apr_socket_timeout_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_apr_table_do', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_apr_table_do_cb', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_thread_mutex_create', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'unsigned int', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_thread_rwlock_create', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_uri_parse', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'const char *', + 'name' => 'uri_string' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'mpxs_apr_uri_unparse', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'uptr' + }, + { + 'type' => 'unsigned', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_uuid_t *', + 'name' => 'mpxs_apr_uuid_get', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'CLASS' + } + ] + }, + { + 'return_type' => 'apr_uuid_t *', + 'name' => 'mpxs_apr_uuid_parse', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'CLASS' + }, + { + 'type' => 'char *', + 'name' => 'buf' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_cleanup_run', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_insert_auth_cfg', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'directive' + }, + { + 'type' => 'char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_setup_client_block', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_special_list_do', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'package' + }, + { + 'type' => 'mpxs_special_list_do_t', + 'name' => 'func' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'mpxs_ModPerl__Interpreter_current', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'class' + } + ] + } +]; + + +1;
diff --git a/2_0_13/xs/tables/current24/APR/FunctionTable.pm b/2_0_13/xs/tables/current24/APR/FunctionTable.pm new file mode 100644 index 0000000..cf3d278 --- /dev/null +++ b/2_0_13/xs/tables/current24/APR/FunctionTable.pm
@@ -0,0 +1,228 @@ +package APR::FunctionTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: this file was manually generated on +# ! Tue Jun 22 22:00:00 2004 +# ! It contains a subset of functions appearing in +# ! ModPerl::FunctionTable used to build APR.so +# ! Eventually this will be autogenerated by +# ! Apache::ParseSource +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$APR::FunctionTable = [ + { + 'return_type' => 'void', + 'name' => 'modperl_trace', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'func' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace_level_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'logfile' + }, + { + 'type' => 'const char *', + 'name' => 'level' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace_logfile_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'logfile_new' + } + ] + }, + { + 'return_type' => 'unsigned long', + 'name' => 'modperl_debug_level', + 'args' => [] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_hash_tie', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + }, + { + 'type' => 'void *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_hash_tied_object', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_sv_setref_uv', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'rv' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'UV', + 'name' => 'uv' + } + ] + }, + { + 'return_type' => 'modperl_uri_t *', + 'name' => 'modperl_uri_new', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_gensym', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'pack' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_error_strerror', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_croak', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + }, + { + 'type' => 'const char*', + 'name' => 'func' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_interp_unselect', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'modperl_bucket_sv_create', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, +]; + +1;
diff --git a/2_0_13/xs/tables/current24/Apache2/ConstantsTable.pm b/2_0_13/xs/tables/current24/Apache2/ConstantsTable.pm new file mode 100644 index 0000000..f54adfd --- /dev/null +++ b/2_0_13/xs/tables/current24/Apache2/ConstantsTable.pm
@@ -0,0 +1,545 @@ +package Apache2::ConstantsTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by Apache2::ParseSource/0.02 +# ! Mon Jul 1 12:38:09 2013 +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$Apache2::ConstantsTable = { + 'ModPerl' => { + 'common' => [ + 'MODPERL_RC_EXIT' + ] + }, + 'Apache2::Const' => { + 'types' => [ + 'DIR_MAGIC_TYPE' + ], + 'satisfy' => [ + 'SATISFY_ALL', + 'SATISFY_ANY', + 'SATISFY_NOSPEC' + ], + 'remotehost' => [ + 'REMOTE_HOST', + 'REMOTE_NAME', + 'REMOTE_NOLOOKUP', + 'REMOTE_DOUBLE_REV' + ], + 'proxy' => [ + 'PROXYREQ_NONE', + 'PROXYREQ_PROXY', + 'PROXYREQ_REVERSE', + 'PROXYREQ_RESPONSE' + ], + 'platform' => [ + 'LF', + 'CR', + 'CRLF', + 'CRLF_ASCII' + ], + 'override' => [ + 'OR_NONE', + 'OR_LIMIT', + 'OR_OPTIONS', + 'OR_FILEINFO', + 'OR_AUTHCFG', + 'OR_INDEXES', + 'OR_UNSET', + 'ACCESS_CONF', + 'RSRC_CONF', + 'EXEC_ON_READ', + 'OR_ALL' + ], + 'options' => [ + 'OPT_NONE', + 'OPT_INDEXES', + 'OPT_INCLUDES', + 'OPT_SYM_LINKS', + 'OPT_EXECCGI', + 'OPT_UNSET', + 'OPT_INC_WITH_EXEC', + 'OPT_SYM_OWNER', + 'OPT_MULTI', + 'OPT_ALL' + ], + 'mpmq' => [ + 'AP_MPMQ_NOT_SUPPORTED', + 'AP_MPMQ_STATIC', + 'AP_MPMQ_DYNAMIC', + 'AP_MPMQ_STARTING', + 'AP_MPMQ_RUNNING', + 'AP_MPMQ_STOPPING', + 'AP_MPMQ_MAX_DAEMON_USED', + 'AP_MPMQ_IS_THREADED', + 'AP_MPMQ_IS_FORKED', + 'AP_MPMQ_HARD_LIMIT_DAEMONS', + 'AP_MPMQ_HARD_LIMIT_THREADS', + 'AP_MPMQ_MAX_THREADS', + 'AP_MPMQ_MIN_SPARE_DAEMONS', + 'AP_MPMQ_MIN_SPARE_THREADS', + 'AP_MPMQ_MAX_SPARE_DAEMONS', + 'AP_MPMQ_MAX_SPARE_THREADS', + 'AP_MPMQ_MAX_REQUESTS_DAEMON', + 'AP_MPMQ_MAX_DAEMONS', + 'AP_MPMQ_MPM_STATE', + 'AP_MPMQ_IS_ASYNC', + 'AP_MPMQ_GENERATION', + 'AP_MPMQ_HAS_SERF' + ], + 'methods' => [ + 'M_GET', + 'M_PUT', + 'M_POST', + 'M_DELETE', + 'M_CONNECT', + 'M_OPTIONS', + 'M_TRACE', + 'M_PATCH', + 'M_PROPFIND', + 'M_PROPPATCH', + 'M_MKCOL', + 'M_COPY', + 'M_MOVE', + 'M_LOCK', + 'M_UNLOCK', + 'M_VERSION_CONTROL', + 'M_CHECKOUT', + 'M_UNCHECKOUT', + 'M_CHECKIN', + 'M_UPDATE', + 'M_LABEL', + 'M_REPORT', + 'M_MKWORKSPACE', + 'M_MKACTIVITY', + 'M_BASELINE_CONTROL', + 'M_MERGE', + 'M_INVALID', + 'METHODS' + ], + 'log' => [ + 'APLOG_EMERG', + 'APLOG_ALERT', + 'APLOG_CRIT', + 'APLOG_ERR', + 'APLOG_WARNING', + 'APLOG_NOTICE', + 'APLOG_INFO', + 'APLOG_DEBUG', + 'APLOG_TRACE1', + 'APLOG_TRACE2', + 'APLOG_TRACE3', + 'APLOG_TRACE4', + 'APLOG_TRACE5', + 'APLOG_TRACE6', + 'APLOG_TRACE7', + 'APLOG_TRACE8', + 'APLOG_LEVELMASK', + 'APLOG_TOCLIENT', + 'APLOG_STARTUP', + 'APLOG_NO_MODULE', + 'APLOG_MODULE_INDEX' + ], + 'input_mode' => [ + 'AP_MODE_READBYTES', + 'AP_MODE_GETLINE', + 'AP_MODE_EATCRLF', + 'AP_MODE_SPECULATIVE', + 'AP_MODE_EXHAUSTIVE', + 'AP_MODE_INIT' + ], + 'http' => [ + 'HTTP_CONTINUE', + 'HTTP_SWITCHING_PROTOCOLS', + 'HTTP_PROCESSING', + 'HTTP_OK', + 'HTTP_CREATED', + 'HTTP_ACCEPTED', + 'HTTP_NON_AUTHORITATIVE', + 'HTTP_NO_CONTENT', + 'HTTP_RESET_CONTENT', + 'HTTP_PARTIAL_CONTENT', + 'HTTP_MULTI_STATUS', + 'HTTP_ALREADY_REPORTED', + 'HTTP_IM_USED', + 'HTTP_MULTIPLE_CHOICES', + 'HTTP_MOVED_PERMANENTLY', + 'HTTP_MOVED_TEMPORARILY', + 'HTTP_SEE_OTHER', + 'HTTP_NOT_MODIFIED', + 'HTTP_USE_PROXY', + 'HTTP_TEMPORARY_REDIRECT', + 'HTTP_PERMANENT_REDIRECT', + 'HTTP_BAD_REQUEST', + 'HTTP_UNAUTHORIZED', + 'HTTP_PAYMENT_REQUIRED', + 'HTTP_FORBIDDEN', + 'HTTP_NOT_FOUND', + 'HTTP_METHOD_NOT_ALLOWED', + 'HTTP_NOT_ACCEPTABLE', + 'HTTP_PROXY_AUTHENTICATION_REQUIRED', + 'HTTP_REQUEST_TIME_OUT', + 'HTTP_CONFLICT', + 'HTTP_GONE', + 'HTTP_LENGTH_REQUIRED', + 'HTTP_PRECONDITION_FAILED', + 'HTTP_REQUEST_ENTITY_TOO_LARGE', + 'HTTP_REQUEST_URI_TOO_LARGE', + 'HTTP_UNSUPPORTED_MEDIA_TYPE', + 'HTTP_RANGE_NOT_SATISFIABLE', + 'HTTP_EXPECTATION_FAILED', + 'HTTP_UNPROCESSABLE_ENTITY', + 'HTTP_LOCKED', + 'HTTP_FAILED_DEPENDENCY', + 'HTTP_UPGRADE_REQUIRED', + 'HTTP_PRECONDITION_REQUIRED', + 'HTTP_TOO_MANY_REQUESTS', + 'HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE', + 'HTTP_INTERNAL_SERVER_ERROR', + 'HTTP_NOT_IMPLEMENTED', + 'HTTP_BAD_GATEWAY', + 'HTTP_SERVICE_UNAVAILABLE', + 'HTTP_GATEWAY_TIME_OUT', + 'HTTP_VARIANT_ALSO_VARIES', + 'HTTP_INSUFFICIENT_STORAGE', + 'HTTP_LOOP_DETECTED', + 'HTTP_NOT_EXTENDED', + 'HTTP_NETWORK_AUTHENTICATION_REQUIRED' + ], + 'filter_type' => [ + 'AP_FTYPE_RESOURCE', + 'AP_FTYPE_CONTENT_SET', + 'AP_FTYPE_PROTOCOL', + 'AP_FTYPE_TRANSCODE', + 'AP_FTYPE_CONNECTION', + 'AP_FTYPE_NETWORK' + ], + 'context' => [ + 'NOT_IN_VIRTUALHOST', + 'NOT_IN_LIMIT', + 'NOT_IN_DIRECTORY', + 'NOT_IN_LOCATION', + 'NOT_IN_FILES', + 'NOT_IN_HTACCESS', + 'NOT_IN_DIR_LOC_FILE', + 'GLOBAL_ONLY' + ], + 'conn_keepalive' => [ + 'AP_CONN_UNKNOWN', + 'AP_CONN_CLOSE', + 'AP_CONN_KEEPALIVE' + ], + 'config' => [ + 'DECLINE_CMD' + ], + 'common' => [ + 'OK', + 'DECLINED', + 'DONE', + 'NOT_FOUND', + 'FORBIDDEN', + 'AUTH_REQUIRED', + 'SERVER_ERROR', + 'REDIRECT' + ], + 'cmd_how' => [ + 'RAW_ARGS', + 'TAKE1', + 'TAKE2', + 'ITERATE', + 'ITERATE2', + 'FLAG', + 'NO_ARGS', + 'TAKE12', + 'TAKE3', + 'TAKE23', + 'TAKE123', + 'TAKE13', + 'TAKE_ARGV' + ], + 'authz_status' => [ + 'AUTHZ_DENIED', + 'AUTHZ_GRANTED', + 'AUTHZ_NEUTRAL', + 'AUTHZ_GENERAL_ERROR', + 'AUTHZ_DENIED_NO_USER' + ], + 'authn_status' => [ + 'AUTH_DENIED', + 'AUTH_GRANTED', + 'AUTH_USER_FOUND', + 'AUTH_USER_NOT_FOUND', + 'AUTH_GENERAL_ERROR' + ], + 'auth' => [ + 'AUTHN_PROVIDER_GROUP', + 'AUTHZ_PROVIDER_GROUP', + 'AUTHN_PROVIDER_VERSION', + 'AUTHZ_PROVIDER_VERSION', + 'AUTHN_DEFAULT_PROVIDER', + 'AUTHN_PROVIDER_NAME_NOTE', + 'AUTHZ_PROVIDER_NAME_NOTE', + 'AUTHN_PREFIX', + 'AUTHZ_PREFIX', + 'AP_AUTH_INTERNAL_PER_URI', + 'AP_AUTH_INTERNAL_PER_CONF', + 'AP_AUTH_INTERNAL_MASK' + ] + }, + 'APR::Const' => { + 'uri' => [ + 'APR_URI_FTP_DEFAULT_PORT', + 'APR_URI_SSH_DEFAULT_PORT', + 'APR_URI_TELNET_DEFAULT_PORT', + 'APR_URI_GOPHER_DEFAULT_PORT', + 'APR_URI_HTTP_DEFAULT_PORT', + 'APR_URI_POP_DEFAULT_PORT', + 'APR_URI_NNTP_DEFAULT_PORT', + 'APR_URI_IMAP_DEFAULT_PORT', + 'APR_URI_PROSPERO_DEFAULT_PORT', + 'APR_URI_WAIS_DEFAULT_PORT', + 'APR_URI_LDAP_DEFAULT_PORT', + 'APR_URI_HTTPS_DEFAULT_PORT', + 'APR_URI_RTSP_DEFAULT_PORT', + 'APR_URI_SNEWS_DEFAULT_PORT', + 'APR_URI_ACAP_DEFAULT_PORT', + 'APR_URI_NFS_DEFAULT_PORT', + 'APR_URI_TIP_DEFAULT_PORT', + 'APR_URI_SIP_DEFAULT_PORT', + 'APR_URI_UNP_OMITSITEPART', + 'APR_URI_UNP_OMITUSER', + 'APR_URI_UNP_OMITPASSWORD', + 'APR_URI_UNP_OMITUSERINFO', + 'APR_URI_UNP_REVEALPASSWORD', + 'APR_URI_UNP_OMITPATHINFO', + 'APR_URI_UNP_OMITQUERY' + ], + 'table' => [ + 'APR_OVERLAP_TABLES_SET', + 'APR_OVERLAP_TABLES_MERGE' + ], + 'status' => [ + 'APR_TIMEUP' + ], + 'socket' => [ + 'APR_SO_LINGER', + 'APR_SO_KEEPALIVE', + 'APR_SO_DEBUG', + 'APR_SO_NONBLOCK', + 'APR_SO_REUSEADDR', + 'APR_SO_SNDBUF', + 'APR_SO_RCVBUF', + 'APR_SO_DISCONNECTED' + ], + 'shutdown_how' => [ + 'APR_SHUTDOWN_READ', + 'APR_SHUTDOWN_WRITE', + 'APR_SHUTDOWN_READWRITE' + ], + 'read_type' => [ + 'APR_BLOCK_READ', + 'APR_NONBLOCK_READ' + ], + 'poll' => [ + 'APR_POLLIN', + 'APR_POLLPRI', + 'APR_POLLOUT', + 'APR_POLLERR', + 'APR_POLLHUP', + 'APR_POLLNVAL', + 'APR_POLLSET_THREADSAFE', + 'APR_POLLSET_NOCOPY', + 'APR_POLLSET_WAKEABLE', + 'APR_POLLSET_NODEFAULT' + ], + 'lockmech' => [ + 'APR_LOCK_FCNTL', + 'APR_LOCK_FLOCK', + 'APR_LOCK_SYSVSEM', + 'APR_LOCK_PROC_PTHREAD', + 'APR_LOCK_POSIXSEM', + 'APR_LOCK_DEFAULT' + ], + 'limit' => [ + 'APR_LIMIT_CPU', + 'APR_LIMIT_MEM', + 'APR_LIMIT_NPROC', + 'APR_LIMIT_NOFILE' + ], + 'hook' => [ + 'APR_HOOK_REALLY_FIRST', + 'APR_HOOK_FIRST', + 'APR_HOOK_MIDDLE', + 'APR_HOOK_LAST', + 'APR_HOOK_REALLY_LAST' + ], + 'fprot' => [ + 'APR_FPROT_USETID', + 'APR_FPROT_UREAD', + 'APR_FPROT_UWRITE', + 'APR_FPROT_UEXECUTE', + 'APR_FPROT_GSETID', + 'APR_FPROT_GREAD', + 'APR_FPROT_GWRITE', + 'APR_FPROT_GEXECUTE', + 'APR_FPROT_WSTICKY', + 'APR_FPROT_WREAD', + 'APR_FPROT_WWRITE', + 'APR_FPROT_WEXECUTE', + 'APR_FPROT_OS_DEFAULT', + 'APR_FPROT_FILE_SOURCE_PERMS' + ], + 'fopen' => [ + 'APR_FOPEN_READ', + 'APR_FOPEN_WRITE', + 'APR_FOPEN_CREATE', + 'APR_FOPEN_APPEND', + 'APR_FOPEN_TRUNCATE', + 'APR_FOPEN_BINARY', + 'APR_FOPEN_EXCL', + 'APR_FOPEN_BUFFERED', + 'APR_FOPEN_DELONCLOSE', + 'APR_FOPEN_XTHREAD', + 'APR_FOPEN_SHARELOCK', + 'APR_FOPEN_NOCLEANUP', + 'APR_FOPEN_SENDFILE_ENABLED', + 'APR_FOPEN_LARGEFILE', + 'APR_FOPEN_SPARSE' + ], + 'flock' => [ + 'APR_FLOCK_SHARED', + 'APR_FLOCK_EXCLUSIVE', + 'APR_FLOCK_TYPEMASK', + 'APR_FLOCK_NONBLOCK' + ], + 'finfo' => [ + 'APR_FINFO_LINK', + 'APR_FINFO_MTIME', + 'APR_FINFO_CTIME', + 'APR_FINFO_ATIME', + 'APR_FINFO_SIZE', + 'APR_FINFO_CSIZE', + 'APR_FINFO_DEV', + 'APR_FINFO_INODE', + 'APR_FINFO_NLINK', + 'APR_FINFO_TYPE', + 'APR_FINFO_USER', + 'APR_FINFO_GROUP', + 'APR_FINFO_UPROT', + 'APR_FINFO_GPROT', + 'APR_FINFO_WPROT', + 'APR_FINFO_ICASE', + 'APR_FINFO_NAME', + 'APR_FINFO_MIN', + 'APR_FINFO_IDENT', + 'APR_FINFO_OWNER', + 'APR_FINFO_PROT', + 'APR_FINFO_NORM', + 'APR_FINFO_DIRENT' + ], + 'filetype' => [ + 'APR_FILETYPE_NOFILE', + 'APR_FILETYPE_REG', + 'APR_FILETYPE_DIR', + 'APR_FILETYPE_CHR', + 'APR_FILETYPE_BLK', + 'APR_FILETYPE_PIPE', + 'APR_FILETYPE_LNK', + 'APR_FILETYPE_SOCK', + 'APR_FILETYPE_UNKFILE' + ], + 'filepath' => [ + 'APR_FILEPATH_NOTABOVEROOT', + 'APR_FILEPATH_SECUREROOTTEST', + 'APR_FILEPATH_SECUREROOT', + 'APR_FILEPATH_NOTRELATIVE', + 'APR_FILEPATH_NOTABSOLUTE', + 'APR_FILEPATH_NATIVE', + 'APR_FILEPATH_TRUENAME', + 'APR_FILEPATH_ENCODING_UNKNOWN', + 'APR_FILEPATH_ENCODING_LOCALE', + 'APR_FILEPATH_ENCODING_UTF8' + ], + 'error' => [ + 'APR_ENOSTAT', + 'APR_ENOPOOL', + 'APR_EBADDATE', + 'APR_EINVALSOCK', + 'APR_ENOPROC', + 'APR_ENOTIME', + 'APR_ENODIR', + 'APR_ENOLOCK', + 'APR_ENOPOLL', + 'APR_ENOSOCKET', + 'APR_ENOTHREAD', + 'APR_ENOTHDKEY', + 'APR_EGENERAL', + 'APR_ENOSHMAVAIL', + 'APR_EBADIP', + 'APR_EBADMASK', + 'APR_EDSOOPEN', + 'APR_EABSOLUTE', + 'APR_ERELATIVE', + 'APR_EINCOMPLETE', + 'APR_EABOVEROOT', + 'APR_EBADPATH', + 'APR_EPATHWILD', + 'APR_ESYMNOTFOUND', + 'APR_EPROC_UNKNOWN', + 'APR_ENOTENOUGHENTROPY', + 'APR_EOF', + 'APR_EINIT', + 'APR_ENOTIMPL', + 'APR_EMISMATCH', + 'APR_EBUSY', + 'APR_EACCES', + 'APR_EEXIST', + 'APR_ENAMETOOLONG', + 'APR_ENOENT', + 'APR_ENOTDIR', + 'APR_ENOSPC', + 'APR_ENOMEM', + 'APR_EMFILE', + 'APR_ENFILE', + 'APR_EBADF', + 'APR_EINVAL', + 'APR_ESPIPE', + 'APR_EAGAIN', + 'APR_EINTR', + 'APR_ENOTSOCK', + 'APR_ECONNREFUSED', + 'APR_EINPROGRESS', + 'APR_ECONNABORTED', + 'APR_ECONNRESET', + 'APR_ETIMEDOUT', + 'APR_EHOSTUNREACH', + 'APR_ENETUNREACH', + 'APR_EFTYPE', + 'APR_EPIPE', + 'APR_EXDEV', + 'APR_ENOTEMPTY', + 'APR_EAFNOSUPPORT', + 'APR_EXCL', + 'APR_END', + 'APR_ENOKEY', + 'APR_ENOIV', + 'APR_EKEYTYPE', + 'APR_ENOSPACE', + 'APR_ECRYPT', + 'APR_EPADDING', + 'APR_EKEYLENGTH', + 'APR_ENOCIPHER', + 'APR_ENODIGEST', + 'APR_ENOENGINE', + 'APR_EINITENGINE', + 'APR_EREINIT' + ], + 'common' => [ + 'APR_SUCCESS' + ] + } +}; + + +1;
diff --git a/2_0_13/xs/tables/current24/Apache2/FunctionTable.pm b/2_0_13/xs/tables/current24/Apache2/FunctionTable.pm new file mode 100644 index 0000000..adaa249 --- /dev/null +++ b/2_0_13/xs/tables/current24/Apache2/FunctionTable.pm
@@ -0,0 +1,21265 @@ +package Apache2::FunctionTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by Apache2::ParseSource/0.02 +# ! Mon Jul 1 12:38:14 2013 +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$Apache2::FunctionTable = [ + { + 'return_type' => 'void', + 'name' => 'ap_abort_on_oom', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_cgi_vars', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_common_vars', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_file_conf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'core_dir_config *', + 'name' => 'conf' + }, + { + 'type' => 'void *', + 'name' => 'url_config' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_add_if_conf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'core_dir_config *', + 'name' => 'conf' + }, + { + 'type' => 'void *', + 'name' => 'url_config' + } + ] + }, + { + 'return_type' => 'ap_filter_t *', + 'name' => 'ap_add_input_filter', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'ap_filter_t *', + 'name' => 'ap_add_input_filter_handle', + 'args' => [ + { + 'type' => 'ap_filter_rec_t *', + 'name' => 'f' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_add_loaded_module', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'mod' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_add_module', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'ap_directive_t *', + 'name' => 'ap_add_node', + 'args' => [ + { + 'type' => 'ap_directive_t **', + 'name' => 'parent' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'current' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'toadd' + }, + { + 'type' => 'int', + 'name' => 'child' + } + ] + }, + { + 'return_type' => 'ap_filter_t *', + 'name' => 'ap_add_output_filter', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'ap_filter_t *', + 'name' => 'ap_add_output_filter_handle', + 'args' => [ + { + 'type' => 'ap_filter_rec_t *', + 'name' => 'f' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_output_filters_by_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_per_dir_conf', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'void *', + 'name' => 'dir_config' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_per_url_conf', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'void *', + 'name' => 'url_config' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_add_version_component', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'const char *', + 'name' => 'component' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_allow_methods', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'reset' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_allow_options', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_allow_overrides', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_allow_standard_methods', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'reset' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_append_pid', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'string' + }, + { + 'type' => 'const char *', + 'name' => 'delim' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_args_to_table', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_table_t **', + 'name' => 'table' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_auth_name', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_auth_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_basic_http_header', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_bin2hex', + 'args' => [ + { + 'type' => 'const void *', + 'name' => 'src' + }, + { + 'type' => 'apr_size_t', + 'name' => 'srclen' + }, + { + 'type' => 'char *', + 'name' => 'dest' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_eoc_create', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_eoc_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_eor_create', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_eor_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_error_create', + 'args' => [ + { + 'type' => 'int', + 'name' => 'error' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'ap_bucket_error_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'int', + 'name' => 'error' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_build_config', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'conf_pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'conftree' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_build_cont_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'current' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'curr_parent' + }, + { + 'type' => 'char *', + 'name' => 'orig_directive' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_byterange_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_calc_scoreboard_size', + 'args' => [] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_calloc', + 'args' => [ + { + 'type' => 'size_t', + 'name' => 'nelem' + }, + { + 'type' => 'size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_cfg_closefile', + 'args' => [ + { + 'type' => 'ap_configfile_t *', + 'name' => 'cfp' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cfg_getc', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'ch' + }, + { + 'type' => 'ap_configfile_t *', + 'name' => 'cfp' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cfg_getline', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bufsize' + }, + { + 'type' => 'ap_configfile_t *', + 'name' => 'cfp' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_check_cmd_context', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'unsigned', + 'name' => 'forbidden' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_check_mpm', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cleanup_scoreboard', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'd' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_clear_auth_internal', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_clear_method_list', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'l' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_close_listeners', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_close_piped_log', + 'args' => [ + { + 'type' => 'piped_log *', + 'name' => 'pl' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_close_selected_listeners', + 'args' => [ + { + 'type' => 'ap_slave_t *', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_construct_server', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_construct_url', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'uri' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_content_length_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'arg0' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_content_type_tolower', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_context_document_root', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_context_prefix', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cookie_check_string', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'string' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cookie_read', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'const char **', + 'name' => 'val' + }, + { + 'type' => 'int', + 'name' => 'remove' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cookie_remove', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'const char *', + 'name' => 'attrs' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cookie_remove2', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name2' + }, + { + 'type' => 'const char *', + 'name' => 'attrs2' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cookie_write', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'const char *', + 'name' => 'val' + }, + { + 'type' => 'const char *', + 'name' => 'attrs' + }, + { + 'type' => 'long', + 'name' => 'maxage' + }, + { + 'type' => '...', + 'name' => 'arg5' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_cookie_write2', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name2' + }, + { + 'type' => 'const char *', + 'name' => 'val' + }, + { + 'type' => 'const char *', + 'name' => 'attrs2' + }, + { + 'type' => 'long', + 'name' => 'maxage' + }, + { + 'type' => '...', + 'name' => 'arg5' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_copy_method_list', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'dest' + }, + { + 'type' => 'ap_method_list_t *', + 'name' => 'src' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_core_child_status', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'pid_t', + 'name' => 'pid' + }, + { + 'type' => 'ap_generation_t', + 'name' => 'gen' + }, + { + 'type' => 'int', + 'name' => 'slot' + }, + { + 'type' => 'mpm_child_status', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_core_input_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_core_output_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_core_reorder_directories', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'arg0' + }, + { + 'type' => 'server_rec *', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_core_translate', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_count_dirs', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + } + ] + }, + { + 'return_type' => 'ap_conf_vector_t*', + 'name' => 'ap_create_conn_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'char **', + 'name' => 'ap_create_environment', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'ap_conf_vector_t *', + 'name' => 'ap_create_per_dir_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ap_conf_vector_t*', + 'name' => 'ap_create_request_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_create_sb_handle', + 'args' => [ + { + 'type' => 'ap_sb_handle_t **', + 'name' => 'new_sbh' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'child_num' + }, + { + 'type' => 'int', + 'name' => 'thread_num' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_create_scoreboard', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_scoreboard_e', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_custom_response', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'const char *', + 'name' => 'string' + } + ] + }, + { + 'return_type' => 'ap_dbd_t*', + 'name' => 'ap_dbd_acquire', + 'args' => [ + { + 'type' => 'request_rec*', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'ap_dbd_t*', + 'name' => 'ap_dbd_cacquire', + 'args' => [ + { + 'type' => 'conn_rec*', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_dbd_close', + 'args' => [ + { + 'type' => 'server_rec*', + 'name' => 'arg0' + }, + { + 'type' => 'ap_dbd_t*', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'ap_dbd_t*', + 'name' => 'ap_dbd_open', + 'args' => [ + { + 'type' => 'apr_pool_t*', + 'name' => 'arg0' + }, + { + 'type' => 'server_rec*', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_dbd_prepare', + 'args' => [ + { + 'type' => 'server_rec*', + 'name' => 'arg0' + }, + { + 'type' => 'const char*', + 'name' => 'arg1' + }, + { + 'type' => 'const char*', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_destroy_sub_req', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_die', + 'args' => [ + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_directory_walk', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_discard_request_body', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_document_root', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_dump_mutexes', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'out' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_error_log2stderr', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'ap_escape_errorlog_item', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'dest' + }, + { + 'type' => 'const char *', + 'name' => 'source' + }, + { + 'type' => 'apr_size_t', + 'name' => 'buflen' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_html2', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'toasc' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_logitem', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_path_segment', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_path_segment_buffer', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'c' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_quotes', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'instring' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_shell_cmd', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_urlencoded', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_escape_urlencoded_buffer', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'c' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_exists_config_define', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_exists_scoreboard_image', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_explode_recent_gmt', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'tm' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_explode_recent_localtime', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'tm' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_expr_exec', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const ap_expr_info_t *', + 'name' => 'expr' + }, + { + 'type' => 'const char **', + 'name' => 'err' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_expr_exec_ctx', + 'args' => [ + { + 'type' => 'ap_expr_eval_ctx_t *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_expr_exec_re', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const ap_expr_info_t *', + 'name' => 'expr' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'ap_regmatch_t *', + 'name' => 'pmatch' + }, + { + 'type' => 'const char **', + 'name' => 'source' + }, + { + 'type' => 'const char **', + 'name' => 'err' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_expr_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_expr_lookup_default', + 'args' => [ + { + 'type' => 'ap_expr_lookup_parms *', + 'name' => 'parms' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_expr_parse', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'ap_expr_info_t *', + 'name' => 'info' + }, + { + 'type' => 'const char *', + 'name' => 'expr' + }, + { + 'type' => 'ap_expr_lookup_fn_t *', + 'name' => 'lookup_fn' + } + ] + }, + { + 'return_type' => 'ap_expr_info_t *', + 'name' => 'ap_expr_parse_cmd_mi', + 'args' => [ + { + 'type' => 'const cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'const char *', + 'name' => 'expr' + }, + { + 'type' => 'unsigned int', + 'name' => 'flags' + }, + { + 'type' => 'const char **', + 'name' => 'err' + }, + { + 'type' => 'ap_expr_lookup_fn_t *', + 'name' => 'lookup_fn' + }, + { + 'type' => 'int', + 'name' => 'module_index' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_expr_str_exec', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const ap_expr_info_t *', + 'name' => 'expr' + }, + { + 'type' => 'const char **', + 'name' => 'err' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_expr_str_exec_re', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const ap_expr_info_t *', + 'name' => 'expr' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'ap_regmatch_t *', + 'name' => 'pmatch' + }, + { + 'type' => 'const char **', + 'name' => 'source' + }, + { + 'type' => 'const char **', + 'name' => 'err' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fatal_signal_child_setup', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fatal_signal_setup', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'in_pconf' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fflush', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_field_noparam', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'intype' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_file_walk', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_filter_flush', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_filter_protocol', + 'args' => [ + { + 'type' => 'ap_filter_t*', + 'name' => 'f' + }, + { + 'type' => 'unsigned int', + 'name' => 'proto_flags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_finalize_request_protocol', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_finalize_sub_req_protocol', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'sub_r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_find_child_by_pid', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'pid' + } + ] + }, + { + 'return_type' => 'const command_rec *', + 'name' => 'ap_find_command', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'const command_rec *', + 'name' => 'cmds' + } + ] + }, + { + 'return_type' => 'const command_rec *', + 'name' => 'ap_find_command_in_modules', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'cmd_name' + }, + { + 'type' => 'module **', + 'name' => 'mod' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_find_last_token', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'line' + }, + { + 'type' => 'const char *', + 'name' => 'tok' + } + ] + }, + { + 'return_type' => 'module *', + 'name' => 'ap_find_linked_module', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_find_list_item', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'line' + }, + { + 'type' => 'const char *', + 'name' => 'tok' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_find_module_name', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_find_module_short_name', + 'args' => [ + { + 'type' => 'int', + 'name' => 'module_index' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_find_path_info', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'uri' + }, + { + 'type' => 'const char *', + 'name' => 'path_info' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_find_token', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'line' + }, + { + 'type' => 'const char *', + 'name' => 'tok' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_fini_vhost_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 'main_server' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_fixup_virtual_hosts', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 'main_server' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_flush_conn', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fprintf', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_fputstrs', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_get_basic_auth_pw', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char **', + 'name' => 'pw' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_get_brigade', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bucket' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'long', + 'name' => 'ap_get_client_block', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bufsiz' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_get_conn_module_loglevel', + 'args' => [ + { + 'type' => 'const conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'int', + 'name' => 'index' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_get_conn_server_module_loglevel', + 'args' => [ + { + 'type' => 'const conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'const server_rec *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'index' + } + ] + }, + { + 'return_type' => 'apr_socket_t *', + 'name' => 'ap_get_conn_socket', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_get_core_module_config', + 'args' => [ + { + 'type' => 'const ap_conf_vector_t *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_get_input_filter_handle', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'apr_off_t', + 'name' => 'ap_get_limit_req_body', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'ap_get_limit_xml_body', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_get_list_item', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'field' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_get_loadavg', + 'args' => [ + { + 'type' => 'ap_loadavg_t *', + 'name' => 'ld' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_get_local_host', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_get_mime_headers', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_get_mime_headers_core', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_get_module_config', + 'args' => [ + { + 'type' => 'const ap_conf_vector_t *', + 'name' => 'cv' + }, + { + 'type' => 'const module *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_get_output_filter_handle', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_remote_host', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'conn' + }, + { + 'type' => 'void *', + 'name' => 'dir_config' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'int *', + 'name' => 'str_is_ip' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_remote_logname', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_get_request_module_loglevel', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'index' + } + ] + }, + { + 'return_type' => 'void **', + 'name' => 'ap_get_request_note', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_size_t', + 'name' => 'note_num' + } + ] + }, + { + 'return_type' => 'global_score *', + 'name' => 'ap_get_scoreboard_global', + 'args' => [] + }, + { + 'return_type' => 'process_score *', + 'name' => 'ap_get_scoreboard_process', + 'args' => [ + { + 'type' => 'int', + 'name' => 'x' + } + ] + }, + { + 'return_type' => 'worker_score *', + 'name' => 'ap_get_scoreboard_worker', + 'args' => [ + { + 'type' => 'ap_sb_handle_t *', + 'name' => 'sbh' + } + ] + }, + { + 'return_type' => 'worker_score *', + 'name' => 'ap_get_scoreboard_worker_from_indexes', + 'args' => [ + { + 'type' => 'int', + 'name' => 'child_num' + }, + { + 'type' => 'int', + 'name' => 'thread_num' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_banner', + 'args' => [] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_built', + 'args' => [] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_description', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_get_server_module_loglevel', + 'args' => [ + { + 'type' => 'const server_rec *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'index' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_name', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_name_for_url', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_port_t', + 'name' => 'ap_get_server_port', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'ap_get_server_protocol', + 'args' => [ + { + 'type' => 'server_rec*', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_get_server_revision', + 'args' => [ + { + 'type' => 'ap_version_t *', + 'name' => 'version' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_server_version', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_get_sload', + 'args' => [ + { + 'type' => 'ap_sload_t *', + 'name' => 'ld' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_get_status_line', + 'args' => [ + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_get_token', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'accept_line' + }, + { + 'type' => 'int', + 'name' => 'accept_white' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_getline', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'n' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'fold' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_getparents', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'line' + }, + { + 'type' => 'char', + 'name' => 'stop' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_conf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'line' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_conf_nc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'line' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_nc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'line' + }, + { + 'type' => 'char', + 'name' => 'stop' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_nulls', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'line' + }, + { + 'type' => 'char', + 'name' => 'stop' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_nulls_nc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'line' + }, + { + 'type' => 'char', + 'name' => 'stop' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_white', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'line' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_getword_white_nc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'line' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_global_mutex_create', + 'args' => [ + { + 'type' => 'apr_global_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char **', + 'name' => 'name' + }, + { + 'type' => 'const char *', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'instance_id' + }, + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'options' + } + ] + }, + { + 'return_type' => 'gid_t', + 'name' => 'ap_gname2id', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_access_checker', + 'args' => [ + { + 'type' => 'ap_HOOK_access_checker_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_access_checker_ex', + 'args' => [ + { + 'type' => 'ap_HOOK_access_checker_ex_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_auth_checker', + 'args' => [ + { + 'type' => 'ap_HOOK_auth_checker_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_check_access', + 'args' => [ + { + 'type' => 'ap_HOOK_access_checker_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_check_access_ex', + 'args' => [ + { + 'type' => 'ap_HOOK_access_checker_ex_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_check_authn', + 'args' => [ + { + 'type' => 'ap_HOOK_check_user_id_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_check_authz', + 'args' => [ + { + 'type' => 'ap_HOOK_auth_checker_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_check_config', + 'args' => [ + { + 'type' => 'ap_HOOK_check_config_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_check_user_id', + 'args' => [ + { + 'type' => 'ap_HOOK_check_user_id_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_child_init', + 'args' => [ + { + 'type' => 'ap_HOOK_child_init_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_child_status', + 'args' => [ + { + 'type' => 'ap_HOOK_child_status_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_create_connection', + 'args' => [ + { + 'type' => 'ap_HOOK_create_connection_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_create_request', + 'args' => [ + { + 'type' => 'ap_HOOK_create_request_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_default_port', + 'args' => [ + { + 'type' => 'ap_HOOK_default_port_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_drop_privileges', + 'args' => [ + { + 'type' => 'ap_HOOK_drop_privileges_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_end_generation', + 'args' => [ + { + 'type' => 'ap_HOOK_end_generation_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_error_log', + 'args' => [ + { + 'type' => 'ap_HOOK_error_log_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_expr_lookup', + 'args' => [ + { + 'type' => 'ap_HOOK_expr_lookup_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_fixups', + 'args' => [ + { + 'type' => 'ap_HOOK_fixups_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_generate_log_id', + 'args' => [ + { + 'type' => 'ap_HOOK_generate_log_id_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_access_checker', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_access_checker_ex', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_auth_checker', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_check_config', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_check_user_id', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_child_init', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_child_status', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_create_connection', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_create_request', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_default_port', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_drop_privileges', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_end_generation', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_error_log', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_expr_lookup', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_fixups', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_generate_log_id', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_get_mgmt_items', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_get_suexec_identity', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_handler', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_header_parser', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_http_scheme', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_insert_error_filter', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_insert_filter', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_insert_network_bucket', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_log_transaction', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_map_to_storage', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_get_mgmt_items', + 'args' => [ + { + 'type' => 'ap_HOOK_get_mgmt_items_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_monitor', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_mpm', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_mpm_get_name', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_mpm_query', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_mpm_register_timed_callback', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_note_auth_failure', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_open_logs', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_optional_fn_retrieve', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_post_config', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_post_read_request', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_pre_config', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_pre_connection', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_pre_mpm', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_pre_read_request', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_process_connection', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_quick_handler', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_session_decode', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_session_encode', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_session_load', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_session_save', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_status_hook', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_get_suexec_identity', + 'args' => [ + { + 'type' => 'ap_HOOK_get_suexec_identity_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_test_config', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_translate_name', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_type_checker', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_watchdog_exit', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_watchdog_init', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_watchdog_need', + 'args' => [] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_hook_get_watchdog_step', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_handler', + 'args' => [ + { + 'type' => 'ap_HOOK_handler_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_header_parser', + 'args' => [ + { + 'type' => 'ap_HOOK_header_parser_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_http_scheme', + 'args' => [ + { + 'type' => 'ap_HOOK_http_scheme_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_insert_error_filter', + 'args' => [ + { + 'type' => 'ap_HOOK_insert_error_filter_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_insert_filter', + 'args' => [ + { + 'type' => 'ap_HOOK_insert_filter_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_insert_network_bucket', + 'args' => [ + { + 'type' => 'ap_HOOK_insert_network_bucket_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_log_transaction', + 'args' => [ + { + 'type' => 'ap_HOOK_log_transaction_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_map_to_storage', + 'args' => [ + { + 'type' => 'ap_HOOK_map_to_storage_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_monitor', + 'args' => [ + { + 'type' => 'ap_HOOK_monitor_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_mpm', + 'args' => [ + { + 'type' => 'ap_HOOK_mpm_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_mpm_get_name', + 'args' => [ + { + 'type' => 'ap_HOOK_mpm_get_name_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_mpm_query', + 'args' => [ + { + 'type' => 'ap_HOOK_mpm_query_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_mpm_register_timed_callback', + 'args' => [ + { + 'type' => 'ap_HOOK_mpm_register_timed_callback_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_note_auth_failure', + 'args' => [ + { + 'type' => 'ap_HOOK_note_auth_failure_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_open_logs', + 'args' => [ + { + 'type' => 'ap_HOOK_open_logs_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_optional_fn_retrieve', + 'args' => [ + { + 'type' => 'ap_HOOK_optional_fn_retrieve_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_post_config', + 'args' => [ + { + 'type' => 'ap_HOOK_post_config_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_post_read_request', + 'args' => [ + { + 'type' => 'ap_HOOK_post_read_request_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_pre_config', + 'args' => [ + { + 'type' => 'ap_HOOK_pre_config_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_pre_connection', + 'args' => [ + { + 'type' => 'ap_HOOK_pre_connection_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_pre_mpm', + 'args' => [ + { + 'type' => 'ap_HOOK_pre_mpm_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_pre_read_request', + 'args' => [ + { + 'type' => 'ap_HOOK_pre_read_request_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_process_connection', + 'args' => [ + { + 'type' => 'ap_HOOK_process_connection_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_quick_handler', + 'args' => [ + { + 'type' => 'ap_HOOK_quick_handler_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_session_decode', + 'args' => [ + { + 'type' => 'ap_HOOK_session_decode_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_session_encode', + 'args' => [ + { + 'type' => 'ap_HOOK_session_encode_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_session_load', + 'args' => [ + { + 'type' => 'ap_HOOK_session_load_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_session_save', + 'args' => [ + { + 'type' => 'ap_HOOK_session_save_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_status_hook', + 'args' => [ + { + 'type' => 'ap_HOOK_status_hook_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_test_config', + 'args' => [ + { + 'type' => 'ap_HOOK_test_config_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_translate_name', + 'args' => [ + { + 'type' => 'ap_HOOK_translate_name_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_type_checker', + 'args' => [ + { + 'type' => 'ap_HOOK_type_checker_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_watchdog_exit', + 'args' => [ + { + 'type' => 'ap_HOOK_watchdog_exit_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_watchdog_init', + 'args' => [ + { + 'type' => 'ap_HOOK_watchdog_init_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_watchdog_need', + 'args' => [ + { + 'type' => 'ap_HOOK_watchdog_need_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_hook_watchdog_step', + 'args' => [ + { + 'type' => 'ap_HOOK_watchdog_step_t *', + 'name' => 'pf' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_ht_time', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'int', + 'name' => 'gmt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_http_chunk_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_http_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_http_header_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_http_outerror_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_if_walk', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_increment_counts', + 'args' => [ + { + 'type' => 'ap_sb_handle_t *', + 'name' => 'sbh' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_ind', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'char', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_index_of_response', + 'args' => [ + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_init_rng', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_init_scoreboard', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'shared_score' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_init_vhost_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_init_virtual_host', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'server_rec *', + 'name' => 'main_server' + }, + { + 'type' => 'server_rec **', + 'name' => 'ps' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_internal_fast_redirect', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'sub_req' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_internal_redirect', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'new_uri' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_internal_redirect_handler', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'new_uri' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_invoke_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_directory', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_initial_req', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_matchexp', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_rdirectory', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_recursion_limit_exceeded', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_is_url', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'u' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_limit_section', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_lingering_close', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_list_provider_groups', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'ap_list_provider_names', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_listen_pre_config', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_location_walk', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_assert', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szExp' + }, + { + 'type' => 'const char *', + 'name' => 'szFile' + }, + { + 'type' => 'int', + 'name' => 'nLine' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_cerror_', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'const conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg7' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_command_line', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_cserror_', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'const conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'const server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg8' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_error_', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'const server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg7' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_perror_', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg7' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_pid', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_log_rerror_', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg7' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_logs_child_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_lookup_provider', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_name' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_make_content_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_make_dirstr_parent', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_make_dirstr_prefix', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'd' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_make_etag', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'force_weak' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_make_full_path', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'const char *', + 'name' => 'dir' + }, + { + 'type' => 'const char *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'ap_method_list_t *', + 'name' => 'ap_make_method_list', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'nelts' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_malloc', + 'args' => [ + { + 'type' => 'size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_matches_request_vhost', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'host' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_md5', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'string' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_md5_binary', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'buf' + }, + { + 'type' => 'int', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_md5contextTo64', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_md5digest', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'infile' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_meets_conditions', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_merge_log_config', + 'args' => [ + { + 'type' => 'const struct ap_logconf *', + 'name' => 'old_conf' + }, + { + 'type' => 'struct ap_logconf *', + 'name' => 'new_conf' + } + ] + }, + { + 'return_type' => 'ap_conf_vector_t*', + 'name' => 'ap_merge_per_dir_configs', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'base' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'new_conf' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_method_in_list', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'l' + }, + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_method_is_limited', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_method_list_add', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'l' + }, + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_method_list_remove', + 'args' => [ + { + 'type' => 'ap_method_list_t *', + 'name' => 'l' + }, + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_method_name_of', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'methnum' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_method_number_of', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_method_register', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'methname' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_method_registry_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_mpm_dump_pidfile', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'out' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_end_gen_helper', + 'args' => [ + { + 'type' => 'void *unused', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_pod_check', + 'args' => [ + { + 'type' => 'ap_pod_t *', + 'name' => 'pod' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_pod_close', + 'args' => [ + { + 'type' => 'ap_pod_t *', + 'name' => 'pod' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_mpm_pod_killpg', + 'args' => [ + { + 'type' => 'ap_pod_t *', + 'name' => 'pod' + }, + { + 'type' => 'int', + 'name' => 'num' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_pod_open', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_pod_t **', + 'name' => 'pod' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_pod_signal', + 'args' => [ + { + 'type' => 'ap_pod_t *', + 'name' => 'pod' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_query', + 'args' => [ + { + 'type' => 'int', + 'name' => 'query_code' + }, + { + 'type' => 'int *', + 'name' => 'result' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_register_timed_callback', + 'args' => [ + { + 'type' => 'apr_time_t', + 'name' => 't' + }, + { + 'type' => 'ap_mpm_callback_fn_t *', + 'name' => 'cbfn' + }, + { + 'type' => 'void *', + 'name' => 'baton' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_mpm_rewrite_args', + 'args' => [ + { + 'type' => 'process_rec *', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mpm_safe_kill', + 'args' => [ + { + 'type' => 'pid_t', + 'name' => 'pid' + }, + { + 'type' => 'int', + 'name' => 'sig' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_coredumpdir', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_graceful_shutdown', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_max_mem_free', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_max_requests', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_pidfile', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_mpm_set_thread_stacksize', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_mutex_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_mutex_register', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'const char *', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'default_dir' + }, + { + 'type' => 'apr_lockmech_e', + 'name' => 'default_mech' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'options' + } + ] + }, + { + 'return_type' => 'struct ap_logconf *', + 'name' => 'ap_new_log_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const struct ap_logconf *', + 'name' => 'old' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_no2slash', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_note_auth_failure', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_note_basic_auth_failure', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_note_digest_auth_failure', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_old_write_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_open_logs', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's_main' + } + ] + }, + { + 'return_type' => 'piped_log *', + 'name' => 'ap_open_piped_log', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'program' + } + ] + }, + { + 'return_type' => 'piped_log *', + 'name' => 'ap_open_piped_log_ex', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'program' + }, + { + 'type' => 'apr_cmdtype_e', + 'name' => 'cmdtype' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_open_stderr_log', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_os_create_privileged_process', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_proc_t *', + 'name' => 'newproc' + }, + { + 'type' => 'const char *', + 'name' => 'progname' + }, + { + 'type' => 'const char * const *', + 'name' => 'args' + }, + { + 'type' => 'const char * const *', + 'name' => 'env' + }, + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_os_escape_path', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'partial' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_os_is_path_absolute', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'dir' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_parse_form_data', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'struct ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_array_header_t **', + 'name' => 'ptr' + }, + { + 'type' => 'apr_size_t', + 'name' => 'num' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_parse_htaccess', + 'args' => [ + { + 'type' => 'ap_conf_vector_t **', + 'name' => 'result' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'int', + 'name' => 'override_opts' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'override_list' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'const char *', + 'name' => 'access_name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_parse_log_level', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'int *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_parse_mutex', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'arg' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_lockmech_e *', + 'name' => 'mutexmech' + }, + { + 'type' => 'const char **', + 'name' => 'mutexfile' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_parse_uri', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'uri' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_parse_vhost_addrs', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_pass_brigade', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_pass_brigade_fchk', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bucket' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_pbase64decode', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'bufcoded' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_pbase64encode', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char *', + 'name' => 'string' + } + ] + }, + { + 'return_type' => 'ap_configfile_t *', + 'name' => 'ap_pcfg_open_custom', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'descr' + }, + { + 'type' => 'void *', + 'name' => 'param' + }, + { + 'type' => 'apr_status_t (*getc_func) (char *ch, void *param)', + 'name' => 'arg3' + }, + { + 'type' => 'apr_status_t (*gets_func) (void *buf, apr_size_t bufsiz, void *param)', + 'name' => 'arg4' + }, + { + 'type' => 'apr_status_t (*close_func) (void *param)', + 'name' => 'arg5' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_pcfg_openfile', + 'args' => [ + { + 'type' => 'ap_configfile_t **', + 'name' => 'ret_cfg' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_pcfg_strerror', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_configfile_t *', + 'name' => 'cfp' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'ap_pcw_srv_cb_t', + 'name' => 'srv_cb' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_default_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_directory_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'core_server_config *', + 'name' => 'sconf' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_files_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'core_dir_config *', + 'name' => 'dconf' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_location_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'core_server_config *', + 'name' => 'sconf' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'name' => 'dir_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pcw_walk_server_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'module *', + 'name' => 'modp' + }, + { + 'type' => 'ap_pcw_srv_cb_t', + 'name' => 'srv_cb' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_file_t *', + 'name' => 'ap_piped_log_read_fd', + 'args' => [ + { + 'type' => 'piped_log *', + 'name' => 'pl' + } + ] + }, + { + 'return_type' => 'apr_file_t *', + 'name' => 'ap_piped_log_write_fd', + 'args' => [ + { + 'type' => 'piped_log *', + 'name' => 'pl' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_pool_cleanup_set_null', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'ap_regex_t *', + 'name' => 'ap_pregcomp', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'pattern' + }, + { + 'type' => 'int', + 'name' => 'cflags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_pregfree', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_regex_t *', + 'name' => 'reg' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_pregsub', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'input' + }, + { + 'type' => 'const char *', + 'name' => 'source' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'ap_regmatch_t', + 'name' => 'pmatch' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_pregsub_ex', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'result' + }, + { + 'type' => 'const char *', + 'name' => 'input' + }, + { + 'type' => 'const char *', + 'name' => 'source' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'ap_regmatch_t', + 'name' => 'pmatch' + }, + { + 'type' => 'apr_size_t', + 'name' => 'maxlen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_proc_mutex_create', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char **', + 'name' => 'name' + }, + { + 'type' => 'const char *', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'instance_id' + }, + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'options' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_process_async_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_process_child_status', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'pid' + }, + { + 'type' => 'apr_exit_why_e', + 'name' => 'why' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_process_config_tree', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'conftree' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_process_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'void *', + 'name' => 'csd' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_process_fnmatch_configs', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'conftree' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'int', + 'name' => 'optional' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_process_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_process_request_after_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_process_request_internal', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_process_resource_config', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'conftree' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_psignature', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'prefix' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_pstr2_alnum', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'src' + }, + { + 'type' => 'const char **', + 'name' => 'dest' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_random_insecure_bytes', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_random_parent_after_fork', + 'args' => [] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'ap_random_pick', + 'args' => [ + { + 'type' => 'apr_uint32_t', + 'name' => 'min' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'max' + } + ] + }, + { + 'return_type' => 'apr_time_t', + 'name' => 'ap_rationalize_mtime', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + } + ] + }, + { + 'return_type' => 'server_rec *', + 'name' => 'ap_read_config', + 'args' => [ + { + 'type' => 'process_rec *', + 'name' => 'process' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'const char *', + 'name' => 'config_name' + }, + { + 'type' => 'ap_directive_t **', + 'name' => 'conftree' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_read_pid', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'pid_t *', + 'name' => 'mypid' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_read_request', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_realloc', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'ptr' + }, + { + 'type' => 'size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_recent_ctime', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_recent_ctime_ex', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + }, + { + 'type' => 'int', + 'name' => 'option' + }, + { + 'type' => 'int *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_recent_rfc822_date', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_reclaim_child_processes', + 'args' => [ + { + 'type' => 'int', + 'name' => 'terminate' + }, + { + 'type' => 'ap_reclaim_callback_fn_t *', + 'name' => 'mpm_callback' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_regcomp', + 'args' => [ + { + 'type' => 'ap_regex_t *', + 'name' => 'preg' + }, + { + 'type' => 'const char *', + 'name' => 'regex' + }, + { + 'type' => 'int', + 'name' => 'cflags' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'ap_regerror', + 'args' => [ + { + 'type' => 'int', + 'name' => 'errcode' + }, + { + 'type' => 'const ap_regex_t *', + 'name' => 'preg' + }, + { + 'type' => 'char *', + 'name' => 'errbuf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'errbuf_size' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_regexec', + 'args' => [ + { + 'type' => 'const ap_regex_t *', + 'name' => 'preg' + }, + { + 'type' => 'const char *', + 'name' => 'string' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'ap_regmatch_t *', + 'name' => 'pmatch' + }, + { + 'type' => 'int', + 'name' => 'eflags' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_regexec_len', + 'args' => [ + { + 'type' => 'const ap_regex_t *', + 'name' => 'preg' + }, + { + 'type' => 'const char *', + 'name' => 'buff' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'ap_regmatch_t *', + 'name' => 'pmatch' + }, + { + 'type' => 'int', + 'name' => 'eflags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_regfree', + 'args' => [ + { + 'type' => 'ap_regex_t *', + 'name' => 'preg' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_register_auth_provider', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_name' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + }, + { + 'type' => 'const void *', + 'name' => 'provider' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_register_config_hooks', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_register_errorlog_handler', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char *', + 'name' => 'tag' + }, + { + 'type' => 'ap_errorlog_handler_fn_t *', + 'name' => 'handler' + }, + { + 'type' => 'int', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_register_extra_mpm_process', + 'args' => [ + { + 'type' => 'pid_t', + 'name' => 'pid' + }, + { + 'type' => 'ap_generation_t', + 'name' => 'gen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_register_hooks', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_register_input_filter', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_in_filter_func', + 'name' => 'filter_func' + }, + { + 'type' => 'ap_init_filter_func', + 'name' => 'filter_init' + }, + { + 'type' => 'ap_filter_type', + 'name' => 'ftype' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_register_log_hooks', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_register_output_filter', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_out_filter_func', + 'name' => 'filter_func' + }, + { + 'type' => 'ap_init_filter_func', + 'name' => 'filter_init' + }, + { + 'type' => 'ap_filter_type', + 'name' => 'ftype' + } + ] + }, + { + 'return_type' => 'ap_filter_rec_t *', + 'name' => 'ap_register_output_filter_protocol', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_out_filter_func', + 'name' => 'filter_func' + }, + { + 'type' => 'ap_init_filter_func', + 'name' => 'filter_init' + }, + { + 'type' => 'ap_filter_type', + 'name' => 'ftype' + }, + { + 'type' => 'unsigned int', + 'name' => 'proto_flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_register_provider', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_name' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + }, + { + 'type' => 'const void *', + 'name' => 'provider' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'ap_register_request_note', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_relieve_child_processes', + 'args' => [ + { + 'type' => 'ap_reclaim_callback_fn_t *', + 'name' => 'mpm_callback' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_input_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_loaded_module', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'mod' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_module', + 'args' => [ + { + 'type' => 'module *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_output_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_remove_pid', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_reopen_scoreboard', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_shm_t **', + 'name' => 'shm' + }, + { + 'type' => 'int', + 'name' => 'detached' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_replace_stderr_log', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_request_has_body', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_reserve_module_slots', + 'args' => [ + { + 'type' => 'int', + 'name' => 'count' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_reserve_module_slots_directive', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'directive' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_reset_module_loglevels', + 'args' => [ + { + 'type' => 'struct ap_logconf *', + 'name' => 'l' + }, + { + 'type' => 'int', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_resolve_env', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'word' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_response_code_string', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'error_index' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_retained_data_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_retained_data_get', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rflush', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_rgetline_core', + 'args' => [ + { + 'type' => 'char **', + 'name' => 's' + }, + { + 'type' => 'apr_size_t', + 'name' => 'n' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'read' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'fold' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rind', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'char', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rprintf', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rputc', + 'args' => [ + { + 'type' => 'int', + 'name' => 'c' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rputs', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_access_checker', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_access_checker_ex', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_auth_checker', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_check_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_check_user_id', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_child_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pchild' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_child_status', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'pid_t', + 'name' => 'pid' + }, + { + 'type' => 'ap_generation_t', + 'name' => 'gen' + }, + { + 'type' => 'int', + 'name' => 'slot' + }, + { + 'type' => 'mpm_child_status', + 'name' => 'state' + } + ] + }, + { + 'return_type' => 'conn_rec *', + 'name' => 'ap_run_create_connection', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'csd' + }, + { + 'type' => 'long', + 'name' => 'conn_id' + }, + { + 'type' => 'void *', + 'name' => 'sbh' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'alloc' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_create_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_port_t', + 'name' => 'ap_run_default_port', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_drop_privileges', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pchild' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_end_generation', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'ap_generation_t', + 'name' => 'gen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_error_log', + 'args' => [ + { + 'type' => 'const ap_errorlog_info *', + 'name' => 'info' + }, + { + 'type' => 'const char *', + 'name' => 'errstr' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_expr_lookup', + 'args' => [ + { + 'type' => 'ap_expr_lookup_parms *', + 'name' => 'parms' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_fixups', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_generate_log_id', + 'args' => [ + { + 'type' => 'const conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char **', + 'name' => 'id' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_get_mgmt_items', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'val' + }, + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + } + ] + }, + { + 'return_type' => 'ap_unix_identity_t *', + 'name' => 'ap_run_get_suexec_identity', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_header_parser', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_run_http_scheme', + 'args' => [ + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_insert_error_filter', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_insert_filter', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_run_insert_network_bucket', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_log_transaction', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_map_to_storage', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_monitor', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_mpm', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'server_rec *', + 'name' => 'server_conf' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_run_mpm_get_name', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_mpm_query', + 'args' => [ + { + 'type' => 'int', + 'name' => 'query_code' + }, + { + 'type' => 'int *', + 'name' => 'result' + }, + { + 'type' => 'apr_status_t *', + 'name' => 'rv' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_run_mpm_register_timed_callback', + 'args' => [ + { + 'type' => 'apr_time_t', + 'name' => 't' + }, + { + 'type' => 'ap_mpm_callback_fn_t *', + 'name' => 'cbfn' + }, + { + 'type' => 'void *', + 'name' => 'baton' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_note_auth_failure', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'auth_type' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_open_logs', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_optional_fn_retrieve', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_post_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_post_read_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_pre_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_pre_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'void *', + 'name' => 'csd' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_pre_mpm', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'ap_scoreboard_e', + 'name' => 'sb_type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_pre_read_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_process_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_quick_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'lookup_uri' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_rewrite_args', + 'args' => [ + { + 'type' => 'process_rec *', + 'name' => 'process' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_run_session_decode', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'session_rec *', + 'name' => 'z' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_run_session_encode', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'session_rec *', + 'name' => 'z' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_run_session_load', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'session_rec **', + 'name' => 'z' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_run_session_save', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'session_rec *', + 'name' => 'z' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_status_hook', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_sub_req', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_run_test_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_translate_name', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_type_checker', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_watchdog_exit', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_watchdog_init', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_watchdog_need', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'parent' + }, + { + 'type' => 'int', + 'name' => 'singleton' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_run_watchdog_step', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_runtime_dir_relative', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rvputs', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => '...', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rwrite', + 'args' => [ + { + 'type' => 'const void *', + 'name' => 'buf' + }, + { + 'type' => 'int', + 'name' => 'nbyte' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'ap_rxplus_t*', + 'name' => 'ap_rxplus_compile', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'pattern' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_rxplus_exec', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'ap_rxplus_t *', + 'name' => 'rx' + }, + { + 'type' => 'const char *', + 'name' => 'pattern' + }, + { + 'type' => 'char **', + 'name' => 'newpattern' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_rxplus_match', + 'args' => [ + { + 'type' => 'ap_rxplus_t *', + 'name' => 'rx' + }, + { + 'type' => 'int', + 'name' => 'n' + }, + { + 'type' => 'int *', + 'name' => 'len' + }, + { + 'type' => 'const char **', + 'name' => 'match' + } + ] + }, + { + 'return_type' => 'char*', + 'name' => 'ap_rxplus_pmatch', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'ap_rxplus_t *', + 'name' => 'rx' + }, + { + 'type' => 'int', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_satisfies', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_save_brigade', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade **', + 'name' => 'save_to' + }, + { + 'type' => 'apr_bucket_brigade **', + 'name' => 'b' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_scan_script_header_err', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'f' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_scan_script_header_err_brigade', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_scan_script_header_err_brigade_ex', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'int', + 'name' => 'module_index' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_scan_script_header_err_core', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'int (*getsfunc) (char *, int, void *)', + 'name' => 'arg2' + }, + { + 'type' => 'void *', + 'name' => 'getsfunc_data' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_scan_script_header_err_core_ex', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'int (*getsfunc) (char *, int, void *)', + 'name' => 'arg2' + }, + { + 'type' => 'void *', + 'name' => 'getsfunc_data' + }, + { + 'type' => 'int', + 'name' => 'module_index' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_scan_script_header_err_ex', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'f' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'int', + 'name' => 'module_index' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_scan_script_header_err_strs', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'const char **', + 'name' => 'termch' + }, + { + 'type' => 'int *', + 'name' => 'termarg' + }, + { + 'type' => '...', + 'name' => 'arg4' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_scan_script_header_err_strs_ex', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'const char **', + 'name' => 'termch' + }, + { + 'type' => 'int *', + 'name' => 'termarg' + }, + { + 'type' => '...', + 'name' => 'arg5' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_send_error_response', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'recursive_error' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_send_fd', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fd' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_send_http_options', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_send_http_trace', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_send_interim_response', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'send_headers' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'ap_send_mmap', + 'args' => [ + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_size_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_server_root_relative', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_accept_ranges', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'ap_set_config_vectors', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'section_vector' + }, + { + 'type' => 'const char *section', + 'name' => 'arg2' + }, + { + 'type' => 'module *', + 'name' => 'mod' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_content_length', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_off_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_content_type', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'ct' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_context_info', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'prefix' + }, + { + 'type' => 'const char *', + 'name' => 'document_root' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_core_module_config', + 'args' => [ + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'cv' + }, + { + 'type' => 'void *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_deprecated', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_document_root', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'document_root' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_etag', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_extended_status', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'int', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_file_slot', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_flag_slot', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'int', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_flag_slot_char', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'int', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_int_slot', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_set_keepalive', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_last_modified', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_listenbacklog', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_listener', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'int', + 'name' => 'argc' + }, + { + 'type' => 'char *const', + 'name' => 'argv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_module_config', + 'args' => [ + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'cv' + }, + { + 'type' => 'const module *', + 'name' => 'm' + }, + { + 'type' => 'void *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_module_loglevel', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'struct ap_logconf *', + 'name' => 'l' + }, + { + 'type' => 'int', + 'name' => 'index' + }, + { + 'type' => 'int', + 'name' => 'level' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_mutex', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_name_virtual_host', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_receive_buffer_size', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_reqtail', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'int', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_scoreboard', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_send_buffer_size', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_server_protocol', + 'args' => [ + { + 'type' => 'server_rec*', + 'name' => 's' + }, + { + 'type' => 'const char*', + 'name' => 'proto' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_string_slot', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_set_string_slot_lower', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'void *', + 'name' => 'struct_ptr' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_set_sub_req_protocol', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'rnew' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_setup_auth_internal', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_setup_client_block', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'read_policy' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_setup_listeners', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_setup_make_content_type', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_setup_prelinked_modules', + 'args' => [ + { + 'type' => 'process_rec *', + 'name' => 'process' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_should_client_block', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_show_directives', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'ap_show_modules', + 'args' => [] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_show_mpm', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_signal_server', + 'args' => [ + { + 'type' => 'int *', + 'name' => 'arg0' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_single_module_configure', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'module *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_size_list_item', + 'args' => [ + { + 'type' => 'const char **', + 'name' => 'field' + }, + { + 'type' => 'int *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_soak_end_container', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'char *', + 'name' => 'directive' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_some_auth_required', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_start_lingering_close', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_state_query', + 'args' => [ + { + 'type' => 'int', + 'name' => 'query_code' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_str2_alnum', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'src' + }, + { + 'type' => 'char *', + 'name' => 'dest' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_str_tolower', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_str_toupper', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_strcasecmp_match', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'const char *', + 'name' => 'expected' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_strcasestr', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 's1' + }, + { + 'type' => 'const char *', + 'name' => 's2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_strchr', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_strchr_c', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_strcmp_match', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'const char *', + 'name' => 'expected' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_stripprefix', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'bigstring' + }, + { + 'type' => 'const char *', + 'name' => 'prefix' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_strrchr', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_strrchr_c', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_strstr', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_strstr_c', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_sub_req_lookup_dirent', + 'args' => [ + { + 'type' => 'const apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'subtype' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next_filter' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_sub_req_lookup_file', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'new_file' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next_filter' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_sub_req_lookup_uri', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'new_uri' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next_filter' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'ap_sub_req_method_uri', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'method' + }, + { + 'type' => 'const char *', + 'name' => 'new_uri' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next_filter' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_sub_req_output_filter', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_sys_privileges_handlers', + 'args' => [ + { + 'type' => 'int', + 'name' => 'inc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_time_process_request', + 'args' => [ + { + 'type' => 'ap_sb_handle_t *', + 'name' => 'sbh' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_timeout_parameter_parse', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'timeout_parameter' + }, + { + 'type' => 'apr_interval_time_t *', + 'name' => 'timeout' + }, + { + 'type' => 'const char *', + 'name' => 'default_time_unit' + } + ] + }, + { + 'return_type' => 'uid_t', + 'name' => 'ap_uname2id', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unescape_all', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unescape_url', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unescape_url_keep2f', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'url' + }, + { + 'type' => 'int', + 'name' => 'decode_slashes' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unescape_urlencoded', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'query' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_unixd_accept', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'accepted' + }, + { + 'type' => 'ap_listen_rec *', + 'name' => 'lr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptrans' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_unixd_set_global_mutex_perms', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'gmutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_unixd_set_proc_mutex_perms', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'pmutex' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_unixd_set_rlimit', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'cmd' + }, + { + 'type' => 'struct rlimit **', + 'name' => 'plimit' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unixd_setup_child', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'ap_unregister_extra_mpm_process', + 'args' => [ + { + 'type' => 'pid_t', + 'name' => 'pid' + }, + { + 'type' => 'ap_generation_t *', + 'name' => 'old_gen' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_update_child_status', + 'args' => [ + { + 'type' => 'ap_sb_handle_t *', + 'name' => 'sbh' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_update_child_status_from_conn', + 'args' => [ + { + 'type' => 'ap_sb_handle_t *', + 'name' => 'sbh' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_update_child_status_from_indexes', + 'args' => [ + { + 'type' => 'int', + 'name' => 'child_num' + }, + { + 'type' => 'int', + 'name' => 'thread_num' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_update_mtime', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_time_t', + 'name' => 'dependency_mtime' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_update_vhost_from_headers', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_update_vhost_given_ip', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'conn' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_varbuf_cfg_getline', + 'args' => [ + { + 'type' => 'struct ap_varbuf *', + 'name' => 'vb' + }, + { + 'type' => 'ap_configfile_t *', + 'name' => 'cfp' + }, + { + 'type' => 'apr_size_t', + 'name' => 'max_len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_varbuf_free', + 'args' => [ + { + 'type' => 'struct ap_varbuf *', + 'name' => 'vb' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_varbuf_grow', + 'args' => [ + { + 'type' => 'struct ap_varbuf *', + 'name' => 'vb' + }, + { + 'type' => 'apr_size_t', + 'name' => 'new_size' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_varbuf_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'struct ap_varbuf *', + 'name' => 'vb' + }, + { + 'type' => 'apr_size_t', + 'name' => 'init_size' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'ap_varbuf_pdup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'struct ap_varbuf *', + 'name' => 'vb' + }, + { + 'type' => 'const char *', + 'name' => 'prepend' + }, + { + 'type' => 'apr_size_t', + 'name' => 'prepend_len' + }, + { + 'type' => 'const char *', + 'name' => 'append' + }, + { + 'type' => 'apr_size_t', + 'name' => 'append_len' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'new_len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'ap_varbuf_regsub', + 'args' => [ + { + 'type' => 'struct ap_varbuf *', + 'name' => 'vb' + }, + { + 'type' => 'const char *', + 'name' => 'input' + }, + { + 'type' => 'const char *', + 'name' => 'source' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'ap_regmatch_t', + 'name' => 'pmatch' + }, + { + 'type' => 'apr_size_t', + 'name' => 'maxlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_varbuf_strmemcat', + 'args' => [ + { + 'type' => 'struct ap_varbuf *', + 'name' => 'vb' + }, + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'int', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_vhost_iterate_given_conn', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'conn' + }, + { + 'type' => 'ap_vhost_iterate_conn_cb', + 'name' => 'func_cb' + }, + { + 'type' => 'void*', + 'name' => 'baton' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_vrprintf', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'va_list', + 'name' => 'vlist' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'ap_wait_or_timeout', + 'args' => [ + { + 'type' => 'apr_exit_why_e *', + 'name' => 'status' + }, + { + 'type' => 'int *', + 'name' => 'exitcode' + }, + { + 'type' => 'apr_proc_t *', + 'name' => 'ret' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'ap_walk_config', + 'args' => [ + { + 'type' => 'ap_directive_t *', + 'name' => 'conftree' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'section_vector' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'ap_xml_parse_input', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_xml_doc **', + 'name' => 'pdoc' + } + ] + }, + { + 'return_type' => 'apr_memnode_t *', + 'name' => 'apr_allocator_alloc', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_allocator_create', + 'args' => [ + { + 'type' => 'apr_allocator_t **', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_destroy', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_free', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_memnode_t *', + 'name' => 'memnode' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_max_free_set', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'apr_thread_mutex_t *', + 'name' => 'apr_allocator_mutex_get', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_mutex_set', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_allocator_owner_get', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_allocator_owner_set', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_app_initialize', + 'args' => [ + { + 'type' => 'int *', + 'name' => 'argc' + }, + { + 'type' => 'char const * const * *', + 'name' => 'argv' + }, + { + 'type' => 'char const * const * *', + 'name' => 'env' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_array_append', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'first' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'second' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_array_cat', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'dst' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'src' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_array_clear', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_array_copy', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_array_copy_hdr', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_array_make', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'nelts' + }, + { + 'type' => 'int', + 'name' => 'elt_size' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_array_pop', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_array_pstrcat', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_array_header_t *', + 'name' => 'arr' + }, + { + 'type' => 'const char', + 'name' => 'sep' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_array_push', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'arr' + } + ] + }, + { + 'return_type' => 'apr_int64_t', + 'name' => 'apr_atoi64', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_atomic_add32', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_atomic_cas32', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'with' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'cmp' + } + ] + }, + { + 'return_type' => 'void*', + 'name' => 'apr_atomic_casptr', + 'args' => [ + { + 'type' => 'volatile void **', + 'name' => 'mem' + }, + { + 'type' => 'void *', + 'name' => 'with' + }, + { + 'type' => 'const void *', + 'name' => 'cmp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_atomic_dec32', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_atomic_inc32', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_atomic_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_atomic_read32', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_atomic_set32', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_atomic_sub32', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_atomic_xchg32', + 'args' => [ + { + 'type' => 'volatile apr_uint32_t *', + 'name' => 'mem' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void*', + 'name' => 'apr_atomic_xchgptr', + 'args' => [ + { + 'type' => 'volatile void **', + 'name' => 'mem' + }, + { + 'type' => 'void *', + 'name' => 'with' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_decode', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'plain_dst' + }, + { + 'type' => 'const char *', + 'name' => 'coded_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_decode_binary', + 'args' => [ + { + 'type' => 'unsigned char *', + 'name' => 'plain_dst' + }, + { + 'type' => 'const char *', + 'name' => 'coded_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_decode_len', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'coded_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_encode', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'coded_dst' + }, + { + 'type' => 'const char *', + 'name' => 'plain_src' + }, + { + 'type' => 'int', + 'name' => 'len_plain_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_encode_binary', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'coded_dst' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'plain_src' + }, + { + 'type' => 'int', + 'name' => 'len_plain_src' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_base64_encode_len', + 'args' => [ + { + 'type' => 'int', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_bucket_brigade *', + 'name' => 'apr_brigade_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_destroy', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_flatten', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'char *', + 'name' => 'c' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_brigade_insert_file', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'apr_off_t', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_length', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'int', + 'name' => 'read_all' + }, + { + 'type' => 'apr_off_t *', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_partition', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_off_t', + 'name' => 'point' + }, + { + 'type' => 'apr_bucket **', + 'name' => 'after_point' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_pflatten', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'char **', + 'name' => 'c' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_printf', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg4' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_putc', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_puts', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_putstrs', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_bucket_brigade *', + 'name' => 'apr_brigade_split', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'e' + } + ] + }, + { + 'return_type' => 'apr_bucket_brigade *', + 'name' => 'apr_brigade_split_ex', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'e' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'a' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_split_line', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bbOut' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bbIn' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'maxbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_to_iovec', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'int *', + 'name' => 'nvec' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_vprintf', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'va_list', + 'name' => 'va' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_vputstrs', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'va_list', + 'name' => 'va' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_write', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_brigade_writev', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + }, + { + 'type' => 'apr_brigade_flush', + 'name' => 'flush' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nvec' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_bucket_alloc', + 'args' => [ + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket_alloc_t *', + 'name' => 'apr_bucket_alloc_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_bucket_alloc_t *', + 'name' => 'apr_bucket_alloc_create_ex', + 'args' => [ + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_bucket_alloc_destroy', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_copy_notimpl', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'e' + }, + { + 'type' => 'apr_bucket **', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_bucket_destroy_noop', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_eos_create', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_eos_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_file_create', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fd' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_file_enable_mmap', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'int', + 'name' => 'enabled' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_file_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'fd' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_flush_create', + 'args' => [ + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_flush_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_bucket_free', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'block' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_heap_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + }, + { + 'type' => 'void (*free_func)(void *data)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_heap_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + }, + { + 'type' => 'void (*free_func)(void *data)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_immortal_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_immortal_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_mmap_create', + 'args' => [ + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_mmap_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_pipe_create', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thispipe' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_pipe_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thispipe' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_pool_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_pool_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_setaside_noop', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'data' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_setaside_notimpl', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'data' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_shared_copy', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket **', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_bucket_shared_destroy', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_shared_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_shared_split', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_size_t', + 'name' => 'point' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_simple_copy', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket **', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_simple_split', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_size_t', + 'name' => 'point' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_socket_create', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thissock' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_socket_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'thissock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_bucket_split_notimpl', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'data' + }, + { + 'type' => 'apr_size_t', + 'name' => 'point' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_transient_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'apr_bucket_transient_make', + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbyte' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_collapse_spaces', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'dest' + }, + { + 'type' => 'const char *', + 'name' => 'src' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_cpystrn', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'dst' + }, + { + 'type' => 'const char *', + 'name' => 'src' + }, + { + 'type' => 'apr_size_t', + 'name' => 'dst_size' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_block_cleanup', + 'args' => [ + { + 'type' => 'apr_crypto_block_t *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_block_decrypt', + 'args' => [ + { + 'type' => 'unsigned char **', + 'name' => 'out' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'outlen' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'in' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inlen' + }, + { + 'type' => 'apr_crypto_block_t *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_block_decrypt_finish', + 'args' => [ + { + 'type' => 'unsigned char *', + 'name' => 'out' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'outlen' + }, + { + 'type' => 'apr_crypto_block_t *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_block_decrypt_init', + 'args' => [ + { + 'type' => 'apr_crypto_block_t **', + 'name' => 'ctx' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'blockSize' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'iv' + }, + { + 'type' => 'const apr_crypto_key_t *', + 'name' => 'key' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_block_encrypt', + 'args' => [ + { + 'type' => 'unsigned char **', + 'name' => 'out' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'outlen' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'in' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inlen' + }, + { + 'type' => 'apr_crypto_block_t *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_block_encrypt_finish', + 'args' => [ + { + 'type' => 'unsigned char *', + 'name' => 'out' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'outlen' + }, + { + 'type' => 'apr_crypto_block_t *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_block_encrypt_init', + 'args' => [ + { + 'type' => 'apr_crypto_block_t **', + 'name' => 'ctx' + }, + { + 'type' => 'const unsigned char **', + 'name' => 'iv' + }, + { + 'type' => 'const apr_crypto_key_t *', + 'name' => 'key' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'blockSize' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_cleanup', + 'args' => [ + { + 'type' => 'apr_crypto_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_clear', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'void *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_crypto_driver_name', + 'args' => [ + { + 'type' => 'const apr_crypto_driver_t *', + 'name' => 'driver' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_error', + 'args' => [ + { + 'type' => 'const apu_err_t **', + 'name' => 'result' + }, + { + 'type' => 'const apr_crypto_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_get_block_key_modes', + 'args' => [ + { + 'type' => 'apr_hash_t **', + 'name' => 'modes' + }, + { + 'type' => 'const apr_crypto_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_get_block_key_types', + 'args' => [ + { + 'type' => 'apr_hash_t **', + 'name' => 'types' + }, + { + 'type' => 'const apr_crypto_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_get_driver', + 'args' => [ + { + 'type' => 'const apr_crypto_driver_t **', + 'name' => 'driver' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'const char *', + 'name' => 'params' + }, + { + 'type' => 'const apu_err_t **', + 'name' => 'result' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_make', + 'args' => [ + { + 'type' => 'apr_crypto_t **', + 'name' => 'f' + }, + { + 'type' => 'const apr_crypto_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'const char *', + 'name' => 'params' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_passphrase', + 'args' => [ + { + 'type' => 'apr_crypto_key_t **', + 'name' => 'key' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'ivSize' + }, + { + 'type' => 'const char *', + 'name' => 'pass' + }, + { + 'type' => 'apr_size_t', + 'name' => 'passLen' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'salt' + }, + { + 'type' => 'apr_size_t', + 'name' => 'saltLen' + }, + { + 'type' => 'const apr_crypto_block_key_type_e', + 'name' => 'type' + }, + { + 'type' => 'const apr_crypto_block_key_mode_e', + 'name' => 'mode' + }, + { + 'type' => 'const int', + 'name' => 'doPad' + }, + { + 'type' => 'const int', + 'name' => 'iterations' + }, + { + 'type' => 'const apr_crypto_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_crypto_hash_t *', + 'name' => 'apr_crypto_sha256_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_crypto_shutdown', + 'args' => [ + { + 'type' => 'const apr_crypto_driver_t *', + 'name' => 'driver' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_ctime', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_date_checkmask', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'mask' + } + ] + }, + { + 'return_type' => 'apr_time_t', + 'name' => 'apr_date_parse_http', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'date' + } + ] + }, + { + 'return_type' => 'apr_time_t', + 'name' => 'apr_date_parse_rfc', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'date' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_check_conn', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbd_close', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbd_datum_get', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_row_t *', + 'name' => 'row' + }, + { + 'type' => 'int', + 'name' => 'col' + }, + { + 'type' => 'apr_dbd_type_e', + 'name' => 'type' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_dbd_error', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'int', + 'name' => 'errnum' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_dbd_escape', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'string' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbd_get_driver', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'const apr_dbd_driver_t **', + 'name' => 'driver' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_dbd_get_entry', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_row_t *', + 'name' => 'row' + }, + { + 'type' => 'int', + 'name' => 'col' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_dbd_get_name', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_results_t *', + 'name' => 'res' + }, + { + 'type' => 'int', + 'name' => 'col' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_get_row', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_results_t *', + 'name' => 'res' + }, + { + 'type' => 'apr_dbd_row_t **', + 'name' => 'row' + }, + { + 'type' => 'int', + 'name' => 'rownum' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbd_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_dbd_name', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + } + ] + }, + { + 'return_type' => 'void*', + 'name' => 'apr_dbd_native_handle', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_num_cols', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_results_t *', + 'name' => 'res' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_num_tuples', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_results_t *', + 'name' => 'res' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbd_open', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'params' + }, + { + 'type' => 'apr_dbd_t **', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbd_open_ex', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'params' + }, + { + 'type' => 'apr_dbd_t **', + 'name' => 'handle' + }, + { + 'type' => 'const char **', + 'name' => 'error' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_pbquery', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'int *', + 'name' => 'nrows' + }, + { + 'type' => 'apr_dbd_prepared_t *', + 'name' => 'statement' + }, + { + 'type' => 'const void **', + 'name' => 'args' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_pbselect', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'apr_dbd_results_t **', + 'name' => 'res' + }, + { + 'type' => 'apr_dbd_prepared_t *', + 'name' => 'statement' + }, + { + 'type' => 'int', + 'name' => 'random' + }, + { + 'type' => 'const void **', + 'name' => 'args' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_pquery', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'int *', + 'name' => 'nrows' + }, + { + 'type' => 'apr_dbd_prepared_t *', + 'name' => 'statement' + }, + { + 'type' => 'int', + 'name' => 'nargs' + }, + { + 'type' => 'const char **', + 'name' => 'args' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_prepare', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'const char *', + 'name' => 'query' + }, + { + 'type' => 'const char *', + 'name' => 'label' + }, + { + 'type' => 'apr_dbd_prepared_t **', + 'name' => 'statement' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_pselect', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'apr_dbd_results_t **', + 'name' => 'res' + }, + { + 'type' => 'apr_dbd_prepared_t *', + 'name' => 'statement' + }, + { + 'type' => 'int', + 'name' => 'random' + }, + { + 'type' => 'int', + 'name' => 'nargs' + }, + { + 'type' => 'const char **', + 'name' => 'args' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_pvbquery', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'int *', + 'name' => 'nrows' + }, + { + 'type' => 'apr_dbd_prepared_t *', + 'name' => 'statement' + }, + { + 'type' => '...', + 'name' => 'arg5' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_pvbselect', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'apr_dbd_results_t **', + 'name' => 'res' + }, + { + 'type' => 'apr_dbd_prepared_t *', + 'name' => 'statement' + }, + { + 'type' => 'int', + 'name' => 'random' + }, + { + 'type' => '...', + 'name' => 'arg6' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_pvquery', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'int *', + 'name' => 'nrows' + }, + { + 'type' => 'apr_dbd_prepared_t *', + 'name' => 'statement' + }, + { + 'type' => '...', + 'name' => 'arg5' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_pvselect', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'apr_dbd_results_t **', + 'name' => 'res' + }, + { + 'type' => 'apr_dbd_prepared_t *', + 'name' => 'statement' + }, + { + 'type' => 'int', + 'name' => 'random' + }, + { + 'type' => '...', + 'name' => 'arg6' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_query', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'int *', + 'name' => 'nrows' + }, + { + 'type' => 'const char *', + 'name' => 'statement' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_select', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'apr_dbd_results_t **', + 'name' => 'res' + }, + { + 'type' => 'const char *', + 'name' => 'statement' + }, + { + 'type' => 'int', + 'name' => 'random' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_set_dbname', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_transaction_end', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_transaction_t *', + 'name' => 'trans' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_transaction_mode_get', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_transaction_t *', + 'name' => 'trans' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_transaction_mode_set', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_dbd_transaction_t *', + 'name' => 'trans' + }, + { + 'type' => 'int', + 'name' => 'mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbd_transaction_start', + 'args' => [ + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'apr_dbd_transaction_t **', + 'name' => 'trans' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_dbm_close', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_delete', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_dbm_exists', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_fetch', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'key' + }, + { + 'type' => 'apr_datum_t *', + 'name' => 'pvalue' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_firstkey', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t *', + 'name' => 'pkey' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_dbm_freedatum', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_dbm_get_usednames', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'pathname' + }, + { + 'type' => 'const char **', + 'name' => 'used1' + }, + { + 'type' => 'const char **', + 'name' => 'used2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_get_usednames_ex', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'pathname' + }, + { + 'type' => 'const char **', + 'name' => 'used1' + }, + { + 'type' => 'const char **', + 'name' => 'used2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_dbm_geterror', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'int *', + 'name' => 'errcode' + }, + { + 'type' => 'char *', + 'name' => 'errbuf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'errbufsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_nextkey', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t *', + 'name' => 'pkey' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_open', + 'args' => [ + { + 'type' => 'apr_dbm_t **', + 'name' => 'dbm' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cntxt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_open_ex', + 'args' => [ + { + 'type' => 'apr_dbm_t **', + 'name' => 'dbm' + }, + { + 'type' => 'const char*', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cntxt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dbm_store', + 'args' => [ + { + 'type' => 'apr_dbm_t *', + 'name' => 'dbm' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'key' + }, + { + 'type' => 'apr_datum_t', + 'name' => 'value' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_close', + 'args' => [ + { + 'type' => 'apr_dir_t *', + 'name' => 'thedir' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_make', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_make_recursive', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_open', + 'args' => [ + { + 'type' => 'apr_dir_t **', + 'name' => 'new_dir' + }, + { + 'type' => 'const char *', + 'name' => 'dirname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_read', + 'args' => [ + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'apr_dir_t *', + 'name' => 'thedir' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_remove', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dir_rewind', + 'args' => [ + { + 'type' => 'apr_dir_t *', + 'name' => 'thedir' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_dso_error', + 'args' => [ + { + 'type' => 'apr_dso_handle_t *', + 'name' => 'dso' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bufsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dso_load', + 'args' => [ + { + 'type' => 'apr_dso_handle_t **', + 'name' => 'res_handle' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ctx' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dso_sym', + 'args' => [ + { + 'type' => 'apr_dso_handle_sym_t *', + 'name' => 'ressym' + }, + { + 'type' => 'apr_dso_handle_t *', + 'name' => 'handle' + }, + { + 'type' => 'const char *', + 'name' => 'symname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_dso_unload', + 'args' => [ + { + 'type' => 'apr_dso_handle_t *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_dynamic_fn_register', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'apr_opt_fn_t *', + 'name' => 'pfn' + } + ] + }, + { + 'return_type' => 'apr_opt_fn_t *', + 'name' => 'apr_dynamic_fn_retrieve', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_env_delete', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'envvar' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_env_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'value' + }, + { + 'type' => 'const char *', + 'name' => 'envvar' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_env_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'envvar' + }, + { + 'type' => 'const char *', + 'name' => 'value' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_append', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'from_path' + }, + { + 'type' => 'const char *', + 'name' => 'to_path' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_attrs_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_fileattrs_t', + 'name' => 'attributes' + }, + { + 'type' => 'apr_fileattrs_t', + 'name' => 'attr_mask' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_buffer_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bufsize' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_file_buffer_size_get', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_close', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_copy', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'from_path' + }, + { + 'type' => 'const char *', + 'name' => 'to_path' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_data_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_data_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'file' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_datasync', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_dup', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'new_file' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'old_file' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_dup2', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'new_file' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'old_file' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_eof', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fptr' + } + ] + }, + { + 'return_type' => 'apr_int32_t', + 'name' => 'apr_file_flags_get', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'f' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_flush', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_getc', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'ch' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_gets', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'str' + }, + { + 'type' => 'int', + 'name' => 'len' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_info_get', + 'args' => [ + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_inherit_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_inherit_unset', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_link', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'from_path' + }, + { + 'type' => 'const char *', + 'name' => 'to_path' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_lock', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_mktemp', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'fp' + }, + { + 'type' => 'char *', + 'name' => 'templ' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_mtime_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_name_get', + 'args' => [ + { + 'type' => 'const char **', + 'name' => 'new_path' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_namedpipe_create', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'newf' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flag' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_flags_stderr', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_flags_stdin', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_flags_stdout', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_stderr', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_stdin', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_open_stdout', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'thefile' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_perms_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perms' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_pipe_create', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'in' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'out' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_pipe_create_ex', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'in' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'out' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'blocking' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_pipe_timeout_get', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thepipe' + }, + { + 'type' => 'apr_interval_time_t *', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_pipe_timeout_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thepipe' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_file_pool_get', + 'args' => [ + { + 'type' => 'const apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_file_printf', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fptr' + }, + { + 'type' => 'const char *', + 'name' => 'format' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_putc', + 'args' => [ + { + 'type' => 'char', + 'name' => 'ch' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_puts', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_read', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_read_full', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbytes' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'bytes_read' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_remove', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_rename', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'from_path' + }, + { + 'type' => 'const char *', + 'name' => 'to_path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_seek', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'apr_seek_where_t', + 'name' => 'where' + }, + { + 'type' => 'apr_off_t *', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_setaside', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'new_file' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'old_file' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_sync', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_trunc', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'fp' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_ungetc', + 'args' => [ + { + 'type' => 'char', + 'name' => 'ch' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_unlock', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_write', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'const void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_write_full', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'const void *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbytes' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'bytes_written' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_writev', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nvec' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_file_writev_full', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nvec' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_encoding', + 'args' => [ + { + 'type' => 'int *', + 'name' => 'style' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'path' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_list_merge', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'liststr' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'pathelts' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_list_split', + 'args' => [ + { + 'type' => 'apr_array_header_t **', + 'name' => 'pathelts' + }, + { + 'type' => 'const char *', + 'name' => 'liststr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_merge', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'newpath' + }, + { + 'type' => 'const char *', + 'name' => 'rootpath' + }, + { + 'type' => 'const char *', + 'name' => 'addpath' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_filepath_name_get', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pathname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_root', + 'args' => [ + { + 'type' => 'const char **', + 'name' => 'rootpath' + }, + { + 'type' => 'const char **', + 'name' => 'filepath' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_filepath_set', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_fnmatch', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pattern' + }, + { + 'type' => 'const char *', + 'name' => 'strings' + }, + { + 'type' => 'int', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_fnmatch_test', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pattern' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_generate_random_bytes', + 'args' => [ + { + 'type' => 'unsigned char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_gethostname', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'int', + 'name' => 'len' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getnameinfo', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'hostname' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getopt', + 'args' => [ + { + 'type' => 'apr_getopt_t *', + 'name' => 'os' + }, + { + 'type' => 'const char *', + 'name' => 'opts' + }, + { + 'type' => 'char *', + 'name' => 'option_ch' + }, + { + 'type' => 'const char **', + 'name' => 'option_arg' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getopt_init', + 'args' => [ + { + 'type' => 'apr_getopt_t **', + 'name' => 'os' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + }, + { + 'type' => 'int', + 'name' => 'argc' + }, + { + 'type' => 'const char * const *', + 'name' => 'argv' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getopt_long', + 'args' => [ + { + 'type' => 'apr_getopt_t *', + 'name' => 'os' + }, + { + 'type' => 'const apr_getopt_option_t *', + 'name' => 'opts' + }, + { + 'type' => 'int *', + 'name' => 'option_ch' + }, + { + 'type' => 'const char **', + 'name' => 'option_arg' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_getservbyname', + 'args' => [ + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + }, + { + 'type' => 'const char *', + 'name' => 'servname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_gid_get', + 'args' => [ + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'const char *', + 'name' => 'groupname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_gid_name_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'groupname' + }, + { + 'type' => 'apr_gid_t', + 'name' => 'groupid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_child_init', + 'args' => [ + { + 'type' => 'apr_global_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_create', + 'args' => [ + { + 'type' => 'apr_global_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_lockmech_e', + 'name' => 'mech' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_destroy', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_lock', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_global_mutex_lockfile', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_global_mutex_name', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_global_mutex_pool_get', + 'args' => [ + { + 'type' => 'const apr_global_mutex_t *', + 'name' => 'theglobal_mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_trylock', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_global_mutex_unlock', + 'args' => [ + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hash_clear', + 'args' => [ + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_copy', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'h' + } + ] + }, + { + 'return_type' => 'unsigned int', + 'name' => 'apr_hash_count', + 'args' => [ + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_hash_do', + 'args' => [ + { + 'type' => 'apr_hash_do_callback_fn_t *comp', + 'name' => 'arg0' + }, + { + 'type' => 'void *', + 'name' => 'rec' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'ht' + } + ] + }, + { + 'return_type' => 'apr_hash_index_t *', + 'name' => 'apr_hash_first', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_hash_get', + 'args' => [ + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + }, + { + 'type' => 'const void *', + 'name' => 'key' + }, + { + 'type' => 'apr_ssize_t', + 'name' => 'klen' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_make', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_make_custom', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_hashfunc_t', + 'name' => 'hash_func' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'h1' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'h2' + }, + { + 'type' => 'void * (*merger)(apr_pool_t *p, const void *key, apr_ssize_t klen, const void *h1_val, const void *h2_val, const void *data)', + 'name' => 'arg3' + }, + { + 'type' => 'const void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_hash_index_t *', + 'name' => 'apr_hash_next', + 'args' => [ + { + 'type' => 'apr_hash_index_t *', + 'name' => 'hi' + } + ] + }, + { + 'return_type' => 'apr_hash_t *', + 'name' => 'apr_hash_overlay', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'overlay' + }, + { + 'type' => 'const apr_hash_t *', + 'name' => 'base' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_hash_pool_get', + 'args' => [ + { + 'type' => 'const apr_hash_t *', + 'name' => 'thehash' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hash_set', + 'args' => [ + { + 'type' => 'apr_hash_t *', + 'name' => 'ht' + }, + { + 'type' => 'const void *', + 'name' => 'key' + }, + { + 'type' => 'apr_ssize_t', + 'name' => 'klen' + }, + { + 'type' => 'const void *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hash_this', + 'args' => [ + { + 'type' => 'apr_hash_index_t *', + 'name' => 'hi' + }, + { + 'type' => 'const void **', + 'name' => 'key' + }, + { + 'type' => 'apr_ssize_t *', + 'name' => 'klen' + }, + { + 'type' => 'void **', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'unsigned int', + 'name' => 'apr_hashfunc_default', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_ssize_t *', + 'name' => 'klen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hook_debug_show', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hook_deregister_all', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hook_sort_all', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_hook_sort_register', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szHookName' + }, + { + 'type' => 'apr_array_header_t **', + 'name' => 'aHooks' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_initialize', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_ipsubnet_create', + 'args' => [ + { + 'type' => 'apr_ipsubnet_t **', + 'name' => 'ipsub' + }, + { + 'type' => 'const char *', + 'name' => 'ipstr' + }, + { + 'type' => 'const char *', + 'name' => 'mask_or_numbits' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ipsubnet_test', + 'args' => [ + { + 'type' => 'apr_ipsubnet_t *', + 'name' => 'ipsub' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_is_empty_array', + 'args' => [ + { + 'type' => 'const apr_array_header_t *', + 'name' => 'a' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_is_empty_table', + 'args' => [ + { + 'type' => 'const apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_itoa', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_get_option', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'LDAP *', + 'name' => 'ldap' + }, + { + 'type' => 'int', + 'name' => 'option' + }, + { + 'type' => 'void *', + 'name' => 'outvalue' + }, + { + 'type' => 'apr_ldap_err_t **', + 'name' => 'result_err' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_info', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_ldap_err_t **', + 'name' => 'result_err' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'LDAP **', + 'name' => 'ldap' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'int', + 'name' => 'portno' + }, + { + 'type' => 'int', + 'name' => 'secure' + }, + { + 'type' => 'apr_ldap_err_t **', + 'name' => 'result_err' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_is_ldap_url', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_is_ldapi_url', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_is_ldaps_url', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_ldap_rebind_add', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'LDAP *', + 'name' => 'ld' + }, + { + 'type' => 'const char *', + 'name' => 'bindDN' + }, + { + 'type' => 'const char *', + 'name' => 'bindPW' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_ldap_rebind_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_ldap_rebind_remove', + 'args' => [ + { + 'type' => 'LDAP *', + 'name' => 'ld' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_set_option', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'LDAP *', + 'name' => 'ldap' + }, + { + 'type' => 'int', + 'name' => 'option' + }, + { + 'type' => 'const void *', + 'name' => 'invalue' + }, + { + 'type' => 'apr_ldap_err_t **', + 'name' => 'result_err' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_ssl_deinit', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_ssl_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'cert_auth_file' + }, + { + 'type' => 'int', + 'name' => 'cert_file_type' + }, + { + 'type' => 'apr_ldap_err_t **', + 'name' => 'result_err' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_url_parse', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'url_in' + }, + { + 'type' => 'apr_ldap_url_desc_t **', + 'name' => 'ludpp' + }, + { + 'type' => 'apr_ldap_err_t **', + 'name' => 'result_err' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_ldap_url_parse_ext', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'url_in' + }, + { + 'type' => 'apr_ldap_url_desc_t **', + 'name' => 'ludpp' + }, + { + 'type' => 'apr_ldap_err_t **', + 'name' => 'result_err' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_ltoa', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'long', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_match_glob', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'pattern' + }, + { + 'type' => 'apr_array_header_t **', + 'name' => 'result' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mcast_hops', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_byte_t', + 'name' => 'ttl' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mcast_interface', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'iface' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mcast_join', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'join' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'iface' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'source' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mcast_leave', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'addr' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'iface' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'source' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mcast_loopback', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_byte_t', + 'name' => 'opt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'input' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4_final', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'apr_md4_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4_init', + 'args' => [ + { + 'type' => 'apr_md4_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4_set_xlate', + 'args' => [ + { + 'type' => 'apr_md4_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'apr_xlate_t *', + 'name' => 'xlate' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md4_update', + 'args' => [ + { + 'type' => 'apr_md4_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'input' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'const void *', + 'name' => 'input' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_encode', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'password' + }, + { + 'type' => 'const char *', + 'name' => 'salt' + }, + { + 'type' => 'char *', + 'name' => 'result' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_final', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_init', + 'args' => [ + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_set_xlate', + 'args' => [ + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'apr_xlate_t *', + 'name' => 'xlate' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_md5_update', + 'args' => [ + { + 'type' => 'apr_md5_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'const void *', + 'name' => 'input' + }, + { + 'type' => 'apr_size_t', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_add', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'char *', + 'name' => 'baton' + }, + { + 'type' => 'const apr_size_t', + 'name' => 'data_size' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_uint16_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_memcache_add_multget_key', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'data_pool' + }, + { + 'type' => 'const char*', + 'name' => 'key' + }, + { + 'type' => 'apr_hash_t **', + 'name' => 'values' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_add_server', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'apr_memcache_server_t *', + 'name' => 'server' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_uint16_t', + 'name' => 'max_servers' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_memcache_t **', + 'name' => 'mc' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_decr', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'n' + }, + { + 'type' => 'apr_uint32_t *', + 'name' => 'new_value' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_delete', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_disable_server', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'apr_memcache_server_t *', + 'name' => 'ms' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_enable_server', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'apr_memcache_server_t *', + 'name' => 'ms' + } + ] + }, + { + 'return_type' => 'apr_memcache_server_t *', + 'name' => 'apr_memcache_find_server', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const char *', + 'name' => 'host' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + } + ] + }, + { + 'return_type' => 'apr_memcache_server_t *', + 'name' => 'apr_memcache_find_server_hash', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const apr_uint32_t', + 'name' => 'hash' + } + ] + }, + { + 'return_type' => 'apr_memcache_server_t *', + 'name' => 'apr_memcache_find_server_hash_default', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'baton' + }, + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const apr_uint32_t', + 'name' => 'hash' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_getp', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char*', + 'name' => 'key' + }, + { + 'type' => 'char **', + 'name' => 'baton' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + }, + { + 'type' => 'apr_uint16_t *', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_memcache_hash', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const char *', + 'name' => 'data' + }, + { + 'type' => 'const apr_size_t', + 'name' => 'data_len' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_memcache_hash_crc32', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'baton' + }, + { + 'type' => 'const char *', + 'name' => 'data' + }, + { + 'type' => 'const apr_size_t', + 'name' => 'data_len' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_memcache_hash_default', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'baton' + }, + { + 'type' => 'const char *', + 'name' => 'data' + }, + { + 'type' => 'const apr_size_t', + 'name' => 'data_len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_incr', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'n' + }, + { + 'type' => 'apr_uint32_t *', + 'name' => 'nv' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_multgetp', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'data_pool' + }, + { + 'type' => 'apr_hash_t *', + 'name' => 'values' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_replace', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'char *', + 'name' => 'baton' + }, + { + 'type' => 'const apr_size_t', + 'name' => 'data_size' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_uint16_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_server_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'host' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'min' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'smax' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'max' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'ttl' + }, + { + 'type' => 'apr_memcache_server_t **', + 'name' => 'ns' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_set', + 'args' => [ + { + 'type' => 'apr_memcache_t *', + 'name' => 'mc' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'char *', + 'name' => 'baton' + }, + { + 'type' => 'const apr_size_t', + 'name' => 'data_size' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_uint16_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_stats', + 'args' => [ + { + 'type' => 'apr_memcache_server_t *', + 'name' => 'ms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_memcache_stats_t **', + 'name' => 'stats' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_memcache_version', + 'args' => [ + { + 'type' => 'apr_memcache_server_t *', + 'name' => 'ms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char **', + 'name' => 'baton' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mmap_create', + 'args' => [ + { + 'type' => 'apr_mmap_t **', + 'name' => 'newmmap' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flag' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cntxt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mmap_delete', + 'args' => [ + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mmap_dup', + 'args' => [ + { + 'type' => 'apr_mmap_t **', + 'name' => 'new_mmap' + }, + { + 'type' => 'apr_mmap_t *', + 'name' => 'old_mmap' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_mmap_offset', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'addr' + }, + { + 'type' => 'apr_mmap_t *', + 'name' => 'mm' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_off_t_toa', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_off_t', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_optional_hook_add', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'void (*pfn)(void)', + 'name' => 'arg1' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPre' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSucc' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'apr_optional_hook_get', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'szName' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_os_default_encoding', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_dir_get', + 'args' => [ + { + 'type' => 'apr_os_dir_t **', + 'name' => 'thedir' + }, + { + 'type' => 'apr_dir_t *', + 'name' => 'dir' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_dir_put', + 'args' => [ + { + 'type' => 'apr_dir_t **', + 'name' => 'dir' + }, + { + 'type' => 'apr_os_dir_t *', + 'name' => 'thedir' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_dso_handle_get', + 'args' => [ + { + 'type' => 'apr_os_dso_handle_t *', + 'name' => 'dso' + }, + { + 'type' => 'apr_dso_handle_t *', + 'name' => 'aprdso' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_dso_handle_put', + 'args' => [ + { + 'type' => 'apr_dso_handle_t **', + 'name' => 'dso' + }, + { + 'type' => 'apr_os_dso_handle_t', + 'name' => 'thedso' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_exp_time_get', + 'args' => [ + { + 'type' => 'apr_os_exp_time_t **', + 'name' => 'ostime' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'aprtime' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_exp_time_put', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'aprtime' + }, + { + 'type' => 'apr_os_exp_time_t **', + 'name' => 'ostime' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_file_get', + 'args' => [ + { + 'type' => 'apr_os_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_file_put', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'file' + }, + { + 'type' => 'apr_os_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_global_mutex_get', + 'args' => [ + { + 'type' => 'apr_os_global_mutex_t *', + 'name' => 'ospmutex' + }, + { + 'type' => 'apr_global_mutex_t *', + 'name' => 'pmutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_imp_time_get', + 'args' => [ + { + 'type' => 'apr_os_imp_time_t **', + 'name' => 'ostime' + }, + { + 'type' => 'apr_time_t *', + 'name' => 'aprtime' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_imp_time_put', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'aprtime' + }, + { + 'type' => 'apr_os_imp_time_t **', + 'name' => 'ostime' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'const char*', + 'name' => 'apr_os_locale_encoding', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_pipe_put', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'file' + }, + { + 'type' => 'apr_os_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_pipe_put_ex', + 'args' => [ + { + 'type' => 'apr_file_t **', + 'name' => 'file' + }, + { + 'type' => 'apr_os_file_t *', + 'name' => 'thefile' + }, + { + 'type' => 'int', + 'name' => 'register_cleanup' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_proc_mutex_get', + 'args' => [ + { + 'type' => 'apr_os_proc_mutex_t *', + 'name' => 'ospmutex' + }, + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'pmutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_proc_mutex_put', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t **', + 'name' => 'pmutex' + }, + { + 'type' => 'apr_os_proc_mutex_t *', + 'name' => 'ospmutex' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_shm_get', + 'args' => [ + { + 'type' => 'apr_os_shm_t *', + 'name' => 'osshm' + }, + { + 'type' => 'apr_shm_t *', + 'name' => 'shm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_shm_put', + 'args' => [ + { + 'type' => 'apr_shm_t **', + 'name' => 'shm' + }, + { + 'type' => 'apr_os_shm_t *', + 'name' => 'osshm' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_sock_get', + 'args' => [ + { + 'type' => 'apr_os_sock_t *', + 'name' => 'thesock' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_sock_make', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'apr_sock' + }, + { + 'type' => 'apr_os_sock_info_t *', + 'name' => 'os_sock_info' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_sock_put', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'sock' + }, + { + 'type' => 'apr_os_sock_t *', + 'name' => 'thesock' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_os_thread_t', + 'name' => 'apr_os_thread_current', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'apr_os_thread_equal', + 'args' => [ + { + 'type' => 'apr_os_thread_t', + 'name' => 'tid1' + }, + { + 'type' => 'apr_os_thread_t', + 'name' => 'tid2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_thread_get', + 'args' => [ + { + 'type' => 'apr_os_thread_t **', + 'name' => 'thethd' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_thread_put', + 'args' => [ + { + 'type' => 'apr_thread_t **', + 'name' => 'thd' + }, + { + 'type' => 'apr_os_thread_t *', + 'name' => 'thethd' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_threadkey_get', + 'args' => [ + { + 'type' => 'apr_os_threadkey_t *', + 'name' => 'thekey' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_threadkey_put', + 'args' => [ + { + 'type' => 'apr_threadkey_t **', + 'name' => 'key' + }, + { + 'type' => 'apr_os_threadkey_t *', + 'name' => 'thekey' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_os_uuid_get', + 'args' => [ + { + 'type' => 'unsigned char *', + 'name' => 'uuid_data' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_palloc', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_palloc_debug', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_parse_addr_port', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'addr' + }, + { + 'type' => 'char **', + 'name' => 'scope_id' + }, + { + 'type' => 'apr_port_t *', + 'name' => 'port' + }, + { + 'type' => 'const char *', + 'name' => 'str' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_password_get', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'prompt' + }, + { + 'type' => 'char *', + 'name' => 'pwbuf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'bufsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_password_validate', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'passwd' + }, + { + 'type' => 'const char *', + 'name' => 'hash' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_pcalloc_debug', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_pmemdup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'm' + }, + { + 'type' => 'apr_size_t', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_poll', + 'args' => [ + { + 'type' => 'apr_pollfd_t *', + 'name' => 'aprset' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'numsock' + }, + { + 'type' => 'apr_int32_t *', + 'name' => 'nsds' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_poll_method_defname', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollcb_add', + 'args' => [ + { + 'type' => 'apr_pollcb_t *', + 'name' => 'pollcb' + }, + { + 'type' => 'apr_pollfd_t *', + 'name' => 'descriptor' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollcb_create', + 'args' => [ + { + 'type' => 'apr_pollcb_t **', + 'name' => 'pollcb' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'size' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollcb_create_ex', + 'args' => [ + { + 'type' => 'apr_pollcb_t **', + 'name' => 'pollcb' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'size' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pollset_method_e', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollcb_poll', + 'args' => [ + { + 'type' => 'apr_pollcb_t *', + 'name' => 'pollcb' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_pollcb_cb_t', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'baton' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollcb_remove', + 'args' => [ + { + 'type' => 'apr_pollcb_t *', + 'name' => 'pollcb' + }, + { + 'type' => 'apr_pollfd_t *', + 'name' => 'descriptor' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_add', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + }, + { + 'type' => 'const apr_pollfd_t *', + 'name' => 'descriptor' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_create', + 'args' => [ + { + 'type' => 'apr_pollset_t **', + 'name' => 'pollset' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'size' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_create_ex', + 'args' => [ + { + 'type' => 'apr_pollset_t **', + 'name' => 'pollset' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'size' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pollset_method_e', + 'name' => 'method' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_destroy', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_pollset_method_name', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_poll', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_int32_t *', + 'name' => 'num' + }, + { + 'type' => 'const apr_pollfd_t **', + 'name' => 'descriptors' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_remove', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + }, + { + 'type' => 'const apr_pollfd_t *', + 'name' => 'descriptor' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pollset_wakeup', + 'args' => [ + { + 'type' => 'apr_pollset_t *', + 'name' => 'pollset' + } + ] + }, + { + 'return_type' => 'apr_abortfunc_t', + 'name' => 'apr_pool_abort_get', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_abort_set', + 'args' => [ + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abortfunc' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_allocator_t *', + 'name' => 'apr_pool_allocator_get', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_child_cleanup_set', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*plain_cleanup)(void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_status_t (*child_cleanup)(void *)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_cleanup_for_exec', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_cleanup_kill', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_cleanup_null', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_cleanup_register', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*plain_cleanup)(void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_status_t (*child_cleanup)(void *)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_cleanup_run', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_clear', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_clear_debug', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_create_core_ex', + 'args' => [ + { + 'type' => 'apr_pool_t **', + 'name' => 'newpool' + }, + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abort_fn' + }, + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_create_core_ex_debug', + 'args' => [ + { + 'type' => 'apr_pool_t **', + 'name' => 'newpool' + }, + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abort_fn' + }, + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_create_ex', + 'args' => [ + { + 'type' => 'apr_pool_t **', + 'name' => 'newpool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'parent' + }, + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abort_fn' + }, + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_create_ex_debug', + 'args' => [ + { + 'type' => 'apr_pool_t **', + 'name' => 'newpool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'parent' + }, + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abort_fn' + }, + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_create_unmanaged_ex', + 'args' => [ + { + 'type' => 'apr_pool_t **', + 'name' => 'newpool' + }, + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abort_fn' + }, + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_create_unmanaged_ex_debug', + 'args' => [ + { + 'type' => 'apr_pool_t **', + 'name' => 'newpool' + }, + { + 'type' => 'apr_abortfunc_t', + 'name' => 'abort_fn' + }, + { + 'type' => 'apr_allocator_t *', + 'name' => 'allocator' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_destroy', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_destroy_debug', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'file_line' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_initialize', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'apr_pool_is_ancestor', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_note_subprocess', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + }, + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'apr_kill_conditions_e', + 'name' => 'how' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_pool_parent_get', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_pre_cleanup_register', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'apr_status_t (*plain_cleanup)(void *)', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_tag', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'tag' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_pool_terminate', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_userdata_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_userdata_set', + 'args' => [ + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_pool_userdata_setn', + 'args' => [ + { + 'type' => 'const void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup)(void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_create', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'new_proc' + }, + { + 'type' => 'const char *', + 'name' => 'progname' + }, + { + 'type' => 'const char * const *', + 'name' => 'args' + }, + { + 'type' => 'const char * const *', + 'name' => 'env' + }, + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_detach', + 'args' => [ + { + 'type' => 'int', + 'name' => 'daemonize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_fork', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_kill', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int', + 'name' => 'sig' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_child_init', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_create', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_lockmech_e', + 'name' => 'mech' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_proc_mutex_defname', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_destroy', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_lock', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_proc_mutex_lockfile', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_proc_mutex_name', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_proc_mutex_pool_get', + 'args' => [ + { + 'type' => 'const apr_proc_mutex_t *', + 'name' => 'theproc_mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_trylock', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_mutex_unlock', + 'args' => [ + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_other_child_alert', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int', + 'name' => 'reason' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_refresh', + 'args' => [ + { + 'type' => 'apr_other_child_rec_t *', + 'name' => 'ocr' + }, + { + 'type' => 'int', + 'name' => 'reason' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_refresh_all', + 'args' => [ + { + 'type' => 'int', + 'name' => 'reason' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_register', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'void (*maintenance) (int reason, void *, int status)', + 'name' => 'arg1' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'write_fd' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_proc_other_child_unregister', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_wait', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int *', + 'name' => 'exitcode' + }, + { + 'type' => 'apr_exit_why_e *', + 'name' => 'exitwhy' + }, + { + 'type' => 'apr_wait_how_e', + 'name' => 'waithow' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_proc_wait_all_procs', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + }, + { + 'type' => 'int *', + 'name' => 'exitcode' + }, + { + 'type' => 'apr_exit_why_e *', + 'name' => 'exitwhy' + }, + { + 'type' => 'apr_wait_how_e', + 'name' => 'waithow' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_addrspace_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'addrspace' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_child_err_set', + 'args' => [ + { + 'type' => 'struct apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'child_err' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'parent_err' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_child_errfn_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_child_errfn_t *', + 'name' => 'errfn' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_child_in_set', + 'args' => [ + { + 'type' => 'struct apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'child_in' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'parent_in' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_child_out_set', + 'args' => [ + { + 'type' => 'struct apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'child_out' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'parent_out' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_cmdtype_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_cmdtype_e', + 'name' => 'cmd' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_create', + 'args' => [ + { + 'type' => 'apr_procattr_t **', + 'name' => 'new_attr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_detach_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'detach' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_dir_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'const char *', + 'name' => 'dir' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_error_check_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'chk' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_group_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'const char *', + 'name' => 'groupname' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_io_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'in' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'out' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'err' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_limit_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'what' + }, + { + 'type' => 'struct rlimit *', + 'name' => 'limit' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_procattr_user_set', + 'args' => [ + { + 'type' => 'apr_procattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'const char *', + 'name' => 'username' + }, + { + 'type' => 'const char *', + 'name' => 'password' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_psprintf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrcat', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => '...', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrcatv', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nvec' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'nbytes' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrdup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrmemdup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'apr_size_t', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pstrndup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'apr_size_t', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_pvsprintf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'va_list', + 'name' => 'ap' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_create', + 'args' => [ + { + 'type' => 'apr_queue_t **', + 'name' => 'queue' + }, + { + 'type' => 'unsigned int', + 'name' => 'queue_capacity' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'a' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_interrupt_all', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_pop', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + }, + { + 'type' => 'void **', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_push', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'unsigned int', + 'name' => 'apr_queue_size', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_term', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_trypop', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + }, + { + 'type' => 'void **', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_queue_trypush', + 'args' => [ + { + 'type' => 'apr_queue_t *', + 'name' => 'queue' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_random_add_entropy', + 'args' => [ + { + 'type' => 'apr_random_t *', + 'name' => 'g' + }, + { + 'type' => 'const void *', + 'name' => 'entropy_' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bytes' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_random_after_fork', + 'args' => [ + { + 'type' => 'apr_proc_t *', + 'name' => 'proc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_random_barrier', + 'args' => [ + { + 'type' => 'apr_random_t *', + 'name' => 'g' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_random_init', + 'args' => [ + { + 'type' => 'apr_random_t *', + 'name' => 'g' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_crypto_hash_t *', + 'name' => 'pool_hash' + }, + { + 'type' => 'apr_crypto_hash_t *', + 'name' => 'key_hash' + }, + { + 'type' => 'apr_crypto_hash_t *', + 'name' => 'prng_hash' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_random_insecure_bytes', + 'args' => [ + { + 'type' => 'apr_random_t *', + 'name' => 'g' + }, + { + 'type' => 'void *', + 'name' => 'random' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_random_insecure_ready', + 'args' => [ + { + 'type' => 'apr_random_t *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_random_secure_bytes', + 'args' => [ + { + 'type' => 'apr_random_t *', + 'name' => 'g' + }, + { + 'type' => 'void *', + 'name' => 'random' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_random_secure_ready', + 'args' => [ + { + 'type' => 'apr_random_t *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_random_t *', + 'name' => 'apr_random_standard_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_acquire', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + }, + { + 'type' => 'void **', + 'name' => 'resource' + } + ] + }, + { + 'return_type' => 'apr_uint32_t', + 'name' => 'apr_reslist_acquired_count', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_reslist_cleanup_order_set', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'mode' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_create', + 'args' => [ + { + 'type' => 'apr_reslist_t **', + 'name' => 'reslist' + }, + { + 'type' => 'int', + 'name' => 'min' + }, + { + 'type' => 'int', + 'name' => 'smax' + }, + { + 'type' => 'int', + 'name' => 'hmax' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'ttl' + }, + { + 'type' => 'apr_reslist_constructor', + 'name' => 'con' + }, + { + 'type' => 'apr_reslist_destructor', + 'name' => 'de' + }, + { + 'type' => 'void *', + 'name' => 'params' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_destroy', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_invalidate', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + }, + { + 'type' => 'void *', + 'name' => 'resource' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_maintain', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_reslist_release', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + }, + { + 'type' => 'void *', + 'name' => 'resource' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_reslist_timeout_set', + 'args' => [ + { + 'type' => 'apr_reslist_t *', + 'name' => 'reslist' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_rfc822_date', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'date_str' + }, + { + 'type' => 'apr_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_rmm_addr_get', + 'args' => [ + { + 'type' => 'apr_rmm_t *', + 'name' => 'rmm' + }, + { + 'type' => 'apr_rmm_off_t', + 'name' => 'entity' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_rmm_attach', + 'args' => [ + { + 'type' => 'apr_rmm_t **', + 'name' => 'rmm' + }, + { + 'type' => 'apr_anylock_t *', + 'name' => 'lock' + }, + { + 'type' => 'void *', + 'name' => 'membuf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_rmm_off_t', + 'name' => 'apr_rmm_calloc', + 'args' => [ + { + 'type' => 'apr_rmm_t *', + 'name' => 'rmm' + }, + { + 'type' => 'apr_size_t', + 'name' => 'reqsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_rmm_destroy', + 'args' => [ + { + 'type' => 'apr_rmm_t *', + 'name' => 'rmm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_rmm_detach', + 'args' => [ + { + 'type' => 'apr_rmm_t *', + 'name' => 'rmm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_rmm_free', + 'args' => [ + { + 'type' => 'apr_rmm_t *', + 'name' => 'rmm' + }, + { + 'type' => 'apr_rmm_off_t', + 'name' => 'entity' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_rmm_init', + 'args' => [ + { + 'type' => 'apr_rmm_t **', + 'name' => 'rmm' + }, + { + 'type' => 'apr_anylock_t *', + 'name' => 'lock' + }, + { + 'type' => 'void *', + 'name' => 'membuf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'memsize' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_rmm_off_t', + 'name' => 'apr_rmm_malloc', + 'args' => [ + { + 'type' => 'apr_rmm_t *', + 'name' => 'rmm' + }, + { + 'type' => 'apr_size_t', + 'name' => 'reqsize' + } + ] + }, + { + 'return_type' => 'apr_rmm_off_t', + 'name' => 'apr_rmm_offset_get', + 'args' => [ + { + 'type' => 'apr_rmm_t *', + 'name' => 'rmm' + }, + { + 'type' => 'void *', + 'name' => 'entity' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_rmm_overhead_get', + 'args' => [ + { + 'type' => 'int', + 'name' => 'n' + } + ] + }, + { + 'return_type' => 'apr_rmm_off_t', + 'name' => 'apr_rmm_realloc', + 'args' => [ + { + 'type' => 'apr_rmm_t *', + 'name' => 'rmm' + }, + { + 'type' => 'void *', + 'name' => 'entity' + }, + { + 'type' => 'apr_size_t', + 'name' => 'reqsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_close', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_delete', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'const apr_sdbm_datum_t', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_fetch', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'apr_sdbm_datum_t *', + 'name' => 'value' + }, + { + 'type' => 'apr_sdbm_datum_t', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_firstkey', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'apr_sdbm_datum_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_lock', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_nextkey', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'apr_sdbm_datum_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_open', + 'args' => [ + { + 'type' => 'apr_sdbm_t **', + 'name' => 'db' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'perms' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_sdbm_rdonly', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_store', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + }, + { + 'type' => 'apr_sdbm_datum_t', + 'name' => 'key' + }, + { + 'type' => 'apr_sdbm_datum_t', + 'name' => 'value' + }, + { + 'type' => 'int', + 'name' => 'opt' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sdbm_unlock', + 'args' => [ + { + 'type' => 'apr_sdbm_t *', + 'name' => 'db' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_setup_signal_thread', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_base64', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'clear' + }, + { + 'type' => 'int', + 'name' => 'len' + }, + { + 'type' => 'char *', + 'name' => 'out' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_final', + 'args' => [ + { + 'type' => 'unsigned char', + 'name' => 'digest' + }, + { + 'type' => 'apr_sha1_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_init', + 'args' => [ + { + 'type' => 'apr_sha1_ctx_t *', + 'name' => 'context' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_update', + 'args' => [ + { + 'type' => 'apr_sha1_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'const char *', + 'name' => 'input' + }, + { + 'type' => 'unsigned int', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sha1_update_binary', + 'args' => [ + { + 'type' => 'apr_sha1_ctx_t *', + 'name' => 'context' + }, + { + 'type' => 'const unsigned char *', + 'name' => 'input' + }, + { + 'type' => 'unsigned int', + 'name' => 'inputLen' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_attach', + 'args' => [ + { + 'type' => 'apr_shm_t **', + 'name' => 'm' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'apr_shm_baseaddr_get', + 'args' => [ + { + 'type' => 'const apr_shm_t *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_create', + 'args' => [ + { + 'type' => 'apr_shm_t **', + 'name' => 'm' + }, + { + 'type' => 'apr_size_t', + 'name' => 'reqsize' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_destroy', + 'args' => [ + { + 'type' => 'apr_shm_t *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_detach', + 'args' => [ + { + 'type' => 'apr_shm_t *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_shm_pool_get', + 'args' => [ + { + 'type' => 'const apr_shm_t *', + 'name' => 'theshm' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_shm_remove', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_shm_size_get', + 'args' => [ + { + 'type' => 'const apr_shm_t *', + 'name' => 'm' + } + ] + }, + { + 'return_type' => 'apr_sigfunc_t *', + 'name' => 'apr_signal', + 'args' => [ + { + 'type' => 'int', + 'name' => 'signo' + }, + { + 'type' => 'apr_sigfunc_t *', + 'name' => 'func' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_signal_block', + 'args' => [ + { + 'type' => 'int', + 'name' => 'signum' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_signal_description_get', + 'args' => [ + { + 'type' => 'int', + 'name' => 'signum' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_signal_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pglobal' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_signal_thread', + 'args' => [ + { + 'type' => 'int(*signal_handler)(int signum)', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_signal_unblock', + 'args' => [ + { + 'type' => 'int', + 'name' => 'signum' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_sleep', + 'args' => [ + { + 'type' => 'apr_interval_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_snprintf', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'const char *', + 'name' => 'format' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_sockaddr_equal', + 'args' => [ + { + 'type' => 'const apr_sockaddr_t *', + 'name' => 'addr1' + }, + { + 'type' => 'const apr_sockaddr_t *', + 'name' => 'addr2' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sockaddr_info_get', + 'args' => [ + { + 'type' => 'apr_sockaddr_t **', + 'name' => 'sa' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'family' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sockaddr_ip_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'addr' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_sockaddr_ip_getbuf', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'buflen' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_accept', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'new_sock' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'connection_pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_addr_get', + 'args' => [ + { + 'type' => 'apr_sockaddr_t **', + 'name' => 'sa' + }, + { + 'type' => 'apr_interface_e', + 'name' => 'which' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_atmark', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'int *', + 'name' => 'atmark' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_atreadeof', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'int *', + 'name' => 'atreadeof' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_bind', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_close', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_connect', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sa' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_create', + 'args' => [ + { + 'type' => 'apr_socket_t **', + 'name' => 'new_sock' + }, + { + 'type' => 'int', + 'name' => 'family' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'int', + 'name' => 'protocol' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_data_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_data_set', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup)(void*)', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_inherit_set', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_inherit_unset', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_listen', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'backlog' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_opt_get', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + }, + { + 'type' => 'apr_int32_t *', + 'name' => 'on' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_opt_set', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'on' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_socket_pool_get', + 'args' => [ + { + 'type' => 'const apr_socket_t *', + 'name' => 'thesocket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_protocol_get', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'int *', + 'name' => 'protocol' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_recv', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_recvfrom', + 'args' => [ + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'from' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_send', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_sendfile', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + }, + { + 'type' => 'apr_hdtr_t *', + 'name' => 'hdtr' + }, + { + 'type' => 'apr_off_t *', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_sendto', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'where' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'flags' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_sendv', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'const struct iovec *', + 'name' => 'vec' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'nvec' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_shutdown', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'thesocket' + }, + { + 'type' => 'apr_shutdown_how_e', + 'name' => 'how' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_timeout_get', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_interval_time_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_timeout_set', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_socket_type_get', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'sock' + }, + { + 'type' => 'int *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_stat', + 'args' => [ + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_strerror', + 'args' => [ + { + 'type' => 'apr_status_t', + 'name' => 'statcode' + }, + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'bufsize' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_strfsize', + 'args' => [ + { + 'type' => 'apr_off_t', + 'name' => 'size' + }, + { + 'type' => 'char *', + 'name' => 'buf' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_strftime', + 'args' => [ + { + 'type' => 'char *', + 'name' => 's' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'retsize' + }, + { + 'type' => 'apr_size_t', + 'name' => 'max' + }, + { + 'type' => 'const char *', + 'name' => 'format' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'tm' + } + ] + }, + { + 'return_type' => 'const apr_strmatch_pattern *', + 'name' => 'apr_strmatch_precompile', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'case_sensitive' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_strnatcasecmp', + 'args' => [ + { + 'type' => 'char const *', + 'name' => 'a' + }, + { + 'type' => 'char const *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_strnatcmp', + 'args' => [ + { + 'type' => 'char const *', + 'name' => 'a' + }, + { + 'type' => 'char const *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_strtoff', + 'args' => [ + { + 'type' => 'apr_off_t *', + 'name' => 'offset' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'char **', + 'name' => 'end' + }, + { + 'type' => 'int', + 'name' => 'base' + } + ] + }, + { + 'return_type' => 'apr_int64_t', + 'name' => 'apr_strtoi64', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'char **', + 'name' => 'end' + }, + { + 'type' => 'int', + 'name' => 'base' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_strtok', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'str' + }, + { + 'type' => 'const char *', + 'name' => 'sep' + }, + { + 'type' => 'char **', + 'name' => 'last' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_add', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_addn', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_clear', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'apr_table_t *', + 'name' => 'apr_table_clone', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_compress', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'unsigned', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_table_t *', + 'name' => 'apr_table_copy', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_table_do', + 'args' => [ + { + 'type' => 'void *comp', + 'name' => 'arg0' + }, + { + 'type' => 'void *', + 'name' => 'rec' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 't' + }, + { + 'type' => '...', + 'name' => 'arg3' + } + ] + }, + { + 'return_type' => 'const apr_array_header_t *', + 'name' => 'apr_table_elts', + 'args' => [ + { + 'type' => 'const apr_table_t *', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_table_get', + 'args' => [ + { + 'type' => 'const apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_table_t *', + 'name' => 'apr_table_make', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'nelts' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_merge', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_mergen', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_overlap', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 'a' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 'b' + }, + { + 'type' => 'unsigned', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_table_t *', + 'name' => 'apr_table_overlay', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 'overlay' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 'base' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_set', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_setn', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_table_unset', + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_table_vdo', + 'args' => [ + { + 'type' => 'void *comp', + 'name' => 'arg0' + }, + { + 'type' => 'void *', + 'name' => 'rec' + }, + { + 'type' => 'const apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'va_list', + 'name' => 'vp' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_temp_dir_get', + 'args' => [ + { + 'type' => 'const char **', + 'name' => 'temp_dir' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_terminate', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_terminate2', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'apr_text_append', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_text_header *', + 'name' => 'hdr' + }, + { + 'type' => 'const char *', + 'name' => 'text' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_broadcast', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_create', + 'args' => [ + { + 'type' => 'apr_thread_cond_t **', + 'name' => 'cond' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_destroy', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_thread_cond_pool_get', + 'args' => [ + { + 'type' => 'const apr_thread_cond_t *', + 'name' => 'thethread_cond' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_signal', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_timedwait', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_cond_wait', + 'args' => [ + { + 'type' => 'apr_thread_cond_t *', + 'name' => 'cond' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_create', + 'args' => [ + { + 'type' => 'apr_thread_t **', + 'name' => 'new_thread' + }, + { + 'type' => 'apr_threadattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_thread_start_t', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_data_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'thread' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_data_set', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup) (void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'thread' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_detach', + 'args' => [ + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_exit', + 'args' => [ + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + }, + { + 'type' => 'apr_status_t', + 'name' => 'retval' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_join', + 'args' => [ + { + 'type' => 'apr_status_t *', + 'name' => 'retval' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_create', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t **', + 'name' => 'mutex' + }, + { + 'type' => 'unsigned int', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_destroy', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_lock', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_thread_mutex_pool_get', + 'args' => [ + { + 'type' => 'const apr_thread_mutex_t *', + 'name' => 'thethread_mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_trylock', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_mutex_unlock', + 'args' => [ + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'mutex' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_once', + 'args' => [ + { + 'type' => 'apr_thread_once_t *', + 'name' => 'control' + }, + { + 'type' => 'void (*func)(void)', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_once_init', + 'args' => [ + { + 'type' => 'apr_thread_once_t **', + 'name' => 'control' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_busy_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_pool_create', + 'args' => [ + { + 'type' => 'apr_thread_pool_t **', + 'name' => 'me' + }, + { + 'type' => 'apr_size_t', + 'name' => 'init_threads' + }, + { + 'type' => 'apr_size_t', + 'name' => 'max_threads' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_pool_destroy', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_thread_pool_get', + 'args' => [ + { + 'type' => 'const apr_thread_t *', + 'name' => 'thethread' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_idle_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_idle_max_get', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_idle_max_set', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + }, + { + 'type' => 'apr_size_t', + 'name' => 'cnt' + } + ] + }, + { + 'return_type' => 'apr_interval_time_t', + 'name' => 'apr_thread_pool_idle_wait_get', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_interval_time_t', + 'name' => 'apr_thread_pool_idle_wait_set', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_pool_push', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + }, + { + 'type' => 'apr_thread_start_t', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'param' + }, + { + 'type' => 'apr_byte_t', + 'name' => 'priority' + }, + { + 'type' => 'void *', + 'name' => 'owner' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_pool_schedule', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + }, + { + 'type' => 'apr_thread_start_t', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'param' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'time' + }, + { + 'type' => 'void *', + 'name' => 'owner' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_scheduled_tasks_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_pool_task_owner_get', + 'args' => [ + { + 'type' => 'apr_thread_t *', + 'name' => 'thd' + }, + { + 'type' => 'void **', + 'name' => 'owner' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_pool_tasks_cancel', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + }, + { + 'type' => 'void *', + 'name' => 'owner' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_tasks_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_tasks_high_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_tasks_run_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_thread_max_get', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_thread_max_set', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + }, + { + 'type' => 'apr_size_t', + 'name' => 'cnt' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_threads_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_threads_high_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_threads_idle_timeout_count', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_threshold_get', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'apr_thread_pool_threshold_set', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + }, + { + 'type' => 'apr_size_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_pool_top', + 'args' => [ + { + 'type' => 'apr_thread_pool_t *', + 'name' => 'me' + }, + { + 'type' => 'apr_thread_start_t', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'param' + }, + { + 'type' => 'apr_byte_t', + 'name' => 'priority' + }, + { + 'type' => 'void *', + 'name' => 'owner' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_create', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t **', + 'name' => 'rwlock' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_destroy', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'apr_thread_rwlock_pool_get', + 'args' => [ + { + 'type' => 'const apr_thread_rwlock_t *', + 'name' => 'thethread_rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_rdlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_tryrdlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_trywrlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_unlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_thread_rwlock_wrlock', + 'args' => [ + { + 'type' => 'apr_thread_rwlock_t *', + 'name' => 'rwlock' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_thread_yield', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadattr_create', + 'args' => [ + { + 'type' => 'apr_threadattr_t **', + 'name' => 'new_attr' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadattr_detach_get', + 'args' => [ + { + 'type' => 'apr_threadattr_t *', + 'name' => 'attr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadattr_detach_set', + 'args' => [ + { + 'type' => 'apr_threadattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'on' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadattr_guardsize_set', + 'args' => [ + { + 'type' => 'apr_threadattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_size_t', + 'name' => 'guardsize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadattr_stacksize_set', + 'args' => [ + { + 'type' => 'apr_threadattr_t *', + 'name' => 'attr' + }, + { + 'type' => 'apr_size_t', + 'name' => 'stacksize' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_data_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'threadkey' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_data_set', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_status_t (*cleanup) (void *)', + 'name' => 'arg2' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'threadkey' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_private_create', + 'args' => [ + { + 'type' => 'apr_threadkey_t **', + 'name' => 'key' + }, + { + 'type' => 'void (*dest)(void *)', + 'name' => 'arg1' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_private_delete', + 'args' => [ + { + 'type' => 'apr_threadkey_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_private_get', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'new_mem' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_threadkey_private_set', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'priv' + }, + { + 'type' => 'apr_threadkey_t *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_ansi_put', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'result' + }, + { + 'type' => 'time_t', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_time_clock_hires', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_get', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_gmt', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_t', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_gmt_get', + 'args' => [ + { + 'type' => 'apr_time_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_exp_t *', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_lt', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_t', + 'name' => 'input' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_time_exp_tz', + 'args' => [ + { + 'type' => 'apr_time_exp_t *', + 'name' => 'result' + }, + { + 'type' => 'apr_time_t', + 'name' => 'input' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'offs' + } + ] + }, + { + 'return_type' => 'apr_time_t', + 'name' => 'apr_time_now', + 'args' => [] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_tokenize_to_argv', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'arg_str' + }, + { + 'type' => 'char ***', + 'name' => 'argv_out' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'token_context' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uid_current', + 'args' => [ + { + 'type' => 'apr_uid_t *', + 'name' => 'userid' + }, + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uid_get', + 'args' => [ + { + 'type' => 'apr_uid_t *', + 'name' => 'userid' + }, + { + 'type' => 'apr_gid_t *', + 'name' => 'groupid' + }, + { + 'type' => 'const char *', + 'name' => 'username' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uid_homepath_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'dirname' + }, + { + 'type' => 'const char *', + 'name' => 'username' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uid_name_get', + 'args' => [ + { + 'type' => 'char **', + 'name' => 'username' + }, + { + 'type' => 'apr_uid_t', + 'name' => 'userid' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uri_parse', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'uri' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'uptr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uri_parse_hostinfo', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'hostinfo' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'uptr' + } + ] + }, + { + 'return_type' => 'apr_port_t', + 'name' => 'apr_uri_port_of_scheme', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'scheme_str' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_uri_unparse', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_uri_t *', + 'name' => 'uptr' + }, + { + 'type' => 'unsigned', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_uuid_format', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'const apr_uuid_t *', + 'name' => 'uuid' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_uuid_get', + 'args' => [ + { + 'type' => 'apr_uuid_t *', + 'name' => 'uuid' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_uuid_parse', + 'args' => [ + { + 'type' => 'apr_uuid_t *', + 'name' => 'uuid' + }, + { + 'type' => 'const char *', + 'name' => 'uuid_str' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_version', + 'args' => [ + { + 'type' => 'apr_version_t *', + 'name' => 'pvsn' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_version_string', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'apr_vformatter', + 'args' => [ + { + 'type' => 'int (*flush_func)(apr_vformatter_buff_t *b)', + 'name' => 'arg0' + }, + { + 'type' => 'apr_vformatter_buff_t *', + 'name' => 'c' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => 'va_list', + 'name' => 'ap' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_vsnprintf', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'const char *', + 'name' => 'format' + }, + { + 'type' => 'va_list', + 'name' => 'ap' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_wait_for_io_or_timeout', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'for_read' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_close', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_conv_buffer', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + }, + { + 'type' => 'const char *', + 'name' => 'inbuf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'inbytes_left' + }, + { + 'type' => 'char *', + 'name' => 'outbuf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'outbytes_left' + } + ] + }, + { + 'return_type' => 'apr_int32_t', + 'name' => 'apr_xlate_conv_byte', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + }, + { + 'type' => 'unsigned char', + 'name' => 'inchar' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_open', + 'args' => [ + { + 'type' => 'apr_xlate_t **', + 'name' => 'convset' + }, + { + 'type' => 'const char *', + 'name' => 'topage' + }, + { + 'type' => 'const char *', + 'name' => 'frompage' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xlate_sb_get', + 'args' => [ + { + 'type' => 'apr_xlate_t *', + 'name' => 'convset' + }, + { + 'type' => 'int *', + 'name' => 'onoff' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_xml_empty_elem', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_xml_elem *', + 'name' => 'elem' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'apr_xml_insert_uri', + 'args' => [ + { + 'type' => 'apr_array_header_t *', + 'name' => 'uri_array' + }, + { + 'type' => 'const char *', + 'name' => 'uri' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xml_parse_file', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_xml_parser **', + 'name' => 'parser' + }, + { + 'type' => 'apr_xml_doc **', + 'name' => 'ppdoc' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'xmlfd' + }, + { + 'type' => 'apr_size_t', + 'name' => 'buffer_length' + } + ] + }, + { + 'return_type' => 'apr_xml_parser *', + 'name' => 'apr_xml_parser_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xml_parser_done', + 'args' => [ + { + 'type' => 'apr_xml_parser *', + 'name' => 'parser' + }, + { + 'type' => 'apr_xml_doc **', + 'name' => 'pdoc' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'apr_xml_parser_feed', + 'args' => [ + { + 'type' => 'apr_xml_parser *', + 'name' => 'parser' + }, + { + 'type' => 'const char *', + 'name' => 'data' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'apr_xml_parser_geterror', + 'args' => [ + { + 'type' => 'apr_xml_parser *', + 'name' => 'parser' + }, + { + 'type' => 'char *', + 'name' => 'errbuf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'errbufsize' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_xml_quote_elem', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'elem' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'apr_xml_quote_string', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'quotes' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'apr_xml_to_text', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const apr_xml_elem *', + 'name' => 'elem' + }, + { + 'type' => 'int', + 'name' => 'style' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'namespaces' + }, + { + 'type' => 'int *', + 'name' => 'ns_map' + }, + { + 'type' => 'const char **', + 'name' => 'pbuf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'psize' + } + ] + } +]; + + +1;
diff --git a/2_0_13/xs/tables/current24/Apache2/StructureTable.pm b/2_0_13/xs/tables/current24/Apache2/StructureTable.pm new file mode 100644 index 0000000..0bf8530 --- /dev/null +++ b/2_0_13/xs/tables/current24/Apache2/StructureTable.pm
@@ -0,0 +1,5468 @@ +package Apache2::StructureTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by Apache2::ParseSource/0.02 +# ! Mon Jul 1 12:38:15 2013 +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$Apache2::StructureTable = [ + { + 'type' => 'ap_HOOK_access_checker_ex_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_access_checker_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_auth_checker_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_check_config_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_check_user_id_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_child_init_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_child_status_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_create_connection_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_create_request_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_default_port_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_drop_privileges_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_end_generation_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_error_log_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_expr_lookup_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_fixups_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_generate_log_id_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_get_mgmt_items_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_get_suexec_identity_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_handler_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_header_parser_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_http_scheme_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_insert_error_filter_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_insert_filter_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_insert_network_bucket_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_log_transaction_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_map_to_storage_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_monitor_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_mpm_get_name_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_mpm_query_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_mpm_register_timed_callback_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_mpm_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_note_auth_failure_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_open_logs_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_optional_fn_retrieve_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_post_config_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_post_read_request_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_pre_config_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_pre_connection_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_pre_mpm_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_pre_read_request_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_process_connection_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_quick_handler_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_session_decode_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_session_encode_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_session_load_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_session_save_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_status_hook_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_test_config_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_translate_name_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_type_checker_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_watchdog_exit_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_watchdog_init_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_watchdog_need_t', + 'elts' => [] + }, + { + 'type' => 'ap_HOOK_watchdog_step_t', + 'elts' => [] + }, + { + 'type' => 'ap_LINK_access_checker_ex_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_access_checker_ex_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_access_checker_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_access_checker_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_auth_checker_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_auth_checker_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_check_config_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_check_config_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_check_user_id_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_check_user_id_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_child_init_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_child_init_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_child_status_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_child_status_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_create_connection_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_create_connection_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_create_request_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_create_request_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_default_port_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_default_port_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_drop_privileges_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_drop_privileges_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_end_generation_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_end_generation_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_error_log_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_error_log_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_expr_lookup_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_expr_lookup_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_fixups_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_fixups_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_generate_log_id_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_generate_log_id_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_get_mgmt_items_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_get_mgmt_items_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_get_suexec_identity_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_get_suexec_identity_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_handler_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_handler_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_header_parser_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_header_parser_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_http_scheme_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_http_scheme_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_insert_error_filter_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_insert_error_filter_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_insert_filter_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_insert_filter_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_insert_network_bucket_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_insert_network_bucket_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_log_transaction_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_log_transaction_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_map_to_storage_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_map_to_storage_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_monitor_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_monitor_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_mpm_get_name_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_mpm_get_name_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_mpm_query_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_mpm_query_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_mpm_register_timed_callback_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_mpm_register_timed_callback_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_mpm_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_mpm_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_note_auth_failure_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_note_auth_failure_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_open_logs_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_open_logs_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_optional_fn_retrieve_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_optional_fn_retrieve_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_post_config_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_post_config_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_post_read_request_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_post_read_request_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_pre_config_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_pre_config_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_pre_connection_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_pre_connection_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_pre_mpm_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_pre_mpm_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_pre_read_request_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_pre_read_request_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_process_connection_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_process_connection_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_quick_handler_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_quick_handler_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_session_decode_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_session_decode_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_session_encode_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_session_encode_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_session_load_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_session_load_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_session_save_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_session_save_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_status_hook_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_status_hook_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_test_config_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_test_config_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_translate_name_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_translate_name_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_type_checker_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_type_checker_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_watchdog_exit_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_watchdog_exit_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_watchdog_init_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_watchdog_init_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_watchdog_need_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_watchdog_need_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_LINK_watchdog_step_t', + 'elts' => [ + { + 'type' => 'ap_HOOK_watchdog_step_t *', + 'name' => 'pFunc' + }, + { + 'type' => 'const char *', + 'name' => 'szName' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszPredecessors' + }, + { + 'type' => 'const char * const *', + 'name' => 'aszSuccessors' + }, + { + 'type' => 'int', + 'name' => 'nOrder' + } + ] + }, + { + 'type' => 'ap_bucket_error', + 'elts' => [ + { + 'type' => 'apr_bucket_refcount', + 'name' => 'refcount' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'const char *', + 'name' => 'data' + } + ] + }, + { + 'type' => 'ap_conf_vector_t', + 'elts' => [] + }, + { + 'type' => 'ap_configfile_t', + 'elts' => [ + { + 'type' => 'apr_status_t(*) (char *ch, void *param)', + 'name' => 'getch' + }, + { + 'type' => 'apr_status_t(*) (void *buf, apr_size_t bufsiz, void *param)', + 'name' => 'getstr' + }, + { + 'type' => 'apr_status_t(*) (void *param)', + 'name' => 'close' + }, + { + 'type' => 'void *', + 'name' => 'param' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'unsigned', + 'name' => 'line_number' + } + ] + }, + { + 'type' => 'ap_conn_keepalive_e', + 'elts' => [] + }, + { + 'type' => 'ap_cookie_do', + 'elts' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'const char *', + 'name' => 'encoded' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'new_cookies' + }, + { + 'type' => 'int', + 'name' => 'duplicated' + } + ] + }, + { + 'type' => 'ap_dbd_t', + 'elts' => [ + { + 'type' => 'apr_dbd_t *', + 'name' => 'handle' + }, + { + 'type' => 'const apr_dbd_driver_t *', + 'name' => 'driver' + }, + { + 'type' => 'apr_hash_t *', + 'name' => 'prepared' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + } + ] + }, + { + 'type' => 'ap_directive_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'directive' + }, + { + 'type' => 'const char *', + 'name' => 'args' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'next' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'first_child' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'parent' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'int', + 'name' => 'line_num' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'last' + } + ] + }, + { + 'type' => 'ap_errorlog_format_item', + 'elts' => [ + { + 'type' => 'ap_errorlog_handler_fn_t *', + 'name' => 'func' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + }, + { + 'type' => 'unsigned int', + 'name' => 'flags' + }, + { + 'type' => 'unsigned int', + 'name' => 'min_loglevel' + } + ] + }, + { + 'type' => 'ap_errorlog_handler', + 'elts' => [ + { + 'type' => 'ap_errorlog_handler_fn_t *', + 'name' => 'func' + }, + { + 'type' => 'int', + 'name' => 'flags' + } + ] + }, + { + 'type' => 'ap_errorlog_handler_fn_t', + 'elts' => [] + }, + { + 'type' => 'ap_errorlog_info', + 'elts' => [ + { + 'type' => 'const server_rec *', + 'name' => 's' + }, + { + 'type' => 'const conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'const request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const request_rec *', + 'name' => 'rmain' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'file' + }, + { + 'type' => 'int', + 'name' => 'line' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'int', + 'name' => 'using_syslog' + }, + { + 'type' => 'int', + 'name' => 'startup' + }, + { + 'type' => 'const char *', + 'name' => 'format' + } + ] + }, + { + 'type' => 'ap_expr_eval_ctx_t', + 'elts' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char **', + 'name' => 'err' + }, + { + 'type' => 'const ap_expr_info_t *', + 'name' => 'info' + }, + { + 'type' => 'ap_regmatch_t *', + 'name' => 're_pmatch' + }, + { + 'type' => 'apr_size_t', + 'name' => 're_nmatch' + }, + { + 'type' => 'const char **', + 'name' => 're_source' + }, + { + 'type' => 'const char **', + 'name' => 'vary_this' + }, + { + 'type' => 'const char **', + 'name' => 'result_string' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'int', + 'name' => 'reclvl' + } + ] + }, + { + 'type' => 'ap_expr_info_t', + 'elts' => [ + { + 'type' => 'ap_expr_t *', + 'name' => 'root_node' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'unsigned int', + 'name' => 'line_number' + }, + { + 'type' => 'unsigned int', + 'name' => 'flags' + }, + { + 'type' => 'int', + 'name' => 'module_index' + } + ] + }, + { + 'type' => 'ap_expr_list_func_t', + 'elts' => [] + }, + { + 'type' => 'ap_expr_lookup_fn_t', + 'elts' => [] + }, + { + 'type' => 'ap_expr_lookup_parms', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'flags' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'const void **', + 'name' => 'func' + }, + { + 'type' => 'const void **', + 'name' => 'data' + }, + { + 'type' => 'const char **', + 'name' => 'err' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'type' => 'ap_expr_op_binary_t', + 'elts' => [] + }, + { + 'type' => 'ap_expr_op_unary_t', + 'elts' => [] + }, + { + 'type' => 'ap_expr_string_func_t', + 'elts' => [] + }, + { + 'type' => 'ap_expr_t', + 'elts' => [] + }, + { + 'type' => 'ap_expr_var_func_t', + 'elts' => [] + }, + { + 'type' => 'ap_filter_func', + 'elts' => [ + { + 'type' => 'ap_out_filter_func', + 'name' => 'out_func' + }, + { + 'type' => 'ap_in_filter_func', + 'name' => 'in_func' + } + ] + }, + { + 'type' => 'ap_filter_provider_t', + 'elts' => [] + }, + { + 'type' => 'ap_filter_rec_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_filter_func', + 'name' => 'filter_func' + }, + { + 'type' => 'ap_init_filter_func', + 'name' => 'filter_init_func' + }, + { + 'type' => 'ap_filter_rec_t *', + 'name' => 'next' + }, + { + 'type' => 'ap_filter_provider_t *', + 'name' => 'providers' + }, + { + 'type' => 'ap_filter_type', + 'name' => 'ftype' + }, + { + 'type' => 'int', + 'name' => 'debug' + }, + { + 'type' => 'unsigned int', + 'name' => 'proto_flags' + } + ] + }, + { + 'type' => 'ap_filter_t', + 'elts' => [ + { + 'type' => 'ap_filter_rec_t *', + 'name' => 'frec' + }, + { + 'type' => 'void *', + 'name' => 'ctx' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'next' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'type' => 'ap_filter_type', + 'elts' => [] + }, + { + 'type' => 'ap_form_pair_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'value' + } + ] + }, + { + 'type' => 'ap_generation_t', + 'elts' => [] + }, + { + 'type' => 'ap_in_filter_func', + 'elts' => [] + }, + { + 'type' => 'ap_init_filter_func', + 'elts' => [] + }, + { + 'type' => 'ap_input_mode_t', + 'elts' => [] + }, + { + 'type' => 'ap_list_provider_groups_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + } + ] + }, + { + 'type' => 'ap_list_provider_names_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'provider_name' + } + ] + }, + { + 'type' => 'ap_listen_rec', + 'elts' => [ + { + 'type' => 'ap_listen_rec *', + 'name' => 'next' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'sd' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'bind_addr' + }, + { + 'type' => 'accept_function', + 'name' => 'accept_func' + }, + { + 'type' => 'int', + 'name' => 'active' + }, + { + 'type' => 'const char *', + 'name' => 'protocol' + }, + { + 'type' => 'ap_slave_t *', + 'name' => 'slave' + } + ] + }, + { + 'type' => 'ap_loadavg_t', + 'elts' => [ + { + 'type' => 'float', + 'name' => 'loadavg' + }, + { + 'type' => 'float', + 'name' => 'loadavg5' + }, + { + 'type' => 'float', + 'name' => 'loadavg15' + } + ] + }, + { + 'type' => 'ap_method_list_t', + 'elts' => [ + { + 'type' => 'apr_int64_t', + 'name' => 'method_mask' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'method_list' + } + ] + }, + { + 'type' => 'ap_mgmt_item_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'description' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'ap_mgmt_type_e', + 'name' => 'vtype' + }, + { + 'type' => 'ap_mgmt_value', + 'name' => 'v' + } + ] + }, + { + 'type' => 'ap_mgmt_type_e', + 'elts' => [] + }, + { + 'type' => 'ap_mgmt_value', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 's_value' + }, + { + 'type' => 'long', + 'name' => 'i_value' + }, + { + 'type' => 'apr_hash_t *', + 'name' => 'h_value' + } + ] + }, + { + 'type' => 'ap_module_symbol_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'module *', + 'name' => 'modp' + } + ] + }, + { + 'type' => 'ap_mpm_callback_fn_t', + 'elts' => [] + }, + { + 'type' => 'ap_out_filter_func', + 'elts' => [] + }, + { + 'type' => 'ap_pcw_dir_cb_t', + 'elts' => [] + }, + { + 'type' => 'ap_pcw_srv_cb_t', + 'elts' => [] + }, + { + 'type' => 'ap_pod_t', + 'elts' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'pod_in' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'pod_out' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'type' => 'ap_reclaim_callback_fn_t', + 'elts' => [] + }, + { + 'type' => 'ap_regex_t', + 'elts' => [ + { + 'type' => 'void *', + 'name' => 're_pcre' + }, + { + 'type' => 'int', + 'name' => 're_nsub' + }, + { + 'type' => 'apr_size_t', + 'name' => 're_erroffset' + } + ] + }, + { + 'type' => 'ap_regmatch_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'rm_so' + }, + { + 'type' => 'int', + 'name' => 'rm_eo' + } + ] + }, + { + 'type' => 'ap_rxplus_t', + 'elts' => [ + { + 'type' => 'ap_regex_t', + 'name' => 'rx' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'flags' + }, + { + 'type' => 'const char *', + 'name' => 'subs' + }, + { + 'type' => 'const char *', + 'name' => 'match' + }, + { + 'type' => 'apr_size_t', + 'name' => 'nmatch' + }, + { + 'type' => 'ap_regmatch_t *', + 'name' => 'pmatch' + } + ] + }, + { + 'type' => 'ap_sb_handle_t', + 'elts' => [] + }, + { + 'type' => 'ap_scoreboard_e', + 'elts' => [] + }, + { + 'type' => 'ap_slave_t', + 'elts' => [] + }, + { + 'type' => 'ap_sload_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'idle' + }, + { + 'type' => 'int', + 'name' => 'busy' + }, + { + 'type' => 'apr_off_t', + 'name' => 'bytes_served' + }, + { + 'type' => 'unsigned long', + 'name' => 'access_count' + } + ] + }, + { + 'type' => 'ap_slotmem_callback_fn_t', + 'elts' => [] + }, + { + 'type' => 'ap_slotmem_instance_t', + 'elts' => [] + }, + { + 'type' => 'ap_slotmem_provider_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)', + 'name' => 'doall' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t **inst, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool)', + 'name' => 'create' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t **inst, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool)', + 'name' => 'attach' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int item_id, void**mem)', + 'name' => 'dptr' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int item_id, unsigned char *dest, apr_size_t dest_len)', + 'name' => 'get' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *slot, unsigned int item_id, unsigned char *src, apr_size_t src_len)', + 'name' => 'put' + }, + { + 'type' => 'unsigned int(*)(ap_slotmem_instance_t *s)', + 'name' => 'num_slots' + }, + { + 'type' => 'unsigned int(*)(ap_slotmem_instance_t *s)', + 'name' => 'num_free_slots' + }, + { + 'type' => 'apr_size_t(*)(ap_slotmem_instance_t *s)', + 'name' => 'slot_size' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int *item_id)', + 'name' => 'grab' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int item_id)', + 'name' => 'release' + }, + { + 'type' => 'apr_status_t(*)(ap_slotmem_instance_t *s, unsigned int item_id)', + 'name' => 'fgrab' + } + ] + }, + { + 'type' => 'ap_slotmem_type_t', + 'elts' => [] + }, + { + 'type' => 'ap_socache_instance_t', + 'elts' => [] + }, + { + 'type' => 'ap_socache_iterator_t', + 'elts' => [] + }, + { + 'type' => 'ap_unix_identity_t', + 'elts' => [ + { + 'type' => 'uid_t', + 'name' => 'uid' + }, + { + 'type' => 'gid_t', + 'name' => 'gid' + }, + { + 'type' => 'int', + 'name' => 'userdir' + } + ] + }, + { + 'type' => 'ap_version_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'major' + }, + { + 'type' => 'int', + 'name' => 'minor' + }, + { + 'type' => 'int', + 'name' => 'patch' + }, + { + 'type' => 'const char *', + 'name' => 'add_string' + } + ] + }, + { + 'type' => 'ap_vhost_iterate_conn_cb', + 'elts' => [] + }, + { + 'type' => 'ap_watchdog_callback_fn_t', + 'elts' => [] + }, + { + 'type' => 'ap_watchdog_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_access_compat_ap_satisfies_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_authn_cache_store_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_dbd_acquire_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_dbd_cacquire_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_dbd_close_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_dbd_open_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_dbd_prepare_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_find_loaded_module_symbol_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_ident_lookup_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_logio_add_bytes_in_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_logio_add_bytes_out_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_logio_get_last_bytes_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_register_rewrite_mapfunc_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_request_insert_filter_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_request_remove_filter_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_session_get_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_session_load_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_session_save_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_session_set_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_signal_server_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_watchdog_get_instance_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_watchdog_register_callback_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_ap_watchdog_set_callback_interval_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_authn_ap_auth_name_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_authn_ap_auth_type_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_authn_ap_list_provider_names_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_authz_ap_list_provider_names_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_authz_some_auth_required_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_modperl_interp_unselect_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_modperl_thx_interp_get_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_cache_check_subgroups_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_cache_checkuserid_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_cache_compare_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_cache_comparedn_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_cache_getuserdn_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_connection_close_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_connection_find_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_connection_open_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_connection_unbind_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_uldap_ssl_supported_t', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_xml2enc_charset_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_OFN_xml2enc_filter_t + ', + 'elts' => [] + }, + { + 'type' => 'apr_abortfunc_t', + 'elts' => [] + }, + { + 'type' => 'apr_allocator_t', + 'elts' => [] + }, + { + 'type' => 'apr_anylock_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'union apr_anylock_u_t', + 'name' => 'lock' + } + ] + }, + { + 'type' => 'apr_array_header_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'int', + 'name' => 'elt_size' + }, + { + 'type' => 'int', + 'name' => 'nelts' + }, + { + 'type' => 'int', + 'name' => 'nalloc' + }, + { + 'type' => 'char *', + 'name' => 'elts' + } + ] + }, + { + 'type' => 'apr_brigade_flush', + 'elts' => [] + }, + { + 'type' => 'apr_bucket', + 'elts' => [ + { + 'type' => '_ANON 68', + 'name' => 'link' + }, + { + 'type' => 'const apr_bucket_type_t *', + 'name' => 'type' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'apr_off_t', + 'name' => 'start' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'void(*)(void *e)', + 'name' => 'free' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'type' => 'apr_bucket_alloc_t', + 'elts' => [] + }, + { + 'type' => 'apr_bucket_brigade', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_bucket_list', + 'name' => 'list' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'bucket_alloc' + } + ] + }, + { + 'type' => 'apr_bucket_file', + 'elts' => [ + { + 'type' => 'apr_bucket_refcount', + 'name' => 'refcount' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'fd' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'readpool' + }, + { + 'type' => 'int', + 'name' => 'can_mmap' + } + ] + }, + { + 'type' => 'apr_bucket_heap', + 'elts' => [ + { + 'type' => 'apr_bucket_refcount', + 'name' => 'refcount' + }, + { + 'type' => 'char *', + 'name' => 'base' + }, + { + 'type' => 'apr_size_t', + 'name' => 'alloc_len' + }, + { + 'type' => 'void(*)(void *data)', + 'name' => 'free_func' + } + ] + }, + { + 'type' => 'apr_bucket_mmap', + 'elts' => [ + { + 'type' => 'apr_bucket_refcount', + 'name' => 'refcount' + }, + { + 'type' => 'apr_mmap_t *', + 'name' => 'mmap' + } + ] + }, + { + 'type' => 'apr_bucket_pool', + 'elts' => [ + { + 'type' => 'apr_bucket_heap', + 'name' => 'heap' + }, + { + 'type' => 'const char *', + 'name' => 'base' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + } + ] + }, + { + 'type' => 'apr_bucket_refcount', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'refcount' + } + ] + }, + { + 'type' => 'apr_bucket_structs', + 'elts' => [] + }, + { + 'type' => 'apr_bucket_type_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'num_func' + }, + { + 'type' => 'int', + 'name' => 'is_metadata' + }, + { + 'type' => 'void(*)(void *data)', + 'name' => 'destroy' + }, + { + 'type' => 'apr_status_t(*)(apr_bucket *b, const char **str, apr_size_t *len, + apr_read_type_e block)', + 'name' => 'read' + }, + { + 'type' => 'apr_status_t(*)(apr_bucket *e, apr_pool_t *pool)', + 'name' => 'setaside' + }, + { + 'type' => 'apr_status_t(*)(apr_bucket *e, apr_size_t point)', + 'name' => 'split' + }, + { + 'type' => 'apr_status_t(*)(apr_bucket *e, apr_bucket **c)', + 'name' => 'copy' + } + ] + }, + { + 'type' => 'apr_byte_t', + 'elts' => [] + }, + { + 'type' => 'apr_child_errfn_t', + 'elts' => [] + }, + { + 'type' => 'apr_cmdtype_e', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_block_key_mode_e', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_block_key_type_e', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_block_t', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_config_t', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_driver_t', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_hash_add_t', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_hash_finish_t', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_hash_init_t', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_hash_t', + 'elts' => [ + { + 'type' => 'apr_crypto_hash_init_t *', + 'name' => 'init' + }, + { + 'type' => 'apr_crypto_hash_add_t *', + 'name' => 'add' + }, + { + 'type' => 'apr_crypto_hash_finish_t *', + 'name' => 'finish' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'type' => 'apr_crypto_key_t', + 'elts' => [] + }, + { + 'type' => 'apr_crypto_t', + 'elts' => [] + }, + { + 'type' => 'apr_datatype_e', + 'elts' => [] + }, + { + 'type' => 'apr_datum_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'dptr' + }, + { + 'type' => 'apr_size_t', + 'name' => 'dsize' + } + ] + }, + { + 'type' => 'apr_dbd_driver_t', + 'elts' => [] + }, + { + 'type' => 'apr_dbd_prepared_t', + 'elts' => [] + }, + { + 'type' => 'apr_dbd_results_t', + 'elts' => [] + }, + { + 'type' => 'apr_dbd_row_t', + 'elts' => [] + }, + { + 'type' => 'apr_dbd_t', + 'elts' => [] + }, + { + 'type' => 'apr_dbd_transaction_t', + 'elts' => [] + }, + { + 'type' => 'apr_dbd_type_e', + 'elts' => [] + }, + { + 'type' => 'apr_dbm_t', + 'elts' => [] + }, + { + 'type' => 'apr_descriptor', + 'elts' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 's' + } + ] + }, + { + 'type' => 'apr_dev_t', + 'elts' => [] + }, + { + 'type' => 'apr_dir_t', + 'elts' => [] + }, + { + 'type' => 'apr_dso_handle_sym_t', + 'elts' => [] + }, + { + 'type' => 'apr_dso_handle_t', + 'elts' => [] + }, + { + 'type' => 'apr_exit_why_e', + 'elts' => [] + }, + { + 'type' => 'apr_file_t', + 'elts' => [] + }, + { + 'type' => 'apr_fileattrs_t', + 'elts' => [] + }, + { + 'type' => 'apr_fileperms_t', + 'elts' => [] + }, + { + 'type' => 'apr_filetype_e', + 'elts' => [] + }, + { + 'type' => 'apr_finfo_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'valid' + }, + { + 'type' => 'apr_fileperms_t', + 'name' => 'protection' + }, + { + 'type' => 'apr_filetype_e', + 'name' => 'filetype' + }, + { + 'type' => 'apr_uid_t', + 'name' => 'user' + }, + { + 'type' => 'apr_gid_t', + 'name' => 'group' + }, + { + 'type' => 'apr_ino_t', + 'name' => 'inode' + }, + { + 'type' => 'apr_dev_t', + 'name' => 'device' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'nlink' + }, + { + 'type' => 'apr_off_t', + 'name' => 'size' + }, + { + 'type' => 'apr_off_t', + 'name' => 'csize' + }, + { + 'type' => 'apr_time_t', + 'name' => 'atime' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + }, + { + 'type' => 'apr_time_t', + 'name' => 'ctime' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'filehand' + } + ] + }, + { + 'type' => 'apr_getopt_err_fn_t', + 'elts' => [] + }, + { + 'type' => 'apr_getopt_option_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'optch' + }, + { + 'type' => 'int', + 'name' => 'has_arg' + }, + { + 'type' => 'const char *', + 'name' => 'description' + } + ] + }, + { + 'type' => 'apr_getopt_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'cont' + }, + { + 'type' => 'apr_getopt_err_fn_t *', + 'name' => 'errfn' + }, + { + 'type' => 'void *', + 'name' => 'errarg' + }, + { + 'type' => 'int', + 'name' => 'ind' + }, + { + 'type' => 'int', + 'name' => 'opt' + }, + { + 'type' => 'int', + 'name' => 'reset' + }, + { + 'type' => 'int', + 'name' => 'argc' + }, + { + 'type' => 'const char **', + 'name' => 'argv' + }, + { + 'type' => 'char const *', + 'name' => 'place' + }, + { + 'type' => 'int', + 'name' => 'interleave' + }, + { + 'type' => 'int', + 'name' => 'skip_start' + }, + { + 'type' => 'int', + 'name' => 'skip_end' + } + ] + }, + { + 'type' => 'apr_gid_t', + 'elts' => [] + }, + { + 'type' => 'apr_global_mutex_t', + 'elts' => [] + }, + { + 'type' => 'apr_hash_do_callback_fn_t', + 'elts' => [] + }, + { + 'type' => 'apr_hash_index_t', + 'elts' => [] + }, + { + 'type' => 'apr_hash_t', + 'elts' => [] + }, + { + 'type' => 'apr_hashfunc_t', + 'elts' => [] + }, + { + 'type' => 'apr_hdtr_t', + 'elts' => [ + { + 'type' => 'iovec *', + 'name' => 'headers' + }, + { + 'type' => 'int', + 'name' => 'numheaders' + }, + { + 'type' => 'iovec *', + 'name' => 'trailers' + }, + { + 'type' => 'int', + 'name' => 'numtrailers' + } + ] + }, + { + 'type' => 'apr_in_addr_t', + 'elts' => [ + { + 'type' => 'in_addr_t', + 'name' => 's_addr' + } + ] + }, + { + 'type' => 'apr_ino_t', + 'elts' => [] + }, + { + 'type' => 'apr_int16_t', + 'elts' => [] + }, + { + 'type' => 'apr_int32_t', + 'elts' => [] + }, + { + 'type' => 'apr_int64_t', + 'elts' => [] + }, + { + 'type' => 'apr_interface_e', + 'elts' => [] + }, + { + 'type' => 'apr_interval_time_t', + 'elts' => [] + }, + { + 'type' => 'apr_ipsubnet_t', + 'elts' => [] + }, + { + 'type' => 'apr_kill_conditions_e', + 'elts' => [] + }, + { + 'type' => 'apr_ldap_err_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'reason' + }, + { + 'type' => 'const char *', + 'name' => 'msg' + }, + { + 'type' => 'int', + 'name' => 'rc' + } + ] + }, + { + 'type' => 'apr_ldap_opt_tls_cert_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'const char *', + 'name' => 'password' + } + ] + }, + { + 'type' => 'apr_ldap_url_desc_t', + 'elts' => [ + { + 'type' => 'apr_ldap_url_desc_t *', + 'name' => 'lud_next' + }, + { + 'type' => 'char *', + 'name' => 'lud_scheme' + }, + { + 'type' => 'char *', + 'name' => 'lud_host' + }, + { + 'type' => 'int', + 'name' => 'lud_port' + }, + { + 'type' => 'char *', + 'name' => 'lud_dn' + }, + { + 'type' => 'char **', + 'name' => 'lud_attrs' + }, + { + 'type' => 'int', + 'name' => 'lud_scope' + }, + { + 'type' => 'char *', + 'name' => 'lud_filter' + }, + { + 'type' => 'char **', + 'name' => 'lud_exts' + }, + { + 'type' => 'int', + 'name' => 'lud_crit_exts' + } + ] + }, + { + 'type' => 'apr_lockmech_e', + 'elts' => [] + }, + { + 'type' => 'apr_md4_ctx_t', + 'elts' => [ + { + 'type' => 'apr_uint32_t[4]', + 'name' => 'state' + }, + { + 'type' => 'apr_uint32_t[2]', + 'name' => 'count' + }, + { + 'type' => 'unsigned char[64]', + 'name' => 'buffer' + }, + { + 'type' => 'apr_xlate_t *', + 'name' => 'xlate' + } + ] + }, + { + 'type' => 'apr_md5_ctx_t', + 'elts' => [ + { + 'type' => 'apr_uint32_t[4]', + 'name' => 'state' + }, + { + 'type' => 'apr_uint32_t[2]', + 'name' => 'count' + }, + { + 'type' => 'unsigned char[64]', + 'name' => 'buffer' + }, + { + 'type' => 'apr_xlate_t *', + 'name' => 'xlate' + } + ] + }, + { + 'type' => 'apr_memcache_conn_t', + 'elts' => [] + }, + { + 'type' => 'apr_memcache_hash_func', + 'elts' => [] + }, + { + 'type' => 'apr_memcache_server_func', + 'elts' => [] + }, + { + 'type' => 'apr_memcache_server_status_t', + 'elts' => [] + }, + { + 'type' => 'apr_memcache_server_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'host' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'apr_memcache_server_status_t', + 'name' => 'status' + }, + { + 'type' => 'apr_reslist_t *', + 'name' => 'conns' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'lock' + }, + { + 'type' => 'apr_time_t', + 'name' => 'btime' + } + ] + }, + { + 'type' => 'apr_memcache_stats_t', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'version' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'pid' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'uptime' + }, + { + 'type' => 'apr_time_t', + 'name' => 'time' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'pointer_size' + }, + { + 'type' => 'apr_time_t', + 'name' => 'rusage_user' + }, + { + 'type' => 'apr_time_t', + 'name' => 'rusage_system' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'curr_items' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'total_items' + }, + { + 'type' => 'apr_uint64_t', + 'name' => 'bytes' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'curr_connections' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'total_connections' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'connection_structures' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'cmd_get' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'cmd_set' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'get_hits' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'get_misses' + }, + { + 'type' => 'apr_uint64_t', + 'name' => 'evictions' + }, + { + 'type' => 'apr_uint64_t', + 'name' => 'bytes_read' + }, + { + 'type' => 'apr_uint64_t', + 'name' => 'bytes_written' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'limit_maxbytes' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'threads' + } + ] + }, + { + 'type' => 'apr_memcache_t', + 'elts' => [ + { + 'type' => 'apr_uint32_t', + 'name' => 'flags' + }, + { + 'type' => 'apr_uint16_t', + 'name' => 'nalloc' + }, + { + 'type' => 'apr_uint16_t', + 'name' => 'ntotal' + }, + { + 'type' => 'apr_memcache_server_t **', + 'name' => 'live_servers' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'hash_baton' + }, + { + 'type' => 'apr_memcache_hash_func', + 'name' => 'hash_func' + }, + { + 'type' => 'void *', + 'name' => 'server_baton' + }, + { + 'type' => 'apr_memcache_server_func', + 'name' => 'server_func' + } + ] + }, + { + 'type' => 'apr_memcache_value_t', + 'elts' => [ + { + 'type' => 'apr_status_t', + 'name' => 'status' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'char *', + 'name' => 'data' + }, + { + 'type' => 'apr_uint16_t', + 'name' => 'flags' + } + ] + }, + { + 'type' => 'apr_memnode_t', + 'elts' => [ + { + 'type' => 'apr_memnode_t *', + 'name' => 'next' + }, + { + 'type' => 'apr_memnode_t **', + 'name' => 'ref' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'index' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'free_index' + }, + { + 'type' => 'char *', + 'name' => 'first_avail' + }, + { + 'type' => 'char *', + 'name' => 'endp' + } + ] + }, + { + 'type' => 'apr_mmap_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'cntxt' + }, + { + 'type' => 'void *', + 'name' => 'mm' + }, + { + 'type' => 'apr_size_t', + 'name' => 'size' + }, + { + 'type' => '_ANON 66', + 'name' => 'link' + } + ] + }, + { + 'type' => 'apr_off_t', + 'elts' => [] + }, + { + 'type' => 'apr_opt_fn_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_dir_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_dso_handle_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_exp_time_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'tm_sec' + }, + { + 'type' => 'int', + 'name' => 'tm_min' + }, + { + 'type' => 'int', + 'name' => 'tm_hour' + }, + { + 'type' => 'int', + 'name' => 'tm_mday' + }, + { + 'type' => 'int', + 'name' => 'tm_mon' + }, + { + 'type' => 'int', + 'name' => 'tm_year' + }, + { + 'type' => 'int', + 'name' => 'tm_wday' + }, + { + 'type' => 'int', + 'name' => 'tm_yday' + }, + { + 'type' => 'int', + 'name' => 'tm_isdst' + }, + { + 'type' => 'long int', + 'name' => 'tm_gmtoff' + }, + { + 'type' => 'const char *', + 'name' => 'tm_zone' + } + ] + }, + { + 'type' => 'apr_os_file_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_global_mutex_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_proc_mutex_t *', + 'name' => 'proc_mutex' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'thread_mutex' + } + ] + }, + { + 'type' => 'apr_os_imp_time_t', + 'elts' => [ + { + 'type' => '__time_t', + 'name' => 'tv_sec' + }, + { + 'type' => '__suseconds_t', + 'name' => 'tv_usec' + } + ] + }, + { + 'type' => 'apr_os_proc_mutex_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'crossproc' + }, + { + 'type' => 'pthread_mutex_t *', + 'name' => 'pthread_interproc' + }, + { + 'type' => 'pthread_mutex_t *', + 'name' => 'intraproc' + } + ] + }, + { + 'type' => 'apr_os_proc_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_shm_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_sock_info_t', + 'elts' => [ + { + 'type' => 'apr_os_sock_t *', + 'name' => 'os_sock' + }, + { + 'type' => 'sockaddr *', + 'name' => 'local' + }, + { + 'type' => 'sockaddr *', + 'name' => 'remote' + }, + { + 'type' => 'int', + 'name' => 'family' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'int', + 'name' => 'protocol' + } + ] + }, + { + 'type' => 'apr_os_sock_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_thread_t', + 'elts' => [] + }, + { + 'type' => 'apr_os_threadkey_t', + 'elts' => [] + }, + { + 'type' => 'apr_other_child_rec_t', + 'elts' => [] + }, + { + 'type' => 'apr_pollcb_cb_t', + 'elts' => [] + }, + { + 'type' => 'apr_pollcb_t', + 'elts' => [] + }, + { + 'type' => 'apr_pollfd_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_datatype_e', + 'name' => 'desc_type' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'reqevents' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'rtnevents' + }, + { + 'type' => 'apr_descriptor', + 'name' => 'desc' + }, + { + 'type' => 'void *', + 'name' => 'client_data' + } + ] + }, + { + 'type' => 'apr_pollset_method_e', + 'elts' => [] + }, + { + 'type' => 'apr_pollset_t', + 'elts' => [] + }, + { + 'type' => 'apr_pool_t', + 'elts' => [] + }, + { + 'type' => 'apr_port_t', + 'elts' => [] + }, + { + 'type' => 'apr_proc_mutex_t', + 'elts' => [] + }, + { + 'type' => 'apr_proc_t', + 'elts' => [ + { + 'type' => 'pid_t', + 'name' => 'pid' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'in' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'out' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'err' + } + ] + }, + { + 'type' => 'apr_procattr_t', + 'elts' => [] + }, + { + 'type' => 'apr_queue_t', + 'elts' => [] + }, + { + 'type' => 'apr_random_t', + 'elts' => [] + }, + { + 'type' => 'apr_read_type_e', + 'elts' => [] + }, + { + 'type' => 'apr_reslist_constructor', + 'elts' => [] + }, + { + 'type' => 'apr_reslist_destructor', + 'elts' => [] + }, + { + 'type' => 'apr_reslist_t', + 'elts' => [] + }, + { + 'type' => 'apr_rmm_off_t', + 'elts' => [] + }, + { + 'type' => 'apr_rmm_t', + 'elts' => [] + }, + { + 'type' => 'apr_sdbm_datum_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'dptr' + }, + { + 'type' => 'int', + 'name' => 'dsize' + } + ] + }, + { + 'type' => 'apr_sdbm_t', + 'elts' => [] + }, + { + 'type' => 'apr_seek_where_t', + 'elts' => [] + }, + { + 'type' => 'apr_sha1_ctx_t', + 'elts' => [ + { + 'type' => 'apr_uint32_t[5]', + 'name' => 'digest' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'count_lo' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'count_hi' + }, + { + 'type' => 'apr_uint32_t[16]', + 'name' => 'data' + }, + { + 'type' => 'int', + 'name' => 'local' + } + ] + }, + { + 'type' => 'apr_shm_t', + 'elts' => [] + }, + { + 'type' => 'apr_short_interval_time_t', + 'elts' => [] + }, + { + 'type' => 'apr_shutdown_how_e', + 'elts' => [] + }, + { + 'type' => 'apr_sigfunc_t', + 'elts' => [] + }, + { + 'type' => 'apr_signum_t', + 'elts' => [] + }, + { + 'type' => 'apr_size_t', + 'elts' => [] + }, + { + 'type' => 'apr_sockaddr_t', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'char *', + 'name' => 'hostname' + }, + { + 'type' => 'char *', + 'name' => 'servname' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'family' + }, + { + 'type' => 'apr_socklen_t', + 'name' => 'salen' + }, + { + 'type' => 'int', + 'name' => 'ipaddr_len' + }, + { + 'type' => 'int', + 'name' => 'addr_str_len' + }, + { + 'type' => 'void *', + 'name' => 'ipaddr_ptr' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'next' + }, + { + 'type' => 'union _ANON 1', + 'name' => 'sa' + } + ] + }, + { + 'type' => 'apr_socket_t', + 'elts' => [] + }, + { + 'type' => 'apr_socklen_t', + 'elts' => [] + }, + { + 'type' => 'apr_ssize_t', + 'elts' => [] + }, + { + 'type' => 'apr_status_t', + 'elts' => [] + }, + { + 'type' => 'apr_strmatch_pattern', + 'elts' => [ + { + 'type' => 'const char *(*)(const apr_strmatch_pattern *this_pattern, + const char *s, apr_size_t slen)', + 'name' => 'compare' + }, + { + 'type' => 'const char *', + 'name' => 'pattern' + }, + { + 'type' => 'apr_size_t', + 'name' => 'length' + }, + { + 'type' => 'void *', + 'name' => 'context' + } + ] + }, + { + 'type' => 'apr_table_entry_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'char *', + 'name' => 'val' + }, + { + 'type' => 'apr_uint32_t', + 'name' => 'key_checksum' + } + ] + }, + { + 'type' => 'apr_table_t', + 'elts' => [] + }, + { + 'type' => 'apr_text', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'text' + }, + { + 'type' => 'apr_text *', + 'name' => 'next' + } + ] + }, + { + 'type' => 'apr_text_header', + 'elts' => [ + { + 'type' => 'apr_text *', + 'name' => 'first' + }, + { + 'type' => 'apr_text *', + 'name' => 'last' + } + ] + }, + { + 'type' => 'apr_thread_cond_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_mutex_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_once_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_pool_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_rwlock_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_start_t', + 'elts' => [] + }, + { + 'type' => 'apr_thread_t', + 'elts' => [] + }, + { + 'type' => 'apr_threadattr_t', + 'elts' => [] + }, + { + 'type' => 'apr_threadkey_t', + 'elts' => [] + }, + { + 'type' => 'apr_time_exp_t', + 'elts' => [ + { + 'type' => 'apr_int32_t', + 'name' => 'tm_usec' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_sec' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_min' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_hour' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_mday' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_mon' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_year' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_wday' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_yday' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_isdst' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'tm_gmtoff' + } + ] + }, + { + 'type' => 'apr_time_t', + 'elts' => [] + }, + { + 'type' => 'apr_uid_t', + 'elts' => [] + }, + { + 'type' => 'apr_uint16_t', + 'elts' => [] + }, + { + 'type' => 'apr_uint32_t', + 'elts' => [] + }, + { + 'type' => 'apr_uint64_t', + 'elts' => [] + }, + { + 'type' => 'apr_uintptr_t', + 'elts' => [] + }, + { + 'type' => 'apr_uri_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'scheme' + }, + { + 'type' => 'char *', + 'name' => 'hostinfo' + }, + { + 'type' => 'char *', + 'name' => 'user' + }, + { + 'type' => 'char *', + 'name' => 'password' + }, + { + 'type' => 'char *', + 'name' => 'hostname' + }, + { + 'type' => 'char *', + 'name' => 'port_str' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'char *', + 'name' => 'query' + }, + { + 'type' => 'char *', + 'name' => 'fragment' + }, + { + 'type' => 'hostent *', + 'name' => 'hostent' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'unsigned', + 'name' => 'is_initialized' + }, + { + 'type' => 'unsigned', + 'name' => 'dns_looked_up' + }, + { + 'type' => 'unsigned', + 'name' => 'dns_resolved' + } + ] + }, + { + 'type' => 'apr_uuid_t', + 'elts' => [ + { + 'type' => 'unsigned char[16]', + 'name' => 'data' + } + ] + }, + { + 'type' => 'apr_version_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'major' + }, + { + 'type' => 'int', + 'name' => 'minor' + }, + { + 'type' => 'int', + 'name' => 'patch' + }, + { + 'type' => 'int', + 'name' => 'is_dev' + } + ] + }, + { + 'type' => 'apr_vformatter_buff_t', + 'elts' => [ + { + 'type' => 'char *', + 'name' => 'curpos' + }, + { + 'type' => 'char *', + 'name' => 'endpos' + } + ] + }, + { + 'type' => 'apr_wait_how_e', + 'elts' => [] + }, + { + 'type' => 'apr_xlate_t', + 'elts' => [] + }, + { + 'type' => 'apr_xml_attr', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'ns' + }, + { + 'type' => 'const char *', + 'name' => 'value' + }, + { + 'type' => 'apr_xml_attr *', + 'name' => 'next' + } + ] + }, + { + 'type' => 'apr_xml_doc', + 'elts' => [ + { + 'type' => 'apr_xml_elem *', + 'name' => 'root' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'namespaces' + } + ] + }, + { + 'type' => 'apr_xml_elem', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'ns' + }, + { + 'type' => 'const char *', + 'name' => 'lang' + }, + { + 'type' => 'apr_text_header', + 'name' => 'first_cdata' + }, + { + 'type' => 'apr_text_header', + 'name' => 'following_cdata' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'parent' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'next' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'first_child' + }, + { + 'type' => 'apr_xml_attr *', + 'name' => 'attr' + }, + { + 'type' => 'apr_xml_elem *', + 'name' => 'last_child' + }, + { + 'type' => 'apr_xml_ns_scope *', + 'name' => 'ns_scope' + }, + { + 'type' => 'void *', + 'name' => 'priv' + } + ] + }, + { + 'type' => 'apr_xml_parser', + 'elts' => [] + }, + { + 'type' => 'cmd_parms', + 'elts' => [ + { + 'type' => 'void *', + 'name' => 'info' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'int', + 'name' => 'override_opts' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'override_list' + }, + { + 'type' => 'apr_int64_t', + 'name' => 'limited' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'limited_xmethods' + }, + { + 'type' => 'ap_method_list_t *', + 'name' => 'xlimited' + }, + { + 'type' => 'ap_configfile_t *', + 'name' => 'config_file' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'directive' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'temp_pool' + }, + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'const command_rec *', + 'name' => 'cmd' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'context' + }, + { + 'type' => 'const ap_directive_t *', + 'name' => 'err_directive' + } + ] + }, + { + 'type' => 'command_rec', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'cmd_func', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'cmd_data' + }, + { + 'type' => 'int', + 'name' => 'req_override' + }, + { + 'type' => 'enum cmd_how', + 'name' => 'args_how' + }, + { + 'type' => 'const char *', + 'name' => 'errmsg' + } + ] + }, + { + 'type' => 'conn_rec', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'server_rec *', + 'name' => 'base_server' + }, + { + 'type' => 'void *', + 'name' => 'vhost_lookup_data' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'local_addr' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'client_addr' + }, + { + 'type' => 'char *', + 'name' => 'client_ip' + }, + { + 'type' => 'char *', + 'name' => 'remote_host' + }, + { + 'type' => 'char *', + 'name' => 'remote_logname' + }, + { + 'type' => 'char *', + 'name' => 'local_ip' + }, + { + 'type' => 'char *', + 'name' => 'local_host' + }, + { + 'type' => 'long', + 'name' => 'id' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'conn_config' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'notes' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'input_filters' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'output_filters' + }, + { + 'type' => 'void *', + 'name' => 'sbh' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'bucket_alloc' + }, + { + 'type' => 'conn_state_t *', + 'name' => 'cs' + }, + { + 'type' => 'int', + 'name' => 'data_in_input_filters' + }, + { + 'type' => 'int', + 'name' => 'data_in_output_filters' + }, + { + 'type' => 'unsigned int', + 'name' => 'clogging_input_filters' + }, + { + 'type' => 'signed int', + 'name' => 'double_reverse' + }, + { + 'type' => 'unsigned', + 'name' => 'aborted' + }, + { + 'type' => 'ap_conn_keepalive_e', + 'name' => 'keepalive' + }, + { + 'type' => 'int', + 'name' => 'keepalives' + }, + { + 'type' => 'const struct ap_logconf *', + 'name' => 'log' + }, + { + 'type' => 'const char *', + 'name' => 'log_id' + }, + { + 'type' => 'apr_thread_t *', + 'name' => 'current_thread' + } + ] + }, + { + 'type' => 'core_net_rec', + 'elts' => [] + }, + { + 'type' => 'htaccess_result', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'dir' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'int', + 'name' => 'override_opts' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'override_list' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'htaccess' + }, + { + 'type' => 'const struct htaccess_result *', + 'name' => 'next' + } + ] + }, + { + 'type' => 'modperl_uri_t', + 'elts' => [ + { + 'type' => 'apr_uri_t', + 'name' => 'uri' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'char *', + 'name' => 'path_info' + } + ] + }, + { + 'type' => 'module', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'version' + }, + { + 'type' => 'int', + 'name' => 'minor_version' + }, + { + 'type' => 'int', + 'name' => 'module_index' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'void *', + 'name' => 'dynamic_load_handle' + }, + { + 'type' => 'module_struct *', + 'name' => 'next' + }, + { + 'type' => 'unsigned long', + 'name' => 'magic' + }, + { + 'type' => 'void(*) (process_rec *process)', + 'name' => 'rewrite_args' + }, + { + 'type' => 'void *(*) (apr_pool_t *p, char *dir)', + 'name' => 'create_dir_config' + }, + { + 'type' => 'void *(*) (apr_pool_t *p, void *base_conf, void *new_conf)', + 'name' => 'merge_dir_config' + }, + { + 'type' => 'void *(*) (apr_pool_t *p, server_rec *s)', + 'name' => 'create_server_config' + }, + { + 'type' => 'void *(*) (apr_pool_t *p, void *base_conf, + void *new_conf)', + 'name' => 'merge_server_config' + }, + { + 'type' => 'const command_rec *', + 'name' => 'cmds' + }, + { + 'type' => 'void(*) (apr_pool_t *p)', + 'name' => 'register_hooks' + } + ] + }, + { + 'type' => 'piped_log', + 'elts' => [] + }, + { + 'type' => 'process_rec', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'const char *', + 'name' => 'short_name' + }, + { + 'type' => 'const char * const *', + 'name' => 'argv' + }, + { + 'type' => 'int', + 'name' => 'argc' + } + ] + }, + { + 'type' => 'request_rec', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'conn_rec *', + 'name' => 'connection' + }, + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'request_rec *', + 'name' => 'next' + }, + { + 'type' => 'request_rec *', + 'name' => 'prev' + }, + { + 'type' => 'request_rec *', + 'name' => 'main' + }, + { + 'type' => 'char *', + 'name' => 'the_request' + }, + { + 'type' => 'int', + 'name' => 'assbackwards' + }, + { + 'type' => 'int', + 'name' => 'proxyreq' + }, + { + 'type' => 'int', + 'name' => 'header_only' + }, + { + 'type' => 'int', + 'name' => 'proto_num' + }, + { + 'type' => 'char *', + 'name' => 'protocol' + }, + { + 'type' => 'const char *', + 'name' => 'hostname' + }, + { + 'type' => 'apr_time_t', + 'name' => 'request_time' + }, + { + 'type' => 'const char *', + 'name' => 'status_line' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'int', + 'name' => 'method_number' + }, + { + 'type' => 'const char *', + 'name' => 'method' + }, + { + 'type' => 'apr_int64_t', + 'name' => 'allowed' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'allowed_xmethods' + }, + { + 'type' => 'ap_method_list_t *', + 'name' => 'allowed_methods' + }, + { + 'type' => 'apr_off_t', + 'name' => 'sent_bodyct' + }, + { + 'type' => 'apr_off_t', + 'name' => 'bytes_sent' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + }, + { + 'type' => 'const char *', + 'name' => 'range' + }, + { + 'type' => 'apr_off_t', + 'name' => 'clength' + }, + { + 'type' => 'int', + 'name' => 'chunked' + }, + { + 'type' => 'int', + 'name' => 'read_body' + }, + { + 'type' => 'int', + 'name' => 'read_chunked' + }, + { + 'type' => 'unsigned', + 'name' => 'expecting_100' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'kept_body' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'body_table' + }, + { + 'type' => 'apr_off_t', + 'name' => 'remaining' + }, + { + 'type' => 'apr_off_t', + 'name' => 'read_length' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'headers_in' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'headers_out' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'err_headers_out' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'subprocess_env' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'notes' + }, + { + 'type' => 'const char *', + 'name' => 'content_type' + }, + { + 'type' => 'const char *', + 'name' => 'handler' + }, + { + 'type' => 'const char *', + 'name' => 'content_encoding' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'content_languages' + }, + { + 'type' => 'char *', + 'name' => 'vlist_validator' + }, + { + 'type' => 'char *', + 'name' => 'user' + }, + { + 'type' => 'char *', + 'name' => 'ap_auth_type' + }, + { + 'type' => 'char *', + 'name' => 'unparsed_uri' + }, + { + 'type' => 'char *', + 'name' => 'uri' + }, + { + 'type' => 'char *', + 'name' => 'filename' + }, + { + 'type' => 'char *', + 'name' => 'canonical_filename' + }, + { + 'type' => 'char *', + 'name' => 'path_info' + }, + { + 'type' => 'char *', + 'name' => 'args' + }, + { + 'type' => 'int', + 'name' => 'used_path_info' + }, + { + 'type' => 'int', + 'name' => 'eos_sent' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'per_dir_config' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'request_config' + }, + { + 'type' => 'const struct ap_logconf *', + 'name' => 'log' + }, + { + 'type' => 'const char *', + 'name' => 'log_id' + }, + { + 'type' => 'const struct htaccess_result *', + 'name' => 'htaccess' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'output_filters' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'input_filters' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'proto_output_filters' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'proto_input_filters' + }, + { + 'type' => 'int', + 'name' => 'no_cache' + }, + { + 'type' => 'int', + 'name' => 'no_local_copy' + }, + { + 'type' => 'apr_thread_mutex_t *', + 'name' => 'invoke_mtx' + }, + { + 'type' => 'apr_uri_t', + 'name' => 'parsed_uri' + }, + { + 'type' => 'apr_finfo_t', + 'name' => 'finfo' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'useragent_addr' + }, + { + 'type' => 'char *', + 'name' => 'useragent_ip' + } + ] + }, + { + 'type' => 'server_addr_rec', + 'elts' => [ + { + 'type' => 'server_addr_rec *', + 'name' => 'next' + }, + { + 'type' => 'char *', + 'name' => 'virthost' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'host_addr' + }, + { + 'type' => 'apr_port_t', + 'name' => 'host_port' + } + ] + }, + { + 'type' => 'server_rec', + 'elts' => [ + { + 'type' => 'process_rec *', + 'name' => 'process' + }, + { + 'type' => 'server_rec *', + 'name' => 'next' + }, + { + 'type' => 'char *', + 'name' => 'error_fname' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'error_log' + }, + { + 'type' => 'ap_logconf', + 'name' => 'log' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'module_config' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'lookup_defaults' + }, + { + 'type' => 'const char *', + 'name' => 'defn_name' + }, + { + 'type' => 'unsigned', + 'name' => 'defn_line_number' + }, + { + 'type' => 'char', + 'name' => 'is_virtual' + }, + { + 'type' => 'apr_port_t', + 'name' => 'port' + }, + { + 'type' => 'const char *', + 'name' => 'server_scheme' + }, + { + 'type' => 'char *', + 'name' => 'server_admin' + }, + { + 'type' => 'char *', + 'name' => 'server_hostname' + }, + { + 'type' => 'server_addr_rec *', + 'name' => 'addrs' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'keep_alive_timeout' + }, + { + 'type' => 'int', + 'name' => 'keep_alive_max' + }, + { + 'type' => 'int', + 'name' => 'keep_alive' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'names' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'wild_names' + }, + { + 'type' => 'const char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'pathlen' + }, + { + 'type' => 'int', + 'name' => 'limit_req_line' + }, + { + 'type' => 'int', + 'name' => 'limit_req_fieldsize' + }, + { + 'type' => 'int', + 'name' => 'limit_req_fields' + }, + { + 'type' => 'void *', + 'name' => 'context' + } + ] + }, + { + 'type' => 'session_rec', + 'elts' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_uuid_t *', + 'name' => 'uuid' + }, + { + 'type' => 'const char *', + 'name' => 'remote_user' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'entries' + }, + { + 'type' => 'const char *', + 'name' => 'encoded' + }, + { + 'type' => 'apr_time_t', + 'name' => 'expiry' + }, + { + 'type' => 'long', + 'name' => 'maxage' + }, + { + 'type' => 'int', + 'name' => 'dirty' + }, + { + 'type' => 'int', + 'name' => 'cached' + }, + { + 'type' => 'int', + 'name' => 'written' + } + ] + }, + { + 'type' => 'subrequest_rec', + 'elts' => [] + }, + { + 'type' => 'unixd_config_rec', + 'elts' => [ + { + 'type' => 'const char *', + 'name' => 'user_name' + }, + { + 'type' => 'const char *', + 'name' => 'group_name' + }, + { + 'type' => 'uid_t', + 'name' => 'user_id' + }, + { + 'type' => 'gid_t', + 'name' => 'group_id' + }, + { + 'type' => 'int', + 'name' => 'suexec_enabled' + }, + { + 'type' => 'const char *', + 'name' => 'chroot_dir' + }, + { + 'type' => 'const char *', + 'name' => 'suexec_disabled_reason' + } + ] + }, + { + 'type' => 'modperl_interp_t', + 'elts' => [ + { + 'type' => 'modperl_interp_pool_t *', + 'name' => 'mip' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + }, + { + 'type' => 'int', + 'name' => 'num_requests' + }, + { + 'type' => 'U8', + 'name' => 'flags' + }, + { + 'type' => 'modperl_config_con_t *', + 'name' => 'ccfg' + }, + { + 'type' => 'int', + 'name' => 'refcnt' + }, + { + 'type' => 'unsigned long', + 'name' => 'tid' + } + ] + }, + { + 'type' => 'modperl_interp_pool_t', + 'elts' => [ + { + 'type' => 'server_rec *', + 'name' => 'server' + }, + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'modperl_tipool_config_t *', + 'name' => 'tipool_cfg' + }, + { + 'type' => 'modperl_interp_t *', + 'name' => 'parent' + } + ] + }, + { + 'type' => 'modperl_tipool_t', + 'elts' => [ + { + 'type' => 'perl_mutex', + 'name' => 'tiplock' + }, + { + 'type' => 'perl_cond', + 'name' => 'available' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'idle' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'busy' + }, + { + 'type' => 'int', + 'name' => 'in_use' + }, + { + 'type' => 'int', + 'name' => 'size' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'modperl_tipool_config_t *', + 'name' => 'cfg' + }, + { + 'type' => 'modperl_tipool_vtbl_t *', + 'name' => 'func' + } + ] + }, + { + 'type' => 'modperl_tipool_config_t', + 'elts' => [ + { + 'type' => 'int', + 'name' => 'start' + }, + { + 'type' => 'int', + 'name' => 'min_spare' + }, + { + 'type' => 'int', + 'name' => 'max_spare' + }, + { + 'type' => 'int', + 'name' => 'max' + }, + { + 'type' => 'int', + 'name' => 'max_requests' + } + ] + } +]; + + +1;
diff --git a/2_0_13/xs/tables/current24/ModPerl/FunctionTable.pm b/2_0_13/xs/tables/current24/ModPerl/FunctionTable.pm new file mode 100644 index 0000000..9449ee3 --- /dev/null +++ b/2_0_13/xs/tables/current24/ModPerl/FunctionTable.pm
@@ -0,0 +1,8580 @@ +package ModPerl::FunctionTable; + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! WARNING: generated by ModPerl::ParseSource/0.01 +# ! Mon Jul 1 12:38:19 2013 +# ! do NOT edit, any changes will be lost ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +$ModPerl::FunctionTable = [ + { + 'return_type' => 'int', + 'name' => 'modperl_access_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_apr_array_header2avrv', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_array_header_t *', + 'name' => 'array' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_authen_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_authz_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_array_header_t *', + 'name' => 'modperl_avrv2apr_array_header', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'SV *', + 'name' => 'avrv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_brigade_dump', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'apr_file_t *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'modperl_bucket_sv_create', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'handler' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'AV *', + 'name' => 'args' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_connection', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_files', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_per_dir', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_per_srv', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_pre_connection', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'void *', + 'name' => 'csd' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_callback_process', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_callback_run_handlers', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'modperl_hook_run_mode_e', + 'name' => 'run_mode' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_cgi_header_parse', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + }, + { + 'type' => 'const char **', + 'name' => 'body' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_child_init_handler', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'modperl_cleanup_data_t *', + 'name' => 'modperl_cleanup_data_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_END', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_access_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_add_var', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg1' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_authen_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_authn_provider', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg1' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_authz_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_authz_provider', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg1' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_child_exit_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_child_init_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_cleanup_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_config_requires', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_fixup_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_header_parser_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_init_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_input_filter_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_max', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_max_requests', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_max_spare', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_min_spare', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_interp_start', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_load_module', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_log_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_map_to_storage_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_modules', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_open_logs_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_options', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_output_filter_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_pass_env', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_perl', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_perldo', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_pod', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_pod_cut', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_post_config_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_post_config_requires', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_post_read_request_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_pre_connection_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_process_connection_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_cmd_push_filter_handlers', + 'args' => [ + { + 'type' => 'MpAV **', + 'name' => 'handlers' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_cmd_push_handlers', + 'args' => [ + { + 'type' => 'MpAV **', + 'name' => 'handlers' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_requires', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_response_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_set_env', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg1' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_set_input_filter', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_set_output_filter', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_set_var', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg1' + }, + { + 'type' => 'const char *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_switches', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_trace', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'mconfig' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_trans_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_cmd_type_handlers', + 'args' => [ + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'void *', + 'name' => 'dummy' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'U16 *', + 'name' => 'modperl_code_attrs', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'CV *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_config_apply_PerlModule', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_config_apply_PerlPostConfigRequire', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_config_apply_PerlRequire', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'modperl_config_con_t *', + 'name' => 'modperl_config_con_new', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_config_dir_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'char *', + 'name' => 'dir' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_config_dir_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'basev' + }, + { + 'type' => 'void *', + 'name' => 'addv' + } + ] + }, + { + 'return_type' => 'modperl_config_dir_t *', + 'name' => 'modperl_config_dir_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_config_insert', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptmp' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'override_options' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'conf' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_config_insert_parms', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_config_insert_request', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'override_options' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_config_insert_server', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_config_is_perl_option_enabled', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_config_req_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'modperl_config_req_t *', + 'name' => 'modperl_config_req_new', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_config_request_cleanup', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'char **', + 'name' => 'modperl_config_srv_argv_init', + 'args' => [ + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'int *', + 'name' => 'argc' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_config_srv_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_config_srv_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'basev' + }, + { + 'type' => 'void *', + 'name' => 'addv' + } + ] + }, + { + 'return_type' => 'modperl_config_srv_t *', + 'name' => 'modperl_config_srv_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_const_compile', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'const char *', + 'name' => 'arg' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char **', + 'name' => 'modperl_constants_group_lookup_apache2_const', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char **', + 'name' => 'modperl_constants_group_lookup_apr_const', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char **', + 'name' => 'modperl_constants_group_lookup_modperl', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_constants_lookup_apache2_const', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_constants_lookup_apr_const', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_constants_lookup_modperl', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_croak', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + }, + { + 'type' => 'const char*', + 'name' => 'func' + } + ] + }, + { + 'return_type' => 'unsigned long', + 'name' => 'modperl_debug_level', + 'args' => [] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_dir_config', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'sv_val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_clear', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_configure_request_dir', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_configure_request_srv', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_configure_server', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_default_populate', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_hash_keys', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_hv_store', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_init', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_request_populate', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_request_tie', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_request_unpopulate', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_request_untie', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_sync_dir_env_hash2table', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_config_dir_t *', + 'name' => 'dcfg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_sync_srv_env_hash2table', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_env_unload', + 'args' => [] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_error_strerror', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_status_t', + 'name' => 'rc' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_errsv', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'int', + 'name' => 'status' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_errsv_prepend', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'pat' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_file2package', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'file' + } + ] + }, + { + 'return_type' => 'U16 *', + 'name' => 'modperl_filter_attributes', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'package' + }, + { + 'type' => 'SV *', + 'name' => 'cvrv' + } + ] + }, + { + 'return_type' => 'modperl_filter_t *', + 'name' => 'modperl_filter_mg_get', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'obj' + } + ] + }, + { + 'return_type' => 'modperl_filter_t *', + 'name' => 'modperl_filter_new', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'modperl_filter_mode_e', + 'name' => 'mode' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'input_mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_filter_resolve_init_handler', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'handler' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_filter_runtime_add', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'modperl_filter_mode_e', + 'name' => 'mode' + }, + { + 'type' => 'modperl_filter_add_t', + 'name' => 'addfunc' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + }, + { + 'type' => 'const char *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_fixup_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'U32', + 'name' => 'modperl_flags_lookup_dir', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'U32', + 'name' => 'modperl_flags_lookup_srv', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_get_perl_module_config', + 'args' => [ + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_anon_cnt_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_global_anon_cnt_next', + 'args' => [] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_global_get', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'modperl_global_get_pconf', + 'args' => [] + }, + { + 'return_type' => 'server_rec *', + 'name' => 'modperl_global_get_server_rec', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_init', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_init_pconf', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_init_server_rec', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec * server_rec', + 'name' => 'arg1' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_lock', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_lock_pconf', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_lock_server_rec', + 'args' => [] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'modperl_global_request', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'svr' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_request_cfg_set', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_request_obj_set', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'svr' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_request_set', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_set', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_set_pconf', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_set_server_rec', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'arg0' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_unlock', + 'args' => [ + { + 'type' => 'modperl_global_t *', + 'name' => 'global' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_unlock_pconf', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_global_unlock_server_rec', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_handler_anon_add', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'anon' + }, + { + 'type' => 'CV *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'CV *', + 'name' => 'modperl_handler_anon_get', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'anon' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_handler_anon_init', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'modperl_mgv_t *', + 'name' => 'modperl_handler_anon_next', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'MpAV *', + 'name' => 'modperl_handler_array_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'MpAV *', + 'name' => 'base_a' + }, + { + 'type' => 'MpAV *', + 'name' => 'add_a' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_connection', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_files', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_per_dir', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_per_srv', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_pre_connection', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_desc_process', + 'args' => [ + { + 'type' => 'int', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'modperl_handler_t *', + 'name' => 'modperl_handler_dup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'h' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_equal', + 'args' => [ + { + 'type' => 'modperl_handler_t *', + 'name' => 'h1' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'h2' + } + ] + }, + { + 'return_type' => 'MpAV **', + 'name' => 'modperl_handler_get_handlers', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'modperl_handler_action_e', + 'name' => 'action' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_lookup', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'MpAV **', + 'name' => 'modperl_handler_lookup_handlers', + 'args' => [ + { + 'type' => 'modperl_config_dir_t *', + 'name' => 'dcfg' + }, + { + 'type' => 'modperl_config_srv_t *', + 'name' => 'scfg' + }, + { + 'type' => 'modperl_config_req_t *', + 'name' => 'rcfg' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'int', + 'name' => 'idx' + }, + { + 'type' => 'modperl_handler_action_e', + 'name' => 'action' + }, + { + 'type' => 'const char **', + 'name' => 'desc' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_handler_make_args', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'AV **', + 'name' => 'avp' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_handler_name', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_handler_t *', + 'name' => 'handler' + } + ] + }, + { + 'return_type' => 'modperl_handler_t *', + 'name' => 'modperl_handler_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'modperl_handler_t *', + 'name' => 'modperl_handler_new_from_sv', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_perl_add_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'modperl_handler_action_e', + 'name' => 'action' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_handler_perl_get_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'MpAV **', + 'name' => 'handp' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_push_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'MpAV *', + 'name' => 'handlers' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_handler_resolve', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_handler_t **', + 'name' => 'handp' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_hash_seed_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_hash_seed_set', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_hash_tie', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + }, + { + 'type' => 'void *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_hash_tied_object', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_hash_tied_object_rv', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_header_parser_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_hook_init', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_hook_pre_config', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_init', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_init_globals', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_init_vhost', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 'base_server' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_input_filter_add_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_input_filter_add_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_input_filter_flush', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_input_filter_handler', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'input_mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'modperl_input_filter_read', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'wanted' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_input_filter_write', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_interp_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_clone_init', + 'args' => [ + { + 'type' => 'modperl_interp_t *', + 'name' => 'interp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_destroy', + 'args' => [ + { + 'type' => 'modperl_interp_t *', + 'name' => 'interp' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_get', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_init', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_mip_walk', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'current_perl' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'parent_perl' + }, + { + 'type' => 'modperl_interp_pool_t *', + 'name' => 'mip' + }, + { + 'type' => 'modperl_interp_mip_walker_t', + 'name' => 'walker' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_mip_walk_servers', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'current_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 'base_server' + }, + { + 'type' => 'modperl_interp_mip_walker_t', + 'name' => 'walker' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_new', + 'args' => [ + { + 'type' => 'modperl_interp_pool_t *', + 'name' => 'mip' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_interp_pool_destroy', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_pool_get', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_pool_select', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_interp_pool_set', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_interp_t *', + 'name' => 'interp' + }, + { + 'type' => 'int', + 'name' => 'cleanup' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_interp_select', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_interp_unselect', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_apache_init', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_handle_tie', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + }, + { + 'type' => 'char *', + 'name' => 'classname' + }, + { + 'type' => 'void *', + 'name' => 'ptr' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_io_handle_tied', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + }, + { + 'type' => 'char *', + 'name' => 'classname' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_handle_untie', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_io_perlio_override_stdin', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_io_perlio_override_stdout', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_perlio_restore_stdin', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_io_perlio_restore_stdout', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'GV *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_io_tie_stdin', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_io_tie_stdout', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_is_running', + 'args' => [] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_append', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'new_list' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_first', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_last', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_new', + 'args' => [] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_prepend', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'new_list' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_remove', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'rlist' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_list_remove_data', + 'args' => [ + { + 'type' => 'modperl_list_t *', + 'name' => 'list' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'modperl_list_t **', + 'name' => 'listp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_log_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_map_to_storage_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_mgv_append', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_mgv_as_string', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'modperl_mgv_t *', + 'name' => 'modperl_mgv_compile', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_mgv_equal', + 'args' => [ + { + 'type' => 'modperl_mgv_t *', + 'name' => 'mgv1' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'mgv2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_mgv_hash_handlers', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'modperl_mgv_t *', + 'name' => 'modperl_mgv_last', + 'args' => [ + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_mgv_last_name', + 'args' => [ + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_mgv_lookup', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + } + ] + }, + { + 'return_type' => 'GV *', + 'name' => 'modperl_mgv_lookup_autoload', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'modperl_mgv_t *', + 'name' => 'modperl_mgv_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_mgv_require_module', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_mgv_t *', + 'name' => 'symbol' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_mgv_resolve', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_handler_t *', + 'name' => 'handler' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'int', + 'name' => 'logfailure' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_modglobal_hash_keys', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'modperl_modglobal_key_t *', + 'name' => 'modperl_modglobal_lookup', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_module_add', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'mod_cmds' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_module_config_get_obj', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'pmodule' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'v' + } + ] + }, + { + 'return_type' => 'PTR_TBL_t *', + 'name' => 'modperl_module_config_table_get', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'int', + 'name' => 'create' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_module_config_table_set', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'table' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_newSVsv_obj', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'stashsv' + }, + { + 'type' => 'SV *', + 'name' => 'obj' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_open_logs_handler', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'modperl_options_t *', + 'name' => 'modperl_options_merge', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_options_t *', + 'name' => 'base' + }, + { + 'type' => 'modperl_options_t *new', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'modperl_options_t *', + 'name' => 'modperl_options_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'modperl_options_set', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_options_t *', + 'name' => 'o' + }, + { + 'type' => 'const char *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_output_filter_add_connection', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_output_filter_add_request', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_output_filter_flush', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_output_filter_handler', + 'args' => [ + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'modperl_output_filter_read', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'wanted' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_output_filter_write', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_package_unload', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_av_push_elts_ref', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'AV *', + 'name' => 'dst' + }, + { + 'type' => 'AV *', + 'name' => 'src' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_call_endav', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_call_list', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'AV *', + 'name' => 'subs' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_core_global_init', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_destruct', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'perl' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_perl_destruct_level', + 'args' => [] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_do_join', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_do_sprintf', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'I32', + 'name' => 'len' + }, + { + 'type' => 'SV **', + 'name' => 'sarg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_exit', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'int', + 'name' => 'status' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_gensym', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'pack' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_avcv_call', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_modglobal_key_t *', + 'name' => 'gkey' + }, + { + 'type' => 'const char *', + 'name' => 'package' + }, + { + 'type' => 'I32', + 'name' => 'packlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_avcv_clear', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_modglobal_key_t *', + 'name' => 'gkey' + }, + { + 'type' => 'const char *', + 'name' => 'package' + }, + { + 'type' => 'I32', + 'name' => 'packlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_avcv_register', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_modglobal_key_t *', + 'name' => 'gkey' + }, + { + 'type' => 'const char *', + 'name' => 'package' + }, + { + 'type' => 'I32', + 'name' => 'packlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_request_restore', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_global_request_save', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'HE *', + 'name' => 'modperl_perl_hv_fetch_he', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'HV *', + 'name' => 'hv' + }, + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'I32', + 'name' => 'klen' + }, + { + 'type' => 'U32', + 'name' => 'hash' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_init_ids_server', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_perl_module_loaded', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_pp_set', + 'args' => [ + { + 'type' => 'modperl_perl_opcode_e', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_pp_set_all', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_pp_unset', + 'args' => [ + { + 'type' => 'modperl_perl_opcode_e', + 'name' => 'idx' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_perl_pp_unset_all', + 'args' => [] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_perl_sv_setref_uv', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'rv' + }, + { + 'type' => 'const char *', + 'name' => 'classname' + }, + { + 'type' => 'UV', + 'name' => 'uv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_pnotes', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'HV **', + 'name' => 'pnotes' + }, + { + 'type' => 'SV *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'val' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_pnotes_kill', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'cl_data' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_post_config_handler', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pconf' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'plog' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'ptemp' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_post_post_config_phase', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_post_read_request_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_pre_connection_handler', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'void *', + 'name' => 'csd' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_process_connection_handler', + 'args' => [ + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_ptr2obj', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'classname' + }, + { + 'type' => 'void *', + 'name' => 'ptr' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_register_auth_provider', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_name' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + }, + { + 'type' => 'SV *', + 'name' => 'callback1' + }, + { + 'type' => 'SV *', + 'name' => 'callback2' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_register_auth_provider_name', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'const char *', + 'name' => 'provider_group' + }, + { + 'type' => 'const char *', + 'name' => 'provider_name' + }, + { + 'type' => 'const char *', + 'name' => 'provider_version' + }, + { + 'type' => 'const char *', + 'name' => 'callback1' + }, + { + 'type' => 'const char *', + 'name' => 'callback2' + }, + { + 'type' => 'int', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_register_handler_hooks', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_register_hooks', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'ssize_t', + 'name' => 'modperl_request_read', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'buffer' + }, + { + 'type' => 'size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_require_file', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'pv' + }, + { + 'type' => 'int', + 'name' => 'logfailure' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_require_module', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'pv' + }, + { + 'type' => 'int', + 'name' => 'logfailure' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_response_finish', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_response_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_response_handler_cgi', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_response_init', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_restart_count', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_restart_count_inc', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 'base_server' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_run', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_run_filter', + 'args' => [ + { + 'type' => 'modperl_filter_t *', + 'name' => 'filter' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'modperl_server_desc', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'modperl_server_pool', + 'args' => [] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'modperl_server_user_pool', + 'args' => [] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_set_perl_module_config', + 'args' => [ + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'cv' + }, + { + 'type' => 'void *', + 'name' => 'cfg' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_slurp_filename', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'int', + 'name' => 'tainted' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_spawn_proc_prog', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'command' + }, + { + 'type' => 'const char ***', + 'name' => 'argv' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'script_in' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'script_out' + }, + { + 'type' => 'apr_file_t **', + 'name' => 'script_err' + } + ] + }, + { + 'return_type' => 'PerlInterpreter *', + 'name' => 'modperl_startup', + 'args' => [ + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_str_toupper', + 'args' => [ + { + 'type' => 'char *', + 'name' => 'str' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'modperl_sv2request_rec', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'server_rec *', + 'name' => 'modperl_sv2server_rec', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_clear', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + } + ] + }, + { + 'return_type' => 'PTR_TBL_t *', + 'name' => 'modperl_svptr_table_clone', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PerlInterpreter *', + 'name' => 'proto_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'source' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_delete', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + }, + { + 'type' => 'void *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_destroy', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + } + ] + }, + { + 'return_type' => 'void *', + 'name' => 'modperl_svptr_table_fetch', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + }, + { + 'type' => 'void *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_free', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + } + ] + }, + { + 'return_type' => 'PTR_TBL_t *', + 'name' => 'modperl_svptr_table_new', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_split', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_svptr_table_store', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'PTR_TBL_t *', + 'name' => 'tbl' + }, + { + 'type' => 'void *', + 'name' => 'oldv' + }, + { + 'type' => 'void *', + 'name' => 'newv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_sys_dlclose', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'handle' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_sys_is_dir', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'modperl_table_get_set', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'table' + }, + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'sv_val' + }, + { + 'type' => 'int', + 'name' => 'do_taint' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_threaded_mpm', + 'args' => [] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_threads_started', + 'args' => [] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'modperl_thx_interp_get', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'thx' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_thx_interp_set', + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'thx' + }, + { + 'type' => 'modperl_interp_t *', + 'name' => 'interp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_add', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_destroy', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_init', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + } + ] + }, + { + 'return_type' => 'modperl_tipool_t *', + 'name' => 'modperl_tipool_new', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_tipool_config_t *', + 'name' => 'cfg' + }, + { + 'type' => 'void *', + 'name' => 'func' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'modperl_list_t *', + 'name' => 'modperl_tipool_pop', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_putback', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'listp' + }, + { + 'type' => 'int', + 'name' => 'num_requests' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_putback_data', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'int', + 'name' => 'num_requests' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tipool_remove', + 'args' => [ + { + 'type' => 'modperl_tipool_t *', + 'name' => 'tipool' + }, + { + 'type' => 'modperl_list_t *', + 'name' => 'listp' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_create', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_tls_t **', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_create_request_rec', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_get', + 'args' => [ + { + 'type' => 'modperl_tls_t *', + 'name' => 'key' + }, + { + 'type' => 'void **', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_get_request_rec', + 'args' => [ + { + 'type' => 'request_rec * *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tls_reset_cleanup', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'modperl_tls_t *', + 'name' => 'key' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_tls_reset_cleanup_request_rec', + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'request_rec *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_set', + 'args' => [ + { + 'type' => 'modperl_tls_t *', + 'name' => 'key' + }, + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_tls_set_request_rec', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace', + 'args' => [ + { + 'type' => 'const char *', + 'name' => 'func' + }, + { + 'type' => 'const char *', + 'name' => 'fmt' + }, + { + 'type' => '...', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace_level_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'logfile' + }, + { + 'type' => 'const char *', + 'name' => 'level' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_trace_logfile_set', + 'args' => [ + { + 'type' => 'apr_file_t *', + 'name' => 'logfile_new' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_trans_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'modperl_type_handler', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'modperl_uri_t *', + 'name' => 'modperl_uri_new', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_wbucket_flush', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_wbucket_t *', + 'name' => 'b' + }, + { + 'type' => 'int', + 'name' => 'add_flush_bucket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_wbucket_pass', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'modperl_wbucket_t *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'int', + 'name' => 'add_flush_bucket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'modperl_wbucket_write', + 'attr' => [ + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'modperl_wbucket_t *', + 'name' => 'b' + }, + { + 'type' => 'const char *', + 'name' => 'buf' + }, + { + 'type' => 'apr_size_t *', + 'name' => 'wlen' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_xs_dl_handles_clear', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'modperl_xs_dl_handles_close', + 'args' => [ + { + 'type' => 'void **', + 'name' => 'handles' + } + ] + }, + { + 'return_type' => 'void **', + 'name' => 'modperl_xs_dl_handles_get', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'modperl_xs_sv2request_rec', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'char *', + 'name' => 'classname' + }, + { + 'type' => 'CV *', + 'name' => 'cv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_cleanup', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_concat', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_destroy', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Brigade_first', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_APR__Brigade_flatten', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_insert_head', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Brigade_insert_tail', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Brigade_is_empty', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Brigade_last', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Brigade_length', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'int', + 'name' => 'read_all' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Brigade_next', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'apr_pool_t *', + 'name' => 'mpxs_APR__Brigade_pool', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Brigade_prev', + 'args' => [ + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__BucketAlloc_new', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'CLASS' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Bucket_insert_after', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Bucket_insert_before', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'a' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'b' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Bucket_is_eos', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Bucket_is_flush', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'apr_bucket *', + 'name' => 'mpxs_APR__Bucket_new', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'list' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_APR__Bucket_read', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Bucket_remove', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_bucket *', + 'name' => 'bucket' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_APR__Bucket_setaside', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'b_sv' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Finfo_stat', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'fname' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'wanted' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'unsigned long', + 'name' => 'mpxs_APR__OS_current_thread_id', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Pool_clear', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'obj' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Socket_fileno', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + } + ] + }, + { + 'return_type' => 'apr_int32_t', + 'name' => 'mpxs_APR__Socket_opt_get', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Socket_opt_set', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'opt' + }, + { + 'type' => 'apr_int32_t', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_APR__Socket_poll', + 'args' => [ + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'pool' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 'timeout' + }, + { + 'type' => 'apr_int16_t', + 'name' => 'reqevents' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_APR__Socket_recv', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_APR__Socket_timeout_set', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'apr_interval_time_t', + 'name' => 't' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__String_strfsize', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_off_t', + 'name' => 'size' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_APR__Table_EXISTS', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'apr_table_t *', + 'name' => 't' + }, + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_APR__Table_FETCH', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + }, + { + 'type' => 'const char *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_APR__Table_NEXTKEY', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'tsv' + }, + { + 'type' => 'SV *', + 'name' => 'key' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Table_copy', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'base' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Table_make', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'int', + 'name' => 'nelts' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__Table_overlay', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'base' + }, + { + 'type' => 'apr_table_t *', + 'name' => 'overlay' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'mpxs_APR__URI_port', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'uri' + }, + { + 'type' => 'SV *', + 'name' => 'portsv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_APR__URI_rpath', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'apr_uri' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__CmdParms_add_config', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__CmdParms_info', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__CmdParms_override_opts', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'cmd_parms *', + 'name' => 'parms' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Connection_add_input_filter', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Connection_add_output_filter', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + } + ] + }, + { + 'return_type' => 'apr_socket_t *', + 'name' => 'mpxs_Apache2__Connection_client_socket', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 's' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__Connection_get_remote_host', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'int', + 'name' => 'type' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'dir_config' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Connection_pnotes', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'SV *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Connection_pnotes_kill', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Directive_as_hash', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'tree' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Directive_as_string', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_directive_t *', + 'name' => 'self' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Filter_ctx', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'SV *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_Apache2__Filter_fflush', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'filter' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'brigade' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_Apache2__Filter_get_brigade', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + }, + { + 'type' => 'ap_input_mode_t', + 'name' => 'mode' + }, + { + 'type' => 'apr_read_type_e', + 'name' => 'block' + }, + { + 'type' => 'apr_off_t', + 'name' => 'readbytes' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_Apache2__Filter_pass_brigade', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'ap_filter_t *', + 'name' => 'f' + }, + { + 'type' => 'apr_bucket_brigade *', + 'name' => 'bb' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_Apache2__Filter_print', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_Apache2__Filter_read', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Filter_remove', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Filter_seen_eos', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Log_BOOT', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Log_log', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'int', + 'name' => 'logtype' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__MPM_BOOT', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__MPM_query', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'self' + }, + { + 'type' => 'int', + 'name' => 'query_code' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__Module_add', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'package' + }, + { + 'type' => 'SV *', + 'name' => 'cmds' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__Module_ap_api_major_version', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'module *', + 'name' => 'mod' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__Module_ap_api_minor_version', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'module *', + 'name' => 'mod' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__Module_get_config', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'pmodule' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'ap_conf_vector_t *', + 'name' => 'v' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__Module_loaded', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_FILENO', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_GETC', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_OPEN', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'self' + }, + { + 'type' => 'SV *', + 'name' => 'arg1' + }, + { + 'type' => 'SV *', + 'name' => 'arg2' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_add_config', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + }, + { + 'type' => 'int', + 'name' => 'override' + }, + { + 'type' => 'char *', + 'name' => 'path' + }, + { + 'type' => 'int', + 'name' => 'override_options' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_add_input_filter', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_add_output_filter', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'callback' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_allow_override_opts', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_as_string', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_auth_name', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_auth_type', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_child_terminate', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_content_languages', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'languages' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_content_type', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'type' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_document_root', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'new_root' + } + ] + }, + { + 'return_type' => 'apr_finfo_t *', + 'name' => 'mpxs_Apache2__RequestRec_finfo', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_finfo_t *', + 'name' => 'finfo' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_get_handlers', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'const char *', + 'name' => 'mpxs_Apache2__RequestRec_handler', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_is_perl_option_enabled', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'mpxs_Apache2__RequestRec_location', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_location_merge', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'location' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_new', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'conn_rec *', + 'name' => 'c' + }, + { + 'type' => 'SV *', + 'name' => 'base_pool_sv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_no_cache', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'flag' + } + ] + }, + { + 'return_type' => 'apr_uri_t *', + 'name' => 'mpxs_Apache2__RequestRec_parsed_uri', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_pnotes', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_pnotes_kill', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_print', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_proxyreq', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_push_handlers', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_read', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_rflush', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_Apache2__RequestRec_sendfile', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'filename' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__RequestRec_set_basic_credentials', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'username' + }, + { + 'type' => 'char *', + 'name' => 'password' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__RequestRec_set_handlers', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => '', + 'name' => 'mpxs_Apache2__RequestRec_set_last_modified', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'apr_time_t', + 'name' => 'mtime' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__RequestRec_subprocess_env', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'key' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_Apache2__RequestRec_write', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'apr_size_t', + 'name' => 'len' + }, + { + 'type' => 'apr_off_t', + 'name' => 'offset' + } + ] + }, + { + 'return_type' => 'request_rec *', + 'name' => 'mpxs_Apache2__RequestUtil_request', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'svr' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__ServerRec_add_config', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'SV *', + 'name' => 'lines' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_Apache2__ServerRec_get_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__ServerRec_is_perl_option_enabled', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__ServerRec_is_virtual', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'SV *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__ServerRec_loglevel', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'int', + 'name' => 'loglevel' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__ServerRec_push_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_Apache2__ServerRec_set_handlers', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'server_rec *', + 'name' => 's' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__ServerUtil_BOOT', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_Apache2__ServerUtil_server_shutdown_cleanup_register', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'cv' + }, + { + 'type' => 'SV *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_ModPerl__Global_special_list_call', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_ModPerl__Global_special_list_clear', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_ModPerl__Global_special_list_register', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'package' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_ModPerl__Util_untaint', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_ap_allow_methods', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'long', + 'name' => 'mpxs_ap_get_client_block', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'SV *', + 'name' => 'buffer' + }, + { + 'type' => 'int', + 'name' => 'bufsiz' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_ap_log_error', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'int', + 'name' => 'level' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'SV *', + 'name' => 'msg' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_ap_register_auth_provider', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_ap_requires', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_ap_rprintf', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_ap_run_sub_req', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_ap_rvputs', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'mpxs_ap_unescape_url', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'url' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_apr_base64_decode', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'SV *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_apr_base64_encode', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'sv' + }, + { + 'type' => 'SV *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_brigade_create', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'CLASS' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'apr_bucket_alloc_t *', + 'name' => 'ba' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_ipsubnet_create', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'const char *', + 'name' => 'ipstr' + }, + { + 'type' => 'const char *', + 'name' => 'mask_or_numbits' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_apr_password_validate', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'passwd' + }, + { + 'type' => 'const char *', + 'name' => 'hash' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_apr_pool_DESTROY', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'obj' + } + ] + }, + { + 'return_type' => '', + 'name' => 'mpxs_apr_pool_cleanup', + 'args' => [ + { + 'type' => 'void *', + 'name' => 'cleanup_data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_apr_pool_cleanup_register', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'p' + }, + { + 'type' => 'SV *', + 'name' => 'cv' + }, + { + 'type' => 'SV *', + 'name' => 'arg' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_pool_create', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'parent_pool_obj' + } + ] + }, + { + 'return_type' => '', + 'name' => 'mpxs_apr_pool_parent_get', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_pool_t *', + 'name' => 'child_pool' + } + ] + }, + { + 'return_type' => '', + 'name' => 'mpxs_apr_sockaddr_ip_get', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_sockaddr_t *', + 'name' => 'sockaddr' + } + ] + }, + { + 'return_type' => 'apr_size_t', + 'name' => 'mpxs_apr_socket_send', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_socket_t *', + 'name' => 'socket' + }, + { + 'type' => 'SV *', + 'name' => 'sv_buf' + }, + { + 'type' => 'SV *', + 'name' => 'sv_len' + } + ] + }, + { + 'return_type' => 'apr_interval_time_t', + 'name' => 'mpxs_apr_socket_timeout_get', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_apr_table_do', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'I32', + 'name' => 'items' + }, + { + 'type' => 'SV **', + 'name' => 'mark' + }, + { + 'type' => 'SV **', + 'name' => 'sp' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_apr_table_do_cb', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + }, + { + 'type' => 'const char *', + 'name' => 'key' + }, + { + 'type' => 'const char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_thread_mutex_create', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'unsigned int', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_thread_rwlock_create', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + } + ] + }, + { + 'return_type' => 'SV *', + 'name' => 'mpxs_apr_uri_parse', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'classname' + }, + { + 'type' => 'SV *', + 'name' => 'p_sv' + }, + { + 'type' => 'const char *', + 'name' => 'uri_string' + } + ] + }, + { + 'return_type' => 'char *', + 'name' => 'mpxs_apr_uri_unparse', + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'apr_uri_t *', + 'name' => 'uptr' + }, + { + 'type' => 'unsigned', + 'name' => 'flags' + } + ] + }, + { + 'return_type' => 'apr_uuid_t *', + 'name' => 'mpxs_apr_uuid_get', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'CLASS' + } + ] + }, + { + 'return_type' => 'apr_uuid_t *', + 'name' => 'mpxs_apr_uuid_parse', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'CLASS' + }, + { + 'type' => 'char *', + 'name' => 'buf' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_cleanup_run', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'void *', + 'name' => 'data' + } + ] + }, + { + 'return_type' => 'void', + 'name' => 'mpxs_insert_auth_cfg', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'request_rec *', + 'name' => 'r' + }, + { + 'type' => 'char *', + 'name' => 'directive' + }, + { + 'type' => 'char *', + 'name' => 'val' + } + ] + }, + { + 'return_type' => 'apr_status_t', + 'name' => 'mpxs_setup_client_block', + 'args' => [ + { + 'type' => 'request_rec *', + 'name' => 'r' + } + ] + }, + { + 'return_type' => 'int', + 'name' => 'mpxs_special_list_do', + 'attr' => [ + 'static' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter*', + 'name' => 'my_perl' + }, + { + 'type' => 'const char *', + 'name' => 'name' + }, + { + 'type' => 'SV *', + 'name' => 'package' + }, + { + 'type' => 'mpxs_special_list_do_t', + 'name' => 'func' + } + ] + }, + { + 'return_type' => 'modperl_interp_t *', + 'name' => 'mpxs_ModPerl__Interpreter_current', + 'attr' => [ + 'static', + '__inline__' + ], + 'args' => [ + { + 'type' => 'PerlInterpreter *', + 'name' => 'my_perl' + }, + { + 'type' => 'SV *', + 'name' => 'class' + } + ] + } +]; + + +1;
diff --git a/2_0_13/xs/typemap b/2_0_13/xs/typemap new file mode 100644 index 0000000..f9a9818 --- /dev/null +++ b/2_0_13/xs/typemap
@@ -0,0 +1,89 @@ +TYPEMAP +void * T_VPTR +char_len * T_CHAR_LEN +const char_len * T_CONST_CHAR_LEN + +###################################################################### +OUTPUT +T_POOLOBJ + sv_setref_pv($arg, \"${ntype}\", (void*)$var); + +T_APACHEOBJ + sv_setref_pv($arg, \"${ntype}\", (void*)$var); + +T_HASHOBJ + $arg = modperl_hash_tie(aTHX_ \"${ntype}\", $arg, $var); + +T_VPTR + sv_setiv($arg, PTR2IV($var)); + +T_UVPTR + sv_setuv($arg, PTR2UV($var)); + +T_APR_TIME + sv_setnv($arg, (NV)(apr_time_sec($var))); + +T_UVOBJ + modperl_perl_sv_setref_uv(aTHX_ $arg, \"${ntype}\", (UV)$var); + +###################################################################### +INPUT +T_PTROBJ + if (SvROK($arg) && sv_derived_from($arg, \"${ntype}\")) { + IV tmp = SvIV((SV*)SvRV($arg)); + $var = INT2PTR($type, tmp); + } + else { + Perl_croak(aTHX_ SvROK($arg) ? + \"$var is not of type ${ntype}\" : + \"$var is not a blessed reference\"); + } + +T_POOLOBJ + if (SvROK($arg) && sv_derived_from($arg, \"${ntype}\")) { + IV tmp = SvIV((SV*)SvRV($arg)); + if (tmp == 0) { + Perl_croak(aTHX_ \"invalid pool object (already destroyed?)\"); + } + $var = INT2PTR($type, tmp); + } + else { + Perl_croak(aTHX_ SvROK($arg) ? + \"$var is not of type ${ntype}\" : + \"$var is not a blessed reference\"); + } + +T_UVOBJ + if (SvROK($arg) && sv_derived_from($arg, \"${ntype}\")) { + UV tmp = SvUV((SV*)SvRV($arg)); + $var = INT2PTR($type, tmp); + } + else { + Perl_croak(aTHX_ SvROK($arg) ? + \"$var is not of type ${ntype}\" : + \"$var is not a blessed reference\"); + } + +T_APACHEOBJ + $var = modperl_xs_sv2request_rec(aTHX_ $arg, \"$ntype\", cv) + +T_HASHOBJ + $var = modperl_hash_tied_object(aTHX_ \"${ntype}\", $arg) + +T_APACHEREF + $var = modperl_xs_sv2request_rec(aTHX_ $arg, \"$ntype\", cv) + +T_VPTR + $var = INT2PTR($type, SvIV(SvROK($arg) ? SvRV($arg) : $arg)) + +T_UVPTR + $var = INT2PTR($type, SvUV(SvROK($arg) ? SvRV($arg) : $arg)) + +T_APR_TIME + $var = (apr_time_t)(apr_time_from_sec(SvNV($arg))) + +T_CHAR_LEN + $var = (char *)SvPV($arg, ${var}_len) + +T_CONST_CHAR_LEN + $var = (const char *)SvPV($arg, ${var}_len)