httpd-apreq-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject cvs commit: httpd-apreq-2/glue/perl/xsbuilder/maps apreq_functions.map
Date Sat, 03 Jul 2004 15:45:53 GMT
joes        2004/07/03 08:45:53

  Modified:    .        CHANGES
               build    xsbuilder.pl
               glue/perl/t/apreq request.t
               glue/perl/xsbuilder/Apache/Upload Apache__Upload.h Upload_pm
               glue/perl/xsbuilder/maps apreq_functions.map
  Log:
  Replaced APR::PerlIO implementation of $upload->fh with a TIEHANDLE
  API layered over APR::Brigade.   Without this change, one filehandle's
  seek pointer could become stale after another handle (on the same upload)
  is read from.
  
  Revision  Changes    Path
  1.49      +6 -0      httpd-apreq-2/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/CHANGES,v
  retrieving revision 1.48
  retrieving revision 1.49
  diff -u -r1.48 -r1.49
  --- CHANGES	1 Jul 2004 04:11:24 -0000	1.48
  +++ CHANGES	3 Jul 2004 15:45:53 -0000	1.49
  @@ -4,6 +4,12 @@
   @section v2_04_dev Changes with libapreq2-2.04-dev
   
   - Perl API [joes]
  +  Replaced APR::PerlIO implementation of $upload->fh with a TIEHANDLE
  +  API layered over APR::Brigade.   Without this change, one filehandle's 
  +  seek pointer could become stale after another handle (on the same upload)
  +  is read from.
  +
  +- Perl API [joes]
     Added apreq_xs_croak for throwing APR::Error exceptions and included
     error-checking on $req->param, $req->args, $req->body, $req->upload, 
     and $jar->get.
  
  
  
  1.27      +0 -74     httpd-apreq-2/build/xsbuilder.pl
  
  Index: xsbuilder.pl
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/build/xsbuilder.pl,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- xsbuilder.pl	29 Jun 2004 22:45:30 -0000	1.26
  +++ xsbuilder.pl	3 Jul 2004 15:45:53 -0000	1.27
  @@ -354,80 +354,6 @@
       close $fh;
   }
   
  -use constant GvSHARED => 0;
  -
  -sub write_xs {
  -    my($self, $module, $functions) = @_;
  -
  -    my $fh = $self->open_class_file($module, '.xs');
  -    print $fh "$self->{noedit_warning_c}\n";
  -
  -    my @includes = @{ $self->includes };
  -
  -    if (my $mod_h = $self->mod_h($module)) {
  -        push @includes, $mod_h;
  -    }
  -
  -    for (@includes) {
  -        print $fh qq{\#include "$_"\n\n};
  -    }
  -
  -    my $last_prefix = "";
  -    my $fmap = $self -> typemap -> {function_map} ;
  -    my $myprefix = $self -> my_xs_prefix ;
  -
  -    for my $func (@$functions) {
  -        my $class = $func->{class};
  -        if ($class)
  -            {
  -            my $prefix = $func->{prefix};
  -            $last_prefix = $prefix if $prefix;
  -
  -            if ($func->{name} =~ /^$myprefix/o) {
  -                #e.g. mpxs_Apache__RequestRec_
  -                my $class_prefix = $fmap -> class_c_prefix($class);
  -                if ($func->{name} =~ /$class_prefix/) {
  -                    $prefix = $fmap -> class_xs_prefix($class);
  -                }
  -            }
  -
  -            $prefix = $prefix ? "  PREFIX = $prefix" : "";
  -            print $fh "MODULE = $module    PACKAGE = $class $prefix\n\n";
  -            }
  -
  -        print $fh $func->{code};
  -    }
  -
  -    if (my $destructor = $self->typemap->destructor($last_prefix)) {
  -        my $arg = $destructor->{argspec}[0];
  -
  -        print $fh <<EOF;
  -void
  -$destructor->{name}($arg)
  -    $destructor->{class} $arg
  -
  -EOF
  -    }
  -
  -    print $fh "PROTOTYPES: disabled\n\n";
  -    print $fh "BOOT:\n";
  -    print $fh $self->boot($module);
  -    print $fh "    items = items; /* -Wall */\n";
  -    print $fh <<'EOT' if $module eq "Apache::Upload";
  -    f2g = APR_RETRIEVE_OPTIONAL_FN(apr_perlio_apr_file_to_glob);
  -    if (f2g == NULL)
  -        Perl_croak(aTHX_ "Failed to locate apr_perlio_apr_file_to_glob during BOOT");
  -EOT
  -    print $fh "\n";
  -    if (my $newxs = $self->{newXS}->{$module}) {
  -        for my $xs (@$newxs) {
  -            print $fh qq{   cv = newXS("$xs->[0]", $xs->[1], __FILE__);\n};
  -            print $fh qq{   GvSHARED_on(CvGV(cv));\n} if GvSHARED;
  -        }
  -    }
  -
  -    close $fh;
  -}
   
   package My::TypeMap;
   use base 'ExtUtils::XSBuilder::TypeMap';
  
  
  
  1.13      +1 -1      httpd-apreq-2/glue/perl/t/apreq/request.t
  
  Index: request.t
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/t/apreq/request.t,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- request.t	2 Jul 2004 17:37:07 -0000	1.12
  +++ request.t	3 Jul 2004 15:45:53 -0000	1.13
  @@ -22,7 +22,7 @@
   
   for my $test (qw/slurp bb_read fh_read tempname bad;query=string%%/) {
       # upload a string as a file
  -    my $value = 'DataUpload' x 100_000;
  +    my $value = ('DataUpload' x 10 . "\r\n") x 100;
       my $result = UPLOAD_BODY("$location?test=$test", content => $value); 
       ok t_cmp($value, $result, "basic upload");
       my $i;
  
  
  
  1.12      +148 -101  httpd-apreq-2/glue/perl/xsbuilder/Apache/Upload/Apache__Upload.h
  
  Index: Apache__Upload.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Upload/Apache__Upload.h,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Apache__Upload.h	2 Jul 2004 17:08:30 -0000	1.11
  +++ Apache__Upload.h	3 Jul 2004 15:45:53 -0000	1.12
  @@ -13,7 +13,6 @@
   **  See the License for the specific language governing permissions and
   **  limitations under the License.
   */
  -#include "apr_optional.h"
   
   /* avoid namespace collisions from perl's XSUB.h */
   #include "modperl_perl_unembed.h"
  @@ -21,69 +20,6 @@
   /* XXX modperl_* dependency for T_HASHOBJ support */
   #include "modperl_common_util.h"
   
  -
  -/* Temporary work-around for missing apr_perlio.h file.
  - * #include "apr_perlio.h" 
  - */
  -#ifndef APR_PERLIO_H
  -
  -#ifdef PERLIO_LAYERS
  -#include "perliol.h"
  -#else 
  -#include "iperlsys.h"
  -#endif
  -
  -#include "apr_portable.h"
  -#include "apr_file_io.h"
  -#include "apr_errno.h"
  -
  -#ifndef MP_SOURCE_SCAN
  -#include "apr_optional.h"
  -#endif
  -
  -/* 5.6.0 */
  -#ifndef IoTYPE_RDONLY
  -#define IoTYPE_RDONLY '<'
  -#endif
  -#ifndef IoTYPE_WRONLY
  -#define IoTYPE_WRONLY '>'
  -#endif
  -
  -typedef enum {
  -    APR_PERLIO_HOOK_READ,
  -    APR_PERLIO_HOOK_WRITE
  -} apr_perlio_hook_e;
  -
  -void apr_perlio_init(pTHX);
  -
  -/* The following functions can be used from other .so libs, they just
  - * need to load APR::PerlIO perl module first
  - */
  -#ifndef MP_SOURCE_SCAN
  -
  -#ifdef PERLIO_LAYERS
  -PerlIO *apr_perlio_apr_file_to_PerlIO(pTHX_ apr_file_t *file, apr_pool_t *pool,
  -                                      apr_perlio_hook_e type);
  -APR_DECLARE_OPTIONAL_FN(PerlIO *,
  -                        apr_perlio_apr_file_to_PerlIO,
  -                        (pTHX_ apr_file_t *file, apr_pool_t *pool,
  -                         apr_perlio_hook_e type));
  -#endif /* PERLIO_LAYERS */
  -
  -
  -SV *apr_perlio_apr_file_to_glob(pTHX_ apr_file_t *file, apr_pool_t *pool,
  -                                apr_perlio_hook_e type);
  -APR_DECLARE_OPTIONAL_FN(SV *,
  -                        apr_perlio_apr_file_to_glob,
  -                        (pTHX_ apr_file_t *file, apr_pool_t *pool,
  -                         apr_perlio_hook_e type));
  -#endif /* MP_SOURCE_SCAN */
  -
  -#endif /*APR_PERLIO_H*/
  -
  -
  -
  -
   #define apreq_xs_upload_error_check   do {                              \
       int n = PL_stack_sp - (PL_stack_base + ax - 1);                     \
       apreq_request_t *req;                                               \
  @@ -291,6 +227,7 @@
       }
       XSRETURN_IV((IV)len);
   }
  +
   static XS(apreq_xs_upload_type)
   {
       dXSARGS;
  @@ -315,60 +252,170 @@
       XSRETURN(1);
   }
   
  -static APR_OPTIONAL_FN_TYPE(apr_perlio_apr_file_to_glob) *f2g;
  +static XS(apreq_xs_upload_brigade_copy)
  +{
  +    dXSARGS;
  +    apr_bucket_brigade *bb, *bb_copy;
  +    char *class;
  +
  +    if (items != 2 || !SvPOK(ST(0)) || !SvROK(ST(1)))
  +        Perl_croak(aTHX_ "Usage: Apache::Upload::Brigade->new($bb)");
  +
  +    class = SvPV_nolen(ST(0));
  +    bb = (apr_bucket_brigade *)SvIVX(SvRV(ST(1)));
  +    bb_copy = apr_brigade_create(bb->p,bb->bucket_alloc);
  +    APREQ_BRIGADE_COPY(bb_copy, bb);
   
  -static XS(apreq_xs_upload_fh)
  +    ST(0) = sv_2mortal(sv_setref_pv(newSV(0), class, bb_copy));
  +    XSRETURN(1);
  +}
  +
  +static XS(apreq_xs_upload_brigade_read)
   {
       dXSARGS;
  -    MAGIC *mg;
  -    void *env;
       apr_bucket_brigade *bb;
  +    apr_bucket *e, *end;
  +    IV want = -1, offset = 0;
  +    SV *sv;
       apr_status_t s;
  -    apr_off_t len;
  -    apr_file_t *file;
  +    char *buf;
   
  -    if (items != 1 || !SvROK(ST(0)))
  -        Perl_croak(aTHX_ "Usage: $upload->fh()");
  +    switch (items) {
  +    case 4:
  +        offset = SvIV(ST(3));
  +    case 3:
  +        want = SvIV(ST(2));
  +    case 2:
  +        sv = ST(1);
  +        bb = (apr_bucket_brigade *)SvIVX(SvRV(ST(0)));
  +        break;
  +    default:
  +        Perl_croak(aTHX_ "Usage: $bb->READ($buf,$len,$off)");
  +    }
   
  -    if (!(mg = mg_find(SvRV(ST(0)), PERL_MAGIC_ext)))
  -        Perl_croak(aTHX_ "$upload->fh(): can't find env");
  +    if (want == 0)
  +        XSRETURN_IV(0);
   
  -    env = mg->mg_ptr;
  -    bb = apreq_xs_sv2param(ST(0))->bb;
  -    file = apreq_brigade_spoolfile(bb);
  +    if (APR_BRIGADE_EMPTY(bb))
  +        XSRETURN_UNDEF;
   
  -    if (file == NULL) {
  -        apr_bucket *last;
  -        const char *tmpdir = apreq_env_temp_dir(env, NULL);
  -
  -        s = apreq_file_mktemp(&file, apreq_env_pool(env), tmpdir);
  -
  -        if (s != APR_SUCCESS) {
  -            apreq_log(APREQ_ERROR s, env, "apreq_xs_upload_fh:"
  -                      "apreq_file_mktemp failed");
  -            Perl_croak(aTHX_ "$upload->fh: can't make tempfile");
  -        }
   
  -        s = apreq_brigade_fwrite(file, &len, bb);
  +    if (want == -1) {
  +        const char *data;
  +        apr_size_t dlen;
  +        e = APR_BRIGADE_FIRST(bb);
  +        s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
  +        if (s != APR_SUCCESS)
  +            apreq_xs_croak(aTHX_ newHV(), s, 
  +                           "Apache::Request::Upload::Brigade::READ "
  +                           "apr_bucket_read failed", "APR::Error");
  +        want = dlen;
  +        end = APR_BUCKET_NEXT(e);
  +    }
  +    else {
  +        switch (s = apr_brigade_partition(bb, (apr_off_t)want, &end)) {
  +            apr_off_t len;
   
  -        if (s != APR_SUCCESS) {
  -            apreq_log(APREQ_ERROR s, env, "apreq_xs_upload_fh:"
  -                      "apreq_brigade_fwrite failed");
  -            Perl_croak(aTHX_ "$upload->fh: can't write brigade to tempfile");
  +        case APR_INCOMPLETE:
  +            s = apr_brigade_length(bb, 1, &len);
  +            if (s != APR_SUCCESS)
  +                apreq_xs_croak(aTHX_ newHV(), s, 
  +                               "Apache::Request::Upload::Brigade::READ "
  +                               "apr_brigade_length failed", "APR::Error");
  +            want = len;
  +
  +        case APR_SUCCESS:
  +            break;
  +
  +        default:
  +            apreq_xs_croak(aTHX_ newHV(), s, 
  +                           "Apache::Request::Upload::Brigade::READ "
  +                           "apr_brigade_partition failed", "APR::Error");
           }
  +    }
   
  -        last = apr_bucket_file_create(file, len, 0, bb->p, bb->bucket_alloc);
  -        APR_BRIGADE_INSERT_TAIL(bb, last);
  +    SvUPGRADE(sv, SVt_PV);
  +    SvGROW(sv, want + offset + 1);
  +    buf = SvPVX(sv) + offset;
  +    SvCUR_set(sv, want + offset);
  +
  +    while ((e = APR_BRIGADE_FIRST(bb)) != end) {
  +        const char *data;
  +        apr_size_t dlen;
  +        s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
  +        if (s != APR_SUCCESS)
  +            apreq_xs_croak(aTHX_ newHV(), s, 
  +                           "Apache::Request::Upload::Brigade::READ "
  +                           "apr_bucket_read failed", "APR::Error");
  +        memcpy(buf, data, dlen);
  +        buf += dlen;
  +        apr_bucket_delete(e);
       }
   
  -    /* Reset seek pointer before passing apr_file_t to perl. */
  -    len = 0;
  -    apr_file_seek(file, 0, &len);
  +    *buf = 0;
  +    SvPOK_only(sv);
  +    XSRETURN_IV(want);
  +}
   
  -    /* Should we pass a dup(2) of the file instead? */
  -    ST(0) = f2g(aTHX_ file, bb->p, APR_PERLIO_HOOK_READ);
  -    XSRETURN(1);
  +static XS(apreq_xs_upload_brigade_readline)
  +{
  +    dXSARGS;
  +    apr_bucket_brigade *bb;
  +    apr_bucket *e;
  +    SV *sv;
  +    apr_status_t s;
  +
  +    if (items != 1 || !SvROK(ST(0)))
  +        Perl_croak(aTHX_ "Usage: $bb->READLINE");
  +
  +    bb = (apr_bucket_brigade *)SvIVX(SvRV(ST(0)));
  +
  +    if (APR_BRIGADE_EMPTY(bb))
  +        XSRETURN(0);
  +
  +    XSprePUSH;
  +
  +    sv = sv_2mortal(newSVpvn("",0));
  +    XPUSHs(sv);
  +
  +    while (!APR_BRIGADE_EMPTY(bb)) {
  +        const char *data;
  +        apr_size_t dlen;
  +        const char *eol;
  +
  +        e = APR_BRIGADE_FIRST(bb);
  +        s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
  +        if (s != APR_SUCCESS)
  +            apreq_xs_croak(aTHX_ newHV(), s, 
  +                           "Apache::Request::Upload::Brigade::READLINE "
  +                           "apr_bucket_read failed", "APR::Error");
  +
  +        eol = memchr(data, '\012', dlen); /* look for LF (linefeed) */
  +
  +        if (eol != NULL) {
  +            if (eol < data + dlen - 1) {
  +                dlen = eol - data + 1;
  +                apr_bucket_split(e, dlen);
  +            }
  +
  +            sv_catpvn(sv, data, dlen);
  +            apr_bucket_delete(e);
  +
  +            if (GIMME_V != G_ARRAY || APR_BRIGADE_EMPTY(bb))
  +                break;
  +
  +            sv = sv_2mortal(newSVpvn("",0));
  +            XPUSHs(sv);
  +        }
  +        else {
  +            sv_catpvn(sv, data, dlen);
  +            apr_bucket_delete(e);
  +        }
  +    }
  +
  +    PUTBACK;
   }
  +
   
   static XS(apreq_xs_upload_tempname)
   {
  
  
  
  1.6       +11 -0     httpd-apreq-2/glue/perl/xsbuilder/Apache/Upload/Upload_pm
  
  Index: Upload_pm
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Upload/Upload_pm,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Upload_pm	1 Jul 2004 12:34:53 -0000	1.5
  +++ Upload_pm	3 Jul 2004 15:45:53 -0000	1.6
  @@ -5,6 +5,14 @@
   use APR::Error;
   use Apache::Request;
   
  +package Apache::Upload;
  +sub fh {
  +    my $upload = shift;
  +    my $fh = do {local *FH};
  +    tie *$fh, "Apache::Upload::Brigade", $upload->bb;
  +    return $fh;
  +}
  +
   package Apache::Upload::Error;
   push our(@ISA), "APR::Error";
   
  @@ -18,3 +26,6 @@
           *{$_} = sub {die __PACKAGE__ ."::",  "$_: unsafe operation"};
       }
   }
  +
  +package Apache::Upload::Brigade;
  +push our(@ISA), "APR::Brigade";
  
  
  
  1.26      +6 -1      httpd-apreq-2/glue/perl/xsbuilder/maps/apreq_functions.map
  
  Index: apreq_functions.map
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/maps/apreq_functions.map,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- apreq_functions.map	2 Jul 2004 17:05:45 -0000	1.25
  +++ apreq_functions.map	3 Jul 2004 15:45:53 -0000	1.26
  @@ -27,7 +27,6 @@
    DEFINE_link                     | apreq_xs_upload_link |
    DEFINE_slurp                    | apreq_xs_upload_slurp |
    DEFINE_size                     | apreq_xs_upload_size |
  - DEFINE_fh                       | apreq_xs_upload_fh |
    DEFINE_type                     | apreq_xs_upload_type |
    DEFINE_tempname                | apreq_xs_upload_tempname |
   
  @@ -37,6 +36,12 @@
   
   MODULE=Apache::Upload PACKAGE=Apache::Request PREFIX=Apache__Request_
    DEFINE_upload  | apreq_xs_upload_get |
  +
  +MODULE=Apache::Upload PACKAGE=Apache::Upload::Brigade PREFIX=Apache__Upload__Brigade_
  + DEFINE_new | apreq_xs_upload_brigade_copy |
  + DEFINE_TIEHANDLE | apreq_xs_upload_brigade_copy |
  + DEFINE_READ | apreq_xs_upload_brigade_read |
  + DEFINE_READLINE | apreq_xs_upload_brigade_readline |
   
   ##########  Apache::Cookie:: Functions  ##########
   
  
  
  

Mime
View raw message