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

Hi folks. I have a little bit of code that takes in a couple of arguments and hooks up to a database using DBI. I want it to display back to a web page using CGI methods. It works great on the command line. If I copy the data back into an HTML page the browser looks exactly like I want it to. However.... when I try to pull it up directly from the browser the browser never gets beyond writing the header information. So my question is how can I make the browser wait until the whole HTML is there before trying to display it.

Here's the pertinent parts of my code.

#!/usr/bin/perl #use strict; use CGI; use DBI; use HTML::Template; $| = 1; open (STDERR,">/apps2/apache/cgi-bin/errorLog.txt"); my $q = CGI->new; my $sth; my $env; my $database; my $host; my $port; my $user; my $pw; print $q->header(-nph=>1); my $style = get_style(); print $q->start_html( -title => "XREF", -style => {-code => $style}, ); my $fields = "*"; my $symbol_in = $q->param('symbol'); my $site = $q->param('site'); print $q->h1 ("ACTIV INSTRUMENT TABLE DATA"); my $fields = "*"; #my @fields_in = $q->param('fields'); chomp $symbol_in; chomp $site; chomp $symbol_in; chomp $site; $symbol_in =~ s/\s//; foreach (@fields_in){ $_ =~ s/\s//; #if ($_ eq $type){ #next; #}else{ #$fields = join(',',$fields,split); #} $fields = join(',',$fields,split); } my $symbol = join('\',\'',split(/,/,$symbol_in)); &getConfig; my $dbh = DBI->connect("dbi:Oracle:sid=$database;host=$host", $user, $ +pw) or die "Can't connect to Oracle database: $DBI::errstr\n"; my $sql = qq{ SELECT $fields FROM t_activ_instrument where fps_subject + = '$symbol' }; my $sth = $dbh->prepare($sql); $sth->execute(); my $columns = join("<th>", @{ $sth->{NAME} }); my @row; while(@row = $sth->fetchrow_array) { print $q->table({-scope=>"col", -border=>2, -cellpadding => 5}, $q->th("$columns"), $q->Tr($q->td( join("<td>", @row), "\n")), ); }; $sth->finish; $dbh->disconnect; print $q->end_html; print "\r\n";
Like I said outside the browser looks great. Inside the browser all I get is this (consolidated the style section):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-U +S"> <head> <title>XREF</title> <style type="text/css"> <style> . . . </style> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1 +" /> </head> <body> <h1>ACTIV INSTRUMENT TABLE DATA</h1>

Replies are listed 'Best First'.
Re: DBI output into browser using CGI
by hippo (Archbishop) on Apr 25, 2017 at 15:01 UTC

    As you never assign a value to $user your database connection attempt will fail. This will be recorded in the web server (or CGI server) error log. Always check the error log.

    BTW, this:

    my $sql = qq{ SELECT $fields FROM t_activ_instrument where fps_subject = '$symbol' };

    is an SQL injection attack waiting to happen. Use placeholders, always.

      $user as well as other parameters comes in from another form that calls this page. What I don't get is why it would work on the command line and not the browser.
Re: DBI output into browser using CGI
by haukex (Archbishop) on Apr 25, 2017 at 15:02 UTC
Re: DBI output into browser using CGI
by poj (Abbot) on Apr 25, 2017 at 15:20 UTC

    Cut your program down to a mimimal working page like shown below then add back the db/table stuff. Try writing the error log to /tmp, cgi directories are not normally writeable for the webserver process for security reasons.

    #!/usr/bin/perl use strict; use CGI; use CGI::Carp 'fatalsToBrowser'; # remove after testing my $q = CGI->new; print $q->header(-nph=>1); my $style = get_style(); print $q->start_html( -title => "XREF", -style => {-code => $style}, ); print $q->h1 ("ACTIV INSTRUMENT TABLE DATA"), $q->pre('Table Here'),$q->end_html(); sub get_style { return 'body { color:red };'; }
    poj
Re: DBI output into browser using CGI
by huck (Prior) on Apr 25, 2017 at 15:09 UTC

    Since you didnt see any sign of print $q->end_html; it is clear your program terminated early, and the only path for that is an error termination. as hippo said Always check the error log.

Re: DBI output into browser using CGI
by billycote (Novice) on Apr 25, 2017 at 15:27 UTC
    I think I may have found something here in the tomcat logs. INFO: cgi: runCGI (stderr):install_driver(Oracle) failed: Can't load '/usr/local/lib64/perl5/auto/DBD/Oracle/Oracle.so' for module DBD::Oracle: libclntsh.so.12.1: cannot open shared object file: No such file or directory at /usr/lib64/perl5/DynaLoader.pm line 200, <CONFIG_FILE> line 5. I didn't even think of looking at these at first. d'oh. but what is weird (at least to me) is that tomcat can't load that. Another piece of the puzzle in any case.
      what is weird (at least to me) is that tomcat can't load that.

      In absence of any evidence to the contrary, best guess would be because the tomcat user doesn't have LD_LIBRARY_PATH set correctly. But given that you're using tomcat to run perl CGIs pretty much anything could be going wrong, TBH.

      That was my culprit :) thanks for the help and pointers guys. I'll do my best to clean the other messy parts up too