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]