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

I am trying to retrieve the environment variables from a CGI script after it has been submitted, however, the only environment variables I am able to retrieve are REMOTE_HOST, REMOTE_ADDR, and REQUEST_METHOD. To obtain these I use:
$ip_addr = $ENV{'REMOTE_ADDR'}; $host_name = gethostbyaddr(inet_aton($ip_addr), AF_INET); $req_method = $ENV{'REQUEST_METHOD'};
The other variabels I wish to obtain, but do not show up are as follows:
$host_port = $ENV{'REMOTE_PORT'}; $user_agent = $ENV{'HTTP_USER_AGENT'}; $mac_address = `/sbin/arp -a $ip_addr` =~ /at\s+(\S+)\s+/; $user_referer = $ENV{'HTTP_REFERER'};
I know I can get all of the variables by doing the following:
#!/usr/bin/perl print "Content-type: text/html\n\n"; $n = 0; print "<tt>\n"; foreach $key(sort keys(%ENV)) { print "$key = $ENV{$key}<p>"; @keys[$n] = $ENV{$key}; $n++; } print qq~The remort port is $keys[15]~;
But that seems a little longwinded and unnecessary. If anyone could suggest something shorter or possibly point out what I'm doing wrong that would be great. Thank again!

Replies are listed 'Best First'.
Re: HTTP/CGI Environmnet Variables
by Tanktalus (Canon) on Mar 01, 2005 at 21:23 UTC

    Let's start with some basics before going too deep.

    • What OS and webserver are you using? Different webservers can easily provide different environments. Especially on the less critical variables, I would imagine.
    • Any possibility of a typo? If the print "$key = $ENV{$key}<p>"; line works, then there would be no reason for the other code to work except for keys that aren't quite right (such as in a typo).
    • Any reason to not use CGI to get all this? You're far more likely to get a compile or run-time error that makes things very obvious that it's going wrong if you use an existing module. Typos and the like will already be dealt with.
      In answer to your questions:

    • Red Hat EL 3 with Apache 2.0.46

    • That's correct, but as ikegami states it is a CGI specification problem that I did not completely understand

    • That is true, but as I stated in my reply to chas I want to get those specific environment variables and store them in my database.
Re: HTTP/CGI Environmnet Variables
by ikegami (Patriarch) on Mar 01, 2005 at 22:17 UTC

    CGI/1.1 specification

    • REMOTE_PORT is not listed in the CGI specification.
      (However, Apache supplies it.)
    • HTTP_USER_AGENT is only supplied when the HTTP client actually provided it.
    • HTTP_REFERER is not listed in the CGI specification.
      (However, Apache supplies it when the HTTP client provided it.)

    Could it be that your web server doesn't provide these? If your third snippet returns it, you must have a typo somewhere.

Re: HTTP/CGI Environmnet Variables
by chas (Priest) on Mar 01, 2005 at 21:43 UTC
    I'm not sure what the problem is; the code
    foreach $key(sort keys(%ENV)) { print "$key = $ENV{$key}<p>";}
    should give you all the information available. Why do you need to print it out some other way? As for the rest: In @keys[$n] = $ENV{$key};, the term @keys[$n] should likely be $keys[$n] (an array element not a slice with one entry), but those should be labeled *values*, not *keys*, shouldn't they?
    chas
      You are right on both accounts. I have cut/paste disabled in VNC and got lazy with my typing, but that is correct. I really just want to store those specific instances of REMOTE_HOST, REMOTE_ADDR, REQUEST_METHOD, REMOTE_PORT, HTTP_USER_AGENT, mac address, and HTTP_REFERER in a database. Bascially, I'm keeping track of failed login attempts.
Re: HTTP/CGI Environmnet Variables
by sh1tn (Priest) on Mar 01, 2005 at 22:21 UTC
    #!/usr/bin/perl use strict; print "content-type:text/html\n\n"; print "<body bgcolor=black text=white>"; print "<table wigth=70% bgcolor=#000000 align=center>"; print "<tr><td>$_</td><td align=center bgcolor=#222222>$ENV{$_}</td></ +tr>" for keys %ENV; print "</table>";


      Thanks for the help all. Based on the specifications I now have a more correct setup to store the required information. I'm having some issues getting the browser-type, but I think I can work them out.

      Thanks for the insight and direction. I'll let you know if I can retrieve the other information since HTTP provides it.