Re: security-- Okay, I now sanitize the data from the input form. My intention in this CGI was to show how cool Geo::WeatherNOAA is,
not to distribute a production quality script. But, for those that care, the more secure code sits below.
Re: HTML templates-- yes, I am a big supporter of separating html from code, but not for quick and dirty scripts to demonstrate something. I use HTML::Template and other tools quite frequently, but for this script I do think that it would be overkill.
cheers
#!/usr/bin/perl
use strict;
use Geo::WeatherNOAA;
use CGI qw(param);
my $OK_CHARS = "-a-zA-Z0-9_.@'\"\s";
foreach (param()) {
# sanitize data input from form
if (param($_) =~ /[^$OK_CHARS]/) {
print "Content-type: text/html\n\n";
print "<html><head><title>Form Error</title></head><body><b>Warnin
+g:</b> One of the characters in your form entry is not allowed by thi
+s program. Characters that are allowed are A-Za-z0-9.@-\"'. Please hi
+t back on your browser and try again.</body></html>";
exit(0);
}
}
my ($city, $state);
if (param("city")) {
$city = param("city");
} else {
$city = "Minneapolis";
}
if (param("state")) {
$state = param("state");
} else {
$state = "MN";
}
print "Content-type: text/html\n\n";
print <<EOHTML;
<HTML>
<HEAD>
<TITLE>BenWorld</TITLE>
<link rel="SHORTCUT ICON" href="/bk.ico">
</HEAD>
<BODY TEXT="#003366" BGCOLOR="#FFFFFF" ALINK="#0000FF" VLINK="#FF232D"
+>
<CENTER>
<IMG SRC="/images/benwlogo.jpg"><br>
<HR>
EOHTML
print "<h3><font color = red>Weather Forecast for</font> $city, $state
+</h3>";
my $html_weather_table = get_weather_data($city,$state);
print $html_weather_table;
print "<hr><p>\n";
print "<form><table>
<tr><td colspan = 2 align = center><b>Get weather for another City/Sta
+te</b></td></tr>
<td align = right><b>City:</b></td>
<td align = left><input type = text name = city></td></tr>\n";
print "<tr><td align = right><b>State:</b></td>
<td align = left>";
print_state_select_menu();
print "</td></tr>\n";
print "<tr><td colspan = 2 align = center><input type = submit value =
+ \"Get Forecast\"></td></tr>\n";
print "</table></form>\n";
print "</body></html>\n";
exit;
sub get_weather_data {
my ($city, $state) = @_;
my $filename = "weather_cache/${city}_${state}.out";
my ($return, $time, $mtime, $diff);
if (-e $filename) {
$time = time;
$mtime = (stat("weather_cache/$filename"))[9];
$diff = $time - $mtime;
} else {
$diff = 0;
}
if ($diff > 3600 || !$diff) { # file older than an hour or doesn't
+exist
$return = make_noaa_table($city,$state);
open(CACHE,">$filename") or warn "couldn't open weather_cache/$
+filename: $!";
print CACHE $return;
close(CACHE);
return $return;
} else {
open(CACHE,"<$filename") or warn "couldn't open weather_cache/$
+filename: $!";
{ local $/ = "\0"; $return = <CACHE>; }
close(CACHE);
return $return;
}
}
sub print_state_select_menu {
print '<select name="state" >
<option value=""> -- select one --
<option value="AL">Alabama
<option value="AK">Alaska
<option value="AZ">Arizona
<option value="AR">Arkansas
<option value="CA">California
<option value="CO">Colorado
<option value="CN">Connecticut
<option value="DE">Delaware
<option value="FL">Florida
<option value="GA">Georgia
<option value="HA">Hawaii
<option value="ID">Idaho
<option value="IL">Illinois
<option value="IN">Indiana
<option value="IO">Iowa
<option value="KA">Kansas
<option value="KY">Kentucky
<option value="LA">Louisiana
<option value="ME">Maine
<option value="MD">Maryland
<option value="MA">Massachusetts
<option value="MI">Michigan
<option value="MN">Minnesota
<option value="MS">Mississippi
<option value="MO">Missouri
<option value="MT">Montana
<option value="NE">Nebraska
<option value="NV">Nevada
<option value="NH">New Hampshire
<option value="NJ">New Jersey
<option value="NM">New Mexico
<option value="NY">New York
<option value="NC">North Carolina
<option value="ND">North Dakota
<option value="OH">Ohio
<option value="OK">Oklahoma
<option value="OR">Oregon
<option value="PA">Pennsylvania
<option value="RI">Rhode Island
<option value="SC">South Carolina
<option value="SD">South Dakota
<option value="TN">Tenneessee
<option value="TX">Texas
<option value="UT">Utah
<option value="VT">Vermont
<option value="VA">Virginia
<option value="WA">Washington
<option value="WV">West Virginia
<option value="WI">Wisconsin
<option value="WY">Wyoming
</select>';
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.