Re: mod_perl 2.0 and print/send_http_header method SEGFAULT

2003-01-16 Thread Jérôme Augé
On Thu, Jan 16, 2003 at 10:27:38AM +1100, Stas Bekman wrote:
 
 Cool. Now can you please send the shortest possible example that you still 
 get the SEGFAULT with, so I can reproduce it and fix? Thanks.
 

I finally got a working apache2+mod_perl working in my $HOME dir (I
could not find the core files of the RedHat httpd, problems with uid
permission i guess)

So here are the backtraces.

I included two backtraces :
- the first one is for the crash with $r-send_http_header()
- the second one is for the crash with $r-print() when I remove the
  send_http_header() statement

The config in httpd.conf :

  # mod_perl
  LoadModule perl_module modules/mod_perl.so
  PerlModule Apache2
  PerlTransHandler Apache::SegFault

  # proxy 
  LoadModule proxy_module modules/mod_proxy.so
  LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
  LoadModule proxy_http_module modules/mod_proxy_http.so
  LoadModule proxy_connect_module modules/mod_proxy_connect.so
  ProxyRequests On
  Proxy *
Order deny,allow
Deny from all
Allow from localhost
  /Proxy


Then I issue a simple request with :

  echo -ne GET http://perl.apache.org HTTP/1.0\n\n | nc localhost 8081



-8-- Start Bug Report 8--
1. Problem Description:

 BEGIN 
package Apache::SegFault;

use strict;
use Apache::compat;
use Apache::RequestRec;
use Apache::RequestIO;
use Apache::RequestUtil;
use Apache::Const;
use Apache::ServerUtil;
use Apache::Response;
use Apache::URI;
use APR::Table;

sub handler {
my $r = shift;

return Apache::DECLINED unless( $r-proxyreq );
print STDERR Good, this is a proxyreq ...\n;

return Apache::DECLINED unless( $r-method eq GET );
print STDERR Good, this is a GET method ...\n;

my $content = htmlbodyplop/body/html;

my %headers_out;
$headers_out{ 'Content-length' } = length( $content );
$headers_out{ 'Content-type' } = 'text/html';
foreach (keys %headers_out) {
$r-headers_out-{$_} = $headers_out{$_};
}
$r-content_type( $headers_out{ 'Content-type' } );

print STDERR -- send/print --\n;

# -- SEGFAULT here
$r-send_http_header();

# -- or here, when removing the send_http_header() line above
$r-print( $content );

print STDERR -- end --\n;

return Apache::OK;
}

1;
 END 


2. Used Components and their Configuration:

*** using lib/Apache/BuildConfig.pm
*** Makefile.PL options:
  MP_APXS= /home/jauge/httpd/bin/apxs
  MP_DEBUG   = 1
  MP_GENERATE_XS = 1
  MP_LIBNAME = mod_perl
  MP_MAINTAINER  = 1
  MP_TRACE   = 1
  MP_USE_DSO = 1
  MP_USE_STATIC  = 1


*** /home/jauge/httpd/bin/httpd -V
Server version: Apache/2.0.43
Server built:   Jan 16 2003 15:38:17
Server's Module Magic Number: 20020903:0
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
 -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=/home/jauge/httpd
 -D SUEXEC_BIN=/home/jauge/httpd/bin/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/perl -V
Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
  Platform:
osname=linux, osvers=2.4.18-11smp, archname=i386-linux-thread-multi
uname='linux daffy.perf.redhat.com 2.4.18-11smp #1 smp thu aug 15 06:41:59 edt 
2002 i686 i686 i386 gnulinux '
config_args='-des -Doptimize=-O2 -march=i386 -mcpu=i686 -Dmyhostname=localhost 
-Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr 
-Dprefix=/usr -Darchname=i386-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib 
-Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm 
-Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl 
-Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
  Compiler:
cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing 
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
optimize='-O2 -march=i386 -mcpu=i686',
cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -I/usr/include/gdbm'
ccversion='', gccversion='3.2 20020822 (Red Hat Linux Rawhide 3.2-5)', 
gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234

Re: mod_perl 2.0 and print/send_http_header method SEGFAULT

2003-01-16 Thread Stas Bekman
Jérôme Augé wrote:

