Re: modules that work with both modperl1 and 2
Shannon Eric Peevey wrote: Stas Bekman wrote: This source code was the saving grace for me. If we could add the link to: http://search.cpan.org/src/STAS/Apache-Peek-1.01/t/response/TestApachePeek/basic.pm into the documentation, that would be great. No need to, I've already merged it into the docs: http://perl.apache.org/docs/2.0/user/porting/compat.html#mod_perl_1_0_and_2_0_Constants_Coexistence Also, it would probably be nice to have a link from: http://perl.apache.org/docs/2.0/user/porting/porting.html#Making_Code_Conditional_on_Running_mod_perl_Version to http://perl.apache.org/docs/2.0/user/porting/compat.html#mod_perl_1_0_and_2_0_Constants_Coexistence that would help the "porter" to understand the overall picture of what needs to be done to allow the single code-base to work with both mod_perls... done, thanks for the suggestion. Finally, I found that the PAUSE server did not recognize the $VERSION number, (returned as undef), until I placed it above the BEGIN {} block as following: Yes, not before the BEGIN block, but before any other occurence of the string VERSION. Some claim that this is a bug, others that it's a feature. Depends on who you ask. BTW, to verify your module that its version is parsable correctly by PAUSE, you don't need to submit it to pause, but use: perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' 'file' as explained at: http://pause.perl.org/pause/query?ACTION=pause_04about#conventions I've added a note about this to the porting docs. package Apache::AuthNetLDAP; [...] $VERSION = '0.21'; # setting the constants to help identify which version of mod_perl # is installed use constant MP2 => ($mod_perl::VERSION >= 1.99); [...] Thanks again for all of your help! If you know of any modules that need porting in a like manner, feel free to contact me and I would be happy to help out. I think there are quite a few modules that need porting. Just go to CPAN pick one and go with it. Probably first contact the author so you don't step on their toes. I'm planning on adding more docs as I doing porting myself, and if others find new tricks and useful additions to the existing docs don't hesitate to post them here, just like Shannon did. Which is *very* helpful! Thank you Shannon! I'm also thinking about creating several modules to ease the porting, I'll post more on this when I'll get around writing some first prototypes. __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
Re: modules that work with both modperl1 and 2
Stas Bekman wrote: speeves wrote: Stas Bekman wrote: [...] http://search.cpan.org/src/STAS/Apache-Peek-1.01/t/response/TestApachePeek/basic.pm This source code was the saving grace for me. If we could add the link to: http://search.cpan.org/src/STAS/Apache-Peek-1.01/t/response/TestApachePeek/basic.pm into the documentation, that would be great. hat did it!!! Thank you so much for your patience and help with all that I am working on here. After I test these changes on modperl 1 tomorrow, I should be able to upload it to CPAN, and it will be ready for prime-time... (fingers crossed ;) ) Based on your porting experience if you have additions/corrections to these two documents: http://perl.apache.org/docs/2.0/user/porting/porting.html http://perl.apache.org/docs/2.0/user/porting/compat.html please submit those here. BTW, I have updated the info on the constants: http://perl.apache.org/docs/2.0/user/porting/compat.html#mod_perl_1_0_and_2_0_Constants_Coexistence __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com Also, it would probably be nice to have a link from: http://perl.apache.org/docs/2.0/user/porting/porting.html#Making_Code_Conditional_on_Running_mod_perl_Version to http://perl.apache.org/docs/2.0/user/porting/compat.html#mod_perl_1_0_and_2_0_Constants_Coexistence that would help the "porter" to understand the overall picture of what needs to be done to allow the single code-base to work with both mod_perls... Finally, I found that the PAUSE server did not recognize the $VERSION number, (returned as undef), until I placed it above the BEGIN {} block as following: package Apache::AuthNetLDAP; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); use Net::LDAP; use mod_perl; require Exporter; @ISA = qw(Exporter AutoLoader); # 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. @EXPORT = qw( ); $VERSION = '0.21'; # setting the constants to help identify which version of mod_perl # is installed use constant MP2 => ($mod_perl::VERSION >= 1.99); # test for the version of mod_perl, and use the appropriate libraries BEGIN { if (MP2) { require Apache::Const; require Apache::Access; require Apache::Connection; require Apache::Log; require Apache::RequestRec; require Apache::RequestUtil; Apache::Const->import(-compile => 'HTTP_UNAUTHORIZED','OK'); } else { require Apache::Constants; Apache::Constants->import('HTTP_UNAUTHORIZED','OK'); } } # Preloaded methods go here. #handles Apache requests sub handler { ... } Thanks again for all of your help! If you know of any modules that need porting in a like manner, feel free to contact me and I would be happy to help out. speeves cws
Re: modules that work with both modperl1 and 2
speeves wrote: Stas Bekman wrote: [...] http://search.cpan.org/src/STAS/Apache-Peek-1.01/t/response/TestApachePeek/basic.pm That did it!!! Thank you so much for your patience and help with all that I am working on here. After I test these changes on modperl 1 tomorrow, I should be able to upload it to CPAN, and it will be ready for prime-time... (fingers crossed ;) ) Based on your porting experience if you have additions/corrections to these two documents: http://perl.apache.org/docs/2.0/user/porting/porting.html http://perl.apache.org/docs/2.0/user/porting/compat.html please submit those here. BTW, I have updated the info on the constants: http://perl.apache.org/docs/2.0/user/porting/compat.html#mod_perl_1_0_and_2_0_Constants_Coexistence __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
Re: modules that work with both modperl1 and 2
Stas Bekman wrote: Shannon Eric Peevey wrote: Perrin Harkins wrote: On Mon, 2003-06-09 at 13:57, Shannon Eric Peevey wrote: To answer your original question, Apache::Peek on CPAN now works with both mod_perl versions. And while it uses separate implementations for each version, the test suite uses the same code to test both. Yeah, I've been messing with that, but it seems to me that I need something similar to a preprocessor directive, where I can load the appropriate "use MODULE" lines into the module bases upon which version of modperl they have installed. Is it possible to use the BEGIN {} subroutine as this? You don't need a preprocessor. You can call require inside an if/else conditional, unlike use() statements which run at compile time and skip the conditional logic. For example: if ($mod_perl::VERSION >= 1.99) { require Apache2::Module; import Apache2::Module; } else { require Apache1::Module; import Apache1::Module; } You can put that whole construct in a BEGIN block if you want to. That will make it run before the rest of the code in the current package. - Perrin Ok, I'm back... :( Here is the code, modified to use "require": use mod_perl; # setting the constants to help identify which version of mod_perl # is installed use constant MP2 => ($mod_perl::VERSION >= 1.99); # test for the version of mod_perl, and use the appropriate libraries # if (!MP2) { use Apache::Constants qw(:common); } if (MP2) { require Apache::Const; import Apache::Access; require Apache::Access; import Apache::Access; require Apache::Connection; import Apache::Connection; require Apache::Log; import Apache::Log; require Apache::RequestRec; import Apache::RequestRec; require Apache::RequestUtil; import Apache::RequestUtil; } You don't need to import anything, since none of these modules import anything. Just require will do. Here is the code that is coughing up the error: 102 #Look for user based on UIDAttr 103 104my $attrs = ['dn']; 105 $mesg = $ldap->search( 106 base => $basedn, 107 scope => 'sub', 108 filter => "($uidattr=$user)", 109 attrs => $attrs 110 ); 111 112 if (my $error = $mesg->code()) 113{ 114 $r->note_basic_auth_failure; 115 MP2 ? $r->log_error("user $user: LDAP Connection Failed: $error",$r->uri) : $r->log_reason("us er $user: LDAP Connection Failed: $error",$r->uri); 116 MP2 ? return Apache::Log->HTTP_UNAUTHORIZED : return Apache::Constants->HTTP_UNAUTHORIZED; this should be: return MP2 ? Apache::HTTP_UNAUTHORIZED : Apache::Constants::HTTP_UNAUTHORIZED; and before the handler (at the top of your module) you need to add: BEGIN { if (MP2) { require Apache::Const; Apache::Const->import(-compile => 'HTTP_UNAUTHORIZED'); } else { require Apache::Constants; Apache::Constants->import('HTTP_UNAUTHORIZED'); } } See: http://search.cpan.org/src/STAS/Apache-Peek-1.01/t/response/TestApachePeek/basic.pm 117} 118 119unless ($mesg->count()) 120{ 121 $r->note_basic_auth_failure; 122 MP2 ? $r->log_error("user $user: user entry not found for filter: $uidattr=$user",$r->uri) : $ r->log_reason("user $user: user entry not found for filter: $uidattr=$user",$r->uri); 123 MP2 ? return Apache::Log->HTTP_UNAUTHORIZED : return Apache::Constants->HTTP_UNAUTHORIZED; 124} And, here is the error that I am getting in the Apache2 logs, (using mod_perl 1.99_09) [Mon Jun 09 13:45:30 2003] [error] user asdf: user entry not found for filter: uid=asdf/ [Mon Jun 09 13:45:30 2003] [error] [client 127.0.0.1] Can't locate object method "HTTP_UNAUTHORIZED" via package "Apache::Log" (perhaps you forgot to load "Apache::Log"?) at /usr/local/share/perl/5.6.1/Apache/AuthNetLDAP.pm line 123. As you can see, it is running everything up to the HTTP_UNAUTHORIZED constant... If you have any ideas, I would greatly appreciate it. :) Thanks, speeves cws PS. As a matter of fact, I get the same error when using "use" instead... (Possibly a screwed perl or mod_perl installation? I'm running debian woody, apache 2.0.46, perl 5.6.1, mod_perl 1.99_09.) Hi! That did it!!! Thank you so much for your patience and help with all that I am working on here. After I test these changes on modperl 1 tomorrow, I should be able to upload it to CPAN, and it will be ready for prime-time... (fingers crossed ;) ) Most humbly yours, speeves cws
Re: modules that work with both modperl1 and 2
Shannon Eric Peevey wrote: Perrin Harkins wrote: On Mon, 2003-06-09 at 13:57, Shannon Eric Peevey wrote: To answer your original question, Apache::Peek on CPAN now works with both mod_perl versions. And while it uses separate implementations for each version, the test suite uses the same code to test both. Yeah, I've been messing with that, but it seems to me that I need something similar to a preprocessor directive, where I can load the appropriate "use MODULE" lines into the module bases upon which version of modperl they have installed. Is it possible to use the BEGIN {} subroutine as this? You don't need a preprocessor. You can call require inside an if/else conditional, unlike use() statements which run at compile time and skip the conditional logic. For example: if ($mod_perl::VERSION >= 1.99) { require Apache2::Module; import Apache2::Module; } else { require Apache1::Module; import Apache1::Module; } You can put that whole construct in a BEGIN block if you want to. That will make it run before the rest of the code in the current package. - Perrin Ok, I'm back... :( Here is the code, modified to use "require": use mod_perl; # setting the constants to help identify which version of mod_perl # is installed use constant MP2 => ($mod_perl::VERSION >= 1.99); # test for the version of mod_perl, and use the appropriate libraries # if (!MP2) { use Apache::Constants qw(:common); } if (MP2) { require Apache::Const; import Apache::Access; require Apache::Access; import Apache::Access; require Apache::Connection; import Apache::Connection; require Apache::Log; import Apache::Log; require Apache::RequestRec; import Apache::RequestRec; require Apache::RequestUtil; import Apache::RequestUtil; } You don't need to import anything, since none of these modules import anything. Just require will do. Here is the code that is coughing up the error: 102 #Look for user based on UIDAttr 103 104my $attrs = ['dn']; 105 $mesg = $ldap->search( 106 base => $basedn, 107 scope => 'sub', 108 filter => "($uidattr=$user)", 109 attrs => $attrs 110 ); 111 112 if (my $error = $mesg->code()) 113{ 114 $r->note_basic_auth_failure; 115 MP2 ? $r->log_error("user $user: LDAP Connection Failed: $error",$r->uri) : $r->log_reason("us er $user: LDAP Connection Failed: $error",$r->uri); 116 MP2 ? return Apache::Log->HTTP_UNAUTHORIZED : return Apache::Constants->HTTP_UNAUTHORIZED; this should be: return MP2 ? Apache::HTTP_UNAUTHORIZED : Apache::Constants::HTTP_UNAUTHORIZED; and before the handler (at the top of your module) you need to add: BEGIN { if (MP2) { require Apache::Const; Apache::Const->import(-compile => 'HTTP_UNAUTHORIZED'); } else { require Apache::Constants; Apache::Constants->import('HTTP_UNAUTHORIZED'); } } See: http://search.cpan.org/src/STAS/Apache-Peek-1.01/t/response/TestApachePeek/basic.pm 117} 118 119unless ($mesg->count()) 120{ 121 $r->note_basic_auth_failure; 122 MP2 ? $r->log_error("user $user: user entry not found for filter: $uidattr=$user",$r->uri) : $ r->log_reason("user $user: user entry not found for filter: $uidattr=$user",$r->uri); 123 MP2 ? return Apache::Log->HTTP_UNAUTHORIZED : return Apache::Constants->HTTP_UNAUTHORIZED; 124} And, here is the error that I am getting in the Apache2 logs, (using mod_perl 1.99_09) [Mon Jun 09 13:45:30 2003] [error] user asdf: user entry not found for filter: uid=asdf/ [Mon Jun 09 13:45:30 2003] [error] [client 127.0.0.1] Can't locate object method "HTTP_UNAUTHORIZED" via package "Apache::Log" (perhaps you forgot to load "Apache::Log"?) at /usr/local/share/perl/5.6.1/Apache/AuthNetLDAP.pm line 123. As you can see, it is running everything up to the HTTP_UNAUTHORIZED constant... If you have any ideas, I would greatly appreciate it. :) Thanks, speeves cws PS. As a matter of fact, I get the same error when using "use" instead... (Possibly a screwed perl or mod_perl installation? I'm running debian woody, apache 2.0.46, perl 5.6.1, mod_perl 1.99_09.) -- __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
Re: modules that work with both modperl1 and 2
Perrin Harkins wrote: On Mon, 2003-06-09 at 13:57, Shannon Eric Peevey wrote: Yeah, I've been messing with that, but it seems to me that I need something similar to a preprocessor directive, where I can load the appropriate "use MODULE" lines into the module bases upon which version of modperl they have installed. Is it possible to use the BEGIN {} subroutine as this? You don't need a preprocessor. You can call require inside an if/else conditional, unlike use() statements which run at compile time and skip the conditional logic. For example: if ($mod_perl::VERSION >= 1.99) { require Apache2::Module; import Apache2::Module; } else { require Apache1::Module; import Apache1::Module; } You can put that whole construct in a BEGIN block if you want to. That will make it run before the rest of the code in the current package. - Perrin Ok, I'm back... :( Here is the code, modified to use "require": use mod_perl; # setting the constants to help identify which version of mod_perl # is installed use constant MP2 => ($mod_perl::VERSION >= 1.99); # test for the version of mod_perl, and use the appropriate libraries # if (!MP2) { use Apache::Constants qw(:common); } if (MP2) { require Apache::Const; import Apache::Access; require Apache::Access; import Apache::Access; require Apache::Connection; import Apache::Connection; require Apache::Log; import Apache::Log; require Apache::RequestRec; import Apache::RequestRec; require Apache::RequestUtil; import Apache::RequestUtil; } Here is the code that is coughing up the error: 102 #Look for user based on UIDAttr 103 104my $attrs = ['dn']; 105 $mesg = $ldap->search( 106 base => $basedn, 107 scope => 'sub', 108 filter => "($uidattr=$user)", 109 attrs => $attrs 110 ); 111 112 if (my $error = $mesg->code()) 113{ 114 $r->note_basic_auth_failure; 115 MP2 ? $r->log_error("user $user: LDAP Connection Failed: $error",$r->uri) : $r->log_reason("us er $user: LDAP Connection Failed: $error",$r->uri); 116 MP2 ? return Apache::Log->HTTP_UNAUTHORIZED : return Apache::Constants->HTTP_UNAUTHORIZED; 117} 118 119unless ($mesg->count()) 120{ 121 $r->note_basic_auth_failure; 122 MP2 ? $r->log_error("user $user: user entry not found for filter: $uidattr=$user",$r->uri) : $ r->log_reason("user $user: user entry not found for filter: $uidattr=$user",$r->uri); 123 MP2 ? return Apache::Log->HTTP_UNAUTHORIZED : return Apache::Constants->HTTP_UNAUTHORIZED; 124} And, here is the error that I am getting in the Apache2 logs, (using mod_perl 1.99_09) [Mon Jun 09 13:45:30 2003] [error] user asdf: user entry not found for filter: uid=asdf/ [Mon Jun 09 13:45:30 2003] [error] [client 127.0.0.1] Can't locate object method "HTTP_UNAUTHORIZED" via package "Apache::Log" (perhaps you forgot to load "Apache::Log"?) at /usr/local/share/perl/5.6.1/Apache/AuthNetLDAP.pm line 123. As you can see, it is running everything up to the HTTP_UNAUTHORIZED constant... If you have any ideas, I would greatly appreciate it. :) Thanks, speeves cws PS. As a matter of fact, I get the same error when using "use" instead... (Possibly a screwed perl or mod_perl installation? I'm running debian woody, apache 2.0.46, perl 5.6.1, mod_perl 1.99_09.)
Re: modules that work with both modperl1 and 2
On Mon, 2003-06-09 at 13:57, Shannon Eric Peevey wrote: > Yeah, I've been messing with that, but it seems to me that I need > something similar to a preprocessor directive, where I can load the > appropriate "use MODULE" lines into the module bases upon which version > of modperl they have installed. Is it possible to use the BEGIN {} > subroutine as this? You don't need a preprocessor. You can call require inside an if/else conditional, unlike use() statements which run at compile time and skip the conditional logic. For example: if ($mod_perl::VERSION >= 1.99) { require Apache2::Module; import Apache2::Module; } else { require Apache1::Module; import Apache1::Module; } You can put that whole construct in a BEGIN block if you want to. That will make it run before the rest of the code in the current package. - Perrin
Re: modules that work with both modperl1 and 2
Perrin Harkins wrote: On Mon, 2003-06-09 at 12:12, Shannon Eric Peevey wrote: PS Am having problems with the compile time loading of modules depending on the existence of either modperl1 or 2... "use" dies and "require" is not importing the symbols correctly at runtime... If you read the docs for "use" (perldoc -f use), you will see that "use" is just like: BEGIN { require Module; import Module LIST; } If you want to import things correctly when using require, you have to call import yourself. - Perrin Yeah, I've been messing with that, but it seems to me that I need something similar to a preprocessor directive, where I can load the appropriate "use MODULE" lines into the module bases upon which version of modperl they have installed. Is it possible to use the BEGIN {} subroutine as this? speeves cws
Re: modules that work with both modperl1 and 2
On Mon, 2003-06-09 at 12:12, Shannon Eric Peevey wrote: > PS Am having problems with the compile time loading of modules depending > on the existence of either modperl1 or 2... "use" dies and "require" is > not importing the symbols correctly at runtime... If you read the docs for "use" (perldoc -f use), you will see that "use" is just like: BEGIN { require Module; import Module LIST; } If you want to import things correctly when using require, you have to call import yourself. - Perrin