Perl CGI get user's user-agent - perl

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.

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>";

using perl cgi to fetch cookies

I'm trying to inspect cookie values in a cgi script; my test script looks like
#!/usr/bin/perl -w
use DBI;
use CGI qw/:standard/;
use CGI::Cookie;
my $cgiH = CGI->new;
print header;
print start_html(-title=>'Cookie Terms'), h1("Cookie Terms"), "<hr>\n";
%cookies = CGI::Cookie->fetch;
foreach $k (keys %cookies) {
my $term = "$cookies{$k}";
my $term =~ s/SubjectTerm//;
print "at $k is $term \n";
}
print end_html;
the relevant input to the script (from an HTTP GET) is
Cookie: SubjectTerm1=ponies
Cookie: SubjectTerm2=horses
(this is verified by using either fiddler or debugging the code in my delphi app). the result of my script (omitting the HTML wrapper) is either
at SubjectTerm1 is
at SubjectTerm2 is
or if I change the print statement to
print "at $k is $cookies{$k}\n";
it is
at SubjectTerm1 is SubjectTerm1=ponies; path=/
at SubjectTerm2 is SubjectTerm2=horses; path=/
What I want to arrive it is something like this
at SubjectTerm1 is ponies
at SubjectTerm2 is horses
I know I'm missing something about the hash usage but can't quite figure out what it is.
am I not addressing the %cookies hash correctly?
If you had use warnings you would see you are clobbering the $term with the line
my $term =~ s/SubjectTerm//;
Remove the my.
I think you might be able to extract the value is simply changing the assignment to
my $term = $cookies{$k}->value();
and get rid of the s/SubjectTerm//. But not sure about this sorry.
As an aside, before I answer the question, I'd strongly recommend you look at using something other than CGI.pm -- it's the best of late-90s Perl, and other than being included by default in the core perl distribution has little to recommend it.
Some more modern, more featureful alternatives include:
CGI::Application - http://cgi-app.org/
Mojolicious - http://mojolicio.us/
Dancer - http://www.perldancer.org/
Beyond that, as #Sodved says if you'd included use strict; and use warnings; at the top of your file the first of your problems -- clobbering $term by using my twice -- would have been highlighted immediately.
Once you're using the strict and warnings pragmas (and I'd say, don't leave home without them) you'll also want to change your foreach to either:
foreach (keys %cookies) {
my $term = $cookies{$_};
...
OR
foreach my $k (keys %cookies) {
my $term = $cookies{$k};
...
That is, you'll either need to declare the $k variable, or you may prefer to use Perl's built-in $_ inside the loop -- it's purely a matter of style.
Good luck!

How to use a module in Perl

Guys im really confused on how to use a module i just installed in Perl.
I installed a Corelist module in Perl. And i want to display all the modules that came with Perl 5.006. But there is a hint in doing this by using this code which i dont understand:
my %modules = %{ $Module::CoreList::version{5.006} };
But when i did this
#! usr/bin/perl
use warnings;
use strict;
my %modules = %{$Module::CoreList::version{5.006}};
print %modules;
it gives this error: Module::CoreList::version used only once . I also tried putting
use Module::CoreList; still no luck
The name of the module is 'Module::CoreList'. You should put the following line into your programme:
use Module::CoreList;
Also note the capital L. Perl is case sensitive.
If you simply want to print the hash, just add Data::Dumper module along with strict and warnings, then
print Dumper(\%modules);
Updated: try something like
use warnings;
use strict;
use Module::CoreList;
use Data::Dumper;
my %module = %{ $Module::CoreList::version{5.006} };
print Dumper (\%module);

In Perl, how do I send CGI parameters on the command line?

Normally i get the data from a webpage but i want to send it from the command line to facilitate debugging.
To get the data i do something like:
my $query = new CGI;
my $username = $query->param("the_username");
this doesn't seem to work:
$ ./script.pl the_username=user1
EDIT:
Actually the above works. The if statement that checked $username was wrong (using == instead of eq).
As I found out long time ago, you can indeed pass query string parameters to a script using CGI.pm. I am not recommending this as a preferred debugging method (better to have replicable stuff saved in files which are then directed to the STDIN of the script), however, it does work:
#!/usr/bin/env perl
use warnings; use strict;
use CGI;
my $cgi = CGI->new;
my $param_name = 'the_username';
printf(
"The value of '%s' is '%s'.\n",
$param_name, $cgi->param($param_name)
);
Output:
$ ./t.pl the_username=yadayada
The value of 'the_username' is 'yadayada'.
CGI reads the variables from standard input.
See this part of the CGI.pm documentation:
http://search.cpan.org/dist/CGI/lib/CGI.pod#DEBUGGING

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;