httpd-apreq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Boris Zentner <...@2bz.de>
Subject Re: Apache::Request, APR::Table and UTF8
Date Thu, 07 Oct 2004 23:59:32 GMT
Hi,

Am 08.10.2004 um 00:54 schrieb David Wheeler:

> On Oct 7, 2004, at 3:37 PM, Boris Zentner wrote:
>
>> Thats exactly how my application work. Internaly all data is in the  
>> same charset for perl 5.6.1 and all is utf8 for perl >= 5.8.0.
>
> Bricolage, too.
>
>> The whole discussion came on since I do the conversion from  
>> Apache::Request's byte strings to perls utf8 for most but not all  
>> bytestrings. Then _all_ other application parts have no need to ever  
>> bother with any conversion. But that is not all, other parts can also  
>> insert data into the object ( utf8 or not).
>
> Not Bricolage. It all has to be utf8 or it's not a string. It's just  
> easier not to mix things up.

I have no control over all parts, but there is no problem only, when  
the data is back without the flag of course.

> [...]
>
>> Uhh, I do this already, but in fact I replace Apache::Request with  
>> something similar, so why using Apache::Request?
>
> I don't understand. Did you subclass it or replace it with something  
> else? There's a very big difference--subclassing is much less work!
>

subclass, I thought on getting rid of Apache::Request.

>>> I think that this may not be possible given what you submit to the  
>>> browser and get back from the browser is not Perl data (e.g.,  
>>> params). But pnotes(), for example, should do the right thing.
>>
>> Hmm, look:
>>
>> 1. the data touch my server all data is a sequence of bytes.
>> 2. Apache::Request put this into a table for me. ( the data is  
>> untouched utf8 or not )
>> 3. my module inherited from Apache::Request convert the utf8 data to  
>> utf8 with the flag inside the inherited new.
>>
>>   my $c = 0; # a counter to convert only some data to utf8
>>   for ( values %$t ) {
>>     $_ = Encode::encode_utf8($_) if ( $c++ & 1 );
>>   }
>>
>> I need only these lines in step three and all other modules can use  
>> the Apache::Request object and get straight data. Otherwise I need to  
>> copy the data to maybe pnotes.
>
> So you use your subclass where you need utf8 and use Apache::Request  
> itself where you don't. No?

I use Apache::Request, if I do not feel to change something. Otherwise  
I use a CGI like data container.

>
>> a $t->get should return now the correct data regardless if the flag  
>> was on or off. A $t->set store the data ( the same data as it does  
>> now ) but also the flag. If a $t->get read the data back the flag is  
>> restored. If the data is passed to the next handler in mod_perl it  
>> works as before ( it drops/ignores the flag, the data is the same ).
>
> I see. You're saying that because you basically store back to  
> Apache::Request, you want it to remember what you've stored. But I  
> don't think that Apache::Request was designed for storing data, just  
> for fetching request data and sending response data.
>

Yes.

If a store is not allowed, I'm really wrong and apologize for all the  
noise!

> Can you show the actual code?
>

Sure,

here is some. Have fun.

MyReq
   |
Apache::Request::KL
   |
Apache::Request

The KL::Param is only a fallback Data container, I think it is  
exchangeable by CGI
I have no control over MyReq.pm and MyKL/Common.pm
###################################################################
package Apache::Request::KL;
use Apache::Request;
use APR::Table ();

our @ISA = qw(Apache::Request);

sub init { return shift }

sub new {
   my $class = shift;
   my $rr    = shift;
   my $self  = bless { _r => Apache::Request->new($rr, @_) }, $class;

   $self->init;
   $self;
}

sub _get_params_table {
   my $self = shift;
   return $self->{params_table} ||= $self->{_r}->params;
}

sub param {
   my $self = shift;
   my $ppo = $self->{param_obj};
   if ( $ppo ) {
     return wantarray ? @{[ $ppo->param(@_) ]} : scalar($ppo->param(@_));
   }

   my $t = $self->{params_table}
     ||= $self->{_r}->params;

   if ( @_ == 0 ) {
     my @keys = ();
     $t->do( sub { push @keys, $_[0]; 1 } );
     return wantarray ? (@keys) : scalar(@keys);
   }

   # only one argument
   elsif ( @_ == 1 ) {
     if (wantarray) {
       my @list = $t->get(@_);
       return @list;
     }
     else {
       return $t->get(@_);
     }
   }

   # insert something
   else {
     while ( @_ > 0 ) {
       my ( $k, $v ) = splice @_, 0, 2;
       if ( ref $v eq 'ARRAY' ) {
         $t->unset($k);
         $t->merge( $k => $v->[$_] ) for ( 0 .. $#$v );
       }
       elsif ( !defined($v) ) {
         $t->unset($k);
       }
       else {
         $t->set( $k => $v );
       }
     }
   }
}

1;
######################################################################## 
####
package MyReq;
use strict;
use warnings;
use Encode;
use APR::Table;
use KL::Param;
our @ISA = 'Apache::Request::KL';

sub init {
   my $self = shift;
   my $type = $self->headers_in->{'Content-Type'};
   return if !$type or $type ne 'application/x-www-form-urlencoded';

   # no hint, no change!
   my $hint = $self->param('hint');
   return unless $hint;

  use bytes;
   my $t = $self->_get_params_table;
   my ( $ppo, $k, $v );
   if ( $hint eq $MyKL::Common::HINT_ISO_8859_1 ) {
     $ppo = $self->{param_obj} = KL::Param->new;
     while ( ( $k, $v ) = each %$t ) {
       $ppo->param( $k,
         $MyKL::Common::Skip{$k}
           ? $v
           : Encode::decode( 'iso-8859-1', $v ) );
     }
   }
   elsif ( $hint eq $MyKL::Common::HINT_UTF8 ) {
      $ppo = $self->{param_obj} = KL::Param->new;
     while ( ( $k, $v ) = each %$t ) {
       Encode::encode_utf8($v);
       $ppo->param( $k, $v );
     }
   }

   return $self;
}

1;
--
Boris


Mime
View raw message