Apache-Scriptor

 view release on metacpan or  search on metacpan

Scriptor.pm  view on Meta::CPAN

# ñëó÷àå èìÿ ôàéëà âû÷èñëÿåòñÿ àâòîìàòè÷åñêè íà îñíîâå $uri (ýòî íå âñåãäà
# ðàáîòàåò ïðàâèëüíî - íàïðèìåð, òàêàÿ øòóêà íå ïðîéäåò, åñëè äèðåêòîðèÿ áûëà
# çàâåäåíà êàê Alias Apache).
sub run_uri
{ my ($this,$uri,$path)=@_;
  Header("X-Powered-by: Apache::Scriptor v$VERSION. (C) Dmitry Koterov <koterov at cpan dot org>") if !$CopySend++;

  # Òåïåðü ðàáîòàåì ñ ÊÎÏÈÅÉ îáúåêòà. Òàêèì îáðàçîì, äàëüíåéøèå âûçîâû
  # process_htaccesses è ò.ä. íå îòðàçÿòñÿ íà îáùåì ñîñòîÿíèè îáúåêòà
  # ïîñëå îêîí÷àíèÿ çàïðîñà.
  local $this->{Handlers}={%{$this->{Handlers}}};
  local $this->{404}=$this->{404};

  # Ðàçäåëÿåì íà URL è QUERY_STRING
  local ($ENV{SCRIPT_NAME},$q) = split /\?/, $uri, 2;
  $ENV{QUERY_STRING}=defined $q? $q : "";

  # Âû÷èñëÿåì ïóòü ê ôàéëó ñêðèïòà ïî URI
  if(!$path) {
    $path="$ENV{DOCUMENT_ROOT}$ENV{SCRIPT_NAME}";
  }

  # Ãîòîâèì íîâûå ïåðåìåííûå îêðóæåíèÿ, ÷òîáû ñêðûòü Apache::Scriptor;
  local $ENV{REQUEST_URI}     = $uri;
  local $ENV{SCRIPT_FILENAME} = $path;
  local $ENV{REDIRECT_URL};     delete($ENV{REDIRECT_URL});
  local $ENV{REDIRECT_STATUS};  delete($ENV{REDIRECT_STATUS});
  # Ìåíÿåì òåêóùóþ äèðåêòîðèþ.
  my $MyDir=getcwd(); 
  ($MyDir) = $MyDir=~/(.*)/;
  my ($dir) = $path; $dir=~s{(.)[/\\][^/\\]*$}{$1}sg;
 
  chdir($dir); getcwd(); # getcwd: Ñáðàñûâàåò $ENV{PWD}. Íàì ýòî íàäî? Ôèã çíàåò...
  # Îáðàáàòûâàåì ôàéëû .htaccess.
  $this->process_htaccesses($path);

  # Âñå. Òåïåðü ñîñòîÿíèå ïåðåìåííûõ ñêðèïòà òàêîå æå, êàê ó ñòðàíèöû,
  # êîòîðàÿ â äàëüíåéøåì ïîëó÷èò óïðàâëåíèå. Çàïóñêàåì îáðàáîò÷èêè.
  $this->__run_handlers();
  
  # Âîññòàíàâëèâàåì òåêóùóþ äèðåêòîðèþ
  chdir($MyDir); getcwd(); 
}


