perl cgi form processing - perl

I am working on a file and I am trying to understand how to process a form in hopes of passing a hidden field. for simplicity, lets say i want my scipt to simply show the value of the hidden field when it is first presented to the user, incremented by one, and after it is 'submitted', the new script displayed with the updated hidden field. I am trying to gain insight on the explicit procedure so i can apply it to one of my current projects.
I have searched the web but most examples simply confuse me, can anyone chime in?

Values submitted by the form can be retrieved using the CGI module (since you haven't shown any code, I don't know whether you're using CGI or attempting to handle the CGI interactions by hand; if you're doing it by hand, You're Doing It Wrong) and its param method.
Given the HTML form:
<form action='my_script.cgi' method=POST>
<input type=hidden name=hidden_field value=1>
<input type=submit>
</form>
You can retrieve the hidden value with (in my_script.cgi):
#!/usr/bin/env perl
use strict;
use warnings;
use CGI;
my $q = CGI->new;
my $hidden_value = $q->param('hidden_field');

You could write the value of the hidden field to a cookie. Each time you refresh or revisit the same webpage, your script can read the cookie into the hidden variable and increment it by one. The following example uses a variable instead of a hidden field in the form.
#!/usr/bin/perl
#countvisits.cgi
use strict;
use warnings;
use CGI qw(:standard -debug);
use CGI::Carp qw(fatalsToBrowser);
#declare variables
my ($count, $C_record);
#Create a new CGI object
my $cgi = new CGI;
#Read the cookie
#assign input to variable
$count=$cgi->cookie('count');
$count++;
#create cookie
$C_record = cookie(-name => "count",
-value => $count,
-expires => "6M");
#send cookie to browser
print header(-cookie => $C_record);
#create Web page
print "<HTML>\n";
print "<HEAD><TITLE>Jubilee Book Club</TITLE></HEAD>\n";
print "<BODY>\n";
print "<H1 ALIGN=center>Hello!<BR>\n";
print "You have been here $count times.</H1>\n";
print "</BODY></HTML>\n";

Related

Input parameter for perl CGI script

I need some insight on my Perl CGI script.
First of all all this is running under webmin so i'm doing a custom module.
I'm calling a CGI Perl script passing 2 parameter from another Perl CGI. The link I'm calling is in the following format:
http://IP:8080/foobar/alat.cgi?sysinfo=xxxxxxx&SR=yyyyyyyy
The alat.cgi script look like this
#!/usr/bin/perl
use CGI qw(:standard);
ReadParse();
$q = new CGI;
my $dir = $in->param('SR');
my $s = $in->param('sysinfo');
ui_print_header(undef, $text{'edit_title'}.$dir, "");
print $dir."<br>";
print $s"<br>";
The only output I get printed is the value of $dir and $s seems to be empty.
What am I doing wrong?
As #Сухой27 said, add use strict;, but also use warnings; to the top of your script, right below the shebang (#!/usr/bin/perl) line. Those will tell you about syntax errors and other stuff where Perl is doing something other than you might intend.
With CGI (which is btw not part of the Perl core in the latest 5.22 release any more) and the object oriented approach you are tyring to take, you don't need to use ReadParse(). That is an abomination left in from Perl 4's cgilib.pl times.
I don't know what your ui_print_header function does. I'm guessing it outputs a bunch of HTML. Are you sure you defined it?
With fixing all your syntax errors and using modern syntax, your program would look like this. I'll break down what is happening for you.
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
my $q = CGI->new;
my $dir = $q->param('SR');
my $s = $q->param('sysinfo');
# you need to declare this to use it below
my %text = ( edit_title => 'foo' );
# we declare this sub further down
ui_print_header(undef, $text{'edit_title'} . $dir, q{});
print $dir . '<br />';
print $s . '<br />';
sub ui_print_header {
my ( $foo, $title, $dir, $bar ) = #_;
# do stuff here...
}
Let's look at some of the things I did here.
Saying new CGI as the CGI docs suggest is fine, but since we are using the OOP way you can use the more common CGI->new. It's the same thing really, but it's consistent with the rest of the OOP Perl world and it's more clear that you are calling the new method on the CGI package.
If you have $q, keep using it. There is no $in.
Declare all your variables with my.
Declare %text so you can use $text{'edit_title'} later. Probably you imported that, or ommitted it from the code you showed us.
Declare ui_print_header(). See above.
q{} is the same as '', but it's clearer that it's an empty string.
thank you everyone for the very quick answer, and as I was suspecting I just had some silly mistake.
Adding here the corrected code that now works
#!/usr/bin/perl
# Run alat on selected sysinfo and allow display of output
#use strict;
use diagnostics;
require 'recoverpoint-lib.pl';
use CGI qw(:standard);
ReadParse();
my $q = new CGI;
my $dir = $q->param('SR');
my $s = $q->param('sysinfo');
ui_print_header(undef, $text{'edit_title'}.$dir, "");
print $dir."<br>";
print $s."<br>";
Just to clarify for some of previous answer, this is a custom module of webmin so variable $text is imported and function ui_print_header is a webmin defined one, it basically print the page header in HTML
As you enable strict and warnings you can easily know the errors.Also you should check Apache error logs, I think the script should be like this:
#!/usr/bin/perl
use CGI qw(:standard);
use strict;
use warnings;
ReadParse();
my $q = new CGI;
my $dir = $q->param('SR');
my $s = $q->param('sysinfo');
ui_print_header(undef, $text{'edit_title'}.$dir, "");
print $dir."<br>";
print $s."<br>";

Perl CGI get user's user-agent

I have Perl CGI pages, (.pl extension). How Can I get a persons raw user agent string? There are ways of doing it in Javascript, (which I have been), though I'd rather move over to completely Perl, rather then having some Javascript and some Perl.
In example, to get a person's IP: $ENV{REMOTE_ADDR}
User agent is stored in $ENV{HTTP_USER_AGENT}
Use the CGI module:
#!/usr/bin/perl -wT
use strict;
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
print header;
print start_html("Environment");
foreach my $key (sort(keys(%ENV))) {
print "$key = $ENV{$key}<br>\n";
}
print end_html;
As people have already mentioned, it's always available in the $ENV{HTTP_USER_AGENT} variable. But if you're using CGI.pm, you can also get it by calling the user_agent() function.

Strange behavior when passing parameters to a Perl/CGI script, from another Perl/CGI script

For a project at work, I need to call one Perl/CGI script from another. An extremely simplified version of that script that I'm using for testing is here (the real scripts don't use recursion, but this way I don't have to copy & paste a lot of code):
#!/usr/local/bin/perl
use CGI qw(:standard);
use POSIX 'setsid';
$|=1;
print "Content-type: text/html\n\n";
#names = param;
print "#names";
if(defined(param('submit'))){
#delete_all();
system('perl testParams.pl abc=123');
exit(0);
} else{
print "NO SUBMIT PARAM";
}
What this script is supposed to do:
Print names of all parameters.
If a submit parameter is defined, run the script again but with a parameter called "abc".
If a "submit" parameter is not defined, print "NO SUBMIT PARAM".
What the script actually does:
Print names of all parameters.
If a "submit" parameter is defined, run the script again with the same parameters that the original script was run with.
If a "submit" parameter is not defined, print "NO SUBMIT PARAM".
Any idea what's causing Perl/CGI to ignore the new parameters and instead send the old ones when running the script?
CGI only processes command line args when a CGI environment isn't found. The CGI environment is being inherited from the parent process. You could wipe it using
my %CGI_VARS = map { $_ => 1 } qw(
REQUEST_METHOD
CONTENT_LENGTH
CONTENT_TYPE
...
);
local %ENV =
map { $_ => $ENV{$_} }
grep !$CGI_VARS{$_} && !/^HTTP/,
keys(%ENV);
But this reeks of bad design. Really, your two scripts should be thin front ends to a common module.
You could even use the same script for both (by using a symlink), but alter the behaviour based on the URL used to call up the script.
From CGI with nested apps, each calling param() to get their args the simple answer is to create new CGI object from #ARGV
#!/usr/bin/perl --
use strict;
use warnings;
use CGI ();
Main( #ARGV );
exit( 0 );
sub Main {
my $cgi = #_ ? CGI->new(#_) : CGI->new;
}

basic help for Perl CGI module

I want to use the Perl CGI module for creating CGI scripts. I went through the documentation available
here but I seem to have missed something obvious because I have
run into problems with my first program. Here is the HTML:
<form name="form1" method="post" action="http://localhost/cgi-bin/filters.cgi">
<input name="mainbox" type="checkbox"> Mainbox<br> <br>
<input name="n1" type="checkbox">No. 1 <br><br>
<input name="n2" type="checkbox"> No. 2<br><br>
<input name="n3" type="checkbox">No. 3 <br>
<div style="text-align: center;"><input name="Submit" value="Submit" type="submit"></div>
</form>
I simply want the names of the parameters that are passed to the CGI file to be printed on a new
page. So (with my limited understanding), I wrote the following in filters.cgi:
#!/xampp/perl/bin/perl -w
use strict;
use warnings;
use CGI;
my $query = CGI->new;
print $query = $query->header('text/html');
my #names = $query->param;
my $q1 = CGI->new;
print $q1->header('text/html');
print $q1->start_html('hello');
foreach my $name (#names) {
print $q1->h1($name);
}
print $q1->end_html;
But this prints out nothing. It does not give me any error either and the syntax is OK.
I know I am missing something very simple here but I really want some help with this. How do
I write this script correctly? I am using XAMPP in Windows XP, if that makes any difference.
EDIT: Maybe I should mention that I have tried to figure this out myself. So I wrote the
following script which works:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
my #arr = ('ac', 'fg', 'ty');
my $q1 = CGI->new;
print $q1->header('text/html');
$q1->start_html('hello world');
foreach my $el (#arr) {
print $q1->p($el);
}
$q1->end_html;
So the problem is somewhere in the parameters being passed. I don't even know where to look for
help in the long documentation, so decided to ask here. Also, I have seen the link Nikhil
has posted in the comments. One of the points mentioned there is that I should try running my
script from the command line. How do I pass these parameters from the command line?
The first issue you had was that you were assigning the result of calling $query->header('text/html') back into your $query variable, destroying the query object which meant that the next line my #names = $query->param wasn't working as expected.
Secondly, you were attempting to print the Content-type header twice, once using the $query CGI object and once using the $q1 object.
I have removed the unnecessary CGI object, $q1, and used the original $query object in all cases.
The following is the code with the above fixes applied.
#!/xampp/perl/bin/perl -w
use strict;
use warnings;
use CGI;
my $query = CGI->new;
my #names = $query->param;
print $query->header('text/html');
print $query->start_html('hello');
foreach my $name (#names) {
print $query->h1($name);
}
print $query->end_html;
print $query = $query->header('text/html');
This line is part of your problem. $query->header() returns some text, which isn't a useful value to set $query to. You're also creating two CGI objects ($query and $q1) where you only need one, and printing two sets of headers. Get rid of the duplication and the inappropriate assignment, and you should be fine.

What's the Perl equivalent of PHP's $_SERVER[...]?

What's the Perl equivalent for the following PHP calls?
$_SERVER["HTTP_HOST"]
$_SERVER["REQUEST_URI"]
Any help would be much appreciated.
Another way, than variable environement, is to use CGI :
use strict;
use warnings;
use CGI ;
print CGI->new->url();
Moreover, it also offers a lot of CGI manipulation such
as accessing params send to your cgi, cookies etc...
Environment variables are a series of hidden values that the web server sends to every CGI you run. Your CGI can parse them and use the data they send. Environment variables are stored in a hash called %ENV.
For example, $ENV{'HTTP_HOST'} will give the hostname of your server.
#!/usr/bin/perl
print "Content-type:text/html\n\n";
print <<EndOfHTML;
<html><head><title>Print Environment</title></head>
<body>
EndOfHTML
foreach my $key (sort(keys %ENV)) {
print "$key = $ENV{$key}<br>\n";
}
print "</body></html>";
For more details see CGI Environmental variables
Or you can do this and use the variable $page_url.
my $page_url = 'http';
$page_url.='s' if $ENV{HTTPS};
$page_url.='://';
if($ENV{SERVER_PORT}!=80)
{
$page_url.="$ENV{SERVER_NAME}:$ENV{SERVER_PORT}$ENV{REQUEST_URI}";
}
else
{
$page_url.=$ENV{SERVER_NAME}.$ENV{REQUEST_URI};
}
What's the environment you're working in? If it's CGI script try:
use Data::Dumper;
print Dumper \%ENV;