stas 2003/12/17 13:04:12
Modified: src/docs/2.0/api/Apache compat.pod
src/docs/2.0/user/porting compat.pod
Log:
- document the new overridable mechanism in Apache::compat
- document the four new overridable functions in Apache::compat (2
existed before but now not enabled by default)
- mention the new APR::Finfo class
Revision Changes Path
1.5 +91 -3 modperl-docs/src/docs/2.0/api/Apache/compat.pod
Index: compat.pod
===================================================================
RCS file: /home/cvs/modperl-docs/src/docs/2.0/api/Apache/compat.pod,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -u -r1.4 -r1.5
--- compat.pod 11 Apr 2003 03:20:08 -0000 1.4
+++ compat.pod 17 Dec 2003 21:04:12 -0000 1.5
@@ -1,8 +1,8 @@
-=head1 NAME
+=head1 Name
Apache::compat -- 1.0 backward compatibility functions deprecated in 2.0
-=head1 SYNOPSIS
+=head1 Synopsis
# either add at the very beginning of startup.pl
use Apache2
@@ -11,7 +11,12 @@
PerlModule Apache2
PerlModule Apache::compat
-=head1 DESCRIPTION
+ # override and restore compat functions colliding with mp2 API
+ Apache::compat::override_mp2_api('Apache::Connection::local_addr');
+ my ($local_port, $local_addr) = sockaddr_in($c->local_addr);
+ Apache::compat::restore_mp2_api('Apache::Connection::local_addr');
+
+=head1 Description
C<Apache::compat> provides mod_perl 1.0 compatibility layer and can be
used to smooth the transition process to mod_perl 2.0.
@@ -29,6 +34,89 @@
to L<port your
code|docs::2.0::user::porting::porting> not to use deprecated
functions and stop using the compatibility layer.
+
+
+
+
+
+
+=head1 Compatibility Functions Colliding with mod_perl 2.0 API
+
+Most of the functions provided by Apache::compat don't interfere with
+mod_perl 2.0 API. However there are several functions which have the
+same name in the mod_perl 1.0 and mod_perl 2.0 API, accept the same
+number of arguments, but either the arguments themselves aren't the
+same or the return values are different. For example the mod_perl 1.0
+code:
+
+ require Socket;
+ my $sockaddr_in = $c->local_addr;
+ my ($local_port, $local_addr) = Socket::sockaddr_in($sockaddr_in);
+
+should be adjusted to be:
+
+ require Apache::Connection;
+ require APR::SocketAddr;
+ my $sockaddr = $c->local_addr;
+ my ($local_port, $local_addr) = ($sockaddr->port, $sockaddr->ip_get);
+
+to work under mod_perl 2.0.
+
+As you can see in mod_perl 1.0 API local_addr() was returning a
+SOCKADDR_IN object (see the Socket perl manpage), in mod_perl 2.0 API
+it returns an C<L<APR::SocketAddr|docs::2.0::api::APR::SocketAddr>>
+object, which is a totally different beast. If Apache::compat
+overrides the function C<local_addr()> to be back-compatible with
+mod_perl 1.0 API. Any code that relies on this function to work as it
+should under mod_perl 2.0 will be broken. Therefore the solution is
+not to override C<local_addr()> by default. Instead a special API is
+provided which overrides colliding functions only when needed and
+which can be restored when no longer needed. So for example if you
+have code from mod_perl 1.0:
+
+ my ($local_port, $local_addr) = Socket::sockaddr_in($c->local_addr);
+
+and you aren't ready to port it to to use the mp2 API:
+
+ my ($local_port, $local_addr) = ($c->local_addr->port,
+ $c->local_addr->ip_get);
+
+you could do the following:
+
+ Apache::compat::override_mp2_api('Apache::Connection::local_addr');
+ my ($local_port, $local_addr) = Socket::sockaddr_in($c->local_addr);
+ Apache::compat::restore_mp2_api('Apache::Connection::local_addr');
+
+Notice that you need to restore the API as soon as possible.
+
+Both C<override_mp2_api()> and C<restore_mp2_api()> accept a list of
+functions to operate on.
+
+=head2 Available Overridable Functions
+
+At the moment the following colliding functions are available for
+overriding:
+
+=over
+
+=item * C<Apache::RequestRec::notes>
+
+=item * C<Apache::RequestRec::finfo>
+
+=item * C<Apache::Connection::local_addr>
+
+=item * C<Apache::Connection::remote_addr>
+
+=back
+
+
+
+
+
+
+
+
+
=head1 Use in CPAN Modules
1.28 +59 -18 modperl-docs/src/docs/2.0/user/porting/compat.pod
Index: compat.pod
===================================================================
RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/porting/compat.pod,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -u -r1.27 -r1.28
--- compat.pod 11 Dec 2003 18:06:55 -0000 1.27
+++ compat.pod 17 Dec 2003 21:04:12 -0000 1.28
@@ -824,17 +824,38 @@
=head2 C<$r-E<gt>finfo>
-Probably won't be implemented, because Apache 2.0's finfo
-datastructure can't be mapped into the Perl finfo datastructure.
+As Apache 2.0 doesn't provide an access to the stat structure, but
+hides it in the opaque object you need to use the
+C<L<APR::Finfo|docs::2.0::api::APR::Finfo>> accessor methods.
-C<L<Apache::compat|docs::2.0::api::Apache::compat>> handles that for
-now with:
+It's also possible to to adjust the mod_perl 1.0 code using
+Apache::compat's
+L<overriding|docs::2.0::api::Apache::compat/Compatibility_Functions_Colliding_with_mod_perl_2_0_API>.
+For example:
- sub finfo {
- my $r = shift;
- stat $r->filename;
- \*_;
- }
+ use Apache::compat;
+ Apache::compat::override_mp2_api('Apache::RequestRec::finfo');
+ my $is_writable = -w $r->finfo;
+ Apache::compat::restore_mp2_api('Apache::RequestRec::finfo');
+
+which internally does just the following:
+
+ stat $r->filename and return \*_;
+
+So may be it's easier to just change the code to use this directly, so
+the above example can be adjusted to be:
+
+ my $is_writable = -w $r->filename;
+
+with the performance penalty of an extra C<stat()> system call. If you
+don't want this extra call, you'd have to write:
+
+ use APR::Finfo;
+ use APR::Const -compile => qw(WWRITE);
+ my $is_writable = $r->finfo->protection & APR::WWRITE,
+
+See the C<L<APR::Finfo|docs::2.0::api::APR::Finfo>> manpage for more
+information.
=head2 C<$r-E<gt>notes>
@@ -844,15 +865,18 @@
as a tied hash or calling its I<get()>/I<set()>/I<add()>/I<unset()>
methods.
-If C<L<Apache::compat|docs::2.0::api::Apache::compat>> is loaded the
-old API:
+It's also possible to to adjust the mod_perl 1.0 code using
+Apache::compat's
+L<overriding|docs::2.0::api::Apache::compat/Compatibility_Functions_Colliding_with_mod_perl_2_0_API>:
+ use Apache::compat;
+ Apache::compat::override_mp2_api('Apache::RequestRec::notes');
$r->notes($key => $val);
$val = $r->notes($key);
+ Apache::compat::restore_mp2_api('Apache::RequestRec::notes');
-is supported as well.
-
-See the L<Apache::RequestRec> manpage.
+See the C<L<Apache::RequestRec|docs::2.0::api::Apache::RequestRec>>
+manpage.
=head2 C<$r-E<gt>header_in>
@@ -1051,13 +1075,30 @@
now it'll be written as:
require APR::SockAddr;
- my $serverport = $c->local_addr->port_get;
+ my $serverport = $c->local_addr->port;
my $serverip = $c->local_addr->ip_get;
- my $remoteport = $c->remote_addr->port_get;
+ my $remoteport = $c->remote_addr->port;
my $remoteip = $c->remote_addr->ip_get;
-META: it's not simple to fix this in the compat layer, since it'll
-break the API for normal Apache 2.0 modules. Stay tuned for solutions.
+It's also possible to to adjust the code using Apache::compat's
+L<overriding|docs::2.0::api::Apache::compat/Compatibility_Functions_Colliding_with_mod_perl_2_0_API>:
+
+ use Socket 'sockaddr_in';
+ use Apache::compat;
+
+ Apache::compat::override_mp2_api('Apache::Connection::local_addr');
+ my ($serverport, $serverip) = sockaddr_in($r->connection->local_addr);
+ Apache::compat::restore_mp2_api('Apache::Connection::local_addr');
+
+ Apache::compat::override_mp2_api('Apache::Connection::remote_addr');
+ my ($remoteport, $remoteip) = sockaddr_in($r->connection->remote_addr);
+ Apache::compat::restore_mp2_api('Apache::Connection::remote_addr');
+
+
+
+
+
+
=head1 C<Apache::File>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]