3
votes

I'm doing some development work that uses an embedded Linux for the OS and Boa for the web server. I have a web page that posts to a CGI script, handles the form data, and replies. My development environment was Ubuntu and everything worked fine, but when I ported my code over to the embedded Linux, the CGI module did not instantiate (or at least does not seem to instantiate). Here is a stripped down section of my code. The print statement complains about an uninitialized variable.

use CGI;

use strict;
use warnings;

my $cgiObj = CGI->new();

print $cgiObj->param('wlanPort');

Again, this works fine in my development environment, but fails in the embedded environment. The CGI.pm is installed and there are no errors generated on the CGI->new() command. I have also verified that the form data is being sent, but obviously can't guarantee that it is being received by the Perl script.

I have a feeling that it is a Boa configuration issue and that's what I'll be looking into next. I'm fairly new to Perl, so I'm not sure what else to do. Any ideas?

EDIT: Definitely not a Boa config issue. Still looking into it.

UPDATE: I've simplified my code to the following:

#!/usr/bin/perl
use CGI qw(:standard);
$data = param('wlanPort') || '<i>(No Input)</i>';
print header;                            
print <<END; 
<title>Echoing user input</title>
<p>wlanPort: $data</p>           
END  

As expected, it prints (No Input)

I should also point out that the form is enctype="multipart/form-data" because I have to have a file upload capability and I am using the "POST" method.

I used the HttpFox plugin to inspect the post data and checked on the wlanPort value:

-----------------------------132407047814270795471206851178 Content-Disposition: form-data; name="wlanPort"

eth1

So it is almost definitely being sent...

UPDATE 2: I installed the same version of Perl and Boa being used in the embedded system on my Ubuntu laptop. Works on the laptop, not in the device, which is the same result. I've told my employer that that I've exhausted all possibilities other than the way Boa and (Micro) Perl are built on the device vs. in Ubuntu.

2
Can you give the entire error/warning message? Also, are you sure that 'wlanPort' as a parameter is populated? Why don't you fetch the entire param list: $params = $q->vars(), and then dump the hash with Data::Dumper in a pre block? Then you can verify that the params are what you expect them to be.DavidO
@Chris - maybe try a call to CGI::initialize_globals() just before you stantiate the CGI object.dwarring
@DavidO The only error I get is a concatenation error: Use of uninitialized value in concatenation (.) or string at ./setwirelessconfig.cgi line 28. The code at line 28 is this: print "wlanPort-->" . $cgiObj->param('wlanPort'); I can't use the Data::Dumper because of the small amount of memory that I have available to me in the embedded environment. I can only be sure that the value is being posted.Chris Clark
@snoopy -- initialize_globals didn't have any effect. One new curious thing I've noticed is that the cgiObj->header() is working fine. The company I'm doing the work for has said in the past that due to the limited amount of memory, we are dealing with microPerl. Is it possible that the CGI module is only partially functioning? Can I simply add code to the CGI.pm to check to see if the param() call is being made properly?Chris Clark
"Use of uninitialized value in concatenation (.) or string at ./setwirelessconfig.cgi line 28." - That indicates that param('wlanPort') is returning undef. If $cgiObj was undef, you'd be getting a "can't call method param() on an undefined value" error instead.Sherm Pendley

2 Answers

1
votes

CGI is a beautifully simple protocol and while I cannot answer your question directly, I can suggest some techniques to help isolate the problem.

If your form is being submitted via POST, then the contents of that form will appear as a URLencoded string in the content of the HTTP request your script is getting. Without using the CGI module at all, you should be able to read the the request from STDIN:

my $request = "";
while (<STDIN>) {
   $request .= $_;
}

if (open my $out, ">>/tmp/myapp.log") {
    print $out $request;
    close $out;   
}

You can then examine /tmp/myapp.log to see if you are getting all the information from the request that you think you are.

For completeness, if your form submits via GET, then the arguments will be in the environment variable QUERY_STRING, which you can look at in Perl with $ENV{'QUERY_STRING'}.

There should be no difference in the way CGI's object interface and functional interface parses the request. I am not familiar with boa, but I can't imagine it breaking basic CGI protocol.

A common problem is that you named the form parameter one thing and are looking for a different parameter name in the CGI script. That's always a laugh.

Good luck and hope this helps some.

1
votes

I know this is very old post and OP may not be interested in any new info related to this, but the general question about how to debug CGI scripts has some relevance still. I had similar issues with dev vs. prod environments. To help those who stumble upon this thread, I am posting my experience in dealing with this situation. My simple answer is, to use Log::Log4perl and Data::Dumper modules to demystify this (assuming there is a way to access logs on your prod environment). This way with negligible overhead, you can turn on tracing when problems creep in (even if the code worked before, but due to changes over time, it started failing). Log every relevant bit of information at appropriate log level (trace, debug, info, warning, error, fatal) and configure what level is good for operations. Without these mechanisms, it will be very difficult to get insight into production operations. Hope this helps.

use CGI;
use Log::Log4perl qw(easy);
use Data::Dumper;

use strict;
use warnings;

my $cgiObj = CGI->new();

my $log = Log::Log4perl::get_logger();
$log->trace("CGI Data: " . Dumper($cgiObj));

print $cgiObj->param('wlanPort');