On Thu, Jan 16, 2003 at 10:27:38AM +1100, Stas Bekman wrote:


Cool. Now can you please send the shortest possible example that you still 
get the SEGFAULT with, so I can reproduce it and fix? Thanks.



I finally got a working apache2+mod_perl working in my $HOME dir (I
could not find the core files of the RedHat httpd, problems with uid
permission i guess)

So here are the backtraces.

I included two backtraces :
- the first one is for the crash with $r-send_http_header()
- the second one is for the crash with $r-print() when I remove the
  send_http_header() statement


The problem is that you were calling these functions before the response 
phase (PerlTransHandler in your case), hence triggered the segfaults. I've 
fixed those in cvs. Now if you call any of these functions too early 
mod_perl will croak. Please verify with the latest cvs.

To solve your particular case, you need to use:

$r-set_handlers(PerlResponseHandler = \response);

inside the PerlTransHandler handler, and move all the code that generates 
the response there.

__
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 2.0 and print/send_http_header method SEGFAULT

2003-01-15 Thread Jérôme Augé
On Wed, Jan 15, 2003 at 09:09:37AM +1100, Stas Bekman wrote:
 
 I've applied a fix that hopefully cures this thing in cvs. Please try 
 again with the latest cvs version.
 http://perl.apache.org/download/source.html#2_0_Development_Source_Distribution
 

I installed the CVS version (1.9909) and I still get a SEGFAULT when
using $r-send_http_header() or $r-print() ...

- I fetched the mod_perl CVS sources then launched :
$ perl Makefile.PL MP_APXS=/usr/sbin/apxs
$ make
$ make install
- modified the /etc/httpd/conf.d/perl.conf file
- restarted httpd

I also tested with the Apache::ProxyPassThru module (from
http://perl.apache.org/dist/contrib/ProxyPassThru.pm)
I added a use Apache::compat statement, removed the
$r-handler()/$r-push_handlers() part and I also get a SEGFAULT when it
reach the http_send_header() statement ...

-- 




Re: mod_perl 2.0 and print/send_http_header method SEGFAULT

2003-01-15 Thread Jérôme Augé
I grep'ed into the mod_perl sources and found in
examples/lib/Apache/HelloWorld.pm that send_http_header does not exists
in mod_perl 2.0 and print is not yet implemented. Is this right ? so
this could easily explain my problems :)

in examples/lib/Apache/HelloWorld.pm :
[...]
sub handler {
my $r = shift;

$r-content_type('text/plain');

#send_http_header API function does not exist in 2.0

$r-puts(__PACKAGE__); #print not yet implemented

return Apache::OK;
}
[...]

-- 




Re: mod_perl 2.0 and print/send_http_header method SEGFAULT

2003-01-15 Thread Stas Bekman
Jérôme Augé wrote:

On Wed, Jan 15, 2003 at 09:09:37AM +1100, Stas Bekman wrote:


I've applied a fix that hopefully cures this thing in cvs. Please try 
again with the latest cvs version.
http://perl.apache.org/download/source.html#2_0_Development_Source_Distribution

Since you've never sent the backtrace of SEGFAULT, as explained here:
http://perl.apache.org/docs/2.0/user/help/help.html#Reporting_Problems
there can be more than one problem. I've fixed one, but there can be more 
lurking behind the first one. So if you can send the backtrace, that will 
help a lot.

I installed the CVS version (1.9909) and I still get a SEGFAULT when
using $r-send_http_header() or $r-print() ...

- I fetched the mod_perl CVS sources then launched :
$ perl Makefile.PL MP_APXS=/usr/sbin/apxs
$ make
$ make install
- modified the /etc/httpd/conf.d/perl.conf file
- restarted httpd


Cool. Now can you please send the shortest possible example that you still 
get the SEGFAULT with, so I can reproduce it and fix? Thanks.

