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

Hi all,

In putting together a CGI script, I get the very strange error, apparently from the BEGIN block:

String found where operator expected at test line 13, near "STDOUT "St +atus: 413 Request Entity Too Large\r\n"" (Do you need to predeclare STDOUT?) syntax error at test line 13, near "print" BEGIN not safe after errors--compilation aborted at test line 16.

What does the error BEGIN not safe mean?

Here is my code ...

#!/usr/bin/perl sub BEGIN { # Check for oversize request entity # my $post_maximum = 1047576; my $content_length = defined($ENV{'CONTENT_LENGTH'}) ? $ENV{'CONTE +NT_LENGTH'} : 0; if (($post_maximum > 0) && ($content_length > $post_maximum)) { print STDOUT ( $ENV{'SERVER_PROTOCOL'} || 'HTTP/1.0' ), " 413 +Request entity too large\r\n" print STDOUT "Status: 413 Request Entity Too Large\r\n"; exit 0; } } sub init { local $/ = "\n"; my $request_method = $ENV{'REQUEST_METHOD'} if defined $ENV{'REQUE +ST_METHOD'}; my $content_length = defined($ENV{'CONTENT_LENGTH'}) ? $ENV{'CONTE +NT_LENGTH'} : 0; my $query_string; METHOD: { # process multi-part POST method # if (($request_method =~ /^POST$/) && ($ENV{'CONTENT_TYPE'} =~ m!^multipart/form-data!)) { # On the TODO list! last METHOD; } # process GET or HEAD method # if ($request_method =~ /^(GET|HEAD)$/) { $query_string = $ENV{'QUERY_STRING'} if defined $ENV{'QUER +Y_STRING'}; $query_string ||= $ENV{'REDIRECT_QUERY_STRING'} if defined + $ENV{'REDIRECT_QUERY_STRING'}; last METHOD; } # process POST method # if ($request_method =~ /^POST$/) { if ($content_length > 0) { local $^W = 0; $query_string = read (STDIN, $query_string, $content_l +ength, 0); } $query_string .= (length($query_string) ? '&' : '') . $ENV +{'QUERY_STRING'} if $ENV{'QUERY_STRING'}; last METHOD; } print STDOUT ( $ENV{'SERVER_PROTOCOL'} || 'HTTP/1.0' ), " 405 +Method Not Allowed\r\n" print STDOUT "Status: 405 Method Not Allowed\r\n"; exit 0; } my $results = {}; if ((defined $query_string) && (length $query_string)) { if ($query_string =~ /[&=;]/) { my (@pairs) = split /[&;]/, $query_string; foreach (@pairs) { my ($param, $value) = split '=', $_, 2; $value ||= ''; $param = unescape($param); $value = unescape($value); push @{$results->{$param}}, $value; } } } return $results; } sub unescape { my ($todecode) = @_; return undef unless defined $todecode; $todecode =~ tr/+/ /; $todecode =~ s/%([\da-fA-F]{2})/chr hex($1)/ge; return $todecode; }

Replies are listed 'Best First'.
Re (tilly) 1: Strange Error From BEGIN
by tilly (Archbishop) on Feb 20, 2002 at 13:10 UTC
    Stop handrolling your CGI parsing logic. Use the CGI module instead. It is in the core so you don't even have to worry about installing it. All of the above can be replaced by:
    use strict; use CGI qw(:standard); $CGI::POST_MAX = 1047576; sub init { my $results; foreach my $param (param()) { $results{$param} = [param($result)]; } return $result; }
    OK, throwing in strict.pm was gratuitous goodness that was not needed for the rewrite. And as you can see from the example, given how convenient param() is you don't need to have an init method at all.
Re: Strange Error From BEGIN
by busunsl (Vicar) on Feb 20, 2002 at 11:01 UTC
    You are missing a semicolon at the end of line 12.
Re: Strange Error From BEGIN
by ropey (Hermit) on Feb 20, 2002 at 13:05 UTC
    Turn on Warnings, and use strict
    #!/usr/bin/perl -w
    It will help you track down bugs a lot easier.