Re: [ANNOUNCE] Apache::IncludeHook
Geoffrey Young wrote: hi all... I wanted to let everyone know that I have ported !-- #perl -- SSI tag support to Apache 2.0. it should behave under both prefork and threaded mpms, and work pretty much the same as it did in Apache 1.3, despite the fact that mod_include is now an output filter. while the support is fairly complete, the code is a bit messy and can be refactored. however, I wanted to get something released for people to play with before I needed to move on to something else. geoff++ can you please update this page? http://perl.apache.org/products/apache-modules.html#Porting_CPAN_modules_to_mod_perl_2_0_Status thanks. __ 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: mod_perl v2 Forking
Cameron B. Prince wrote: I have a report generator program written in Perl that I need to start from a CGI. The program takes about 15 minutes to run, so I must fork or double fork. I have two goals: 1) Have no zombies when the program completes 2) Fork in such a way that restarting Apache doesn't kill the forked process. I tried out the code here which is for mod_perl v1: http://perl.apache.org/docs/1.0/guide/performance.html#Forking_and_Executing _Subprocesses_from_mod_perl There are two problems with the code listed in the example: 1) Apache::SubProcess doesn't seem to contain the same methods as the older version. most of them aren't needed (they don't exist in the Apache 2.0 API. 2) open isn't working. (I've already been down this road and switched another call to an external program to use IPC::Run, but that program doesn't take long and needs no fork.) what open()? what's not working? please be more specific, show us some code and the actual error messages. Are you talking about open in http://perl.apache.org/docs/1.0/guide/performance.html#A_Complete_Fork_Example ? I took out the parts of the code that caused problems and ended up with this: $SIG{CHLD} = 'IGNORE'; defined (my $pid = fork) or die Cannot fork: $!\n; unless ($pid) { exec $command; CORE::exit(0); } This works and accomplishes my first goal, but not the second. If I start the program and restart Apache, the program is killed. have you detached the session as explained here? http://perl.apache.org/docs/1.0/guide/performance.html#Detaching_the_Forked_Process I admit I haven't tried this code from the above url with 2.0 yet (and it'd be nice to have such a test (hint! hint!)) but I can't see it in your sample, so I assume that you haven't tried it ;) Also while you are at it, once you figure out all the quirks if you can help us porting http://perl.apache.org/docs/1.0/guide/performance.html#Forking_and_Executing_Subprocesses_from_mod_perl to 2.0 docs that would be very helpful for those coming after you. Thanks. __ 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: Can't build Apache::Dispatch on Windows / Perl 5.8.0
Steve Hay wrote: [...] Having a pointer to where the mod_perl.lib library was installed would be useful. I'm not sure calling it MODPERL_STATIC_LIB_LOCATION would be the best thing on Win32, as it's not a static library as such, but something could be come up with ... Well, if ModPerl::MM does the right thing, a developer will not even need to know where it is located. So probably leaving it as it's now is fine. The only misleading part is that MODPERL_LIB_LOCATION points to the build dir, so it should probably be renamed to reflect that. I'm not sure that's the *only* mis-leading part, but, as you say, if it all works then it shouldn't really matter too much. What other misleading parts are we talking about? The main thing is to get mod_perl.lib installed in the first place under mp1. I remember someone wanted to port ModPerl::MM to mp1, if that happens, than it'd become a non-issue as well ;) __ 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: Can't build Apache::Dispatch on Windows / Perl 5.8.0
Stas Bekman wrote: Steve Hay wrote: [...] Having a pointer to where the mod_perl.lib library was installed would be useful. I'm not sure calling it MODPERL_STATIC_LIB_LOCATION would be the best thing on Win32, as it's not a static library as such, but something could be come up with ... Well, if ModPerl::MM does the right thing, a developer will not even need to know where it is located. So probably leaving it as it's now is fine. The only misleading part is that MODPERL_LIB_LOCATION points to the build dir, so it should probably be renamed to reflect that. I'm not sure that's the *only* mis-leading part, but, as you say, if it all works then it shouldn't really matter too much. What other misleading parts are we talking about? I'm just getting confused with changes in Apache itself, I think. Apache 1 used to have lib, libexec and modules: lib stored the static .lib's, libexec stored the import libraries for various dll's, and modules stored the .so (aka .dll) files for Apache modules. But with Apache 2, I have only lib and modules. The latter still (rightly) contains just the .so files for Apache modules, so presumably all the static *and* import libraries are thrown together into lib now? Now, my mp2's Apache::BuildConfig contains this: 'MODPERL_AP_LIBDIR' = 'C:\\apache2/lib', 'MODPERL_AP_LIBEXECDIR' = 'C:\\apache2/modules', which I find confusing. The first line there is fine, but the second line seems wrong. One would think that MODPERL_AP_LIBEXECDIR specifies where Apache's libexec directory is, but there isn't one any more! Furthermore, it seems that the files that would have been in it are now in lib? So maybe MODPERL_AP_LIBEXECDIR should say C:\\apache2/lib (that's an ugly mess of back- and forward slashes too), and that should be used as the location to install mod_perl.lib into (since mod_perl.lib is one of these import library things). That would be wrong as things stand, though, because MODPERL_AP_LIBEXECDIR seems to be used as the location to install mod_perl.so, which should indeed be C:\\apache2/modules. Perhaps the simplest thing would be to rename MODPERL_AP_LIBEXECDIR to MODPERL_AP_MODDIR since it specifies where Apache's modules directory is and there isn't a libexec anymore? - Steve
Basic authentication
Hi, I'm having a bit of trouble authenticating users. The script I have works, but only a couple of times before it just sends out 401 without prompting the user for their details. We have mod_perl 1.99_05 installed, we don't want to upgrade as we would have more applications to upgrade than time. Any help/questions would be appreciated. The problem script is below: use strict; use Apache::Const qw(OK AUTH_REQUIRED); use lib qw(/var/www/html/opbms/libs); use CheckLogin; use CreateFrames; my $r = shift; print Content-Type:text/html\n\n; my ($status, $password) = $r-get_basic_auth_pw; if ($status != OK) { $r-status($status); exit($status); } my $ip = '127.0.0.1'; my $port = 31555; if (CheckLogin::Check($r-user, $password, $port, $ip) eq '1') { CreateFrames::Create($r-user, $password, $port, $ip); } else { $r-note_basic_auth_failure; $r-status(AUTH_REQUIRED); exit(AUTH_REQUIRED); } Cheers!! This email has been scanned for all viruses by the MessageLabs Email Security System. For more information on a proactive email security service working around the clock, around the globe, visit http://www.messagelabs.com
Re: Basic authentication
Stephen Hardisty wrote: Hi, I'm having a bit of trouble authenticating users. The script I have works, but only a couple of times before it just sends out 401 without prompting the user for their details. We have mod_perl 1.99_05 installed, we don't want to upgrade as we would have more applications to upgrade than time. Any help/questions would be appreciated. The problem script is below: use strict; use Apache::Const qw(OK AUTH_REQUIRED); use lib qw(/var/www/html/opbms/libs); use CheckLogin; use CreateFrames; my $r = shift; print Content-Type:text/html\n\n; don't do that - AUTH_REQUIRED is an error status, so apache will send it's own set of headers. my ($status, $password) = $r-get_basic_auth_pw; if ($status != OK) { $r-status($status); exit($status); } yike! you shouldn't ever play with $r-status. calling exit is also not the standard way. examples of auth handlers abound, so you should really just be following them - even though you are using mod_perl 2.0, the API is really the same wrt get_basic_auth_pw() etc. some examples include the many, many modules on CPAN. you can also find detailed auth examples in http://www.modperlcookbook.org/chapters/ch13.pdf and http://www.modperlcookbook.org/code/ch13/ specifically http://www.modperlcookbook.org/code/ch13/Cookbook/Authenticate.pm HTH --Geoff
Re: mod_perl v2 Forking
Hi, I guess this is off topic for this list, since I would be doing this no matter if I was running CGI or mod_perl or whatever. I am pretty desparate to get this working, and if anyone wants to earn some cash helping me fix things PLEASE call me at 250 655-9513. I have been trying to accomplish the same thing as Cameron, but with the detaching stuff it seemed a lot easier to make a server with IO::Select and not actually start the server from mod_perl. The end result hopefully will be a web user being able to start some things that take time, but not screw things up by interrupting them. But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. The thing is somehow this ends up killing off my parent process, just like in this post: http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html So this is happening to me as well, however the guy in the above example had his problem solved by using Errno and looking for EINTR if that error is raised then catch it and move on, I did get one maybe helpfull thing from my log: Erro was %! ./franken_socket.pl 8607: got - CHLD at Tue Sep 16 02:17:42 2003 I got forked ./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003 begat 8607 ./franken_socket.pl 8599: got - CHLD at Tue Sep 16 02:17:54 2003 ./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003 reaped 1Erro was No child processes %! So it looks like the parent got killed on that error No child process This code works just fine on 5.6 since it is about 150% from examples :) The above is the result of connecting, doing a who, and doing dienow to test the alarm. I also found this: http://archive.develooper.com/[EMAIL PROTECTED]/msg03022.html Which totaly describes my problem as well, but shows it happening with perl 5.8.1.. I'd imagine that your accept() isn't being restarted. How does it work if you change the loop to look like this? use Errno; while (1) { my $client = $server-accept or do { next if $!{EINTR}; last; }; spawn(\function, whatever); } #!/usr/bin/perl -w ## new frankenstein! use strict; use POSIX (); use POSIX 'WNOHANG'; use Errno; use IO::Socket; use FindBin (); use File::Basename (); use File::Spec::Functions; use Net::hostent; use Carp; $|=1; my $pid; open (DIED, /var/log/daemon_log) or warn $!; sub logmsg { print DIED $0 $$: @_ at , scalar localtime, \n } my $listen_socket = IO::Socket::INET-new(LocalPort = 1081, LocalAddr = '127.0.0.1', Proto = 'tcp', Listen= SOMAXCONN, Reuse = 1 ) or die can make a tcp server on port 1080 $!; # make the daemon cross-platform, so exec always calls the script # itself with the right path, no matter how the script was invoked. my $script = File::Basename::basename($0); my $SELF = catfile $FindBin::Bin, $script; # POSIX unmasks the sigprocmask properly my $sigset = POSIX::SigSet-new(); my $action = POSIX::SigAction-new('sigHUP_handler', $sigset, POSIX::SA_NODEFER); my $action_alrm = POSIX::SigAction-new('sigALRM_handler', $sigset, POSIX::SA_NODEFER); POSIX::sigaction(POSIX::SIGHUP, $action); POSIX::sigaction(POSIX::SIGALRM, $action_alrm); sub sigHUP_handler { print got SIGHUP\n; exec($SELF, @ARGV) or die Couldn't restart: $!\n; } sub sigALRM_handler { print got ALARM timeout\n; } $SIG{CHLD} = \REAPER_NEW; sub REAPER { $SIG{CHLD} = \REAPER; # loathe sysV my $waitedpid = wait; logmsg reaped $waitedpid . ($? ? with exit $? : ''); } sub REAPER_NEW { logmsg got - @_\n; my $wpid = undef; while ($wpid = waitpid(-1,WNOHANG)0) { logmsg main $pid -- reaped $wpid . ($? ? with exit $? : '') ; print DIED reaped $wpid . ($? ? with exit $? : ''); } } print PID: $$\n; print ARGV: @ARGV\n; print [Server $0 accepting clients]\n; #while (my $connection = $listen_socket-accept()) { while (1) { my $connection = $listen_socket-accept() or do { next if $!{EINTR}; last; }; print DIED Erro was $! %! \n; $connection-autoflush(1); ## missing seemed to cause client problem, but not telnet if (!defined($pid = fork)) { logmsg cannot fork: $!; }elsif
Re: mod_perl v2 Forking
Eric Frazier wrote: ... But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. Mostly, yes. Look at the perldelta manpage that is distributed with perl 5.8.0, section Safe Signals. If you want to restore the 5.6-ish unsafe signal handling, this is not possible with 5.8.0 :(. But, as it has been acknowledged that this unsafe behaviour is desirable in some cases, it will be possible with perl 5.8.1. You can grab a 5.8.1 release candidate 4 from CPAN : http://search.cpan.org/~jhi/ (RC5 should be out in a few days) and see with it if using unsafe signal handlers solves your problem. You can enable them with the PERL_SIGNALS environment variable. Here's the relevant part of the perlrun manpage that comes with perl 5.8.1 RC4 : =item PERL_SIGNALS In Perls 5.8.1 and later. If set to Cunsafe the pre-Perl-5.8.0 signals behaviour (immediate but unsafe) is restored. If set to Csafe the safe (or deferred) signals are used. See Lperlipc/Deferred Signals (Safe signals). HTH.
RE: mod_perl v2 Forking
Hi, I had a problem with 5.8.1 and forking in that I was either getting zombies using the 5.6 examples or the parent was dying, depending on which example was used. The way round I found was to: # ignore the child, good rule for life $SIG{CHLD} = 'IGNORE'; # then sort out the socket my $server = new IO::Socket::INET(LocalPort = $port, Type = SOCK_STREAM, Proto = tcp, Listen = 5) or die some error; # wait for a connection while(my $client = $server-accept()) { my $pid = fork; die Error. Fork: $!\n unless defined $pid; if($pid == 0) { # all your child code here # when it's done, kill the child: exit(0); } } This seemes reasonably stable. If anybody has a better way, then I'm all ears. Cheers! -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:24 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: mod_perl v2 Forking Hi, I guess this is off topic for this list, since I would be doing this no matter if I was running CGI or mod_perl or whatever. I am pretty desparate to get this working, and if anyone wants to earn some cash helping me fix things PLEASE call me at 250 655-9513. I have been trying to accomplish the same thing as Cameron, but with the detaching stuff it seemed a lot easier to make a server with IO::Select and not actually start the server from mod_perl. The end result hopefully will be a web user being able to start some things that take time, but not screw things up by interrupting them. But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. The thing is somehow this ends up killing off my parent process, just like in this post: http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html So this is happening to me as well, however the guy in the above example had his problem solved by using Errno and looking for EINTR if that error is raised then catch it and move on, I did get one maybe helpfull thing from my log: Erro was %! ./franken_socket.pl 8607: got - CHLD at Tue Sep 16 02:17:42 2003 I got forked ./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003 begat 8607 ./franken_socket.pl 8599: got - CHLD at Tue Sep 16 02:17:54 2003 ./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003 reaped 1Erro was No child processes %! So it looks like the parent got killed on that error No child process This code works just fine on 5.6 since it is about 150% from examples :) The above is the result of connecting, doing a who, and doing dienow to test the alarm. I also found this: http://archive.develooper.com/[EMAIL PROTECTED]/msg03022.html Which totaly describes my problem as well, but shows it happening with perl 5.8.1.. I'd imagine that your accept() isn't being restarted. How does it work if you change the loop to look like this? use Errno; while (1) { my $client = $server-accept or do { next if $!{EINTR}; last; }; spawn(\function, whatever); } #!/usr/bin/perl -w ## new frankenstein! use strict; use POSIX (); use POSIX 'WNOHANG'; use Errno; use IO::Socket; use FindBin (); use File::Basename (); use File::Spec::Functions; use Net::hostent; use Carp; $|=1; my $pid; open (DIED, /var/log/daemon_log) or warn $!; sub logmsg { print DIED $0 $$: @_ at , scalar localtime, \n } my $listen_socket = IO::Socket::INET-new(LocalPort = 1081, LocalAddr = '127.0.0.1', Proto = 'tcp', Listen= SOMAXCONN, Reuse = 1 ) or die can make a tcp server on port 1080 $!; # make the daemon cross-platform, so exec always calls the script # itself with the right path, no matter how the script was invoked. my $script = File::Basename::basename($0); my $SELF = catfile $FindBin::Bin, $script; # POSIX unmasks the sigprocmask properly my $sigset = POSIX::SigSet-new(); my $action = POSIX::SigAction-new('sigHUP_handler', $sigset, POSIX::SA_NODEFER); my $action_alrm = POSIX::SigAction-new('sigALRM_handler', $sigset, POSIX::SA_NODEFER); POSIX::sigaction(POSIX::SIGHUP, $action); POSIX::sigaction(POSIX::SIGALRM, $action_alrm); sub sigHUP_handler { print got SIGHUP\n; exec($SELF, @ARGV)
Re: mod_perl v2 Forking
Hi, That sound like one way to go, I want to be very careful with something like this. You speak as if restoring 5.6 behaviour is the best or only way to go. Do you see any other alternatives? Thanks, Eric At 04:57 PM 9/16/03 +0200, Rafael Garcia-Suarez wrote: Eric Frazier wrote: ... But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. Mostly, yes. Look at the perldelta manpage that is distributed with perl 5.8.0, section Safe Signals. I did read that, it seems kind of misleading. The 5.8 IPC doc was more helpful, but I still didn't get a clear idea how to handle this and the examples are not updated yet. If you want to restore the 5.6-ish unsafe signal handling, this is not possible with 5.8.0 :(. But, as it has been acknowledged that this unsafe behaviour is desirable in some cases, it will be possible with perl 5.8.1. You can grab a 5.8.1 release candidate 4 from CPAN : http://search.cpan.org/~jhi/ (RC5 should be out in a few days) and see with it if using unsafe signal handlers solves your problem. You can enable them with the PERL_SIGNALS environment variable. Here's the relevant part of the perlrun manpage that comes with perl 5.8.1 RC4 : =item PERL_SIGNALS In Perls 5.8.1 and later. If set to Cunsafe the pre-Perl-5.8.0 signals behaviour (immediate but unsafe) is restored. If set to Csafe the safe (or deferred) signals are used. See Lperlipc/Deferred Signals (Safe signals). HTH. (250) 655 - 9513 (PST Time Zone) Inquiry is fatal to certainty. -- Will Durant
RE: mod_perl v2 Forking
Hi, Doing this works for me. But I am ending up with some errors that I didn't have before. Of course my bosses would get mad if I posted all of the code involed, but basicly a database connection that was working fine is now returning mysql server has gone away, meaning that the connection got killed. What is weird/scary, is that if I change your $SIG{CHLD} = 'IGNORE'; back to the handler I was using, the database error goes away, but I am back were I was. Fun huh? :) Thanks, Eric At 03:57 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, I had a problem with 5.8.1 and forking in that I was either getting zombies using the 5.6 examples or the parent was dying, depending on which example was used. The way round I found was to: # ignore the child, good rule for life $SIG{CHLD} = 'IGNORE'; # then sort out the socket my $server = new IO::Socket::INET(LocalPort = $port, Type = SOCK_STREAM, Proto = tcp, Listen = 5) or die some error; # wait for a connection while(my $client = $server-accept()) { my $pid = fork; die Error. Fork: $!\n unless defined $pid; if($pid == 0) { # all your child code here # when it's done, kill the child: exit(0); } } This seemes reasonably stable. If anybody has a better way, then I'm all ears. Cheers! -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:24 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: mod_perl v2 Forking Hi, I guess this is off topic for this list, since I would be doing this no matter if I was running CGI or mod_perl or whatever. I am pretty desparate to get this working, and if anyone wants to earn some cash helping me fix things PLEASE call me at 250 655-9513. I have been trying to accomplish the same thing as Cameron, but with the detaching stuff it seemed a lot easier to make a server with IO::Select and not actually start the server from mod_perl. The end result hopefully will be a web user being able to start some things that take time, but not screw things up by interrupting them. But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. The thing is somehow this ends up killing off my parent process, just like in this post: http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html So this is happening to me as well, however the guy in the above example had his problem solved by using Errno and looking for EINTR if that error is raised then catch it and move on, I did get one maybe helpfull thing from my log: Erro was %! ./franken_socket.pl 8607: got - CHLD at Tue Sep 16 02:17:42 2003 I got forked ./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003 begat 8607 ./franken_socket.pl 8599: got - CHLD at Tue Sep 16 02:17:54 2003 ./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003 reaped 1Erro was No child processes %! So it looks like the parent got killed on that error No child process This code works just fine on 5.6 since it is about 150% from examples :) The above is the result of connecting, doing a who, and doing dienow to test the alarm. I also found this: http://archive.develooper.com/[EMAIL PROTECTED]/msg03022.html Which totaly describes my problem as well, but shows it happening with perl 5.8.1.. I'd imagine that your accept() isn't being restarted. How does it work if you change the loop to look like this? use Errno; while (1) { my $client = $server-accept or do { next if $!{EINTR}; last; }; spawn(\function, whatever); } #!/usr/bin/perl -w ## new frankenstein! use strict; use POSIX (); use POSIX 'WNOHANG'; use Errno; use IO::Socket; use FindBin (); use File::Basename (); use File::Spec::Functions; use Net::hostent; use Carp; $|=1; my $pid; open (DIED, /var/log/daemon_log) or warn $!; sub logmsg { print DIED $0 $$: @_ at , scalar localtime, \n } my $listen_socket = IO::Socket::INET-new(LocalPort = 1081, LocalAddr = '127.0.0.1', Proto = 'tcp', Listen= SOMAXCONN, Reuse = 1 ) or die can make a tcp server on port 1080 $!; # make the daemon cross-platform, so exec always calls the script # itself with the right path, no matter how the script was invoked. my $script = File::Basename::basename($0); my $SELF = catfile $FindBin::Bin, $script; # POSIX unmasks the sigprocmask
RE: mod_perl v2 Forking
Hi, is the database connection created in the child or before it? If it's created inside the child then it'll die ungracefully when the child dies, so put something nice and fluffy to close it before the exit. Otherwise, I don't know I'm afraid. -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:57 To: Stephen Hardisty Cc: [EMAIL PROTECTED] Subject: RE: mod_perl v2 Forking Hi, Doing this works for me. But I am ending up with some errors that I didn't have before. Of course my bosses would get mad if I posted all of the code involed, but basicly a database connection that was working fine is now returning mysql server has gone away, meaning that the connection got killed. What is weird/scary, is that if I change your $SIG{CHLD} = 'IGNORE'; back to the handler I was using, the database error goes away, but I am back were I was. Fun huh? :) Thanks, Eric At 03:57 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, I had a problem with 5.8.1 and forking in that I was either getting zombies using the 5.6 examples or the parent was dying, depending on which example was used. The way round I found was to: # ignore the child, good rule for life $SIG{CHLD} = 'IGNORE'; # then sort out the socket my $server = new IO::Socket::INET(LocalPort = $port, Type = SOCK_STREAM, Proto = tcp, Listen = 5) or die some error; # wait for a connection while(my $client = $server-accept()) { my $pid = fork; die Error. Fork: $!\n unless defined $pid; if($pid == 0) { # all your child code here # when it's done, kill the child: exit(0); } } This seemes reasonably stable. If anybody has a better way, then I'm all ears. Cheers! -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:24 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: mod_perl v2 Forking Hi, I guess this is off topic for this list, since I would be doing this no matter if I was running CGI or mod_perl or whatever. I am pretty desparate to get this working, and if anyone wants to earn some cash helping me fix things PLEASE call me at 250 655-9513. I have been trying to accomplish the same thing as Cameron, but with the detaching stuff it seemed a lot easier to make a server with IO::Select and not actually start the server from mod_perl. The end result hopefully will be a web user being able to start some things that take time, but not screw things up by interrupting them. But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. The thing is somehow this ends up killing off my parent process, just like in this post: http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html So this is happening to me as well, however the guy in the above example had his problem solved by using Errno and looking for EINTR if that error is raised then catch it and move on, I did get one maybe helpfull thing from my log: Erro was %! ./franken_socket.pl 8607: got - CHLD at Tue Sep 16 02:17:42 2003 I got forked ./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003 begat 8607 ./franken_socket.pl 8599: got - CHLD at Tue Sep 16 02:17:54 2003 ./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003 reaped 1Erro was No child processes %! So it looks like the parent got killed on that error No child process This code works just fine on 5.6 since it is about 150% from examples :) The above is the result of connecting, doing a who, and doing dienow to test the alarm. I also found this: http://archive.develooper.com/[EMAIL PROTECTED]/msg03022.html Which totaly describes my problem as well, but shows it happening with perl 5.8.1.. I'd imagine that your accept() isn't being restarted. How does it work if you change the loop to look like this? use Errno; while (1) { my $client = $server-accept or do { next if $!{EINTR}; last; }; spawn(\function, whatever); } #!/usr/bin/perl -w ## new frankenstein! use strict; use POSIX (); use POSIX 'WNOHANG'; use Errno; use IO::Socket; use FindBin (); use File::Basename (); use File::Spec::Functions; use Net::hostent; use Carp; $|=1; my $pid; open (DIED, /var/log/daemon_log) or warn $!; sub logmsg { print DIED $0 $$: @_ at , scalar localtime, \n } my $listen_socket = IO::Socket::INET-new(LocalPort = 1081, LocalAddr = '127.0.0.1', Proto
RE: mod_perl v2 Forking
Hi, Well, I am not sure if this is going to be the best solution long term, but it works! while ( $connection ){ my $return_value = undef; if(/quit|exit/i){ last;} elsif (/closeme/i ) {$connection-close(); } elsif (/date|time/i){ printf $connection %s\n, scalar localtime; exit(0); } that did call to a sub, and then connected to a database. I am wondering if that connection object is better off being global. I changed the connect to be global, restarted and did a test and it worked fine! I was all ready to post back to here with the good news, when just to double check I went back and made the db connect in the local sub like before. And it still worked?! So it seems like I might be in better shape for now, but I might have some long term problems with DB connections dieing, most likely related to this child handling. I have to think that becase the query I am doing is VERY well tested and never causes an issue. Thanks tremedously for everyone's help so far, I at the very least have some directions to go in now. I still would very much like to learn what the correct, put it in the book solution should be.. Eric At 03:57 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, I had a problem with 5.8.1 and forking in that I was either getting zombies using the 5.6 examples or the parent was dying, depending on which example was used. The way round I found was to: # ignore the child, good rule for life $SIG{CHLD} = 'IGNORE'; # then sort out the socket my $server = new IO::Socket::INET(LocalPort = $port, Type = SOCK_STREAM, Proto = tcp, Listen = 5) or die some error; # wait for a connection while(my $client = $server-accept()) { my $pid = fork; die Error. Fork: $!\n unless defined $pid; if($pid == 0) { # all your child code here # when it's done, kill the child: exit(0); } } This seemes reasonably stable. If anybody has a better way, then I'm all ears. Cheers! -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:24 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: mod_perl v2 Forking Hi, I guess this is off topic for this list, since I would be doing this no matter if I was running CGI or mod_perl or whatever. I am pretty desparate to get this working, and if anyone wants to earn some cash helping me fix things PLEASE call me at 250 655-9513. I have been trying to accomplish the same thing as Cameron, but with the detaching stuff it seemed a lot easier to make a server with IO::Select and not actually start the server from mod_perl. The end result hopefully will be a web user being able to start some things that take time, but not screw things up by interrupting them. But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. The thing is somehow this ends up killing off my parent process, just like in this post: http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html So this is happening to me as well, however the guy in the above example had his problem solved by using Errno and looking for EINTR if that error is raised then catch it and move on, I did get one maybe helpfull thing from my log: Erro was %! ./franken_socket.pl 8607: got - CHLD at Tue Sep 16 02:17:42 2003 I got forked ./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003 begat 8607 ./franken_socket.pl 8599: got - CHLD at Tue Sep 16 02:17:54 2003 ./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003 reaped 1Erro was No child processes %! So it looks like the parent got killed on that error No child process This code works just fine on 5.6 since it is about 150% from examples :) The above is the result of connecting, doing a who, and doing dienow to test the alarm. I also found this: http://archive.develooper.com/[EMAIL PROTECTED]/msg03022.html Which totaly describes my problem as well, but shows it happening with perl 5.8.1.. I'd imagine that your accept() isn't being restarted. How does it work if you change the loop to look like this? use Errno; while (1) { my $client = $server-accept or do { next if $!{EINTR}; last; }; spawn(\function, whatever); } #!/usr/bin/perl -w ## new frankenstein! use strict; use POSIX (); use POSIX 'WNOHANG'; use Errno; use IO::Socket; use FindBin (); use File::Basename ();
RE: mod_perl v2 Forking
:) I think that makes sense. It was created in the child. It seemed to be fixed when I made the connection global. When I tried the connection in the child again it might well have been a lucky transpireing of events that let the child stay alive long enough for the query to get completed. So I should keep it global I think. Thanks, Eric At 04:24 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, is the database connection created in the child or before it? If it's created inside the child then it'll die ungracefully when the child dies, so put something nice and fluffy to close it before the exit. Otherwise, I don't know I'm afraid. -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:57 To: Stephen Hardisty Cc: [EMAIL PROTECTED] Subject: RE: mod_perl v2 Forking Hi, Doing this works for me. But I am ending up with some errors that I didn't have before. Of course my bosses would get mad if I posted all of the code involed, but basicly a database connection that was working fine is now returning mysql server has gone away, meaning that the connection got killed. What is weird/scary, is that if I change your $SIG{CHLD} = 'IGNORE'; back to the handler I was using, the database error goes away, but I am back were I was. Fun huh? :) Thanks, Eric At 03:57 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, I had a problem with 5.8.1 and forking in that I was either getting zombies using the 5.6 examples or the parent was dying, depending on which example was used. The way round I found was to: # ignore the child, good rule for life $SIG{CHLD} = 'IGNORE'; # then sort out the socket my $server = new IO::Socket::INET(LocalPort = $port, Type = SOCK_STREAM, Proto = tcp, Listen = 5) or die some error; # wait for a connection while(my $client = $server-accept()) { my $pid = fork; die Error. Fork: $!\n unless defined $pid; if($pid == 0) { # all your child code here # when it's done, kill the child: exit(0); } } This seemes reasonably stable. If anybody has a better way, then I'm all ears. Cheers! -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:24 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: mod_perl v2 Forking Hi, I guess this is off topic for this list, since I would be doing this no matter if I was running CGI or mod_perl or whatever. I am pretty desparate to get this working, and if anyone wants to earn some cash helping me fix things PLEASE call me at 250 655-9513. I have been trying to accomplish the same thing as Cameron, but with the detaching stuff it seemed a lot easier to make a server with IO::Select and not actually start the server from mod_perl. The end result hopefully will be a web user being able to start some things that take time, but not screw things up by interrupting them. But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. The thing is somehow this ends up killing off my parent process, just like in this post: http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html So this is happening to me as well, however the guy in the above example had his problem solved by using Errno and looking for EINTR if that error is raised then catch it and move on, I did get one maybe helpfull thing from my log: Erro was %! ./franken_socket.pl 8607: got - CHLD at Tue Sep 16 02:17:42 2003 I got forked ./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003 begat 8607 ./franken_socket.pl 8599: got - CHLD at Tue Sep 16 02:17:54 2003 ./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003 reaped 1Erro was No child processes %! So it looks like the parent got killed on that error No child process This code works just fine on 5.6 since it is about 150% from examples :) The above is the result of connecting, doing a who, and doing dienow to test the alarm. I also found this: http://archive.develooper.com/[EMAIL PROTECTED]/msg03022.html Which totaly describes my problem as well, but shows it happening with perl 5.8.1.. I'd imagine that your accept() isn't being restarted. How does it work if you change the loop to look like this? use Errno; while (1) { my $client = $server-accept or do { next if $!{EINTR}; last; }; spawn(\function, whatever); } #!/usr/bin/perl -w ## new frankenstein! use strict; use POSIX (); use POSIX 'WNOHANG'; use Errno; use IO::Socket;
RE: mod_perl v2 Forking
Haven't read much of this thread, but is POE an option ? -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 13:17 To: Stephen Hardisty Cc: [EMAIL PROTECTED] Subject: RE: mod_perl v2 Forking :) I think that makes sense. It was created in the child. It seemed to be fixed when I made the connection global. When I tried the connection in the child again it might well have been a lucky transpireing of events that let the child stay alive long enough for the query to get completed. So I should keep it global I think. Thanks, Eric At 04:24 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, is the database connection created in the child or before it? If it's created inside the child then it'll die ungracefully when the child dies, so put something nice and fluffy to close it before the exit. Otherwise, I don't know I'm afraid. -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:57 To: Stephen Hardisty Cc: [EMAIL PROTECTED] Subject: RE: mod_perl v2 Forking Hi, Doing this works for me. But I am ending up with some errors that I didn't have before. Of course my bosses would get mad if I posted all of the code involed, but basicly a database connection that was working fine is now returning mysql server has gone away, meaning that the connection got killed. What is weird/scary, is that if I change your $SIG{CHLD} = 'IGNORE'; back to the handler I was using, the database error goes away, but I am back were I was. Fun huh? :) Thanks, Eric At 03:57 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, I had a problem with 5.8.1 and forking in that I was either getting zombies using the 5.6 examples or the parent was dying, depending on which example was used. The way round I found was to: # ignore the child, good rule for life $SIG{CHLD} = 'IGNORE'; # then sort out the socket my $server = new IO::Socket::INET(LocalPort = $port, Type = SOCK_STREAM, Proto = tcp, Listen = 5) or die some error; # wait for a connection while(my $client = $server-accept()) { my $pid = fork; die Error. Fork: $!\n unless defined $pid; if($pid == 0) { # all your child code here # when it's done, kill the child: exit(0); } } This seemes reasonably stable. If anybody has a better way, then I'm all ears. Cheers! -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:24 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: mod_perl v2 Forking Hi, I guess this is off topic for this list, since I would be doing this no matter if I was running CGI or mod_perl or whatever. I am pretty desparate to get this working, and if anyone wants to earn some cash helping me fix things PLEASE call me at 250 655-9513. I have been trying to accomplish the same thing as Cameron, but with the detaching stuff it seemed a lot easier to make a server with IO::Select and not actually start the server from mod_perl. The end result hopefully will be a web user being able to start some things that take time, but not screw things up by interrupting them. But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. The thing is somehow this ends up killing off my parent process, just like in this post: http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html So this is happening to me as well, however the guy in the above example had his problem solved by using Errno and looking for EINTR if that error is raised then catch it and move on, I did get one maybe helpfull thing from my log: Erro was %! ./franken_socket.pl 8607: got - CHLD at Tue Sep 16 02:17:42 2003 I got forked ./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003 begat 8607 ./franken_socket.pl 8599: got - CHLD at Tue Sep 16 02:17:54 2003 ./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003 reaped 1Erro was No child processes %! So it looks like the parent got killed on that error No child process This code works just fine on 5.6 since it is about 150% from examples :) The above is the result of connecting, doing a who, and doing dienow to test the alarm. I also found this: http://archive.develooper.com/[EMAIL PROTECTED]/msg03022.html Which totaly describes my problem as well, but shows
RE: mod_perl v2 Forking
I guess you could, but if there's already a load of code mightn't be a bit of a pain POE-ing it? -Original Message- From: Gareth Kirwan [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 16:50 To: 'Eric Frazier'; Stephen Hardisty Cc: [EMAIL PROTECTED] Subject: RE: mod_perl v2 Forking Haven't read much of this thread, but is POE an option ? -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 13:17 To: Stephen Hardisty Cc: [EMAIL PROTECTED] Subject: RE: mod_perl v2 Forking :) I think that makes sense. It was created in the child. It seemed to be fixed when I made the connection global. When I tried the connection in the child again it might well have been a lucky transpireing of events that let the child stay alive long enough for the query to get completed. So I should keep it global I think. Thanks, Eric At 04:24 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, is the database connection created in the child or before it? If it's created inside the child then it'll die ungracefully when the child dies, so put something nice and fluffy to close it before the exit. Otherwise, I don't know I'm afraid. -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:57 To: Stephen Hardisty Cc: [EMAIL PROTECTED] Subject: RE: mod_perl v2 Forking Hi, Doing this works for me. But I am ending up with some errors that I didn't have before. Of course my bosses would get mad if I posted all of the code involed, but basicly a database connection that was working fine is now returning mysql server has gone away, meaning that the connection got killed. What is weird/scary, is that if I change your $SIG{CHLD} = 'IGNORE'; back to the handler I was using, the database error goes away, but I am back were I was. Fun huh? :) Thanks, Eric At 03:57 PM 9/16/03 +0100, Stephen Hardisty wrote: Hi, I had a problem with 5.8.1 and forking in that I was either getting zombies using the 5.6 examples or the parent was dying, depending on which example was used. The way round I found was to: # ignore the child, good rule for life $SIG{CHLD} = 'IGNORE'; # then sort out the socket my $server = new IO::Socket::INET(LocalPort = $port, Type = SOCK_STREAM, Proto = tcp, Listen = 5) or die some error; # wait for a connection while(my $client = $server-accept()) { my $pid = fork; die Error. Fork: $!\n unless defined $pid; if($pid == 0) { # all your child code here # when it's done, kill the child: exit(0); } } This seemes reasonably stable. If anybody has a better way, then I'm all ears. Cheers! -Original Message- From: Eric Frazier [mailto:[EMAIL PROTECTED] Sent: 16 September 2003 12:24 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: mod_perl v2 Forking Hi, I guess this is off topic for this list, since I would be doing this no matter if I was running CGI or mod_perl or whatever. I am pretty desparate to get this working, and if anyone wants to earn some cash helping me fix things PLEASE call me at 250 655-9513. I have been trying to accomplish the same thing as Cameron, but with the detaching stuff it seemed a lot easier to make a server with IO::Select and not actually start the server from mod_perl. The end result hopefully will be a web user being able to start some things that take time, but not screw things up by interrupting them. But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I know that there is a change in how signals are handled, they call it deferred signal handling because Perl now is suppose to wait until the Interpeter is in a safe state. As I understand it this might avoid some things like core dumps or other errors related to dieing while trying to do something besides dieing. The thing is somehow this ends up killing off my parent process, just like in this post: http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html So this is happening to me as well, however the guy in the above example had his problem solved by using Errno and looking for EINTR if that error is raised then catch it and move on, I did get one maybe helpfull thing from my log: Erro was %! ./franken_socket.pl 8607: got - CHLD at Tue Sep 16 02:17:42 2003 I got forked ./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003 begat 8607 ./franken_socket.pl 8599: got - CHLD at Tue Sep 16 02:17:54 2003 ./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003 reaped 1Erro was No child processes %! So it looks like the parent got killed on that error No child process This code works
ensuring singularity of users
Hi, I'd like to implement something that tries to ensure that one user can't masquerade as multiple users. I'm looking into Captchas, but I'm wondering what other options there are, and what folks think about that here. My impression so far is that there's no 100% effective way to do it. If there's a better place to ask about this, please let me know. Thanks, Zack -- Zack Brown
client-side certificate extraction
ModPerlers, We have a requirement to change our web servers to require client-side ssl certificates by Oct 1, 2003. Can someone give me some pointers on how mod_perl might be used to extract the user's name at login time. I suspect this might require a handler. This might be used to avoid multiple logins. Thanks Chuck winmail.dat
Re: Can't build Apache::Dispatch on Windows / Perl 5.8.0
Steve Hay wrote: [...] What other misleading parts are we talking about? I'm just getting confused with changes in Apache itself, I think. Apache 1 used to have lib, libexec and modules: lib stored the static .lib's, libexec stored the import libraries for various dll's, and modules stored the .so (aka .dll) files for Apache modules. But with Apache 2, I have only lib and modules. The latter still (rightly) contains just the .so files for Apache modules, so presumably all the static *and* import libraries are thrown together into lib now? Now, my mp2's Apache::BuildConfig contains this: 'MODPERL_AP_LIBDIR' = 'C:\\apache2/lib', 'MODPERL_AP_LIBEXECDIR' = 'C:\\apache2/modules', which I find confusing. The first line there is fine, but the second line seems wrong. One would think that MODPERL_AP_LIBEXECDIR specifies where Apache's libexec directory is, but there isn't one any more! Furthermore, it seems that the files that would have been in it are now in lib? So maybe MODPERL_AP_LIBEXECDIR should say C:\\apache2/lib (that's an ugly mess of back- and forward slashes too), and that should be used as the location to install mod_perl.lib into (since mod_perl.lib is one of these import library things). That would be wrong as things stand, though, because MODPERL_AP_LIBEXECDIR seems to be used as the location to install mod_perl.so, which should indeed be C:\\apache2/modules. Perhaps the simplest thing would be to rename MODPERL_AP_LIBEXECDIR to MODPERL_AP_MODDIR since it specifies where Apache's modules directory is and there isn't a libexec anymore? It's the problem with apxs then, since mp2 just uses the same names as apxs: ~/httpd/prefork/bin/apxs -q LIBEXECDIR /home/stas/httpd/prefork/modules ~/httpd/prefork/bin/apxs -q LIBDIR /home/stas/httpd/prefork/lib I'm not sure if we want to contradict apxs on that. My suggestion is to remove the need for developers to know about those dirs/vars and have it all abstracted behind ModPerl::MM (which already does most of it). If it gets ported to mp1 and uses the same API then no matter what happens behind the scenes it'll do the right thing for the developer. __ 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
(please trim your followups!) Re: mod_perl v2 Forking
whoah! people, please trim the irrelevant stuff in your replies, this thread keeps on growing for no reason. Perhaps you should read http://perl.apache.org/maillist/email-etiquette.html#Extracts_From_Other_Posts if you are new to this list. We want these threads to be useful for those who will later read them in archives. Thank you! __ 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
[Fwd: mod_perl and PHP don't share the environment nicely]
Forwarded on behalf of Andy Lester [EMAIL PROTECTED] Original Message Date: Mon, 15 Sep 2003 14:53:15 -0500 From: Andy Lester [EMAIL PROTECTED] To: Perl 5 Porters [EMAIL PROTECTED], [EMAIL PROTECTED] PHP and mod_perl do not share the environment nicely. PHP's putenv() will cause segfaults. Caveats should be distributed all around in PHP and mod_perl, at the very least, with the following two options: * Recompile Perl itself with -DPERL_USE_SAFE_PUTENV, then recompile mod_perl and Apache, in that order. * Replace all PHP calls to putenv() with apache_setenv(). I'm publishing this so that it will be archived and Googlable. Most of the following is written by, and based research from, Nick Dronen. xoxo, Andy ++ Background / Affected Configuration ++ We've been seeing segmentation faults in an Apache configured with mod_perl and PHP. There are several posts, all to archived PHP mailing lists, with stack traces that match the ones we've been seeing, but no useful resolutions. This document describes the problem and solution so other users who encounter this problem can acquire a clear idea what to do. At first, it looks like the problem is caused by either PHP or the C runtime library. It's not. It's caused by the use of both mod_perl and mod_php in Apache, if (and hopefully only if) your perl is not configured to use the C library's putenv(3) routine. Other Apaches configured to use mod_perl and any other module that manipulates the process's environment may also be affected. At any rate, this is what we're using: * Apache 1.3.28 * PHP 4.3.3 * Perl 5.8.0 * mod_perl 1.28 ++ Symptoms - PHP ++ If PHP is configured with --enable-debug, errors containing apparantly corrupt memory will appear in the log files. (Reformatted here to make it less unreadable.) [Thu Aug 28 13:11:47 2003] Script: '/path/to/file.html' /usr/src/php-4.3.3/Zend/zend_opcode.c(159) : Block 0x08D77C58 status: /usr/src/php-4.3.3/Zend/zend_variables.c(44): Actual location (location was relayed) Beginning: OK (allocated on Zend/zend_language_scanner.c:4718, 64 bytes) End: Overflown (magic=0x08376158 instead of 0x2A8FCC84) At least 4 bytes overflown --- [Thu Aug 28 13:11:47 2003] [error] php Warning: String is not zero-terminated ([EMAIL PROTECTED]) (source: /usr/src/php-4.3.3/Zend/zend_opcode.c:159) in Unknown on line 0 [Thu Aug 28 13:11:47 2003] Script: '/path/to/file.html' --- /usr/src/php-4.3.3/Zend/zend_opcode.c(159): Block 0x08D77D00 status: /usr/src/php-4.3.3/Zend/zend_variables.c(44): Actual location (location was relayed) Beginning: Overrun (magic=0x083763F0, expected=0x7312F8DC) [Thu Aug 28 13:11:47 2003] [notice] child pid 3983 exit signal Segmentation fault Note that the garbage in the String is not zero-terminated line is about 80 characters long and filled with randomness. It's been truncated here. Symptoms - core dumps If your apache is able to create a core file, you can examine the stack trace by doing: $ gdb /path/to/httpd /path/to/core or $ dbx /path/to/httpd /path/to/core In some cases -- specifically when httpd is running suid/sgid -- Apache will not dump core. There is a kernel patch for Linux that changes this behavior so you can get a core dump. The patch is available for Linux kernel versions 2.4.x and 2.5.x at: http://www.ussg.iu.edu/hypermail/linux/kernel/0204.2/1170.html Memory madness can cause segmentation faults at any number of places in a complex program, depending on how memory is accessed. Below is one of the more common stack traces we've seen . A strong sign that you're suffering from this problem is the presence of putenv(3) in the stack. If your stacks look different than this, a sample program appears at the end of this document, along with instructions how to run it. If the program segfaults, you might be seeing the same problem. Here's a classic stack trace (also reformatted a bit): #0 0x4207448f in _int_realloc () from /lib/i686/libc.so.6 #0 0x4207448f in _int_realloc () from /lib/i686/libc.so.6 #1 0x42073416 in realloc () from /lib/i686/libc.so.6 #2 0x4202ab8f in __add_to_environ () from /lib/i686/libc.so.6 #3 0x4202aab8 in putenv () from /lib/i686/libc.so.6 #4 0x080f68ba in zif_putenv ( ht=1, return_value=0x8c01ffc, this_ptr=0x0, return_value_used=0) at /usr/src/php-4.3.3/ext/standard/basic_functions.c:1347 #5 0x080ce2e6 in execute
Re: ensuring singularity of users
On Tue, 2003-09-16 at 12:46, Zack Brown wrote: I'd like to implement something that tries to ensure that one user can't masquerade as multiple users. We talked quite a bit about preventing multiple logins recently. I think it was last week. Check the archives. I'm looking into Captchas Are you trying to prevent multiple people from using the same account, or one person from having multiple windows open, or anyone from using bots? My impression so far is that there's no 100% effective way to do it. That's correct, unless you have control over the client machines. You can require cookies, which will tell you if multiple users on separate browsers are sharing a login, but that's about all you can do without possibly breaking your system for someone. - Perrin
Re: ensuring singularity of users
Perrin Harkins wrote: On Tue, 2003-09-16 at 12:46, Zack Brown wrote: I'd like to implement something that tries to ensure that one user can't masquerade as multiple users. We talked quite a bit about preventing multiple logins recently. I think it was last week. Check the archives. Perhaps someone would like to summarize these and put a short tutorial on perl.apache.org? This question seems to come back pretty often. __ 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: ensuring singularity of users
On Tue, Sep 16, 2003 at 01:55:46PM -0400, Perrin Harkins wrote: On Tue, 2003-09-16 at 12:46, Zack Brown wrote: I'd like to implement something that tries to ensure that one user can't masquerade as multiple users. We talked quite a bit about preventing multiple logins recently. I think it was last week. Check the archives. I'm looking into Captchas Are you trying to prevent multiple people from using the same account, or one person from having multiple windows open, or anyone from using bots? I want to prevent one person from having multiple accounts. My impression so far is that there's no 100% effective way to do it. That's correct, unless you have control over the client machines. You can require cookies, which will tell you if multiple users on separate browsers are sharing a login, but that's about all you can do without possibly breaking your system for someone. Someone can appear to be multiple people by disabling cookies though. I want to ensure that if person A registers to use a site, they are not able to register again using a different login, or else they are only able to register a small enough number of times that it isn't worth it for them to do so. Be well, Zack - Perrin -- Zack Brown
Re: ensuring singularity of users
On Tue, 2003-09-16 at 14:42, Zack Brown wrote: I want to prevent one person from having multiple accounts. Okay. That's correct, unless you have control over the client machines. You can require cookies, which will tell you if multiple users on separate browsers are sharing a login, but that's about all you can do without possibly breaking your system for someone. Someone can appear to be multiple people by disabling cookies though. That's why I said require cookies: you reject all requests from people who don't allow cookies, and then you use the cookies for tracking. A moderately tech-savvy user can delete your cookie and log in again under a separate account, but people who are scared of opening up prefs and messing with cookie management (or people who simply don't care enough to bother) will be stopped. If you have a fixed set of clients who are definitely not using proxies, you can use IP instead of cookies. I want to ensure that if person A registers to use a site, they are not able to register again using a different login Ask them for a credit card then. There's no other way that will really work 100% of the time. - Perrin
Re: ensuring singularity of users
On Tue, Sep 16, 2003 at 03:11:04PM -0400, Perrin Harkins wrote: On Tue, 2003-09-16 at 14:42, Zack Brown wrote: I want to prevent one person from having multiple accounts. Okay. That's correct, unless you have control over the client machines. You can require cookies, which will tell you if multiple users on separate browsers are sharing a login, but that's about all you can do without possibly breaking your system for someone. Someone can appear to be multiple people by disabling cookies though. That's why I said require cookies: you reject all requests from people who don't allow cookies, and then you use the cookies for tracking. A moderately tech-savvy user can delete your cookie and log in again under a separate account, but people who are scared of opening up prefs and messing with cookie management (or people who simply don't care enough to bother) will be stopped. If you have a fixed set of clients who are definitely not using proxies, you can use IP instead of cookies. Any simple way to defeat the system will end up not working. I'm looking for something truly secure. I want to ensure that if person A registers to use a site, they are not able to register again using a different login Ask them for a credit card then. There's no other way that will really work 100% of the time. That's what I figured. Even that won't work all the time, but it will probably limit people to one login per credit card. Unfortunately, then I have to get a merchant account, and there will always be some users who just don't like giving out credit card information. Be well, Zack - Perrin -- Zack Brown
Summary: identifiying unique users
Stas Bekman wrote: Perrin Harkins wrote: Zack Brown wrote: I'd like to implement something that tries to ensure that one user can't masquerade as multiple users. We talked quite a bit about preventing multiple logins recently. I think it was last week. Check the archives. Perhaps someone would like to summarize these and put a short tutorial on perl.apache.org? This question seems to come back pretty often. I tried to recap the discussion and looked in the archive. Am I wrong when I summarize it with it is not possible in a foolproof way? Or, with a bit more words: | How to avoid multiple logins? | | The short answer is: you can't. To ensure that a login is only used | by one person at the same time, you need to have some method to | identify persons. You can't do that based on the information you | can get from a request. And even if you could get information, there | is no guarantee that the information is correct - it can be faked | | IP-address |can hardly be mentioned as a contestor with proxy servers, |firewalls, anonimyzers and the rest; | | MAC-address |there are reports that it is able to get this as part of the UUID |or in an SSL key, but it can't be trusted as a user could simply |change this or make it a non-unique value | | SSL session id |it seems that SSL_SESSION_ID offers some unique recognition of |the client; it stays valid for some time (hours, days) and is |there to avoid needless handshaking | | Cookie |you can do something supplying a unique identifier in a cookie |that you provide, but chances are that you lock up your system. |The interesting issue is 'when do you expire a cookie/user link?' |Do this too early and you will allow logins to hop from one person |to the other, do this too late and you will have problems with |people that (for instance) suffer from a crashing browser | | Where IP and MAC address seem totally unusable, the SSL session and | your own cookie offer a mechanism that can of use. If you aim at the | not-so-technical user and are prepared to be rude to those users | that tamper with your system, you can make it work to some extent. Comments and additions to this summary are welcome through the list. After polishing this, it can be brought into the proper docs. --Frank
Re: Summary: identifiying unique users
Hi all, On Tue, 16 Sep 2003, Frank Maas wrote: | How to avoid multiple logins? | | The short answer is: you can't. Sure you can. Charge $10 per login. 73, Ged.
Re: Summary: identifiying unique users
On Tue, Sep 16, 2003 at 10:46:28PM +0100, Ged Haywood wrote: Hi all, On Tue, 16 Sep 2003, Frank Maas wrote: | How to avoid multiple logins? | | The short answer is: you can't. Sure you can. Charge $10 per login. If they can make more than $10 by faking a login, then it's worth it. 73, Ged. -- Zack Brown