You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axkit-dev@xml.apache.org by jw...@apache.org on 2002/06/06 01:59:19 UTC

cvs commit: xml-axkit/lib/Apache/AxKit/Provider File.pm

jwalt       2002/06/05 16:59:19

  Modified:    .        AxKit.xs Changes MANIFEST axconfig.c axconfig.h
               lib      AxKit.pm
               lib/Apache/AxKit Cache.pm ConfigReader.pm Provider.pm
               lib/Apache/AxKit/Language LibXSLT.pm XPathScript.pm XSP.pm
               lib/Apache/AxKit/Provider File.pm
  Log:
  - fix segfault for non-axkit sites created by AxHandleDirs patch
  - work around yet another LAnguage::LibXSLT strangeness
  - updated AxHandleDirs docs, implemented directory xml
  - implemented AxExternalEncoding
  - added AxKit::FromUTF8 and AxKit::ToUTF, updated all system calls
  
  Revision  Changes    Path
  1.6       +17 -6     xml-axkit/AxKit.xs
  
  Index: AxKit.xs
  ===================================================================
  RCS file: /home/cvs/xml-axkit/AxKit.xs,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AxKit.xs	4 Jun 2002 07:51:54 -0000	1.5
  +++ AxKit.xs	5 Jun 2002 23:59:19 -0000	1.6
  @@ -1,4 +1,4 @@
  -/* $Id: AxKit.xs,v 1.5 2002/06/04 07:51:54 matts Exp $ */
  +/* $Id: AxKit.xs,v 1.6 2002/06/05 23:59:19 jwalt Exp $ */
   
   #ifdef __cplusplus
   extern "C" {
  @@ -62,7 +62,7 @@
       PUTBACK;
       
       cnt = perl_call_method(method, G_SCALAR);
  -    
  +
       SPAGAIN;
       
       if (cnt != 1) {
  @@ -215,8 +215,9 @@
       CODE:
       {
           axkit_dir_config * cfg;
  +        axkit_server_config * scfg;
           HV * config;
  -        
  +
           if (r == NULL) {
               croak("_get_config: Unexpected request_rec = NULL");
           }
  @@ -224,10 +225,10 @@
           if (r->per_dir_config == NULL) {
               croak("_get_config: Unexpected per_dir_config = NULL");
           }
  -        
  +
           cfg = (axkit_dir_config *)
                   ap_get_module_config(r->per_dir_config, &XS_AxKit);
  -        
  +
           if (!cfg) {
               config = newHV();
           }
  @@ -237,6 +238,16 @@
                   config = newHV();
               }
           }
  +
  +        if (r->server == NULL || r->server->module_config == NULL) {
  +            croak("_get_config: Unexpected r->server->module_config = NULL");
  +        }
  +
  +        scfg = (axkit_server_config *)
  +                ap_get_module_config(r->server->module_config, &XS_AxKit);
  +
  +        if (scfg) ax_get_server_config(scfg,config);
  +
           RETVAL = newRV_noinc((SV*)config);
       }
       OUTPUT:
  @@ -451,7 +462,7 @@
           if (!ptr || len < 4) {
               XSRETURN_UNDEF;
           }
  -        
  +
           ret = xmlSAXUserParseMemory(axkitSAXHandler, (void*)&results, ptr, len);
           
           sv_2mortal(error_str);
  
  
  
  1.8       +2 -0      xml-axkit/Changes
  
  Index: Changes
  ===================================================================
  RCS file: /home/cvs/xml-axkit/Changes,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Changes	13 May 2002 19:33:28 -0000	1.7
  +++ Changes	5 Jun 2002 23:59:19 -0000	1.8
  @@ -3,6 +3,8 @@
   1.5.2-dev
    - Added SAXMachines Language module.
    - Seperated ContentProviders from StyleProviders
  + - Added AxExternalEncoding option including TransHandler
  + - Made AxHandleDirs work as documented (updated File provider)
   
   1.5.2
    - Allow AxKit to handle directory requests.
  
  
  
  1.9       +0 -2      xml-axkit/MANIFEST
  
  Index: MANIFEST
  ===================================================================
  RCS file: /home/cvs/xml-axkit/MANIFEST,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- MANIFEST	13 May 2002 19:33:28 -0000	1.8
  +++ MANIFEST	5 Jun 2002 23:59:19 -0000	1.9
  @@ -55,7 +55,6 @@
   axkit.org/mailinglist.xml
   axkit.org/news.xml
   axkit.org/sidebar.xml
  -axkit.org/sidebar_new.xml
   axkit.org/stylesheets/axkit.css
   axkit.org/stylesheets/axkit_html.css
   axkit.org/stylesheets/body_print_html.xps
  @@ -112,7 +111,6 @@
   demo/xsp/showsource.xsp
   demo/xsp/simpletaglib-object.xsp
   demo/xsp/simpletaglib-simple.xsp
  -demo/xsp/tlh.xsp
   demo/xsp/util.xsp
   demo/xsp/webutils.xsp
   examples/.htaccess
  
  
  
  1.9       +169 -39   xml-axkit/axconfig.c
  
  Index: axconfig.c
  ===================================================================
  RCS file: /home/cvs/xml-axkit/axconfig.c,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- axconfig.c	4 Jun 2002 21:51:31 -0000	1.8
  +++ axconfig.c	5 Jun 2002 23:59:19 -0000	1.9
  @@ -1,4 +1,4 @@
  -/* $Id: axconfig.c,v 1.8 2002/06/04 21:51:31 matts Exp $ */
  +/* $Id: axconfig.c,v 1.9 2002/06/05 23:59:19 jwalt Exp $ */
   
   #ifndef WIN32
   #include <modules/perl/mod_perl.h>
  @@ -108,6 +108,7 @@
       new->cache_module = 0;
       new->output_charset = 0;
       new->trace_intermediate = 0;
  +    new->external_encoding = 0;
   
       /* complex types */
       new->type_map = NULL;
  @@ -189,7 +190,7 @@
       
       new->processors = newHV();
       ap_register_cleanup(p, (void*)new->processors, ax_cleanup_hv, ap_null_cleanup);
  -    
  +
       new->dynamic_processors = newAV();
       ap_register_cleanup(p, (void*)new->dynamic_processors, ax_cleanup_av, ap_null_cleanup);
       
  @@ -212,9 +213,9 @@
   
       new->current_plugins = newAV();
       ap_register_cleanup(p, (void*)new->current_plugins, ax_cleanup_av, ap_null_cleanup);
  -    
  +
       /* warn("create dir config: %d\n", new); */
  -    
  +
       return new;
   }
   
  @@ -252,9 +253,9 @@
           }
           sub2 = (AV*)SvRV(*sub2p);
       }
  -    
  +
       /* warn("adding processor in %s/%s with refs: %d\n", key1, key2, SvREFCNT(value)); */
  -    
  +
       av_push(sub2, value);
   }
   
  @@ -438,6 +439,13 @@
           new->trace_intermediate = ap_pstrdup(p, parent_dir->trace_intermediate);
       }
   
  +    if (subdir->external_encoding) {
  +        new->external_encoding = ap_pstrdup(p, subdir->external_encoding);
  +    }
  +    else if (parent_dir->external_encoding) {
  +        new->external_encoding = ap_pstrdup(p, parent_dir->external_encoding);
  +    }
  +
       new->debug_level =
           subdir->debug_level != -1 ? subdir->debug_level :
                                       parent_dir->debug_level;
  @@ -475,7 +483,7 @@
                                       parent_dir->handle_dirs;
       
       /* complex types */
  -    
  +
       {
           /* cfg->error_stylesheet */
           AV * from = NULL;
  @@ -529,10 +537,10 @@
               cval = ap_pstrdup(p, SvPV(val, clen));
               hv_store(new->type_map, key, len, newSVpvn(cval, clen), 0);
           }
  -        
  +
           ap_register_cleanup(p, (void*)new->type_map, ax_cleanup_hv, ap_null_cleanup);
       }
  -    
  +
       {
           /* cfg->dynamic_processors */
           new->dynamic_processors = newAV();
  @@ -560,7 +568,7 @@
                   }
               }
           }
  -        
  +
           ap_register_cleanup(p, (void*)new->dynamic_processors, ax_cleanup_av, ap_null_cleanup);
       }
   
  @@ -594,9 +602,9 @@
           SV * val;
           I32 len;
           char * key;
  -        
  +
           new->processors = newHV();
  -        
  +
           if (!subdir->reset_processors) {
               hv_iterinit(parent_dir->processors);
               while (val = hv_iternextsv(parent_dir->processors, &key, &len)) {
  @@ -654,7 +662,7 @@
                   
                   ary = (AV*)SvRV(subval);
                   ary_len = av_len(ary);
  -                
  +
                   if (ary_len >= 0) {
                       for (i = 0; i <= ary_len; i++) {
                           SV ** elem = av_fetch(ary, i, 0);
  @@ -700,7 +708,7 @@
                   }
               }
           }
  -        
  +
           ap_register_cleanup(p, (void*)new->output_transformers, ax_cleanup_av, ap_null_cleanup);
       }
   
  @@ -732,14 +740,14 @@
                   }
               }
           }
  -        
  +
           ap_register_cleanup(p, (void*)new->current_plugins, ax_cleanup_av, ap_null_cleanup);
       }
  -    
  +
       new->current_styles = newAV();
       av_push(new->current_styles, newSVpv("#default", 0));
       ap_register_cleanup(p, (void*)new->current_styles, ax_cleanup_av, ap_null_cleanup);
  -    
  +
       new->current_medias = newAV();
       av_push(new->current_medias, newSVpv("screen", 0));
       ap_register_cleanup(p, (void*)new->current_medias, ax_cleanup_av, ap_null_cleanup);
  @@ -764,7 +772,7 @@
           new->output_transformers
           );
   */
  -    
  +
       return new;
   }
   
  @@ -775,15 +783,15 @@
                               char *mt, char *sty, char *option)
   {
       AV *processor = newAV();
  -    
  +
       SV **cur_media = av_fetch(ax->current_medias, 0, 0);
       SV **cur_style = av_fetch(ax->current_styles, 0, 0);
  -    
  +
       SV *type = newSVpv((char*)cmd->info, 0);
       SV *mime = newSVpv(mt, 0);
       SV *style = newSVpv(sty, 0);
       SV *opt_sv = newSVpv(option, 0);
  -    
  +
       av_push(processor, type);
       av_push(processor, mime);
       av_push(processor, style);
  @@ -823,7 +831,7 @@
   {
       av_push(ax->error_stylesheet, newSVpvn(mime, strlen(mime)));
       av_push(ax->error_stylesheet, newSVpvn(stylesheet, strlen(stylesheet)));
  -    
  +
       return NULL;
   }
   
  @@ -870,7 +878,7 @@
       }
       
       ap_set_module_config(cmd->server->lookup_defaults, &XS_AxKit, oldconf);
  -    
  +
       return NULL;
   }
   
  @@ -962,13 +970,13 @@
   ax_add_xsp_taglib (cmd_parms *cmd, axkit_dir_config *ax, char *module)
   {
       STRLEN len;
  -    
  +
       ax_preload_module(&module);
  -    
  +
       len = strlen(module);
  -    
  +
       hv_store(ax->xsp_taglibs, module, len, newSViv(1), 0);
  -    
  +
       return NULL;
   }
   
  @@ -977,7 +985,7 @@
   {
       SV * mod_sv = newSVpv(module, 0);
       av_push(ax->output_transformers, mod_sv);
  -    
  +
       return NULL;
   }
   
  @@ -1054,13 +1062,13 @@
       
       if (S_ISDIR(r->finfo.st_mode)) {
           axkit_dir_config * cfg = (axkit_dir_config *)ap_get_module_config(r->per_dir_config, &XS_AxKit);
  -        if (cfg->handle_dirs != 1) {
  +        if (!cfg || cfg->handle_dirs != 1) {
               return DECLINED;
           }
       }
  -    
  +
       handler_sv = newSVpv("AxKit::fast_handler", 0);
  -    
  +
       cfg = perl_get_sv("AxKit::Cfg", FALSE);
       debuglevel = perl_get_sv("AxKit::DebugLevel", FALSE);
       errorlevel = perl_get_sv("Error::Debug", FALSE);
  @@ -1076,7 +1084,7 @@
       LEAVE;
   
       SvREFCNT_dec(handler_sv);
  -    
  +
       if (retval == DECLINED) {
           r->handler = "default-handler";
           return ap_invoke_handler(r);
  @@ -1095,6 +1103,113 @@
       return DECLINED;
   }
   
  +/************ server wide configuration *******************/
  +
  +axkit_server_config *
  +new_axkit_server_config (pool *p)
  +{
  +    axkit_server_config *new =
  +        (axkit_server_config *) ap_palloc(p, sizeof(axkit_server_config));
  +
  +    new->external_encoding = 0;
  +    new->iconv_handle = 0;
  +
  +    return new;
  +}
  +
  +void *
  +create_axkit_server_config (pool *p, server_rec *s)
  +{
  +    axkit_server_config *new = new_axkit_server_config(p);
  +
  +    return new;
  +}
  +
  +static void *
  +merge_axkit_server_config (pool *p, void *parent_dirv, void *subdirv)
  +{
  +    axkit_server_config *parent_dir = (axkit_server_config *)parent_dirv;
  +    axkit_server_config *subdir = (axkit_server_config *)subdirv;
  +    axkit_server_config *new = new_axkit_server_config(p);
  +
  +    if (parent_dir == NULL) {
  +        parent_dir = create_axkit_dir_config(p, "");
  +    }
  +
  +    if (subdir->external_encoding) {
  +        new->external_encoding = ap_pstrdup(p, subdir->external_encoding);
  +        if (strcmp(new->external_encoding,"UTF-8")) {
  +            new->iconv_handle = iconv_open(new->external_encoding,"UTF-8");
  +            ap_register_cleanup(p, (void*)new->iconv_handle, (void (*)(void *))iconv_close, ap_null_cleanup);
  +        }
  +    }
  +    else if (parent_dir->external_encoding) {
  +        new->external_encoding = ap_pstrdup(p, parent_dir->external_encoding);
  +        if (strcmp(new->external_encoding,"UTF-8")) {
  +            new->iconv_handle = iconv_open(new->external_encoding,"UTF-8");
  +            ap_register_cleanup(p, (void*)new->iconv_handle, (void (*)(void *))iconv_close, ap_null_cleanup);
  +        }
  +    }
  +
  +    return new;
  +}
  +
  +static CHAR_P
  +ax_set_external_encoding (cmd_parms *cmd, void *dummy, char *encoding)
  +{
  +    axkit_server_config *ax = (axkit_server_config *)
  +                ap_get_module_config(cmd->server->module_config, &XS_AxKit);
  +    /* warn("setting encoding %s",encoding); */
  +    ax->external_encoding = ap_pstrdup(cmd->pool, encoding);
  +    if (strcmp(ax->external_encoding,"UTF-8")) {
  +        ax->iconv_handle = iconv_open(ax->external_encoding,"UTF-8");
  +        ap_register_cleanup(cmd->pool, (void*)ax->iconv_handle, (void (*)(void *))iconv_close, ap_null_cleanup);
  +    }
  +    return NULL;
  +}
  +
  +static int axkit_fixup_charsets(request_rec *r)
  +{
  +    char *local;
  +    int inbytes, outbytes;
  +    char *icursor, *ocursor;
  +
  +    axkit_server_config * cfg;
  +    /* warn("fixup: '%s'",r->uri); */
  +
  +    if (!r || !r->server || !r->server->module_config)
  +        return DECLINED;
  +
  +    cfg = (axkit_server_config *)ap_get_module_config(r->server->module_config, &XS_AxKit);
  +
  +    if (!cfg || !cfg->iconv_handle)
  +        return DECLINED;
  +
  +    /* can "UTF-8 -> anything" grow by more than a factor 4?
  +     * (UTF-8 -> UCS-4 could be factor 4, add some slack to be safe)
  +     */
  +    inbytes = strlen(r->uri);
  +    outbytes = inbytes*4+12;
  +    local = ap_pcalloc(r->pool, outbytes+1);
  +
  +    /* reset state */
  +    iconv(cfg->iconv_handle,NULL,NULL,NULL,NULL);
  +
  +    icursor = r->uri;
  +    ocursor = local;
  +    /* Try conversion */
  +    if (iconv(cfg->iconv_handle,&icursor,&inbytes,&ocursor,&outbytes) == (size_t)-1) {
  +        /* conversion failed - assume it was sent in target charset */
  +        /*warn("not UTF-8, leaving URL '%s' untouched", r->uri);*/
  +        return DECLINED;
  +    }
  +
  +    /*warn("conversion successful: '%s'",local);*/
  +    r->uri = local;
  +
  +    return DECLINED;
  +}
  +
   static command_rec axkit_mod_cmds[] = {
   
       { "AxAddProcessor", ax_add_processor,
  @@ -1134,7 +1249,7 @@
         "End of media type block" },
   
       { "<AxStyleName", ax_style_name,
  -      NULL, OR_ALL, RAW_ARGS, 
  +      NULL, OR_ALL, RAW_ARGS,
         "Style name block" },
   
       { "</AxStyleName>", ax_style_name_end,
  @@ -1266,6 +1381,11 @@
         OR_ALL, FLAG,
         "On or Off [default] to disable xml-stylesheet PI processing" },
   
  +    { "AxExternalEncoding", ax_set_external_encoding,
  +      NULL,
  +      RSRC_CONF, TAKE1,
  +      "the character set used by the local file system and by URLs [default don't convert]" },
  +
       { NULL }
   };
   
  @@ -1281,11 +1401,11 @@
       axkit_module_init,            /* module initializer */
       create_axkit_dir_config,      /* per-directory config creator */
       merge_axkit_dir_config,       /* dir config merger */
  -    NULL,                         /* server config creator */
  -    NULL,                         /* server config merger */
  +    create_axkit_server_config,   /* server config creator */
  +    merge_axkit_server_config,    /* server config merger */
       axkit_mod_cmds,               /* command table */
       axkit_handlers,               /* [7] list of handlers */
  -    NULL,                         /* [2] filename-to-URI translation */
  +    axkit_fixup_charsets,         /* [2] filename-to-URI translation */
       NULL,                         /* [5] check/validate user_id */
       NULL,                         /* [6] check user_id is valid *here* */
       NULL,                         /* [4] check access by host address */
  @@ -1305,7 +1425,7 @@
   
       retval = newHV();
       if (cfg->cache_dir) {
  -        hv_store(retval, "CacheDir", 
  +        hv_store(retval, "CacheDir",
                   8, (newSVpv(cfg->cache_dir, 0)), 0);
       }
       if (cfg->config_reader_module) {
  @@ -1396,10 +1516,19 @@
               10, newRV_inc((SV*)cfg->xsp_taglibs), 0);
       hv_store(retval, "Plugins",
               7, newRV_inc((SV*)cfg->current_plugins), 0);
  -    
  +
       return retval;
   }
   
  +void
  +ax_get_server_config (axkit_server_config * cfg, HV *retval)
  +{
  +    if (cfg->external_encoding) {
  +        hv_store(retval, "ExternalEncoding",
  +                16, (newSVpv(cfg->external_encoding, 0)), 0);
  +    }
  +}
  +
   void remove_module_cleanup(void * ignore)
   {
       if (ap_find_linked_module(ap_find_module_name(&XS_AxKit))) {
  @@ -1409,6 +1538,7 @@
       (void)hv_delete(GvHV(incgv), "AxKit.pm", 8, G_DISCARD);
   }
   
  +
   /* Diff for styles being relative to .htaccess:
   Index: axconfig.c
   ===================================================================
  @@ -1453,7 +1583,7 @@
   >     else {
   >         style = newSVpv(sty, 0);
   >     }
  ->     
  +>
   >     warn("style: %s\n", SvPV_nolen(style));
   >     
   674,675c703,725
  
  
  
  1.5       +10 -1     xml-axkit/axconfig.h
  
  Index: axconfig.h
  ===================================================================
  RCS file: /home/cvs/xml-axkit/axconfig.h,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- axconfig.h	4 Jun 2002 16:37:12 -0000	1.4
  +++ axconfig.h	5 Jun 2002 23:59:19 -0000	1.5
  @@ -1,4 +1,4 @@
  -/* $Id: axconfig.h,v 1.4 2002/06/04 16:37:12 jwalt Exp $ */
  +/* $Id: axconfig.h,v 1.5 2002/06/05 23:59:19 jwalt Exp $ */
   
   #ifdef WIN32
   #define _INC_DIRENT
  @@ -30,6 +30,7 @@
     #include <http_log.h>
    #endif
   #endif
  +#include <iconv.h>
   
   typedef struct {
       /* simple types */
  @@ -68,11 +69,19 @@
   
   } axkit_dir_config;
   
  +typedef struct {
  +    /* simple types */
  +    char * external_encoding;
  +    iconv_t iconv_handle;
  +} axkit_server_config;
  +
   extern module MODULE_VAR_EXPORT XS_AxKit;
   
   void remove_module_cleanup(void * ignore);
   
   HV * ax_get_config (axkit_dir_config * cfg);
  +
  +void ax_get_server_config (axkit_server_config * cfg, HV *hash);
   
   void maybe_load_module (char * name);
   
  
  
  
  1.19      +51 -5     xml-axkit/lib/AxKit.pm
  
  Index: AxKit.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/AxKit.pm,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- AxKit.pm	4 Jun 2002 17:21:30 -0000	1.18
  +++ AxKit.pm	5 Jun 2002 23:59:19 -0000	1.19
  @@ -1,4 +1,4 @@
  -# $Id: AxKit.pm,v 1.18 2002/06/04 17:21:30 jwalt Exp $
  +# $Id: AxKit.pm,v 1.19 2002/06/05 23:59:19 jwalt Exp $
   
   package AxKit;
   use strict;
  @@ -35,6 +35,27 @@
   # AxKit Utility Functions
   ###############################################################
   
  +sub FromUTF8($) {
  +    if (!$AxKit::Cfg->{from_utf8}) {
  +        return $_[0] if (exists $AxKit::Cfg->{from_utf8});
  +        AxKit::Debug(6,"encoding to ".$AxKit::Cfg->ExternalEncoding());
  +        $AxKit::Cfg->{from_utf8} = undef, return $_[0] if ($AxKit::Cfg->ExternalEncoding() eq "UTF-8");
  +        $AxKit::Cfg->{from_utf8} = Apache::AxKit::CharsetConv->new("UTF-8",$AxKit::Cfg->ExternalEncoding()) || die "ExternalEncoding: No such charset: ".$AxKit::Cfg->ExternalEncoding();
  +    }
  +    return $AxKit::Cfg->{from_utf8}->convert($_[0]);
  +}
  +
  +sub ToUTF8($) {
  +    if (!$AxKit::Cfg->{to_utf8}) {
  +        return $_[0] if (exists $AxKit::Cfg->{to_utf8});
  +        AxKit::Debug(6,"decoding from ".$AxKit::Cfg->ExternalEncoding());
  +        $AxKit::Cfg->{to_utf8} = undef, return $_[0] if ($AxKit::Cfg->ExternalEncoding() eq "UTF-8");
  +        $AxKit::Cfg->{to_utf8} = Apache::AxKit::CharsetConv->new($AxKit::Cfg->ExternalEncoding(), "UTF-8") || die "ExternalEncoding: No such charset: ".$AxKit::Cfg->ExternalEncoding();
  +    }
  +    return $AxKit::Cfg->{to_utf8}->convert($_[0]);
  +}
  +
  +
   sub _Debug {
       my $level = shift;
       if ($level <= $AxKit::DebugLevel) {
  @@ -450,11 +471,11 @@
       my $r;
       if ($uri =~ /^axkit:\/(\/.*)$/) {
           my $abs_uri = $1;
  -        $r = $apache->lookup_uri($abs_uri);
  +        $r = $apache->lookup_uri(AxKit::FromUTF8($abs_uri));
       }
       elsif ($uri =~ /^axkit:(.*)$/) {
           my $rel_uri = $1;
  -        $r = $apache->lookup_uri($rel_uri);
  +        $r = $apache->lookup_uri(AxKit::FromUTF8($rel_uri));
       }
       else {
           throw Apache::AxKit::Exception (-text => "get_axkit_uri for non-axkit URIs is not yet supported");
  @@ -625,6 +646,7 @@
                       $styleprovider,
                       !@$styles, # any more left?
                       );
  +	    AxKit::Debug(5, "$mapto\::handler finished with code $retval");
               $result_code = $retval if $retval != OK;
           }
           else {
  @@ -1159,6 +1181,29 @@
   
       AxOutputCharset iso-8859-1
   
  +=head2 AxExternalEncoding
  +
  +This directive specifies the character encoding used outside of AxKit.
  +Internally, AxKit strictly uses UTF-8 (remember that when you write Taglibs!),
  +but file names on the file system and URIs requested by browsers may use
  +a different encoding, e.g. ISO-8859-15 for most of Europe.
  +
  +This is a server-global directive, so only use it within <VirtualHost ...>
  +containers or on the root level. As a side effect, this option allows you to
  +work with non-ASCII chars in URLs even outside of AxKit. Some Browsers may
  +send URLs in their local charset although the link was encoded in UTF-8, and
  +others always send UTF-8 encoded URLs, regardless of link encoding. If you set
  +this option, AxKit will intercept each request and check if the URL came
  +encoded in UTF-8. If so, AxKit transforms it to the character encoding
  +specified here before Apache gets to resolve the request, so Apache will
  +find the file, even if it is a non-AxKit file.
  +
  +Note: This does not effect the _contents_ of documents, they have their own
  +encoding specifier (in the <?xml ...?> line). For now, it only affects file
  +names and URL processing.
  +
  +    AxExternalEncoding ISO-8859-1
  +
   =head2 AxAddOutputTransformer
   
   Output transformers are applied just before output is sent to the browser.
  @@ -1239,8 +1284,9 @@
   
   =head2 AxHandleDirs
   
  -Enable this option to allow AxKit to process directories. Uses XML::Directory
  -and XML::SAX::Writer to create the directory listing.
  +Enable this option to allow AxKit to process directories. Creates an XML document
  +with the contents of the requested directory. Look at sample output to
  +discover that the format is straightforward and easy to understand.
   
     AxHandleDirs On
   
  
  
  
  1.6       +4 -4      xml-axkit/lib/Apache/AxKit/Cache.pm
  
  Index: Cache.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Cache.pm,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Cache.pm	31 May 2002 19:22:23 -0000	1.5
  +++ Cache.pm	5 Jun 2002 23:59:19 -0000	1.6
  @@ -1,10 +1,10 @@
  -# $Id: Cache.pm,v 1.5 2002/05/31 19:22:23 matts Exp $
  +# $Id: Cache.pm,v 1.6 2002/06/05 23:59:19 jwalt Exp $
   
   package Apache::AxKit::Cache;
   use strict;
   
   use Apache;
  -use Apache::Constants qw(OK DECLINED);
  +use Apache::Constants qw(OK DECLINED SERVER_ERROR);
   use Apache::AxKit::Exception;
   use Digest::MD5 ();
   use Compress::Zlib qw(gzopen);
  @@ -199,7 +199,7 @@
   
   sub deliver {
       my $self = shift;
  -    return if $self->{no_cache};
  +    return SERVER_ERROR if $self->{no_cache};
       my $r = $self->{apache};
   
       {
  @@ -245,7 +245,7 @@
           
           return DECLINED;
       }
  -    
  +
   }
   
   sub reset {
  
  
  
  1.9       +17 -12    xml-axkit/lib/Apache/AxKit/ConfigReader.pm
  
  Index: ConfigReader.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/ConfigReader.pm,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ConfigReader.pm	4 Jun 2002 17:21:30 -0000	1.8
  +++ ConfigReader.pm	5 Jun 2002 23:59:19 -0000	1.9
  @@ -1,4 +1,4 @@
  -# $Id: ConfigReader.pm,v 1.8 2002/06/04 17:21:30 jwalt Exp $
  +# $Id: ConfigReader.pm,v 1.9 2002/06/05 23:59:19 jwalt Exp $
   
   package Apache::AxKit::ConfigReader;
   
  @@ -9,13 +9,13 @@
   sub new {
       my $class = shift;
       my $r = shift;
  -    
  +
   #    my $cfg = AxKit::get_config($r);
   #    if (!$cfg) {
   #        $cfg = {};
   #        AxKit::Debug(2, "Unable to get_config(). Using blank hashref instead");
   #    }
  -    
  +
   #    use Apache::Peek 'Dump';
   #    Dump($cfg);
   #     use Data::Dumper;
  @@ -23,9 +23,9 @@
   #     warn("Cfg: ", Data::Dumper->Dump([$cfg], ['cfg']));
   
       my $self = bless { apache => $r, output_charset_ok => 0 }, $class;
  -    
  +
       $self->get_config($r);
  -    
  +
       if (my $alternate = $self->{cfg}->{ConfigReader} || $r->dir_config('AxConfigReader')) {
           if ($alternate ne __PACKAGE__) {
               AxKit::reconsecrate($self, $alternate);
  @@ -33,7 +33,7 @@
               $self->get_config($r);
           }
       }
  -    
  +
       return $self;
   }
   
  @@ -61,8 +61,8 @@
   # returns the location of the cache dir
   sub CacheDir {
       my $self = shift;
  -    if (my $cachedir = 
  -            $self->{cfg}->{CacheDir} 
  +    if (my $cachedir =
  +            $self->{cfg}->{CacheDir}
               ||
               $self->{apache}->dir_config('AxCacheDir')) {
           return $cachedir;
  @@ -201,7 +201,7 @@
       my $self = shift;
   
       return unless $self->{output_charset_ok};
  -    
  +
   #    warn "OutputCharset\n";
       unless ($self->{cfg}{TranslateOutput} ||
               $self->{apache}->dir_config('AxTranslateOutput')) {
  @@ -235,18 +235,23 @@
           
           $retcharset =~ s/iso/ISO/;
           $retcharset =~ s/(us\-)?ascii/US-ASCII/;
  -        
  +
           return undef if $retcharset =~ /^utf\-?8$/;
   	return undef if $retcharset eq '*';
   # warn "Charset: '$retcharset'\n";
           return $retcharset;
       }
  -    
  +
  +}
  +
  +sub ExternalEncoding {
  +    my $self = shift;
  +    return $self->{cfg}{ExternalEncoding} || "UTF-8";
   }
   
   sub ErrorStyles {
       my $self = shift;
  -    
  +
       my $style = $self->{cfg}{ErrorStylesheet};
       my ($type, $href);
       if (!$style || !@$style) {
  
  
  
  1.10      +2 -2      xml-axkit/lib/Apache/AxKit/Provider.pm
  
  Index: Provider.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Provider.pm,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- Provider.pm	31 May 2002 19:22:23 -0000	1.9
  +++ Provider.pm	5 Jun 2002 23:59:19 -0000	1.10
  @@ -1,4 +1,4 @@
  -# $Id: Provider.pm,v 1.9 2002/05/31 19:22:23 matts Exp $
  +# $Id: Provider.pm,v 1.10 2002/06/05 23:59:19 jwalt Exp $
   
   package Apache::AxKit::Provider;
   use strict;
  @@ -106,7 +106,7 @@
   
           # create a subrequest, so we get the right AxKit::Cfg for the URI
           my $apache = AxKit::Apache->request;
  -        my $sub = $apache->lookup_uri($sysid);
  +        my $sub = $apache->lookup_uri(AxKit::FromUTF8($sysid));
           local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($sub);
       
   #        warn "File provider ext_ent_handler called with '$sysid'\n";
  
  
  
  1.14      +4 -4      xml-axkit/lib/Apache/AxKit/Language/LibXSLT.pm
  
  Index: LibXSLT.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Language/LibXSLT.pm,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- LibXSLT.pm	4 Jun 2002 07:52:17 -0000	1.13
  +++ LibXSLT.pm	5 Jun 2002 23:59:19 -0000	1.14
  @@ -1,4 +1,4 @@
  -# $Id: LibXSLT.pm,v 1.13 2002/06/04 07:52:17 matts Exp $
  +# $Id: LibXSLT.pm,v 1.14 2002/06/05 23:59:19 jwalt Exp $
   
   package Apache::AxKit::Language::LibXSLT;
   
  @@ -73,7 +73,7 @@
   
       my $stylesheet;
       my $cache = $style_cache{$style->key()};
  -    if ($cache && !$style->has_changed($cache->{mtime}) && ref($cache->{depends}) eq 'ARRAY') {
  +    if (ref($cache) eq 'HASH' && !$style->has_changed($cache->{mtime}) && ref($cache->{depends}) eq 'ARRAY') {
           AxKit::Debug(8, "[LibXSLT] checking if stylesheet is cached");
           my $changed = 0;
           DEPENDS:
  @@ -162,7 +162,7 @@
       
       # create a subrequest, so we get the right AxKit::Cfg for the URI
       my $apache = AxKit::Apache->request;
  -    my $sub = $apache->lookup_uri($uri);
  +    my $sub = $apache->lookup_uri(AxKit::FromUTF8($uri));
       local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($sub);
       
       my $provider = Apache::AxKit::Provider->new_content_provider($sub);
  @@ -187,7 +187,7 @@
       
       # create a subrequest, so we get the right AxKit::Cfg for the URI
       my $apache = AxKit::Apache->request;
  -    my $sub = $apache->lookup_uri($uri);
  +    my $sub = $apache->lookup_uri(AxKit::FromUTF8($uri));
       local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($sub);
       
       my $provider = Apache::AxKit::Provider->new_style_provider($sub);
  
  
  
  1.8       +5 -5      xml-axkit/lib/Apache/AxKit/Language/XPathScript.pm
  
  Index: XPathScript.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Language/XPathScript.pm,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- XPathScript.pm	31 May 2002 19:22:24 -0000	1.7
  +++ XPathScript.pm	5 Jun 2002 23:59:19 -0000	1.8
  @@ -1,4 +1,4 @@
  -# $Id: XPathScript.pm,v 1.7 2002/05/31 19:22:24 matts Exp $
  +# $Id: XPathScript.pm,v 1.8 2002/06/05 23:59:19 jwalt Exp $
   
   package Apache::AxKit::Language::XPathScript;
   
  @@ -154,7 +154,7 @@
       
       for my $inc (@$includes) {
   #        warn "Checking mtime for $inc\n";
  -        my $sub = $apache->lookup_uri($inc);
  +        my $sub = $apache->lookup_uri(AxKit::FromUTF8($inc));
           local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($sub);
           
           my $inc_provider = Apache::AxKit::Provider->new_style_provider($sub);
  @@ -295,7 +295,7 @@
       push @{$stash->{$key}{includes}}, $filename;
       
       my $apache = $provider->apache_request;
  -    my $sub = $apache->lookup_uri($filename);
  +    my $sub = $apache->lookup_uri(AxKit::FromUTF8($filename));
       local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($sub);
       
       my $inc_provider = Apache::AxKit::Provider->new_style_provider($sub);
  @@ -348,7 +348,7 @@
           
           # create a subrequest, so we get the right AxKit::Cfg for the URI
           my $apache = AxKit::Apache->request;
  -        my $sub = $apache->lookup_uri($uri);
  +        my $sub = $apache->lookup_uri(AxKit::FromUTF8($uri));
           local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($sub);
           
           my $provider = Apache::AxKit::Provider->new_content_provider($sub);
  @@ -383,7 +383,7 @@
       
       for my $inc (@{$stash->{$filename}{includes}}) {
           
  -        my $sub = $apache->lookup_uri($inc);
  +        my $sub = $apache->lookup_uri(AxKit::FromUTF8($inc));
           local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($sub);
           
           my $inc_provider = Apache::AxKit::Provider->new_style_provider(
  
  
  
  1.15      +2 -2      xml-axkit/lib/Apache/AxKit/Language/XSP.pm
  
  Index: XSP.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Language/XSP.pm,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- XSP.pm	5 Jun 2002 21:53:34 -0000	1.14
  +++ XSP.pm	5 Jun 2002 23:59:19 -0000	1.15
  @@ -1,4 +1,4 @@
  -# $Id: XSP.pm,v 1.14 2002/06/05 21:53:34 matts Exp $
  +# $Id: XSP.pm,v 1.15 2002/06/05 23:59:19 jwalt Exp $
   
   package Apache::AxKit::Language::XSP;
   
  @@ -938,7 +938,7 @@
       
       # create a subrequest, so we get the right AxKit::Cfg for the URI
       my $apache = AxKit::Apache->request;
  -    my $sub = $apache->lookup_uri($uri);
  +    my $sub = $apache->lookup_uri(AxKit::FromUTF8($uri));
       local $AxKit::Cfg = Apache::AxKit::ConfigReader->new($sub);
       
       my $provider = Apache::AxKit::Provider->new_content_provider($sub);
  
  
  
  1.9       +55 -12    xml-axkit/lib/Apache/AxKit/Provider/File.pm
  
  Index: File.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Provider/File.pm,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- File.pm	31 May 2002 19:22:24 -0000	1.8
  +++ File.pm	5 Jun 2002 23:59:19 -0000	1.9
  @@ -1,4 +1,4 @@
  -# $Id: File.pm,v 1.8 2002/05/31 19:22:24 matts Exp $
  +# $Id: File.pm,v 1.9 2002/06/05 23:59:19 jwalt Exp $
   
   package Apache::AxKit::Provider::File;
   use strict;
  @@ -11,9 +11,10 @@
   use Apache::AxKit::Exception;
   use Apache::AxKit::Provider;
   use AxKit;
  -use File::Basename;
  +use File::Spec;
   use Fcntl qw(O_RDONLY LOCK_SH);
   
  +
   sub init {
       my $self = shift;
       my (%p) = @_;
  @@ -21,6 +22,7 @@
       my $stats_done;
       if ($p{key}) {
           AxKit::Debug(8, "File Provider instantiated by key: $p{key}");
  +        # assumed already UTF-8
           $self->{file} = $p{key};
       }
       else {
  @@ -33,21 +35,23 @@
   
               AxKit::Debug(8, "[uri] File Provider looking up uri $p{uri}");
   
  -            $self->{apache} = $r->lookup_uri($p{uri});
  +            # assumed already UTF-8
  +            $self->{apache} = $r->lookup_uri(AxKit::FromUTF8($p{uri}));
               my $status = $self->{apache}->status();
               if ($status != HTTP_OK) {
                   throw Apache::AxKit::Exception::Error(-text => "Subrequest failed with status: " . $status);
               }
  -            $self->{file} = $self->{apache}->filename();
  +            $self->{file} = AxKit::ToUTF8($self->{apache}->filename());
   
               AxKit::Debug(8, "[uri] File Provider set filename to $self->{file}");
           }
           elsif ($p{file}) {
               AxKit::Debug(8, "[file] File Provider given file: $p{file}");
  +            # assumed already UTF-8
               $self->{file} = $p{file};
           }
           else {
  -            $self->{file} = $self->{apache}->filename();
  +            $self->{file} = AxKit::ToUTF8($self->{apache}->filename());
               AxKit::Debug(8, "[req] File Provider given \$r: $self->{file}");
               my @stats = stat($self->{apache}->finfo());
               $self->{mtime} = $stats[9];
  @@ -68,7 +72,7 @@
       }
   
       if (!$stats_done) {
  -        my @stats = stat($self->{file});
  +        my @stats = stat(AxKit::FromUTF8($self->{file}));
           $self->{mtime} = $stats[9];
           if (-e _) {
               if (-r _ ) {
  @@ -88,7 +92,7 @@
   sub _is_dir {
       my $self = shift;
       return $self->{is_dir} if exists $self->{is_dir};
  -    return -d $self->{file};
  +    return $self->{is_dir} = -d AxKit::FromUTF8($self->{file});
   }
   
   sub key {
  @@ -99,7 +103,7 @@
   sub exists {
       my $self = shift;
       return $self->{file_exists} if exists $self->{file_exists};
  -    if (-e $self->{file}) {
  +    if (-e AxKit::FromUTF8($self->{file})) {
           if (-r _ ) {
               $self->{file_exists} = 1;
               return 1;
  @@ -112,6 +116,40 @@
       return;
   }
   
  +sub get_dir_xml {
  +	my $self = shift;
  +	local (*DIR);
  +	my $dir = AxKit::FromUTF8($self->{file});
  +	if (opendir(DIR, $dir)) {
  +		my $output = '<?xml version="1.0" encoding="UTF-8"?>
  +<!DOCTYPE filelist PUBLIC "-//AXKIT/FileList XML V1.0//EN" "file:///dev/null">
  +<filelist xmlns="http://axkit.org/2002/filelist">
  +';
  +		while(my $line = readdir(DIR)) {
  +			my $xmlline = AxKit::ToUTF8($line);
  +			$xmlline =~ s/&/&amp;/;
  +			$xmlline =~ s/</&lt;/;
  +			my @stat = stat(File::Spec->catfile($dir,$line));
  +			my $attr = "size=\"$stat[7]\" atime=\"$stat[8]\" mtime=\"$stat[9]\" ctime=\"$stat[10]\"";
  +			$attr .= ' readable="1"' if (-r _);
  +			$attr .= ' writable="1"' if (-w _);
  +			$attr .= ' executable="1"' if (-x _);
  +			
  +			if (-f _) {
  +				$output .= "<file $attr>$xmlline</file>\n";
  +			} elsif (-d _) {
  +				$output .= "<directory $attr>$xmlline</directory>\n";
  +			} else {
  +				$output .= "<unknown $attr>$xmlline</unknown>\n";
  +			}
  +		}
  +		$output .= "</filelist>\n";
  +		AxKit::Debug(8,"Generated file list: $output");
  +		return $output;
  +	}
  +	return undef;
  +}
  +
   sub process {
       my $self = shift;
   
  @@ -124,6 +162,9 @@
   
       if ( $self->_is_dir ) {
           if ($AxKit::Cfg->HandleDirs()) {
  +	    my $output = $self->get_dir_xml();
  +	    return 0 if (!defined $output);
  +	    $self->{dir_xml} = $output;
               return 1;
           }
           # else
  @@ -153,7 +194,7 @@
   sub mtime {
       my $self = shift;
       return $self->{mtime} if defined $self->{mtime};
  -    return ($self->{mtime} = (stat($self->{file}))[9]);
  +    return ($self->{mtime} = (stat(AxKit::FromUTF8($self->{file})))[9]);
   }
   
   sub get_fh {
  @@ -162,9 +203,9 @@
           throw Apache::AxKit::Exception::IO(-text => "File '$self->{file}' does not exist or is not readable");
       }
       if ($self->_is_dir()) {
  -        throw Apache::AxKit::Exception::IO(-text => "$self->{file} is a directory");
  +        throw Apache::AxKit::Exception::IO(-text => "Can't get filehandle on directory. ($self->{file})");
       }
  -    my $filename = $self->{file};
  +    my $filename = AxKit::FromUTF8($self->{file});
       # chdir(dirname($filename));
       my $fh = Apache->gensym();
       if (sysopen($fh, $filename, O_RDONLY)) {
  @@ -177,8 +218,10 @@
   sub get_strref {
       my $self = shift;
       if ($self->_is_dir()) {
  +        my $xml = $self->{dir_xml} || $self->get_dir_xml();
  +        return \$xml if $xml;
           throw Apache::AxKit::Exception::IO(
  -          -text => "$self->{file} is a directory - please overload File provider and use AxContentProvider option");
  +          -text => "directory $self->{file} cannot be read");
       }
       my $fh = $self->get_fh();
       local $/;