[mp2] Segfault on using $r->content_type()
1. Problem Description: I have an intermittent segfault with one particular ResponseHandler. The segfault, when it occurs, is triggered by calling $r->content_type in a lightly modified CGI::Simple (I made changes to it as it wasn't playing well with mod_perl2). What might be going awry? The relevant changes to CGI::Simple are in the header sub: for ( @other ) { # Don't use \s because of perl bug 21951 next unless my ( $header, $value ) = /([^ \r\n\t=]+)=\"?(.+?)\"?$/; $header =~ s/^(\w)(.*)/\u$1\L$2/; $_ = [ $header, $self->unescapeHTML($value) ]; } $type ||= 'text/html' unless defined $type; $type .= "; charset=$charset" if $type and $type =~ m!^text/! and $type !~ /\bcharset\b/; my $protocol = $ENV{SERVER_PROTOCOL} || 'HTTP/1.0'; push @header, $protocol . ' ' . ( $status || '200 OK' ) if $nph; push @header, ["Server", server_software() ] if $nph; push @header, ["Status", $status ] if $status; push @header, ["Window-Target", $target ]if $target; if ( $p3p ) { $p3p = join ' ', @$p3p if ref( $p3p ) eq 'ARRAY'; push( @header, ["P3P", qq(policyref="/w3c/p3p.xml", CP="$p3p")] ); } # push all the cookies -- there may be several if ( $cookie ) { my @cookie = ref $cookie eq 'ARRAY' ? @{$cookie} : $cookie; for my $cookie ( @cookie ) { my $cs = ref $cookie eq 'CGI::Simple::Cookie' ? $cookie->as_string : $cookie; push @header, ["Set-Cookie", $cs] if $cs; } } # if the user indicates an expiration time, then we need both an Expires # and a Date header (so that the browser is using OUR clock) $expires = 'now' if $self->no_cache;# encourage no caching via expires now push @header, ["Expires", CGI::Simple::Util::expires( $expires, 'http' ) ] if $expires; push @header, ["Date", CGI::Simple::Util::expires( 0, 'http' ) ] if defined $expires || $cookie || $nph; push @header, ["Pragma", "no-cache"] if $self->cache or $self->no_cache; push @header, ["Content-Disposition", "attachment; filename=\"$attachment\"" ] if $attachment; push @header, @other; push @header, ["Content-Type", $type] if $type; if ( $self->{'.mod_perl'} and not $nph ) { my $r = $self->_mod_perl_request(); $r->content_type( $type ) if $type; <--- segfault here --- $r->status($status) if $status; $r->err_headers_out->add( @$_ ) foreach @header; return ''; } my $CRLF = $self->crlf; my $header = join $CRLF, map { join ': ', @$_ } @header; $header .= $CRLF . $CRLF;# add the statutory two CRLFs return $header; 2. Used Components and their Configuration: *** mod_perl version 2.04 *** using /tmp/mod_perl-2.0.4/lib/Apache2/BuildConfig.pm *** Makefile.PL options: MP_APR_LIB => aprext MP_APXS=> /usr/sbin/apxs MP_COMPAT_1X => 1 MP_GENERATE_XS => 1 MP_LIBNAME => mod_perl MP_USE_DSO => 1 *** /usr/sbin/httpd -V Server version: Apache/2.0.52 Server built: Aug 2 2006 05:21:10 Server's Module Magic Number: 20020903:9 Architecture: 32-bit Server compiled with -D APACHE_MPM_DIR="server/mpm/prefork" -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D HTTPD_ROOT="/etc/httpd" -D SUEXEC_BIN="/usr/sbin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_LOCKFILE="logs/accept.lock" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" *** /usr/bin/ldd /usr/sbin/httpd libpcre.so.0 => /lib/libpcre.so.0 (0x00c7b000) libpcreposix.so.0 => /usr/lib/libpcreposix.so.0 (0x009f1000) libaprutil-0.so.0 => /usr/lib/libaprutil-0.so.0 (0x00dba000) libldap-2.2.so.7 => /usr/lib/libldap-2.2.so.7 (0x00aa7000) liblber-2.2.so.7 => /usr/lib/liblber-2.2.so.7 (0x00a82000) libdb-4.2.so => /lib/tls/i686/libdb-4.2.so (0x003ca000) libexpat.so.0 => /usr/lib/libexpat.so.0 (0x00357000) libapr-0.so.0 => /usr/lib/libapr-0.so.0 (0x00111000) librt.so.1 => /lib/tls/librt.so.1 (0x00133000) libm.so.6 => /lib/tls/libm.so.6 (0x004f7000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x0096f000) libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00cec000) libdl.so.2 => /lib/libdl.so.2 (0x0074a000) libc.so.6 => /lib/tls/libc.so.6 (0x00217000) libresolv.so.2 => /lib/libresolv.so.2 (0x00d53000) libsasl2.so.2 => /usr/lib/libsasl2.so.2 (0x00147000) libssl.so.4 => /lib/libssl.so.4 (0x00bdf000) libcrypto.so.4 => /lib/libcrypto.so.4 (0x0051a000) /lib/ld-linux.so.2 (0x00dd9000) libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5
Re: mod_captcha
On Wed, Jun 25, 2008 at 8:19 PM, Aaron Collins <[EMAIL PROTECTED]> wrote: > I'm trying to write a perl based mod_captcha using the recaptcha service, I > was wondering is someone could tell me which handler I should use that would > allow me to have mod_perl intercept a request going to a specific location > and if it i return true continue with the request. In my case I use > ProxyPass to pass request to java. So I'd want to have my handler jump in > give a captcha and when the captcha is approved continue forwarding it on to > the proxypass. If my understanding of mod_perl is incorrect please let me > know if their is a better logic to approach this. You can't do all that within a single HTTP request. What you need to do is check if the person is authorized already (usually through a cookie), and if not, redirect them to your captcha application. When they pass the captcha, you give them a cookie that identifies them, and that cookie allows them in to the protected area. Rather than write this all yourself, I suggest you subclass Apache::AuthTicket. - Perrin > > -- > -Aaron Collins > Systems Engineer/ Release Engineer > Hawaii Information Consortium > 220 S. King St. Suite 2190 > Honolulu, Hawaii 96813 > Cell: 808.203.8756 > Office: 808.587.4213 > > > CONFIDENTIALITY NOTICE: > This email and any attachments are confidential. If you > are not the intended recipient, you do not have permission > to disclose, copy, distribute, or open any attachments. If > you have received this email in error, please notify us > immediately by returning it to the sender and delete this > copy from your system. > > >
Re: mod_perl caching problem
On Tue, Jun 24, 2008 at 9:07 AM, william <[EMAIL PROTECTED]> wrote: > Before asking here, I had read a few articles in perl.apache.org about > caching issue in mod_perl, but I still don't get it right with my > program when I had already changed the input, it still giving me the > result of old input. Are you still having trouble with this, or did you fix the problem? - Perrin
Re: [MP2]mod_perl and index.html
On Thu 26 Jun 2008, titetluc titetluc wrote: > In PerlResponseHandler, $r->main and $r->prev are undefined. I can not > understand why $r->main AND $r->prev are not defined (intuitively, $r->prev > should be defined) I'd expect $r->user to be set, not $r->prev->user nor $r->main->user. But I'd expect $r->prev to be set because $r is the result of an internal redirect. But I am not sure what exactly ap_internal_fast_redirect does. Oh my, I found it. ap_internal_fast_redirect isn't exactly an internal redirect. Instead it overrides the current request with a subreq. Look at modules/http/http_request.c. There is a comment that says something about that function: /* XXX: Is this function is so bogus and fragile that we deep-6 it? */ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r) And yes, it forgets about $r->user at least in apache 2.2.6. Maybe you file a bug for apache? You can check in the AuthenHandler for $r->main. If it is true you can set $r->user as well as $r->main->user. Torsten -- Need professional mod_perl support? Just hire me: [EMAIL PROTECTED]
Re: [MP2]mod_perl and index.html
2008/6/26 Torsten Foertsch <[EMAIL PROTECTED]>: > On Wed 25 Jun 2008, titetluc titetluc wrote: > > PerlModule Test > > > > Require valid-user > > AuthType basic > > AuthName test_index > > SetHandler perl-script > > > > PerlAuthenHandler Apache2::AuthSSO::Test->set_user > > > > PerlResponseHandler Apache2::AuthSSO::Test->display_user > > > > > ** > In addition, I added an empty index.html file in the htdocs/test_index > directory > > > > The Perl Test module is > > > > package Test; > > use warnings; > > use strict; > > use Carp; > > > > use Apache2::Const qw(:common); > > > > sub set_user { > > my ($self, $r) = @_; > > $r->user('myself'); > > return OK; > > } > > sub display_user { > > my ($self, $r) = @_; > > my $user = defined $r->user ? $r->user : 'user is not defined'; > > print $user; > > return OK; > > } > > > > 1; > > > > When I access with my browser to http://localhost/test_index/index.html, > > user is set to 'myself' > > BUT when I access with my browser to http://localhost/test_index/ ... > user > > is not defined !!! > > What happens here? When you access .../index.html your main request matches > the location condition and is served accordingly. If you access .../ the > main > request goes through all phases up to fixup missing the location directives > because the condition does not match. In fixup mod_dir creates an URI > subreq > for each DirectoryIndex. > > mod_dir.c contains the following code: > >/* The sub request lookup is very liberal, and the core > map_to_storage > * handler will almost always result in HTTP_OK as /foo/index.html > * may be /foo with PATH_INFO="/index.html", or even / with > * PATH_INFO="/foo/index.html". To get around this we insist that > the > * the index be a regular filetype. > * > * Another reason is that the core handler also makes the assumption > * that if r->finfo is still NULL by the time it gets called, the > * file does not exist. > */ >if (rr->status == HTTP_OK >&& ( (rr->handler && !strcmp(rr->handler, "proxy-server")) >|| rr->finfo.filetype == APR_REG)) { >ap_internal_fast_redirect(rr, r); >return OK; >} > > You see, for the DirectoryIndex feature to work properly the index document > has to have an associated file. Your index document is a > PerlResponseHandler. > So, I suspect there is no index.html file. In that case $r->filename > is "/path/to/test_index" and $r->path_info "index.html" for the subreq. > > Use the source, Luke! > > Now, I think you can make it working in one of these ways: > > 1) create .../test_index/index.html as a regular file. > 2) redirect /test_index/index.html to a file (Alias ). > Torsten I created the test_index/index.html as a regular file (see the stars above ;-)). The effect is that my PerlResponseHandler is correctly called. But my problem is that I can not retrieved the user (set in the PerlAuthenHandler) in the PerlResponseHandler. In PerlResponseHandler, $r->main and $r->prev are undefined. I can not understand why $r->main AND $r->prev are not defined (intuitively, $r->prev should be defined) > Torsten > > -- > Need professional mod_perl support? > Just hire me: [EMAIL PROTECTED]
Re: [MP2]mod_perl and index.html
On Wed 25 Jun 2008, titetluc titetluc wrote: > PerlModule Test > > Require valid-user > AuthType basic > AuthName test_index > SetHandler perl-script > > PerlAuthenHandler Apache2::AuthSSO::Test->set_user > > PerlResponseHandler Apache2::AuthSSO::Test->display_user > > > In addition, I added an empty index.html file in the htdocs/test_index > directory > > The Perl Test module is > > package Test; > use warnings; > use strict; > use Carp; > > use Apache2::Const qw(:common); > > sub set_user { > my ($self, $r) = @_; > $r->user('myself'); > return OK; > } > sub display_user { > my ($self, $r) = @_; > my $user = defined $r->user ? $r->user : 'user is not defined'; > print $user; > return OK; > } > > 1; > > When I access with my browser to http://localhost/test_index/index.html, > user is set to 'myself' > BUT when I access with my browser to http://localhost/test_index/ ... user > is not defined !!! What happens here? When you access .../index.html your main request matches the location condition and is served accordingly. If you access .../ the main request goes through all phases up to fixup missing the location directives because the condition does not match. In fixup mod_dir creates an URI subreq for each DirectoryIndex. mod_dir.c contains the following code: /* The sub request lookup is very liberal, and the core map_to_storage * handler will almost always result in HTTP_OK as /foo/index.html * may be /foo with PATH_INFO="/index.html", or even / with * PATH_INFO="/foo/index.html". To get around this we insist that the * the index be a regular filetype. * * Another reason is that the core handler also makes the assumption * that if r->finfo is still NULL by the time it gets called, the * file does not exist. */ if (rr->status == HTTP_OK && ( (rr->handler && !strcmp(rr->handler, "proxy-server")) || rr->finfo.filetype == APR_REG)) { ap_internal_fast_redirect(rr, r); return OK; } You see, for the DirectoryIndex feature to work properly the index document has to have an associated file. Your index document is a PerlResponseHandler. So, I suspect there is no index.html file. In that case $r->filename is "/path/to/test_index" and $r->path_info "index.html" for the subreq. Use the source, Luke! Now, I think you can make it working in one of these ways: 1) create .../test_index/index.html as a regular file. 2) redirect /test_index/index.html to a file (Alias ). Torsten -- Need professional mod_perl support? Just hire me: [EMAIL PROTECTED]
Re: mod_perl: performance tips
On Wed 25 Jun 2008, tyju tiui wrote: > but it is still way behind the C module (4 - 5 times fewer requests per > second). Is mod_perl just that much slower than a pure C module? Yes it is slower. MP registers hooks at almost all places possible. Your pure C module probably uses only 1 or 2 of them. I have seen a factor of 2-2.5 between a very simple PerlResponseHandler (something like the code below) and a not heavily tuned Apache sending a plain file consisting of 2 characters. I expect a C module to be even faster. sub { use Apache2::RequestRec (); use Apache2::RequestIO (); $_[0]->content_type('text/plain'); $_[0]->headers_out->set('Content-Length', 2); $_[0]->print('ok'); 0; } Note, without the Content-Length header it would be a lot slower in terms of requests per second. If you want performance write C. MP is a real performance gain (and drop of the server load) compared with CGI loosing almost nothing of the flexibility. So, disable all unnecessary hooks in mod_perl or even better compile them out and allways send a Content-Length header. You can also try to write your output to a temporary file and let the default handler send that file. That may also speed it up (it'll use sendfile) but it depends. Torsten -- Need professional mod_perl support? Just hire me: [EMAIL PROTECTED]