Hi Following some discussion on irc, I've built an implementation of AxKit using a pull pipeline model, which supports multiple pipeline caches, logicsheet style xsp, has a backwards compatibility mode for the old modules and cleans up a few other things.
Ok... Changes. (in no particular order). 1. AxKit.pm no longer has any major portions of cache code. The dependency hooks still remain so as not to remove the need to modify providers, however the cache intercepts theses calls to allow for pipeline dependancies. 2. A new set of Apache::AxKit::Pipeline::* modules implement the features removed from AxKit.pm. These are Apache::AxKit::Pipeline Pipeline base class. Apache::AxKit::Pipeline::Cache. Apache::AxKit::Pipeline::Trace (for AxTraceIntermediate). Apache::AxKit::Pipeline::Language (backwards compat mode to Apache::AxKit::Language::*) Apache::AxKit::Pipeline::XSP (Pipelined XSP) Apache::AxKit::Pipeline::LibXSLT (Pipelined XSLT). 3. Passthru now handles pipeline stages via passthru=N where N is the number of stages to use. 4. Apache::AxKit::Exception::ProviderDeclined exception added to allow for Apache::AxKit::Exception::Declined to return DECLINED. 5. run_axkit_engine no longer has any cache stuff. (now handled via pipeline). 6. get_axkit_uri cleaned up since return values are now cleaner. 7. insert_next/last_stylesheet functions are REMOVED. Can't find a way to support them in new architecture (might be able to do something if big demand, but quick poll on irc suggested no one used them). 8. process_request now just builds pipeline and returns CONTENT, not status. 9. HTTP status now handled via $r->status(). $r->custom_response stuff removed. 10. Removed output_transformer stuff from Apache::AxKit::Cache. now all handled in one place, cache not told to fast_deliver if output_transformers exist. 11. Added some code to not build stack traces non error exceptions. 12. added a compile() method to Language::XSP to support Pipeline::XSP Other things of importance.... You now configure the cache via the AxAdd processor directives. eg AxAddStyleMap application/cache Apache::AxKit::Pipeline::Cache AxAddProcessor application/cache NULL application/x-xsp is hardcoded in axconfig.c, so I've used.... AxAddStyleMap application/x-xsp-pipe Apache::AxKit::Pipeline::XSP AxAddRootProcessor application/x-xsp-pipe NULL {http://www.apache.org/1999/XSP/Core}page Obviously, we might want to fix axconfig.c. Attachments. 1 diff, and a tar of the pipeline modules. Mike.
? blib ? pm_to_blib ? Makefile ? AxKit.c ? XSP.diff.txt.gz ? AxKit.bs ? patch ? get_styles.diff ? pull_pipeline.diff ? lib/Apache/AxKit/Pipeline.pm ? lib/Apache/AxKit/Pipeline ? lib/Apache/AxKit/pm_to_blib ? lib/Apache/AxKit/Makefile ? lib/Apache/AxKit/CharsetConv.c ? lib/Apache/AxKit/CharsetConv.bs Index: lib/AxKit.pm =================================================================== RCS file: /home/cvspublic/xml-axkit/lib/AxKit.pm,v retrieving revision 1.43 diff -u -r1.43 AxKit.pm --- lib/AxKit.pm 18 Mar 2003 15:20:46 -0000 1.43 +++ lib/AxKit.pm 7 May 2003 14:48:19 -0000 @@ -16,7 +16,9 @@ use Apache::AxKit::Provider::File; use Apache::AxKit::Provider::Scalar; use Apache::AxKit::CharsetConv; +use Apache::AxKit::Pipeline; use File::Basename (); +use Data::Dumper; use Compress::Zlib (); use Fcntl; @@ -166,6 +168,8 @@ # Carp::confess("caught SIGUSR2!"); # }; + my $rc = $r->status(); + $AxKit::Cfg = Apache::AxKit::ConfigReader->new($r); # if ($AxKit::Cfg->DebugTime) { @@ -188,9 +192,12 @@ my $provider = Apache::AxKit::Provider->new_content_provider($r); return $provider->decline(reason => "passthru set") - if ($r->notes('axkit_passthru') && $r->dir_config('AxFastPassthru')); + if (($r->notes('axkit_passthru') == 1 ) && $r->dir_config('AxFastPassthru')); - return main_handler($r, $provider); + + my $ret = main_handler($r, $provider); + $r->status($rc); + return $ret; } ######################################### @@ -220,6 +227,8 @@ local $AxKit::DebugLevel; local $Error::Debug; + my $rc = $r->status(); + $AxKit::Cfg = Apache::AxKit::ConfigReader->new($r); if ($AxKit::Cfg->DebugTime) { @@ -242,9 +251,45 @@ my $provider = Apache::AxKit::Provider->new_content_provider($r); return $provider->decline(reason => "passthru set") - if ($r->notes('axkit_passthru') && $r->dir_config('AxFastPassthru')); + if (($r->notes('axkit_passthru') == 1 ) && $r->dir_config('AxFastPassthru')); + + my $ret = main_handler($r, $provider); + $r->status($rc); + return $ret; +} + +sub run_axkit_engine { + my ($r, $provider, $no_output) = @_; + + # get preferred stylesheet and media type + my ($preferred, $media) = get_style_and_media(); + AxKit::Debug(2, "media: $media, preferred style: $preferred"); + + my $styles = get_styles($media, $preferred, $provider, $r); + + # reconsecrate Apache request object (& STDOUT) into our own class - return main_handler($r, $provider); + bless $r, 'AxKit::Apache'; + tie *STDOUT, 'AxKit::Apache', $r; + + if (my $charset = $AxKit::Cfg->OutputCharset) { + AxKit::Debug(5, "Different output charset: $charset"); + if (!$r->notes('axkit_passthru_type')) { + $r->content_type("text/html; charset=$charset"); + } + } + + # This is here so that lookup_uri() works on the real thing + # that we're requesting, not on the thing plus the PATH_INFO + my $uri = $r->uri(); + my $path_info = $r->path_info(); + substr($uri, -length($path_info)) = '' if length($path_info); # trim off the end that many chars (negative offset to substr) + $r->uri($uri); + $ENV{PATH_INFO} = $path_info; + + # Main grunt of the work done here... + return process_request( $r, $provider, $styles, $no_output ); + } sub main_handler { @@ -259,33 +304,17 @@ # setup global pnotes. local $AxKit::Apache::PNOTES = $r->pnotes(); - - if ($r->notes('axkit_passthru')) { - # slow passthru - $r->send_http_header('text/xml'); - eval { - my $fh = $provider->get_fh; - $r->send_fd($fh); - }; - if ($@) { - my $str = $provider->get_strref; - $r->print($str); - } - return OK; - } - - local $AxKit::Cache; my $retcode = eval { # $r->header_out('X-AxKit-Version', $VERSION); chdir(File::Basename::dirname($r->filename)); - $AxKit::OrigType = $r->content_type('changeme'); +# $AxKit::OrigType = $r->content_type('changeme'); reset_depends(); - my $result_code = run_axkit_engine($r, $provider); + my $str_ref = run_axkit_engine($r, $provider); # restore $r if (ref($r) eq 'AxKit::Apache') { @@ -293,7 +322,7 @@ tie *STDOUT, 'Apache', $r; } - deliver_to_browser($r, $result_code); + deliver_to_browser($r, $str_ref); }; my $E = $@; unless ($E) { @@ -315,19 +344,22 @@ my $code = $E->{return_code}; AxKit::Debug(5, "aborting with code $code"); return $code; - } + } elsif($E->isa('Apache::AxKit::Exception::Declined')) { + return DECLINED; + } $r->content_type($AxKit::OrigType) - if $r->content_type() eq 'changeme'; # restore content-type - - if ($E->isa('Apache::AxKit::Exception::Declined')) { + if $r->content_type() eq 'changeme'; # restore content-type + + + if ($E->isa('Apache::AxKit::Exception::ProviderDeclined')) { if ($AxKit::Cfg && $AxKit::Cfg->LogDeclines()) { $r->log->warn("[AxKit] [DECLINED] $E->{reason}") if $E->{reason}; } AxKit::Debug(4, "[DECLINED] From: $E->{-file} : $E->{-line}"); - $r->send_http_header('text/xml'); + $r->send_http_header($AxKit::OrigType); eval { my $fh = $provider->get_fh; $r->send_fd($fh); @@ -380,96 +412,7 @@ return DECLINED; } -sub run_axkit_engine { - my ($r, $provider, $no_output) = @_; - - # get preferred stylesheet and media type - my ($preferred, $media) = get_style_and_media(); - AxKit::Debug(2, "media: $media, preferred style: $preferred"); - - # get cache object - my $cache = Apache::AxKit::Cache->new($r, $provider->key() . ($AxKit::Cfg->GzipOutput ? '.gzip' : '') . ($r->path_info() || ''), $preferred, $media, $r->notes('axkit_cache_extra')); - - my $recreate = 0; # regenerate from source (not cached) - - my $styles = get_styles($media, $preferred, $cache, $provider); - - { - local $^W; - if ($preferred && ($styles->[0]{title} ne $preferred)) { - # we selected a style that didn't exist. - # Make sure we default the cache file, otherwise - # we setup a potential DoS - AxKit::Debug(3, "resetting cache with no preferred style ($preferred ne $styles->[0]{title})"); - $cache = Apache::AxKit::Cache->new($r, $provider->key() . ($AxKit::Cfg->GzipOutput ? '.gzip' : '') . $r->path_info(), '', $media, $r->notes('axkit_cache_extra')); - } - } - - if (!$cache->exists()) { - AxKit::Debug(2, "cache doesn't exist"); - # set no_cache header if cache doesn't exist due to no_cache option - $r->no_cache(1) if $cache->no_cache(); - $recreate++; - } - - if (!$recreate && $AxKit::Cfg->DependencyChecks()) { - $recreate = check_dependencies($r, $provider, $cache); - } - - if (!$recreate && $r->method() eq 'POST') { - $recreate++; - } - - $AxKit::Charset = $AxKit::Cfg->OutputCharset(); - - # Store in package variable for other modules - $AxKit::Cache = $cache; - - if (!$recreate) { - AxKit::Debug(1, "delivering cached copy - all conditions met"); - return $cache->deliver(); - } - - AxKit::Debug(1, "some condition failed. recreating output"); - - # reconsecrate Apache request object (& STDOUT) into our own class - bless $r, 'AxKit::Apache'; - tie *STDOUT, 'AxKit::Apache', $r; - - if (my $charset = $AxKit::Cfg->OutputCharset) { - AxKit::Debug(5, "Different output charset: $charset"); - if (!$r->notes('axkit_passthru_type')) { - $r->content_type("text/html; charset=$charset"); - } - } - - # This is here so that lookup_uri() works on the real thing - # that we're requesting, not on the thing plus the PATH_INFO - my $uri = $r->uri(); - my $path_info = $r->path_info(); - substr($uri, -length($path_info)) = '' if length($path_info); # trim off the end that many chars (negative offset to substr) - $r->uri($uri); - $ENV{PATH_INFO} = $path_info; - - { - # copy styles because we blat the copy - my @copy = @$styles; - $AxKit::_CurrentStylesheets = [EMAIL PROTECTED]; - } - - # Main grunt of the work done here... - my $return_code = process_request( - $r, - $provider, - $AxKit::_CurrentStylesheets, - $no_output, - ); - save_dependencies($r, $cache); - - return $return_code; - -} sub get_axkit_uri { my ($uri) = @_; @@ -510,20 +453,24 @@ } local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($r); - local $AxKit::Cache; my $provider = Apache::AxKit::Provider->new_content_provider($r); - my $result_code = eval { + my $str_ref; + + $str_ref = eval { run_axkit_engine( $r, $provider, 1, # no output ); }; + + my $result_code = $r->status(); + if ($@) { my $E = $@; - if ($E->isa('Apache::AxKit::Exception::Declined')) { + if ($E->isa('Apache::AxKit::Exception::ProviderDeclined')) { if ($AxKit::Cfg && $AxKit::Cfg->LogDeclines()) { $r->log->warn("[AxKit] [DECLINED] $E->{reason}") if $E->{reason}; @@ -535,14 +482,12 @@ my $fh = $provider->get_fh; local $/; $str = <$fh>; - $r->pnotes('xml_string', $str); - $result_code = OK; + $str_ref = \$str; + $result_code = OK; }; if ($@) { eval { - my $pstr = $provider->get_strref; - $str = $$pstr; - $r->pnotes('xml_string', $str); + $str_ref = $provider->get_strref; $result_code = OK; }; if ($@) { @@ -559,34 +504,11 @@ } } - if ($result_code == OK) { - # results now in $r->pnotes('xml_string') - probably... - if ( my $str = $r->pnotes('xml_string') ) { - # NB: this is naive, but "0" isn't valid XML anyway - $r->pnotes('xml_string', undef); - AxKit::Debug(10, "get_axkit_uri returning (str): '$str'"); - return $str; - } - elsif ($r->pnotes('dom_tree')) { - my $str = $r->pnotes('dom_tree')->toString; - $r->pnotes('dom_tree', undef); - AxKit::Debug(10, "get_axkit_uri returning (dom): '$str'"); - return $str; - } - else { - throw Apache::AxKit::Exception ( - -text => "$uri internal request didn't store anything in dom_tree or xml_string", - ); - } - } - elsif ($result_code == DECLINED) { - # probably came from the cache system. Try and read it. - AxKit::Debug(10, "get_axkit_uri cache read"); - return $AxKit::Cache->read(); - } - else { + if($result_code == 200 || $result_code eq OK) { + return ${$str_ref}; + } else { throw Apache::AxKit::Exception ( - -text => "$uri internal request returned unknown result code: ".$result_code, + -text => "$uri internal request returned unknown result code: ".$r->status(), ); } } @@ -598,7 +520,6 @@ tie *STDOUT, 'AxKit::Apache', $r; $r->dir_config->set(AxNoCache => 1); - $AxKit::Cache = Apache::AxKit::Cache->new($r, 'error', '', '', ''); $r->content_type("text/html; charset=UTF-8"); # set a default for errors @@ -606,18 +527,13 @@ my $provider = Apache::AxKit::Provider::Scalar->new( $r, $error, $error_styles - ); - - $r->pnotes('xml_string', $error); + ); eval { - process_request($r, $provider, $error_styles); - if (ref($r) eq 'AxKit::Apache') { - bless $r, 'Apache'; - tie *STDOUT, 'Apache', $r; - } - deliver_to_browser($r); + my $str_ref = process_request($r, $provider, $error_styles); + deliver_to_browser($r, $str_ref); }; + if ($@) { $r->log->error("[AxKit] [FATAL] Error occured while processing Error XML: $@"); return SERVER_ERROR; @@ -626,178 +542,49 @@ return OK; } -sub insert_next_stylesheet { - my ($type, $href) = @_; - my $mapping = $AxKit::Cfg->StyleMap; - my $module = $mapping->{$type}; - if (!$module) { - throw Apache::AxKit::Exception::Declined( - reason => "No implementation mapping available for type '$type'" - ); - } - unshift @$AxKit::_CurrentStylesheets, - { - type => $type, - href => $href, - module => $module, - }; -} - -sub insert_last_stylesheet { - my ($type, $href) = @_; - my $mapping = $AxKit::Cfg->StyleMap; - my $module = $mapping->{$type}; - if (!$module) { - throw Apache::AxKit::Exception::Declined( - reason => "No implementation mapping available for type '$type'" - ); - } - push @$AxKit::_CurrentStylesheets, - { - type => $type, - href => $href, - module => $module, - }; -} - -sub reset_stylesheets { - @$AxKit::_CurrentStylesheets = (); -} +sub insert_next_stylesheet { die("Not supported anymore") } +sub insert_last_stylesheet { die("Not supported anymore") } +sub reset_stylesheets { die("Not supported anymore") } sub process_request { my ($r, $provider, $styles, $no_output) = @_; - my $result_code = OK; - my $num_styles = 0; - for my $style (@$styles) { - AxKit::Debug(4, "styles: ", $style->{module}, "(", $style->{href}, ")"); - $num_styles++; - } - - my $interm_prefix; - my $interm_count = 0; - if ($AxKit::Cfg->TraceIntermediate) { - my $id = $r->notes('AxRequestID'); - $interm_prefix = ($id?$id:$r->uri); - $interm_prefix =~ s{%}{%25}g; - $interm_prefix =~ s{/}{%2f}g; - my $ti = $AxKit::Cfg->TraceIntermediate; - if (defined $id) { - $interm_prefix = substr($interm_prefix,-1).'/'.substr($interm_prefix,-3,2).'/'.substr($interm_prefix,0,-3).'/'; - mkdir($ti.'/'.substr($interm_prefix,0,1),0777); - mkdir($ti.'/'.substr($interm_prefix,0,4),0777); - mkdir($ti.'/'.$interm_prefix,0777); - } else { - $interm_prefix =~ s/[^0-9a-zA-Z.,_|-]/_/g; - $interm_prefix .= '.'; - } - $interm_prefix = $ti.'/'.$interm_prefix; + + # passthru interface.... only take the first N - 1 styles. + # So N=1 is the provider only. N=2 is provider + first stylesheet.... + + my @styles = @$styles; + + if( my $p = $r->notes()->{'axkit_passthru'} ) { + my @passthru = splice( @styles, 0, $p - 1 ); + @styles = @passthru; + + } + + my $pipeline = Apache::AxKit::Pipeline->build_pipeline($r, $provider, scalar(@$styles), @styles); + + if( $AxKit::Cfg->TraceIntermediate ) { + $pipeline = Apache::AxKit::Pipeline::Trace->new( + upstream => $pipeline, + stage => scalar(@styles)+1, + ); + } + + my ($transformer, $doit) = AxKit::get_output_transformer(); + + # If $last_in_chain is true, then whatever is on the end of the chain + # can, if possible by pass the normal deliver mechanisms. + # Otherwise output will go via $r->print(). + + my $last_in_chain = !($no_output || $doit || lc($r->dir_config('Filter')) eq 'on' ); + + my $str_ref = $pipeline->get_strref( $r, $last_in_chain ); + + my $ret_val = $r->status(); + + AxKit::Debug(5, "pipeline finished with apache status $ret_val"); - if ($interm_prefix) { - my $fh = Apache->gensym(); - if (sysopen($fh, $interm_prefix.$interm_count, O_WRONLY|O_CREAT|O_TRUNC)) { - syswrite($fh,${$provider->get_strref}); - close($fh); - $interm_count++; - } else { - AxKit::Debug(1,"could not open $interm_prefix$interm_count for writing: $!"); - } - } - } - - while (@$styles) { - my $style = shift @$styles; - - my $num_left = @$styles; - my $output_to_browser = ($num_left == 0 && !$no_output); - - my $styleprovider = Apache::AxKit::Provider->new_style_provider( - $r, - uri => $style->{href}, - ); - - $r->notes('resetstring', 1); - - no strict 'refs'; - - my $mapto = $style->{module}; - - # if no module is give AxKit should use the default modules - # from the server config. - unless ( $mapto ) { - my $mapping = $AxKit::Cfg->StyleMap; - $mapto = $mapping->{$style->{type}}; - } - - AxKit::Debug(3, "about to execute: $mapto\::handler"); - AxKit::load_module($mapto); - - my $method = "handler"; - if (defined &{"$mapto\::$method"}) { - if ($mapto->stylesheet_exists() && !$styleprovider->exists()) { - throw Apache::AxKit::Exception::Error( - -text => "stylesheet '$style->{href}' could not be found or is not readable" - ); - } - my $retval = $mapto->$method( - $r, - $provider, - $styleprovider, - $output_to_browser, - ); - AxKit::Debug(5, "$mapto\::handler finished with code $retval"); - $result_code = $retval if $retval != OK; - } - else { - throw Apache::AxKit::Exception::Error( - -text => "$mapto Function not found" - ); - } - - if ($interm_prefix) { - my $fh = Apache->gensym(); - if (open($fh, '>'.$interm_prefix.$interm_count)) { - my $xmlstr; - if ($AxKit::Cfg->DebugTidy) { - eval { - require XML::LibXML; - my $parser = new XML::LibXML(); - $parser->keep_blanks(0); - if (my $dom_tree = $r->pnotes('dom_tree')) { - $xmlstr = $dom_tree->toString; - } elsif ($r->pnotes('xml_string')) { - $xmlstr = $r->pnotes('xml_string'); - } else { - die; - } - local $XML::LibXML::setTagCompression = 1; - $xmlstr = $parser->parse_string($xmlstr,$r->uri)->toString(1); - }; - AxKit::Debug(1,"AxDebugTidy unavailable for XML: $@") if $@; - } - if (!defined $xmlstr) { - if (my $dom_tree = $r->pnotes('dom_tree')) { - $xmlstr = $dom_tree->toString; - } elsif ($r->pnotes('xml_string')) { - $xmlstr = $r->pnotes('xml_string'); - } else { - $xmlstr = "<?xml version='1.0'?>\n<empty reason='no data found'/>\n"; - } - } - print($fh $xmlstr); - close($fh); - $interm_count++; - } else { - AxKit::Debug(1,"could not open $interm_prefix$interm_count for writing: $!"); - } - } - - AxKit::Debug(3, "execution of: $mapto\::$method finished"); - - last if $r->notes('axkit_passthru'); - } - - return $result_code; + return $str_ref; } sub get_style_and_media { @@ -814,16 +601,21 @@ } sub get_styles { - my ($media, $style, $cache, $provider) = @_; + my ($media, $style, $provider, $r) = @_; + + # This cache is only generating a key for the style cache. - my $key = $cache->key(); + my $key = Apache::AxKit::Cache->new($r, $provider->key() . + ($AxKit::Cfg->GzipOutput ? '.gzip' : '') . ($r->path_info() || ''), + $style, $media, $r->notes('axkit_cache_extra'))->key(); AxKit::Debug(2, "getting styles and external entities from the XML"); # get styles/ext_ents from cache or re-parse my $styles; - if (exists($AxKit::Stash{$key}) + if (!$r->dir_config('AxDisableGetStylesCache') + && exists($AxKit::Stash{$key}) && !$provider->has_changed($AxKit::Stash{$key}{mtime})) { AxKit::Debug(3, "styles cached"); @@ -842,147 +634,75 @@ } } -sub check_dependencies { - my ($r, $provider, $cache) = @_; - AxKit::Debug(2, "Checking dependencies"); - if ( $provider->has_changed( $cache->mtime() ) ) { - AxKit::Debug(3, "xml newer than cache"); - return 1; - } - else { - my $depend_cache = Apache::AxKit::Cache->new($r, $cache->key(), '.depends'); - my $depends_contents = $depend_cache->read(); - if ($depends_contents) { - DEPENDENCY: - for my $dependency (split(/:/, $depends_contents)) { - AxKit::Debug(3, "Checking dependency: $dependency for resource ", $provider->key()); - my $dep = Apache::AxKit::Provider->new($r, key => $dependency); - if ( $dep->has_changed( $cache->mtime() ) ) { - AxKit::Debug(4, "dependency: $dependency newer"); - return 1; - } - } - } - else { - AxKit::Debug(2, "No dependencies list yet"); - return 1; -# return check_resource_mtimes($provider, $styles, $cache->mtime()); - } - } -} - -sub save_dependencies { - my ($r, $cache) = @_; - - return if $cache->no_cache(); - - eval { - my @depends = get_depends(); - my $depend_cache = Apache::AxKit::Cache->new($r, $cache->key(), '.depends'); - $depend_cache->write(join(':', @depends)); - }; - if ($@) { - AxKit::Debug(2, "Cannot write dependencies cache: $@"); - } -} - sub deliver_to_browser { - my ($r, $result_code) = @_; - $result_code ||= OK; + my ($r, $str_ref) = @_; + if (ref($r) eq 'AxKit::Apache') { + bless $r, 'Apache'; + tie *STDOUT, 'Apache', $r; + } + + my $result_code = $r->status(); + AxKit::Debug(4, "delivering to browser"); - if (length($r->pnotes('xml_string'))) { - # ok, data is in xml_string - AxKit::Debug(4, "Delivering xml_string"); - } - elsif ($r->pnotes('dom_tree')) { - AxKit::Debug(4, "Delivering dom_tree"); - $r->pnotes('xml_string', $r->pnotes('dom_tree')->toString ); - } - else { - AxKit::Debug(5, "Possible cache delivery coming up..."); - } - - if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) { - $AxKit::Cfg->AllowOutputCharset(1); - $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8")); - } - elsif ($r->notes('axkit_passthru_type')) { - $r->content_type($AxKit::OrigType); - } +# +# if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) { +# $AxKit::Cfg->AllowOutputCharset(1); +# $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8")); +# } +# elsif ($r->notes('axkit_passthru_type')) { +# $r->content_type($AxKit::OrigType); +# } if (my $charset = $AxKit::Cfg->OutputCharset()) { my $ct = $r->content_type; $ct =~ s/charset=.*?(;|$)/charset=$charset/i; $r->content_type($ct); } +# +# I've removed all this cause it breaks error documents +# +# if ($result_code != OK && $result_code != 200) { +# # no caching - probably makes no sense, and will be turned off +# # anyways, as currently only XSP pages allow to send custom responses +# AxKit::Debug(4,"sending custom response: $result_code"); +# my ($transformer, $doit) = get_output_transformer(); +# if ($doit) { +# $r->custom_response($result_code,$transformer->( ${$str_ref} )); +# } +# else { +# $r->custom_response($result_code,${$str_ref}); +# } +# return $result_code; +# } +# +# $r->status(200); - if ($result_code != OK && $result_code != 200) { - # no caching - probably makes no sense, and will be turned off - # anyways, as currently only XSP pages allow to send custom responses - AxKit::Debug(4,"sending custom response: $result_code"); - my ($transformer, $doit) = get_output_transformer(); - if ($doit) { - $r->custom_response($result_code,$transformer->($r->pnotes('xml_string') || '')); - } - else { - $r->custom_response($result_code,$r->pnotes('xml_string') || ''); - } - return $result_code; - } - - if ($AxKit::Cache->no_cache() || - lc($r->dir_config('Filter')) eq 'on' || - $r->method() eq 'POST') - { - AxKit::Debug(4, "writing xml string to browser"); - my ($transformer, $doit) = get_output_transformer(); - if ($AxKit::Cfg->DoGzip) { - AxKit::Debug(4, 'Sending gzipped xml string to browser'); - AxKit::Apache::send_http_header($r); - if ($doit) { - $r->print( unpack($]>5.00555?"U0A*":"A*", Compress::Zlib::memGzip( - $transformer->( $r->pnotes('xml_string') ) - ) ) ); - } - else { - $r->print( unpack($]>5.00555?"U0A*":"A*", Compress::Zlib::memGzip( $r->pnotes('xml_string') ) ) ); - } - } - else { - AxKit::Apache::send_http_header($r); - if ($doit) { - $r->print( - $transformer->( $r->pnotes('xml_string') ) - ); - } - else { - $r->print( $r->pnotes('xml_string') ); - } - } - return OK; - } - else { - AxKit::Debug(4, "writing xml string to cache and delivering to browser"); - my $retval = eval { - $AxKit::Cache->write($r->pnotes('xml_string')); - $AxKit::Cache->deliver(); - }; - if (my $E = $@) { - if ($E->isa('Apache::AxKit::Exception::IO')) { - AxKit::Debug(1, "WARNING: Unable to write to AxCacheDir or .xmlstyle_cache"); - AxKit::Apache::send_http_header($r); - $r->print( $r->pnotes('xml_string') ); - } - else { - throw $E; - } - } - else { - return $retval; - } - } + AxKit::Debug(4, "writing xml string to browser"); + my ($transformer, $doit) = get_output_transformer(); + if ($AxKit::Cfg->DoGzip) { + AxKit::Debug(4, 'Sending gzipped xml string to browser'); + AxKit::Apache::send_http_header($r); + if ($doit) { + $r->print( unpack($]>5.00555?"U0A*":"A*", Compress::Zlib::memGzip( + $transformer->( ${$str_ref} ) + ) ) ); + } + else { + $r->print( unpack($]>5.00555?"U0A*":"A*", Compress::Zlib::memGzip( ${$str_ref} ) ) ); + } + } + else { + AxKit::Apache::send_http_header($r); + if ($doit) { + $r->print( $transformer->( ${$str_ref} ) ); + } + else { + $r->print( ${$str_ref} ); + } + } + return OK; } sub prep_exception { @@ -1071,22 +791,11 @@ $r ||= Apache->request; } -sub content_type { - my $self = shift; - - my ($type) = @_; - - if ($type) { -# warn "Writing content type '$type'\n"; - $AxKit::Cache->set_type($type); - } - - $self->SUPER::content_type(@_); -} - sub print { my $self = shift; + delete $self->pnotes()->{'dom_tree'}; + if ($self->notes('resetstring')) { $self->pnotes('xml_string', ''); $self->notes('resetstring', 0); @@ -1097,18 +806,6 @@ } *PRINT = \&print; - -sub no_cache { - my $self = shift; - my ($set) = @_; - - $self->SUPER::no_cache(@_); - - if ($set) { -# warn "caching being turned off!\n"; - $AxKit::Cache->no_cache(1); - } -} sub send_http_header { my $self = shift; Index: lib/Apache/AxKit/Cache.pm =================================================================== RCS file: /home/cvspublic/xml-axkit/lib/Apache/AxKit/Cache.pm,v retrieving revision 1.9 diff -u -r1.9 Cache.pm --- lib/Apache/AxKit/Cache.pm 25 Dec 2002 17:59:21 -0000 1.9 +++ lib/Apache/AxKit/Cache.pm 7 May 2003 14:48:19 -0000 @@ -199,7 +199,9 @@ sub deliver { my $self = shift; - return SERVER_ERROR if $self->{no_cache}; + Apache::AxKit::Exception::Error->throw( + 'attempt to deliver from cache when no cache set' + ) if $self->{no_cache}; my $r = $self->{apache}; { @@ -211,40 +213,36 @@ } } - if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) { - $AxKit::Cfg->AllowOutputCharset(1); - $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8")); - } - elsif ($r->notes('axkit_passthru_type')) { - $r->content_type($AxKit::OrigType); - } +# if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) { +# $AxKit::Cfg->AllowOutputCharset(1); +# $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8")); +# } +# elsif ($r->notes('axkit_passthru_type')) { +# $r->content_type($AxKit::OrigType); +# } my ($transformer, $doit) = AxKit::get_output_transformer(); - if ($doit) { - AxKit::Debug(4, "Cache: Transforming content and printing to browser"); - $r->pnotes('xml_string',$self->read()); - return OK; # upstream deliver_to_browser should handle the rest - } - else { - AxKit::Debug(4, "Cache: Sending untransformed content to browser"); - - # Make sure we unset PATH_INFO or wierd things can happen! - $ENV{PATH_INFO} = ''; - $r->path_info(''); - - if ($self->{gzip} && $AxKit::Cfg->DoGzip) { - AxKit::Debug(4, 'Cache: Delivering gzipped output'); - $r->filename($self->{file}.'.gz'); - } - else { - $r->filename($self->{file}); - } - - return DECLINED; - } + throw Apache::AxKit::Exception::Error->throw( + -text => "cache deliver called when cache can't fast deliver" + ) if $doit; + + AxKit::Debug(4, "Cache: Sending untransformed content to browser"); + + # Make sure we unset PATH_INFO or wierd things can happen! + $ENV{PATH_INFO} = ''; + $r->path_info(''); + + if ($self->{gzip} && $AxKit::Cfg->DoGzip) { + AxKit::Debug(4, 'Cache: Delivering gzipped output'); + $r->filename($self->{file}.'.gz'); + } + else { + $r->filename($self->{file}); + } + Apache::AxKit::Exception::Declined->throw(); # handler will catch } sub reset { Index: lib/Apache/AxKit/Exception.pm =================================================================== RCS file: /home/cvspublic/xml-axkit/lib/Apache/AxKit/Exception.pm,v retrieving revision 1.4 diff -u -r1.4 Exception.pm --- lib/Apache/AxKit/Exception.pm 29 Jan 2003 01:35:49 -0000 1.4 +++ lib/Apache/AxKit/Exception.pm 7 May 2003 14:48:19 -0000 @@ -8,7 +8,7 @@ my $class = shift; my $self = $class->SUPER::new(@_); - if ($AxKit::Cfg && $AxKit::Cfg->StackTrace) { + if ($self->trace() && $AxKit::Cfg && $AxKit::Cfg->StackTrace) { my $i = $Error::Depth + 1; my ($pkg, $file, $line) = caller($i++); my @stacktrace; @@ -22,6 +22,8 @@ return $self; } +sub trace { 1;} + sub stacktrace_list { my $E = shift; return $E->{'stacktrace'} || []; @@ -67,8 +69,15 @@ exists $E->{'-value'} ? $E->{'-value'} : 1; } +package Apache::AxKit::Exception::ProviderDeclined; [EMAIL PROTECTED] = ('Apache::AxKit::Exception'); + +sub trace { 0;} + package Apache::AxKit::Exception::Declined; @ISA = ('Apache::AxKit::Exception'); + +sub trace { 0;} package Apache::AxKit::Exception::Error; @ISA = ('Apache::AxKit::Exception'); Index: lib/Apache/AxKit/Provider.pm =================================================================== RCS file: /home/cvspublic/xml-axkit/lib/Apache/AxKit/Provider.pm,v retrieving revision 1.13 diff -u -r1.13 Provider.pm --- lib/Apache/AxKit/Provider.pm 18 Feb 2003 22:37:22 -0000 1.13 +++ lib/Apache/AxKit/Provider.pm 7 May 2003 14:48:19 -0000 @@ -227,7 +227,7 @@ $pref_style, @$vals[0 .. 2], $xml_styles, $self); if ([EMAIL PROTECTED]) { - throw Apache::AxKit::Exception::Declined( + throw Apache::AxKit::Exception::ProviderDeclined( reason => "No styles defined for '$key'" ); } @@ -240,7 +240,7 @@ my $mapto; AxKit::Debug(4, "get_styles: looking for mapping for style type: '$style->{type}'"); if (!( $mapto = $style_mapping->{ $style->{type} } )) { - throw Apache::AxKit::Exception::Declined( + throw Apache::AxKit::Exception::Error( reason => "No implementation mapping available for type '$style->{type}'" ); } Index: lib/Apache/AxKit/Language/Sablot.pm =================================================================== RCS file: /home/cvspublic/xml-axkit/lib/Apache/AxKit/Language/Sablot.pm,v retrieving revision 1.4 diff -u -r1.4 Sablot.pm --- lib/Apache/AxKit/Language/Sablot.pm 26 May 2002 16:47:58 -0000 1.4 +++ lib/Apache/AxKit/Language/Sablot.pm 7 May 2003 14:48:19 -0000 @@ -55,7 +55,7 @@ $xslt_processor->ClearError(); if ($retcode) { - throw Apache::AxKit::Exception::Declined( + throw Apache::AxKit::Exception::Error( reason => "Sablotron failed to process XML file" ); } Index: lib/Apache/AxKit/Language/XSP.pm =================================================================== RCS file: /home/cvspublic/xml-axkit/lib/Apache/AxKit/Language/XSP.pm,v retrieving revision 1.39 diff -u -r1.39 XSP.pm --- lib/Apache/AxKit/Language/XSP.pm 18 Mar 2003 15:18:20 -0000 1.39 +++ lib/Apache/AxKit/Language/XSP.pm 7 May 2003 14:48:20 -0000 @@ -13,14 +13,14 @@ @ISA = ('Apache::AxKit::Language'); +my $cache; + sub stylesheet_exists () { 0; } sub get_mtime { - return 30; # 30 days in the cache? + return 30; # 30 days in the cache? } -my $cache; - # useful for debugging - not actually used by AxKit: # sub get_code { # my $filename = shift; @@ -33,6 +33,37 @@ # my $parser = get_parser($package, $filename); # return $parser->parsefile($filename); # } + +sub compile{ + my $class = shift; + my ($r, $key, $package, $xml) = @_; + + _register_me_and_others(); + + my $handler = AxKit::XSP::SAXHandler->new_handler( + XSP_Package => $package, + XSP_Line => $key, + XSP_Debug => 1, + ); + my $parser = AxKit::XSP::SAXParser->new( + Handler => $handler, + ); + + local $Apache::AxKit::Language::XSP::ResNamespaces = $r->dir_config('XSPResNamespaces'); + + my $to_eval; + + eval { + $to_eval = $parser->parse($xml); + }; + if ($@) { + throw Apache::AxKit::Exception::Error( + -text => "Parse of '$key' failed: $@" + ); + } + return $to_eval; +} + sub handler { my $class = shift; Index: lib/Apache/AxKit/Plugin/Passthru.pm =================================================================== RCS file: /home/cvspublic/xml-axkit/lib/Apache/AxKit/Plugin/Passthru.pm,v retrieving revision 1.2 diff -u -r1.2 Passthru.pm --- lib/Apache/AxKit/Plugin/Passthru.pm 1 Feb 2002 14:47:21 -0000 1.2 +++ lib/Apache/AxKit/Plugin/Passthru.pm 7 May 2003 14:48:20 -0000 @@ -10,7 +10,7 @@ my %in = $r->args(); if ($in{passthru}) { - $r->notes('axkit_passthru', 1); + $r->notes('axkit_passthru', $in{passthru}); } if ($in{passthru_type}) { $r->notes('axkit_passthru_type', 1);
pipeline.tar
Description: Unix tar archive