I also tested with the Apache::ProxyPassThru module (from
http://perl.apache.org/dist/contrib/ProxyPassThru.pm)
I added a use Apache::compat statement, removed the
$r-handler()/$r-push_handlers() part and I also get a SEGFAULT when it
reach the http_send_header() statement ...



send_http_header is indeed doesn't exist in 2.0, but implemented in 
Apache::compat and should work just fine, as it's exercised in many tests:

grep -Ir send_http_header t
t/compat/request_body.t:# $r-send_http_header('text/plain');
t/compat/request_body.t:q{$r-send_http_header('text/plain')}
t/response/TestCompat/request_body.pm:$r-send_http_header('text/plain');
t/response/TestCompat/apache.pm:$r-send_http_header('text/plain');
t/response/TestCompat/apache_file.pm:$r-send_http_header('text/plain');
t/response/TestCompat/apache_table.pm:$r-send_http_header('text/plain');
t/response/TestCompat/apache_util.pm:$r-send_http_header('text/plain');
t/response/TestCompat/request.pm:$r-send_http_header('text/plain');


__
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 2.0 and print/send_http_header method SEGFAULT

2003-01-15 Thread Stas Bekman
Jérôme Augé wrote:

I grep'ed into the mod_perl sources and found in
examples/lib/Apache/HelloWorld.pm that send_http_header does not exists
in mod_perl 2.0 and print is not yet implemented. Is this right ? so
this could easily explain my problems :)


It's an old example, I've removed it.


in examples/lib/Apache/HelloWorld.pm :
[...]
sub handler {
my $r = shift;

$r-content_type('text/plain');

#send_http_header API function does not exist in 2.0

$r-puts(__PACKAGE__); #print not yet implemented

return Apache::OK;
}
[...]




--


__
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 2.0 and print/send_http_header method SEGFAULT

2003-01-14 Thread Jérôme Augé
On Tue, Jan 14, 2003 at 12:32:29PM +1100, Stas Bekman wrote:
 
 Location /plop/
 SetHandler perl-script
 PerlHeaderParserHandler Apache::Plop
 /Location
 

Well, this is not really what I want to do ...
I would like to catch all the proxy request and apply modifications to
the requested document before forwarding the answer back to the client.
That's why I used the PerlTransHandler which is global and not tied
to a particular directory.

 
 Now to your code:
 
 1. You can't push_handlers when you are inside a response handler.
 Use PerlHeaderParserHandler instead
 
 2. $r-headers_in-do() expects a return value and will abort on 0; see 
 the attached code
 
 also it should be:
 $request-header( $_[0] = $_[1] );
 instead of:
 $request-header( {$_[0]} = $_[1] );
 
 have you looked at error_log? You'd have seen that error reported.
 
 3. This is not good:
 my $request = HTTP::Request-new( $r-method, $r-uri);
 since you don't the whole url. Use this instead:
 my $request = HTTP::Request-new( $r-method, $r-construct_url);
 this requires 'use Apache::URI'
 
 4.  Finally I've used a special header: (which can be anything)
   $request-header( GetReal = 1 );
 to know that now I'm inside the real request.
 

Thanks for your remarks.

I installed modperl-1.99_08 and I keep getting SEGFAULT with my original
code ... I think I'll try to get it working first on mod_perl 1.x then
get back to modperl 2

-- 




Re: mod_perl 2.0 and print/send_http_header method SEGFAULT

2003-01-13 Thread Stas Bekman
Jérôme Augé wrote:

Hi,

