[mp2] Segfault on using $r->content_type()

2008-06-26 Thread Stephen Howard

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

2008-06-26 Thread Perrin Harkins
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

2008-06-26 Thread Perrin Harkins
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

2008-06-26 Thread Torsten Foertsch
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-06-26 Thread titetluc titetluc
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

2008-06-26 Thread Torsten Foertsch
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

2008-06-26 Thread Torsten Foertsch
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]