# Âíóòðåííÿÿ ôóíêöèÿ - çàïóñêàåò îáðàáîò÷èêè äëÿ ôàéëà, êîòîðûé çàäàí â %ENV.
# Âûçûâàåòñÿ Â ÊÎÍÒÅÊÑÒÅ ÝÒÎÃÎ ÔÀÉËÀ (òî åñòü, %ENV íàõîäèòñÿ â òàêîì æå ñîñòîÿíèè,
# êàê ïîñëå îáÿ÷íîãî çàïóñêà ñêðèïòà Àïà÷åì, è òåêóùàÿ äèðåêòîðèÿ ñîîòâåòñòâóåò
# äèðåêòîðèè ñî ñòðàíèöåé).
sub __run_handlers
{ my ($th)=@_;
  # ðàñøèðåíèå ôàéëà
  my ($ext)  = $ENV{SCRIPT_FILENAME}=~m|\.([^.]*)$|; if(!defined $ext) { $ext=""; }

  # âûáèðàåì ñïèñîê îáðàáîò÷èêîâ äëÿ ýòîãî ðàñøèðåíèÿ
  $th->{Handlers}{$ext} 
    or die "$ENV{SCRIPT_NAME}: could not find handlers chain for extension \"$ext\"\n";

  # âõîäíîé áóôåð (âíà÷àëå â íåì ñîäåðæèìîå ôàéëà, åñëè äîñòóïíî)
  my $input="";
  if(open(local *F, $ENV{SCRIPT_FILENAME})) { local ($/,$\); binmode(F); $input=<F>; }

  # ïðîõîäèìñÿ ïî âñåì îáðàáîò÷èêàì
  my $next=1; # íîìåð ñëåäóþùåãî îáðàáîò÷èêà
  my @hands=@{$th->{Handlers}{$ext}};
  NoAutoflush() if @hands>1;
  foreach my $hand (@hands)
  { # Îáúåêò ïåðåíàïðàâëåíèÿ âûâîäà. Åñëè ó íàñ âñåãî îäèí îáðàáîò÷èê, òî 
    # ïåðåíàïðàâëÿòü âûâîä íå ïîòðåáóåòñÿ. Èíà÷å - ïîòðåáóåòñÿ, ÷òî è äåëàåòñÿ
    my $OutObj=$hands[$next++]? CGI::WebOut->new : undef;
    my $func=$hand; # óêàçàòåëü íà ôóíêöèþ
    # Ïðîâåðÿåì - íóæíî ëè çàãðóçèòü îáðàáîò÷èê?
    if((ref($func)||"") ne "CODE") {
      # ïåðåêëþ÷àåì ïàêåò
      package Apache::Scriptor::Handlers; 
      # îáðàáîò÷èêà åùå íåò â ýòîì ïàêåòå?
      if(!*{$func}{CODE}) {
        my $hname="$th->{HandDir}/$func.pl";
        -f $hname or die "$ENV{SCRIPT_NAME}: could not load the file $hname for handler $hand\n";
        do "$hname";
        *{$func}{CODE} or die "$ENV{SCRIPT_NAME}: cannot find handler $hand in $hname after loading $hname\n";
      }
      # ïîëó÷àåì óêàçàòåëü íà ôóíêöèþ îáðàáîò÷èêà
      local $this=$th;
      $func=*{$func}{CODE};
    }
    # Ôóíêöèÿ îáðàáîò÷èêà ïðèíèìàåò ïàðàìåòð: âõîäíîé áóôåð.
    # Åå çàäà÷à - îáðàáîòàòü åãî è, èñïîëüçóÿ print, ïðîïå÷àòàòü ðåçóëüòàò.
    #  ñëó÷àå îøèáêè (ôàéë íå íàéäåí) ôóíêöèÿ äîëæíà âîçâðàòèòü -1!
    my $result=&$func($input);
    if($result eq "-1") {
      if($th->{404} && $th->{404} ne $th->{self_scriptname}) {
        Redirect($th->{404});
        exit;
      } else {
        die "$hand: could not find the file $ENV{SCRIPT_FILENAME}\n";
      }
    }

    # Òî, ÷òî ïîëó÷èëîñü, êëàäåì âî âõîäíîé áóôåð äëÿ ñëåäóþùåãî îáðàáîò÷èêà.
    # Åñëè âûâîä íå ïåðåíàïðàâëÿëñÿ, òî êëàäåì òóäà "".
    $input=$OutObj?$OutObj->buf:"";
  }
  # Îêîí÷àòåëüíûé ðåçóëüòàò îêàæåòñÿ âî âõîäíîì áóôåðå (êàê áóäòî ãîòîâûé äëÿ 
  # ñëåäóþùåãî îáðàáîò÷èêà, êîòîðîãî íåò). Åãî-òî ìû è âûâîäèì â áðàóçåð.
  print $input;
}



package Apache::Scriptor::Handlers;
use CGI::WebOut;
#  ýòîì ïàêåòå ïåðå÷èñëÿþòñÿ ñòàíäàðòíûå îáðàáîò÷èêè, 
# êîòîðûå, ñêîðåå âñåãî, áóäóò èñïðîëüçîâàíû â ïåðâóþ î÷åðåäü.
# Èìåííî â ýòîò ïàêåò ïîïàäàþò îáðàáîò÷èêè, çàãðóæåííûå àâòîìàòè÷åñêè.

# Îáðàáîò÷èê ïî óìîë÷àíèþ - ïðîñòî âûâîäèò òåêñò
sub default
{ my ($input,$fname)=@_;
  -f $ENV{SCRIPT_FILENAME} or return -1;
  CGI::WebOut::Header("Content-type: text/html");



( run in 2.429 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )