You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@perl.apache.org by ch...@skarby.no on 2003/09/30 14:43:14 UTC

[mp2] trouble reading post using CGI.pm

1. Problem Description:

I have trouble getting iniformation from CGI-forms sent by HTTP/POST. To reproduce 
the problem; use the testpackage I've written and included in section 5 of this 
mail. I've also included what I've found relevant from my mod_perl/Apache-setup 
in section 4.

My observation is that there is no problem using GET to transfer form-data,
but no data at all is avaliable through $q->param when using POST.

I have tested this with different versions of mod_perl (1.99_09, snapshot
from cvs this sunday and finally 1.99_10 released yesterday) and CGI.pm
(2.93, 3.00) - as for now I run mod_perl 1.99_10 and CGI.pm 3.0.

If there is something in my setup that causes this, please point me in the
right direction or maybe towards the right documentation. - It is not
totally neccessary for me to use CGI.pm, the most important is to receive
the data ;)

Best regards,
Christian





2. Used Components and their Configuration:

*** mod_perl version 1.9910

*** using /usr/lib/perl5/vendor_perl/5.8.0/i686-linux/Apache2/Apache/BuildConfig.pm
*** Makefile.PL options:
  MP_APXS         => /usr/sbin/apxs2
  MP_AP_PREFIX    => /usr
  MP_COMPAT_1X    => 1
  MP_DEBUG        => 1
  MP_GENERATE_XS  => 1
  MP_INST_APACHE2 => 1
  MP_LIBNAME      => mod_perl
  MP_TRACE        => 1
  MP_USE_DSO      => 1


*** /usr/sbin/apache2 -V
Server version: Apache/2.0.47
Server built:   Sep 27 2003 22:37:55
Server's Module Magic Number: 20020903:4
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="/usr"
 -D SUEXEC_BIN="/usr/sbin/suexec2"
 -D DEFAULT_PIDLOG="/var/run/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="/var/run/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="/etc/apache2/conf/mime.types"
 -D SERVER_CONFIG_FILE="/etc/apache2/conf/apache2.conf"


*** /usr/bin/perl -V
Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.4.23-pre5-ih, archname=i686-linux
    uname='linux admin.interhost.no 2.4.23-pre5-ih #8 sat sep 27 17:13:24 cest 2003 i686 gnulinux '
    config_args='-des -Darchname=i686-linux -Dcc=gcc -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr -Dlocincpth=  -Doptimize=-O3 -march=pentium4 -funroll-loops -fprefetch-loop-arrays -pipe -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Dscriptdir=/usr/bin -Dman3ext=3pm -Dcf_by=Gentoo -Ud_csh -Di_gdbm -Di_db -Di_ndbm'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-DPERL5 -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O3 -march=pentium4 -funroll-loops -fprefetch-loop-arrays -pipe',
    cppflags='-DPERL5 -DPERL5 -fno-strict-aliasing'
    ccversion='', gccversion='3.2.3 20030422 (Gentoo Linux 1.4 3.2.3-r1, propolice)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lpthread -lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lcrypt -lutil
    perllibs=-lpthread -lnsl -ldl -lm -lc -lcrypt -lutil
    libc=/lib/libc-2.3.2.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.3.2'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'


Characteristics of this binary (from libperl): 
  Compile-time options: USE_LARGE_FILES
  Built under linux
  Compiled at Sep 28 2003 20:17:30
  %ENV:
    PERL_LWP_USE_HTTP_10="1"
  @INC:
    /etc/perl
    /usr/lib/perl5/site_perl/5.8.0/i686-linux
    /usr/lib/perl5/site_perl/5.8.0
    /usr/lib/perl5/site_perl
    /usr/lib/perl5/vendor_perl/5.8.0/i686-linux
    /usr/lib/perl5/vendor_perl/5.8.0
    /usr/lib/perl5/vendor_perl
    /usr/lib/perl5/5.8.0/i686-linux
    /usr/lib/perl5/5.8.0
    /usr/local/lib/site_perl
    .


3. This is the core dump trace: (if you get a core dump):

  [CORE TRACE COMES HERE]

This report was generated by -e on Tue Sep 30 12:02:35 2003 GMT.






4. My Apache configuration (relevant parts)

----BEGIN mod_perl.conf -----
<IfDefine PERL>
  <IfModule !mod_perl.c>
    LoadModule perl_module    extramodules/mod_perl.so
  </IfModule>
</IfDefine>

<IfModule mod_perl.c>
  #PerlTrace all
  PerlRequire "/etc/apache2/conf/modules.d/apache2-mod_perl-startup.pl"
</ifModule>
----END mod_perl.conf -----


----BEGIN /etc/apache2/conf/modules.d/apache2-mod_perl-startup.pl -----
use Apache2 ();

# enable if the mod_perl 1.0 compatibility is needed
#use Apache::compat ();

use ModPerl::Util (); #for CORE::GLOBAL::exit

use Apache::RequestRec ();
use Apache::RequestIO ();
use Apache::RequestUtil ();

use Apache::Server ();
use Apache::ServerUtil ();
use Apache::Connection ();
use Apache::Log ();

use APR::Table ();

use ModPerl::Registry ();

use Apache::Const -compile => ':common';
use APR::Const -compile => ':common';

1;
----END /etc/apache2/conf/modules.d/apache2-mod_perl-startup.pl -----


----BEGIN sample from commonapache2.conf -----
	<IfModule mod_perl.c>
		PerlOptions +GlobalRequest
		PerlModule CGItest
		<Location /CGItest>
			SetHandler modperl
			PerlResponseHandler CGItest
		</Location>
	</IfModule>
----END sample from commonapache2.conf -----





5. Test module
----BEGIN CGItest.pm ----
package CGItest;

use strict;
use Apache::RequestRec ();
use Apache::RequestIO ();

use Apache::Const -compile => qw(OK);

use CGI 3.0; CGI->compile;

sub handler {
	my $r = shift;
	my $q = CGI->new($r);

	$r->content_type('text/html');
	my @out = ('<html><body>',
			'<h1>CGItest</h1>',
			'<h2>GET-parameters</h2>',
			'<table>','<tr><th>Key</th><th>Value</th></tr>');
	foreach my $param ($q->url_param) {
		push @out, ('<tr><td>'.$param.'</td><td>'.$q->url_param($param).'</td></tr>');
	}
	push @out, ('</table>',
			'<h2>POST-parameters</h2><h3>(GET-parameters when there is no POST-parameters)</h3>',
			'<table>','<tr><th>Key</th><th>Value</th></tr>');
	foreach my $param ($q->param) {
		push @out, ('<tr><td>'.$param.'</td><td>'.$q->param($param).'</td></tr>');
	}
	push @out, ('</table>');
	
	push @out, ('<h2>GET-form</h2>',
			'<form action="/CGItest" method="get" enctype="application/x-www-form-urlencode">',
			'<table>',
			'<tr><td>GET-a</td><td><input type="text" name="GET-a"></td></tr>',
			'<tr><td>GET-b</td><td><input type="text" name="GET-b"></td></tr>',
			'</table>',
			'<input type="submit" value="GET">',
			'</form>');

	push @out, ('<h2>POST-form</h2>',
			'<form action="/CGItest" method="post" enctype="application/x-www-form-urlencode">',
			'<table>',
			'<tr><td>POST-a</td><td><input type="text" name="POST-a"></td></tr>',
			'<tr><td>POST-b</td><td><input type="text" name="POST-b"></td></tr>',
			'</table>',
			'<input type="submit" value="POST">',
			'</form>');

	push @out, ('<h2>Combined GET/POST-form</h2>',
			'<form action="/CGItest?GET=combined" method="post" enctype="application/x-www-form-urlencode">',
			'<table>',
			'<tr><td>POST-i</td><td><input type="text" name="POST-i"></td></tr>',
			'<tr><td>POST-ii</td><td><input type="text" name="POST-ii"></td></tr>',
			'</table>',
			'<input type="submit" value="GET/POST">',
			'</form>');
	
	push @out, ('</body></html>');
	$r->print(join("\n",@out));	
	return Apache::OK;
}
1;
----END CGItest.pm ----

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: [mp2] trouble reading post using CGI.pm

Posted by Stas Bekman <st...@stason.org>.
christian@skarby.no wrote:
> 1. Problem Description:
> 
> I have trouble getting iniformation from CGI-forms sent by HTTP/POST. To reproduce 
> the problem; use the testpackage I've written and included in section 5 of this 
> mail. I've also included what I've found relevant from my mod_perl/Apache-setup 
> in section 4.
> 
> My observation is that there is no problem using GET to transfer form-data,
> but no data at all is avaliable through $q->param when using POST.
> 
> I have tested this with different versions of mod_perl (1.99_09, snapshot
> from cvs this sunday and finally 1.99_10 released yesterday) and CGI.pm
> (2.93, 3.00) - as for now I run mod_perl 1.99_10 and CGI.pm 3.0.
> 
> If there is something in my setup that causes this, please point me in the
> right direction or maybe towards the right documentation. - It is not
> totally neccessary for me to use CGI.pm, the most important is to receive
> the data ;)
[...]
> ----BEGIN sample from commonapache2.conf -----
> 	<IfModule mod_perl.c>
> 		PerlOptions +GlobalRequest
> 		PerlModule CGItest
> 		<Location /CGItest>
> 			SetHandler modperl
> 			PerlResponseHandler CGItest
> 		</Location>
> 	</IfModule>
> ----END sample from commonapache2.conf -----

Thanks for a very good bug report, Christian.

The problem is very simple. with 'Sethandler modperl' STDIN is not 
tied/perlio'ed so CGI.pm sees no POSTed data.
http://perl.apache.org/docs/2.0/user/config/config.html#C_SetHandler_

The solution is to use 'SetHandler perl-script'. I guess we may need to 
provide a new PerlOptions to enable tied STDIN/STDOUT on demand.

If you have a bit of spare time, another solution is to fix CGI.pm to use 
$r->read(STDIN...) instead of read(STDIN...) if $r is available. Should be a 
trivial patch. And then submit it to Lincoln (and may be CC the modperl list 
so we can approve it for Lincoln to have a better incentive to include your 
patch ;)

besides, since you use 'CGI->new($r)', i.e., passing $r to CGI.pm you don't 
need PerlOptions +GlobalRequest. Though it's unrelated to your problem.

Once Apache::Request 2.0 will be finished (you can already give it a try as it 
should work, see: http://httpd.apache.org/apreq/) you won't need any of the 
above and it'll just work with 'Sethandler modperl'.

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org