📄 cgi.pm
字号:
# If method is GET or HEAD, fetch the query from # the environment. if ($meth=~/^(GET|HEAD)$/) { if ($MOD_PERL) { $query_string = Apache->request->args; } else { $query_string = $ENV{'QUERY_STRING'} if defined $ENV{'QUERY_STRING'}; $query_string ||= $ENV{'REDIRECT_QUERY_STRING'} if defined $ENV{'REDIRECT_QUERY_STRING'}; } last METHOD; } if ($meth eq 'POST') { $self->read_from_client(\*STDIN,\$query_string,$content_length,0) if $content_length > 0; # Some people want to have their cake and eat it too! # Uncomment this line to have the contents of the query string # APPENDED to the POST data. # $query_string .= (length($query_string) ? '&' : '') . $ENV{'QUERY_STRING'} if defined $ENV{'QUERY_STRING'}; last METHOD; } # If $meth is not of GET, POST or HEAD, assume we're being debugged offline. # Check the command line and then the standard input for data. # We use the shellwords package in order to behave the way that # UN*X programmers expect. $query_string = read_from_cmdline() if $DEBUG; } # We now have the query string in hand. We do slightly # different things for keyword lists and parameter lists. if (defined $query_string && length $query_string) { if ($query_string =~ /[&=;]/) { $self->parse_params($query_string); } else { $self->add_parameter('keywords'); $self->{'keywords'} = [$self->parse_keywordlist($query_string)]; } } # Special case. Erase everything if there is a field named # .defaults. if ($self->param('.defaults')) { undef %{$self}; } # Associative array containing our defined fieldnames $self->{'.fieldnames'} = {}; foreach ($self->param('.cgifields')) { $self->{'.fieldnames'}->{$_}++; } # Clear out our default submission button flag if present $self->delete('.submit'); $self->delete('.cgifields'); $self->save_request unless $initializer;}# FUNCTIONS TO OVERRIDE:# Turn a string into a filehandlesub to_filehandle { my $thingy = shift; return undef unless $thingy; return $thingy if UNIVERSAL::isa($thingy,'GLOB'); return $thingy if UNIVERSAL::isa($thingy,'FileHandle'); if (!ref($thingy)) { my $caller = 1; while (my $package = caller($caller++)) { my($tmp) = $thingy=~/[\':]/ ? $thingy : "$package\:\:$thingy"; return $tmp if defined(fileno($tmp)); } } return undef;}# send output to the browsersub put { my($self,@p) = self_or_default(@_); $self->print(@p);}# print to standard output (for overriding in mod_perl)sub print { shift; CORE::print(@_);}# get/set last cgi_errorsub cgi_error { my ($self,$err) = self_or_default(@_); $self->{'.cgi_error'} = $err if defined $err; return $self->{'.cgi_error'};}sub save_request { my($self) = @_; # We're going to play with the package globals now so that if we get called # again, we initialize ourselves in exactly the same way. This allows # us to have several of these objects. @QUERY_PARAM = $self->param; # save list of parameters foreach (@QUERY_PARAM) { next unless defined $_; $QUERY_PARAM{$_}=$self->{$_}; } $QUERY_CHARSET = $self->charset; %QUERY_FIELDNAMES = %{$self->{'.fieldnames'}};}sub parse_params { my($self,$tosplit) = @_; my(@pairs) = split(/[&;]/,$tosplit); my($param,$value); foreach (@pairs) { ($param,$value) = split('=',$_,2); $value = '' unless defined $value; $param = unescape($param); $value = unescape($value); $self->add_parameter($param); push (@{$self->{$param}},$value); }}sub add_parameter { my($self,$param)=@_; return unless defined $param; push (@{$self->{'.parameters'}},$param) unless defined($self->{$param});}sub all_parameters { my $self = shift; return () unless defined($self) && $self->{'.parameters'}; return () unless @{$self->{'.parameters'}}; return @{$self->{'.parameters'}};}# put a filehandle into binary mode (DOS)sub binmode { CORE::binmode($_[1]);}sub _make_tag_func { my ($self,$tagname) = @_; my $func = qq( sub $tagname { shift if \$_[0] && (ref(\$_[0]) && (substr(ref(\$_[0]),0,3) eq 'CGI' || UNIVERSAL::isa(\$_[0],'CGI'))); my(\$attr) = ''; if (ref(\$_[0]) && ref(\$_[0]) eq 'HASH') { my(\@attr) = make_attributes(shift()||undef,1); \$attr = " \@attr" if \@attr; } ); if ($tagname=~/start_(\w+)/i) { $func .= qq! return "<\L$1\E\$attr>";} !; } elsif ($tagname=~/end_(\w+)/i) { $func .= qq! return "<\L/$1\E>"; } !; } else { $func .= qq# return \$XHTML ? "\L<$tagname\E\$attr />" : "\L<$tagname\E\$attr>" unless \@_; my(\$tag,\$untag) = ("\L<$tagname\E\$attr>","\L</$tagname>\E"); my \@result = map { "\$tag\$_\$untag" } (ref(\$_[0]) eq 'ARRAY') ? \@{\$_[0]} : "\@_"; return "\@result"; }#; }return $func;}sub AUTOLOAD { print STDERR "CGI::AUTOLOAD for $AUTOLOAD\n" if $CGI::AUTOLOAD_DEBUG; my $func = &_compile; goto &$func;}sub _compile { my($func) = $AUTOLOAD; my($pack,$func_name); { local($1,$2); # this fixes an obscure variable suicide problem. $func=~/(.+)::([^:]+)$/; ($pack,$func_name) = ($1,$2); $pack=~s/::SUPER$//; # fix another obscure problem $pack = ${"$pack\:\:AutoloadClass"} || $CGI::DefaultClass unless defined(${"$pack\:\:AUTOLOADED_ROUTINES"}); my($sub) = \%{"$pack\:\:SUBS"}; unless (%$sub) { my($auto) = \${"$pack\:\:AUTOLOADED_ROUTINES"}; eval "package $pack; $$auto"; croak("$AUTOLOAD: $@") if $@; $$auto = ''; # Free the unneeded storage (but don't undef it!!!) } my($code) = $sub->{$func_name}; $code = "sub $AUTOLOAD { }" if (!$code and $func_name eq 'DESTROY'); if (!$code) { (my $base = $func_name) =~ s/^(start_|end_)//i; if ($EXPORT{':any'} || $EXPORT{'-any'} || $EXPORT{$base} || (%EXPORT_OK || grep(++$EXPORT_OK{$_},&expand_tags(':html'))) && $EXPORT_OK{$base}) { $code = $CGI::DefaultClass->_make_tag_func($func_name); } } croak("Undefined subroutine $AUTOLOAD\n") unless $code; eval "package $pack; $code"; if ($@) { $@ =~ s/ at .*\n//; croak("$AUTOLOAD: $@"); } } CORE::delete($sub->{$func_name}); #free storage return "$pack\:\:$func_name";}sub _reset_globals { initialize_globals(); }sub _setup_symbols { my $self = shift; my $compile = 0; foreach (@_) { $HEADERS_ONCE++, next if /^[:-]unique_headers$/; $NPH++, next if /^[:-]nph$/; $NOSTICKY++, next if /^[:-]nosticky$/; $DEBUG=0, next if /^[:-]no_?[Dd]ebug$/; $DEBUG=2, next if /^[:-][Dd]ebug$/; $USE_PARAM_SEMICOLONS++, next if /^[:-]newstyle_urls$/; $XHTML++, next if /^[:-]xhtml$/; $XHTML=0, next if /^[:-]no_?xhtml$/; $USE_PARAM_SEMICOLONS=0, next if /^[:-]oldstyle_urls$/; $PRIVATE_TEMPFILES++, next if /^[:-]private_tempfiles$/; $EXPORT{$_}++, next if /^[:-]any$/; $compile++, next if /^[:-]compile$/; # This is probably extremely evil code -- to be deleted some day. if (/^[-]autoload$/) { my($pkg) = caller(1); *{"${pkg}::AUTOLOAD"} = sub { my($routine) = $AUTOLOAD; $routine =~ s/^.*::/CGI::/; &$routine; }; next; } foreach (&expand_tags($_)) { tr/a-zA-Z0-9_//cd; # don't allow weird function names $EXPORT{$_}++; } } _compile_all(keys %EXPORT) if $compile;}sub charset { my ($self,$charset) = self_or_default(@_); $self->{'.charset'} = $charset if defined $charset; $self->{'.charset'};}################################################################################################ THESE FUNCTIONS ARE AUTOLOADED ON DEMAND ###################################################################################################$AUTOLOADED_ROUTINES = ''; # get rid of -w warning$AUTOLOADED_ROUTINES=<<'END_OF_AUTOLOAD';%SUBS = ('URL_ENCODED'=> <<'END_OF_FUNC',sub URL_ENCODED { 'application/x-www-form-urlencoded'; }END_OF_FUNC'MULTIPART' => <<'END_OF_FUNC',sub MULTIPART { 'multipart/form-data'; }END_OF_FUNC'SERVER_PUSH' => <<'END_OF_FUNC',sub SERVER_PUSH { 'multipart/x-mixed-replace;boundary="' . shift() . '"'; }END_OF_FUNC'new_MultipartBuffer' => <<'END_OF_FUNC',# Create a new multipart buffersub new_MultipartBuffer { my($self,$boundary,$length,$filehandle) = @_; return MultipartBuffer->new($self,$boundary,$length,$filehandle);}END_OF_FUNC'read_from_client' => <<'END_OF_FUNC',# Read data from a file handlesub read_from_client { my($self, $fh, $buff, $len, $offset) = @_; local $^W=0; # prevent a warning return undef unless defined($fh); return read($fh, $$buff, $len, $offset);}END_OF_FUNC'delete' => <<'END_OF_FUNC',#### Method: delete# Deletes the named parameter entirely.####sub delete { my($self,@p) = self_or_default(@_); my($name) = rearrange([NAME],@p); CORE::delete $self->{$name}; CORE::delete $self->{'.fieldnames'}->{$name}; @{$self->{'.parameters'}}=grep($_ ne $name,$self->param()); return wantarray ? () : undef;}END_OF_FUNC#### Method: import_names# Import all parameters into the given namespace.# Assumes namespace 'Q' if not specified####'import_names' => <<'END_OF_FUNC',sub import_names { my($self,$namespace,$delete) = self_or_default(@_); $namespace = 'Q' unless defined($namespace); die "Can't import names into \"main\"\n" if \%{"${namespace}::"} == \%::; if ($delete || $MOD_PERL || exists $ENV{'FCGI_ROLE'}) { # can anyone find an easier way to do this? foreach (keys %{"${namespace}::"}) { local *symbol = "${namespace}::${_}"; undef $symbol; undef @symbol; undef %symbol; } } my($param,@value,$var); foreach $param ($self->param) { # protect against silly names ($var = $param)=~tr/a-zA-Z0-9_/_/c; $var =~ s/^(?=\d)/_/; local *symbol = "${namespace}::$var"; @value = $self->param($param); @symbol = @value; $symbol = $value[0]; }}END_OF_FUNC#### Method: keywords# Keywords acts a bit differently. Calling it in a list context# returns the list of keywords. # Calling it in a scalar context gives you the size of the list.####'keywords' => <<'END_OF_FUNC',sub keywords { my($self,@values) = self_or_default(@_); # If values is provided, then we set it. $self->{'keywords'}=[@values] if @values; my(@result) = defined($self->{'keywords'}) ? @{$self->{'keywords'}} : (); @result;}END_OF_FUNC# These are some tie() interfaces for compatibility# with Steve Brenner's cgi-lib.pl routines'Vars' => <<'END_OF_FUNC',sub Vars { my $q = shift; my %in; tie(%in,CGI,$q); return %in if wantarray; return \%in;}END_OF_FUNC# These are some tie() interfaces for compatibility# with Steve Brenner's cgi-lib.pl routines'ReadParse' => <<'END_OF_FUNC',sub ReadParse { local(*in); if (@_) { *in = $_[0]; } else { my $pkg = caller(); *in=*{"${pkg}::in"}; } tie(%in,CGI); return scalar(keys %in);}END_OF_FUNC'PrintHeader' => <<'END_OF_FUNC',sub PrintHeader { my($self) = self_or_default(@_); return $self->header();}END_OF_FUNC'HtmlTop' => <<'END_OF_FUNC',sub HtmlTop { my($self,@p) = self_or_default(@_); return $self->start_html(@p);}END_OF_FUNC'HtmlBot' => <<'END_OF_FUNC',sub HtmlBot { my($self,@p) = self_or_default(@_); return $self->end_html(@p);}END_OF_FUNC'SplitParam' => <<'END_OF_FUNC',sub SplitParam { my ($param) = @_; my (@params) = split ("\0", $param); return (wantarray ? @params : $params[0]);}END_OF_FUNC'MethGet' => <<'END_OF_FUNC',sub MethGet { return request_method() eq 'GET';}END_OF_FUNC'MethPost' => <<'END_OF_FUNC',sub MethPost { return request_method() eq 'POST';}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -