|
ru.cgi.perl- RU.CGI.PERL ------------------------------------------------------------------ From : Nikolay Pichtin 2:5056/30 15 Jul 2002 20:25:56 To : Andrey Kholyavkin Subject : Re: SSI -> CGI -> SSI -------------------------------------------------------------------------------- >> AG> print "ENDOFHTML"; >> AG> <!--#include virtual="header.html"... >> AG> ENDOFHTML >> AG> ... ... >> AG> Получится ли в результате нормальный html? >> В результате на странице (в коде) будет просто >> <!--#include virtual="header.html"... >> Таким макаром не покатит :) AK> Кажется на ЦПАHе есть модуль сказочный, его можно заставить парсить AK> STDOUT на предмет SSI. Только модуль ентот глюкавый. И название не AK> помню Пора в FAQ включать. ж-))) = Вставка = #/usr/bin/perl ####################### ## ## SSI-PL ## ## A library, which implements including perl files from within ## Perl script, taking into account SSI stuff. ## ## function to be called: DoInclude(URI); ## ## V0.1 ## ## Fixed a bug when existing SSIVARS were overwritten by ENV ## ## V0.0 ## ## implemented: ## ## <!--#echo var= ## ## partially supported: ## ## <!--#include ## only virtual includes allowed, and only for HTML files, not CGI. ## CGI files must end with .cgi ## ## <!--# if - elif - else -endif ## no parsing of expr parameter, can contain only $VARNAME ## ## <!--#fsize ## only virtual, ## CGI restrictions same as with #include ## ## ############# ### the path for HTML tree root of your server $HTMLRoot = "/usr/local/apache/share/"; ########### do not change anything below ############## @InHTMLComment; # stack, each level corresponds a level of include # if the element is>0 then we're inside a comment @SSIAccum; # Accumulator stack for an SSI comment @InSSIComment; # stack - if an element = 1 then we're in an SSI comment # 0 - ordinary comment @IFSTACK; # stack of state for if-elif-else-endif statements # 0 - the condition is true, pass the html & stuff # until the elif or else or endif # 1 - the condition is false, wait until the # elif or else is found # 2 - "true" condition branch has ended, # now waiting for endif # sub ReportError { print "<br><font size=1><b>@_[0]</b></font><br>"; } sub debug { # print "!!!" @_[0] } sub TransPath { # translate the path according to the current root of the server local $aFName = @_[0]; if ($aFName =~ /\.\./) { die("'..' are not allowed!"); } if ($aFName =~ /^\/(.*)/) { return $HTMLRoot . $aFName; } else { return $aFName; } return @_[0]; } sub InHTMLComment { return ($InHTMLComment[$#InHTMLComment]); } sub MayOutput { local $a = ($#IFSTACK == -1); local $b = ($IFSTACK[$#IFSTACK] == 0); return $a || $b; } sub SSI_IncludeVirtual { local $VFName = @_[0]; if ($VFName =~ /\.cgi$/) { ReportError ("Can not handle virtual includes for CGI yet..."); } else { # seems to be a normal file.. while not to include it ? # first check for ..!!! # print "VFNAME: $VFName\n"; $VFName = SSI_Eval($VFName); # print "VFNAME: $VFName\n"; DoInclude($VFName); } } sub SSI_FSizeVirtual { local $FName = TransPath(SSI_Eval(@_[0])); if ($FName =~ /\.cgi$/) { ReportError ("Can not handle virtual fsize for CGI..."); } else { # seems to be a normal file.. while not to give size of it ? $FName = TransPath($FName); local $FSize =(stat($FName))[7]; return $FSize; } } sub SSI_Eval { local $Expr = @_[0]; local $Result = $Expr; if ($Expr =~ /^\s*(.*?)\s*$/) { $Expr = $1; } # debug("Expr: $Expr\n"); if ($Expr =~ /^\$(.*?)$/ ) { $Result = $SSIVARS{$1}; } # debug("EVAL: $Expr: $Result\n"); return $Result; } sub SSI_If { return SSI_Eval(@_[0]); } sub ParseSSI { local $SSIStr = @_[0]; local $SSICmd; local $SSIParamStr; local %SSIParams; # debug ("SSI!: $SSIStr\n"); if ($SSIStr =~ /\s*(\w+)\s+(.*)/) { $SSICmd = $1; $SSIParamStr = $2; while ($SSIParamStr ne "") { if ($SSIParamStr =~ /(\w+)\s*=\s*\"(.*?)\"\s+(.*)/) { $SSIParams{$1} = $2; $SSIParamStr = $3; } } # now start checking for particula SSI commands & executing them # print "Cmd: $SSICmd\n"; if ($SSICmd eq 'if') { local $Expr = $SSIParams{'expr'}; if (SSI_If($Expr)) { # debug("IF: true\n"); push (@IFSTACK,0); } else { # debug("IF: false\n"); push (@IFSTACK,1); } } if ($SSICmd eq 'elif') { local $Expr = $SSIParams{'expr'}; if ($IFSTACK[$#IFSTACK] == 1) { if (SSI_If($Expr)) { # debug("ELIF: true\n"); $IFSTACK[$#IFSTACK] = 0; } else { # debug("ELIF: false\n"); $IFSTACK[$#IFSTACK] = 1; } } else { $IFSTACK[$#IFSTACK] = 2; } } if ($SSICmd eq 'else') { if ($IFSTACK[$#IFSTACK] == 1) { # debug("ELSE:\n"); $IFSTACK[$#IFSTACK] = 0; } else { $IFSTACK[$#IFSTACK] = 2; } } elsif ($SSICmd eq 'endif') { # debug("ENDIF:\n"); pop(@IFSTACK); } elsif (MayOutput()) { if ($SSICmd eq 'echo') { local $VarName = $SSIParams{'var'}; print "$SSIVARS{$VarName}"; } elsif ($SSICmd eq 'include') { local $VFName = $SSIParams{'virtual'}; if ($VFName ne "") { SSI_IncludeVirtual($VFName); } } elsif ($SSICmd eq 'set') { local $VarName = $SSIParams{'name'}; $SSIVARS{$VarName} = $SSIParams{'value'}; } if ($SSICmd eq 'fsize') { local $VFName = $SSIParams{'virtual'}; print SSI_FSizeVirtual($VFName); } } } } sub HandleCommentStart { local $Comment = @_[0]; ### we can parse SSI only if we're not in a comment already $ProcessSSI = (!InHTMLComment()); ### increment the current comment level count $InHTMLComment[$#InHTMLComment]++; # debug("CommentStart: $Comment\n"); if (($Comment =~ /^#(.*)$/) && ($ProcessSSI)) { push (@SSIAccum, $1); push (@InSSIComment, 1); } else { push (@InSSIComment, 0); if (MayOutput()) { print "<!-- $Comment"; } } # debug("Start: InHTMLComment = " . InHTMLComment() ."\n"); } sub HandleCommentCont { local $Comment = @_[0]; # print "CommentCont: $Comment\n"; if ($InSSIComment[$#InSSIComment]) { # if the current comment is an SSI one - add the value to an accumulator $SSIAccum[$#SSIAccum] .= " " . $Comment; } else { # else simply print the comment if (MayOutput()) { print "$Comment"; } } } sub HandleCommentEnd { local $Comment = @_[0]; # debug ("CommentEnd: $Comment"); $InHTMLComment[$#InHTMLComment]--; if (pop(@InSSIComment) == 1) { $SSIAccum[$#SSIAccum] .= " " . $Comment; $Comment = pop(@SSIAccum); ParseSSI($Comment); } else { if (MayOutput()) { print "$Comment-->\n"; } } # debug ("End: InHTMLComment = " . InHTMLComment() ); } sub HandleHTML { local $HTML = @_[0]; if (MayOutput()) { print "$HTML"; } } sub ProcessLine { # process the line and return the remainder local $ALine = @_[0]; # debug("CurrLine: $ALine\n"); if ($ALine =~ /^(.*?)\<\!--(.*?)--\>(.*)$/) { # debug("[$1] [$2] [$3]\n"); HandleHTML($1); HandleCommentStart($2); HandleCommentEnd(""); return "$3"; } if (InHTMLComment()) { # debug("CurrLine0: $ALine\n"); if ($ALine =~ /(.*?)--\>(.*)/) { HandleCommentEnd($1); # debug("valright1: $2\n"); return $2; } else { HandleCommentCont($ALine ."\n"); return ""; } } else { # normal run # debug("CurrLine: $ALine\n"); if ($ALine =~ /^(.*?)\<\!--(.*)/g) { HandleHTML($1); local $RestOfLine = $2; if ($RestOfLine =~ /(.*?)--\>(.*)/) { HandleCommentStart($1); HandleCommentCont(""); HandleCommentEnd(""); # debug("valright: $2\n"); return $2; } else { HandleCommentStart($RestOfLine); return ""; } } else { HandleHTML($ALine . "\n"); return ""; } } } sub DoInclude { ### include a file & print it & parse it for SSI stuff local $FName = TransPath(@_[0]); # print "FNAME: $FName\n"; local *SSIHTML; local @SSILINES; local $CurrLine; foreach $aName (keys %ENV) { $SSIVARS{$aName} = $ENV{$aName}; } push (@InHTMLComment, 0); if(open(SSIHTML, "<" . $FName)) { @SSILINES = <SSIHTML>; close (SSIHTML); foreach $CurrLine (@SSILINES) { chomp($CurrLine); while (($CurrLine = ProcessLine($CurrLine)) ne "") { } } } else { ReportError("I/O error while including the file"); } $CommentVal = pop(@InHTMLComment); if ( $CommentVal != 0) { ReportError("Unclosed comment $CommentVal in file $FName"); } } return 1; = Вставка = * Говорит Москва, все остальные работают. (От Фоменко) -- Hиколай ---------------------------------------------------------------------- --- * Origin: Где начало того конца, которым оканчивается начало? (2:5056/30) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.cgi.perl/18133d332ff2.html, оценка из 5, голосов 10
|