naChoZ has asked for the wisdom of the Perl Monks concerning the following question:

crossposted at stackoverflow here.

This has got to be something silly I'm doing wrong. It's such a newbie type problem.

The original script is something that sits and waits for a 3rd party to connect and POST some xml to it, it takes that xml, does some validation, and stores it in a db. That part is fine. The problem is my response. I'm trying to use the header() function from CGI and it's just not behaving. It comes up blank. Obviously I could just do this manually and just print the header string, but now I'm really curious why this is behaving so strangely.

Here is a stripped down test version of the cgi script:

#!/perl/bin/perl use strict; use warnings; use Data::Dumper::Names; use CGI qw(:standard); use Apache2::Connection (); use Apache2::RequestRec (); $| = 1; # Grab the request object provided by mod_perl. # our $request_obj = shift; our $connection = $request_obj->connection; our $remote_ip = $connection->client_ip(); my $cgi = CGI->new($request_obj->args()); print STDERR Dumper($cgi); my $input = $cgi->param('POSTDATA'); print STDERR Dumper($input); my $cgi_header = $cgi->header(); print STDERR Dumper($cgi_header); #my $cgi_full_header = $cgi->header(-type => 'application/xml', -statu +s => '400 Bad Request' ); my $cgi_full_header = $cgi->header(-type => 'application/xml'); print STDERR Dumper($cgi_full_header); my $q = CGI->new({}); print STDERR Dumper($q); my $q_header = $q->header(); print STDERR Dumper($q_header); #my $q_full_header = $q->header(-type => 'application/xml', -status => + '400 Bad Request' ); my $q_full_header = $q->header(-type => 'application/xml' ); print STDERR Dumper($q_full_header); exit;

And the output:

$cgi = bless( { '.r' => bless( do{\(my $o = '94118860562256')}, 'Apach +e2::RequestRec' ), 'param' => { 'POSTDATA' => [ 'test' ], 'XForms:Model' => [ 'test' ] }, 'use_tempfile' => 1, '.fieldnames' => {}, '.charset' => 'ISO-8859-1', 'escape' => 1, '.parameters' => [ 'XForms:Model', 'POSTDATA' ] }, 'CGI' ); $input = 'test'; $cgi_header = ''; $cgi_full_header = ''; $q = bless( { '.parameters' => [ 'XForms:Model', 'POSTDATA' ], 'escape' => 1, '.fieldnames' => {}, '.charset' => 'ISO-8859-1', 'use_tempfile' => 1, '.r' => bless( do{\(my $o = '94118860562256')}, 'Apache2 +::RequestRec' ), 'param' => { 'POSTDATA' => [ '' ], 'XForms:Model' => [ '' ] } }, 'CGI' ); $q_header = ''; $q_full_header = '';

And here is the simple test script I'm using to send the POST.

#!/perl/bin/perl use strict; use warnings; use DBI; use URI; use LWP::UserAgent; use Data::Dumper::Names; my $ua = LWP::UserAgent->new; $ua->max_size( 131072 ); $ua->agent('test_xml_pusher'); $ua->ssl_opts(verify_hostname => 0); my $url = URI->new; $url->scheme('https'); $url->host('xxxxxxxxxxxxxxxxxxxxxxxxx'); $url->port(443); $url->path_segments('test.cgi'); # Yes, I know... it's not valid xml... don't care for the purposes o +f this test. # my $xml = 'test'; my $response = $ua->post( $url, Content => $xml, 'Content-Type' => 'ap +plication/xml' ); print Dumper($response); my $status_line = $response->status_line; print Dumper($status_line); my $content = $response->content; print Dumper($content);

So why is $cgi_header empty? And why does $q end up being a reference to the same thing as $cgi even though I tried initializing it as my $q = CGI->new({});? (I also tried empty quotes instead of empty brackets.)

Any thoughts?


My environment is a centos 7 server running apache httpd 2.4.34 with mod_perl 2.0.11 and perl 5.22.4. (httpd is installed from from SCL, but perl and mod_perl are installed from source.)


Replies are listed 'Best First'.
Re: mod_perl and CGI behavior
by choroba (Cardinal) on Sep 25, 2020 at 19:01 UTC
    Crossposted to StackOverflow. Crossposting isn't bad, but it's considered polite to inform about crossposting to prevent unnecessary work: people not attending both sites might spend a lot of time solving a problem already solved at the other end of the internets.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      Roger that. Updated.


Re: mod_perl and CGI behavior
by davebaker (Pilgrim) on Sep 25, 2020 at 19:49 UTC
    Haven't tested this yet as to whether it makes a difference, but I see you've imported various "standard" functions from by including :standard in the "use CGI qw(:standard);" statement. Because you're using in its object-oriented style (my $cgi = CGI->new() etc.), you don't need to do that, and you might be better off with "use CGI;" instead.

      Unfortunately it seems deeper than that.

      Looking at the code over on github here, you can see that the ->new method checks if mod_perl is being used and, if it is, gives you back an object with the request attached to it, and all that stuff...

      But, regardless, I dumbed down the script to just...

      #!/perl/bin/perl use strict; use warnings; use Data::Dumper::Names; use CGI; use Apache2::Connection (); use Apache2::RequestRec (); $| = 1; my $header = CGI::header(); print STDERR Dumper($header);

      ...and it still outputs just...

      $header = '';


        Yes, something going on at line 1617 of at github, inside sub "header" --
        if (($MOD_PERL >= 1) && !$nph) { $self->r->send_cgi_header($header); return ''; }
        which explains the empty set being returned, after it's invoked a "send_cgi_header" mod_perl method that seems to be designed to take the place of sub "header" as a practical matter.
Re: mod_perl and CGI behavior
by trwww (Priest) on Sep 29, 2020 at 15:16 UTC

    Theres a few problems here, but the most glaring one is you're printing your script's output to STDERR. Where did you get this pattern?

Re: mod_perl and CGI behavior
by Anonymous Monk on Sep 25, 2020 at 21:03 UTC