I'm beginning with mod_perl (mod_perl-1.99_05 + Apache 2.0.40 from
RedHat 8.0) and I want to write a module for rewriting the documents
that passes through the Apache proxy. So, I looked at the
Apache::AdBlocker
(http://perl.apache.org/docs/tutorials/tips/mod_perl_tricks/mod_perl_tricks.html#A_Banner_Ad_Blocker)
module and I'm facing some problems for writing the content of the
documents back to the client.

My main problem is that I get a SEGFAULT when calling the $r-print()
or $r-send_http_header() method.
I get the request, copy the headers from headers_in, make my own
request with LWP, copy the headers to headers_out, then it SEGFAULT
when writing the document ... Are this methods deprecated/not fully
implemented ? what is the correct way to write data to the client ?

The other problem is that if I use the $r-push_handlers(PerlHandler =
\proxy_handler) mechanism, my proxy_handler() function is never
called, so I do the work directly into the handler sub, is this ok ?

I attached my test module below (I register it with a PerlTransHandler
Apache::Plop statement in httpd.conf)


After making your example work, I don't see any segfaults. Please try 
again with modperl-1.99_08 which was released a few days ago.

I've attached Plop.pm that apparently works. Hope that this is what you 
wanted to accomplish. I've used the following config:

Location /plop/
SetHandler perl-script
PerlHeaderParserHandler Apache::Plop
/Location

Now to your code:

1. You can't push_handlers when you are inside a response handler.
Use PerlHeaderParserHandler instead

2. $r-headers_in-do() expects a return value and will abort on 0; see 
the attached code

also it should be:
$request-header( $_[0] = $_[1] );
instead of:
$request-header( {$_[0]} = $_[1] );

have you looked at error_log? You'd have seen that error reported.

3. This is not good:
my $request = HTTP::Request-new( $r-method, $r-uri);
since you don't the whole url. Use this instead:
my $request = HTTP::Request-new( $r-method, $r-construct_url);
this requires 'use Apache::URI'

4.  Finally I've used a special header: (which can be anything)
  $request-header( GetReal = 1 );
to know that now I'm inside the real request.

Hope that this helps.

Also you might want to use a sub-request rather than a heavy weighted LWP 
to accomplish what you do.

__
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
package Apache::Plop;

use strict;
use Apache::RequestRec;
use Apache::RequestIO;
use Apache::RequestUtil;
use Apache::Const;
use Apache::ServerUtil;
use Apache::Response;
use Apache::URI;
use APR::Table;
use LWP::UserAgent;

my $ua = LWP::UserAgent-new();

sub handler {
my $r = shift;

if( $r-proxyreq ) {
return Apache::DECLINED;
}
print STDERR Good, this is a proxyreq ...\n;

$r-handler(perl-script); #ok, let's do it   
$r-push_handlers(PerlResponseHandler = \proxy_handler);
return Apache::OK;
}


sub proxy_handler {
my $r = shift;

if( $r-method ne GET ) {
return Apache::DECLINED;
}
print STDERR Good, this is a GET method ...\n;

if ( ($r-headers_in-get('GetReal')||0) == 1) {
$r-content_type('text/plain');
print hey;
return Apache::OK;
}

# prepare the real request
my $request = HTTP::Request-new( $r-method, $r-construct_url);

# copy headers from client request
my %headers_in;
print STDERR -- client headers --\n;
$r-headers_in()-do(
sub {
warn $_[0]: $_[1]\n;
$headers_in{ $_[0] } = $_[1];
$request-header( $_[0] = $_[1] );
return 1;
}
   );
print STDERR -- end --\n;

# make the real request myself
$ua-agent( $headers_in{ 'User-Agent' } );

$request-header( GetReal = 1 );

warn $request-as_string;

my $response = $ua-request( $request );

if ( ! $response-is_success() ) {
print STDERR == ERROR ==\n;
return Apache::DECLINED;
}

print STDERR -- server headers --\n;
my %headers_out;
$response-headers()-scan(
sub {
print STDERR $_[0]: $_[1]\n;
$headers_out{$_[0]} = $_[1];
}
   );
print STDERR -- end --\n;

# simply override the content
my $content = $response-content;
$content = htmlbodyplop/body/html;

# adjust the headers for the new content
$headers_out{ 'Content-length' } = length( $content );
$headers_out{ 'Content-type' } = 'text/html';

# copy the modified response headers back to Apache
foreach (keys %headers_out) {
$r-headers_out-{$_} = $headers_out{$_};
}
 

Re: mod_perl 2.0 and print/send_http_header method SEGFAULT

2003-01-13 Thread Stas Bekman
Stas Bekman wrote:

Jérôme Augé wrote:

[...]

After making your example work, I don't see any segfaults. Please try 
again with modperl-1.99_08 which was released a few days ago.
[...]

1. You can't push_handlers when you are inside a response handler.
Use PerlHeaderParserHandler instead


I've played some more with your original code and did find the segfault 
you were talking about. Though it happens when you use push_handlers in 
the same phase to which you push to. Hence I didn't see it in the code 
that I've fixed.

So most likely your _05 version will work just fine with the version that 
I've posted in my original reply.

Meanwhile I'm looking at how it's the best to prevent from the segfault to 
happen and push_handlers() be used in a wrong place.

__
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