You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Kevin Bosak <ke...@bosak.net> on 2004/02/11 18:40:32 UTC

Re: File uploads using Apache:;request in mod_perl2

I too am having issues with file uploads using mod_perl2.  I've gotten 
the beta of Apache::Request but it looks like from this thread that 
there's not yet a way to retrieve the uploaded file.  Is this true?

Pete Smith wrote:

> Hi,
> 
> I am new to this list, but I have tried looking through the docs at CPAN and
> googling for people with similar problems to no avail.
> 
> We have upgraded our server to apache2 + mod_perl2. I used to have a routine
> that took a file upload from a multipart form and handed it as a stream to
> Imager and Image::Size like so:
> 
> 
> my $image_upload = $r->upload('image');
> my $file_handle = $image_upload->fh();
> 
> read ($file_handle, my $full_image_data, (stat($file_handle))[7]);
> 
> my $imager = Imager->new();
> 
> $imager->open(data => $full_image_data, type => 'jpeg');
> my ($width) = imgsize(\$full_image_data);
> 
> 
> I now know that I could pass the file handle to Imager and Image::Size
> instead of turning into a scalar stream, but that isn't the problem.
> 
> I have discovered that Apache::Request for mod_perl2 has changed the fh
> method to bb, which apparently returns an APR::Brigade (object I presume)
> instead of a file handle. 
> 
> I have looked for documentation for APR::Brigade, but can find none. I have
> no idea what it is!
> 
> Could somebody please point me in the right direction as to how I can
> achieve the above in mod_perl2?
> 
> Thanks,
> Pete
> 
> 


-- 
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


readdir producing NULL results with glicb 2.2

Posted by O'K Web Design <ok...@rogers.com>.
Hi

     I have a problem with readdir returning no values when running with
mod_perl.  I have seen the docs that suggest a rebuild of Perl will help,
which I have done.  I also saw that there might be some issues with glicb
2.2 only with readdir.  I do have a workaround developed but wondered if
anyone had any ideas before hacking my script.  Mike


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: File uploads using Apache:;request in mod_perl2

Posted by Kevin Bosak <ke...@bosak.net>.
I don't know what you did, but it works now!  Thank you so much for your 
time.


Joe Schaefer wrote:

> 
> Try replacing the apreq_xs_upload_link() function in 
> 
>   glue/perl/xsbuilder/Apache/Request/Apache__Request.h
> 
> with the following one; rebuild and install it.  If this 
> doesn't solve your problem, the next release should include more
> helpful diagnostics, but until then CGI.pm is always available.


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: File uploads using Apache:;request in mod_perl2

Posted by Joe Schaefer <jo...@sunstarsys.com>.
Kevin Bosak <ke...@bosak.net> writes:

> Thanks again for the help but still no luck.
> I set the TMPDIR environment variable manually and restarted apache
> but still can't get the upload file in my script and nothing's being
> written to the tmpdir.  If there's anything else I can try please let
> me know but I may just end up having to use CGI.pm for uploads.

Try replacing the apreq_xs_upload_link() function in 

  glue/perl/xsbuilder/Apache/Request/Apache__Request.h

with the following one; rebuild and install it.  If this 
doesn't solve your problem, the next release should include more
helpful diagnostics, but until then CGI.pm is always available.


APR_INLINE
static XS(apreq_xs_upload_link)
{
    dXSARGS;
    MAGIC *mg;
    void *env;
    const char *name, *fname;
    apr_bucket_brigade *bb;
    apr_file_t *f;

    if (items != 2 || !SvROK(ST(0)))
        Perl_croak(aTHX_ "Usage: $upload->link($name)");

    if (!(mg = mg_find(SvRV(ST(0)), PERL_MAGIC_ext)))
        Perl_croak(aTHX_ "$upload->link($name): can't find env");

    env = mg->mg_ptr;
    bb = apreq_xs_rv2param(ST(0))->bb;
    name = SvPV_nolen(ST(1));

    f = apreq_brigade_spoolfile(bb);
    if (f == NULL) {
        apr_off_t len;
        apr_status_t s;
        const apr_int32_t flags = APR_CREATE | APR_EXCL | APR_WRITE |
            APR_READ | APR_BINARY | APR_BUFFERED;

        s = apr_file_open(&f, name, flags,
                          APR_OS_DEFAULT,
                          apreq_env_pool(env));
        if (s != APR_SUCCESS || 
            apreq_brigade_fwrite(f, &len, bb) != APR_SUCCESS)
            XSRETURN_UNDEF;
    
        XSRETURN_YES;
    }
    if (apr_file_name_get(&fname, f) != APR_SUCCESS)
        XSRETURN_UNDEF;

    if (PerlLIO_link(fname, name) >= 0)
        XSRETURN_YES;
    else {
        apr_status_t s = apr_file_copy(fname, name,
                                       APR_OS_DEFAULT, 
                                       apreq_env_pool(env));
        if (s == APR_SUCCESS)
            XSRETURN_YES;
    }

    XSRETURN_UNDEF;
}

-- 
Joe Schaefer


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: File uploads using Apache:;request in mod_perl2

Posted by Kevin Bosak <ke...@bosak.net>.
Thanks again for the help but still no luck.
I set the TMPDIR environment variable manually and restarted apache but 
still can't get the upload file in my script and nothing's being written 
to the tmpdir.  If there's anything else I can try please let me know 
but I may just end up having to use CGI.pm for uploads.

Joe Schaefer wrote:

> At the moment, grepping Mason's source files for TEMP_DIR or TMPDIR is
> probably the only solution.  I don't think the current Apache::Request 
> for mp2 exposes enough of the C API to be of any help to you.
> 
> If you're using glibc, the sledgehammer approach is to have the 
> sysadmin set/export the TMPDIR environment variable prior to server 
> startup, ie.
> 
>   % TMPDIR=/path/to/my/tmpdir apachectl restart
> 
> This will override any TEMP_DIR settings coming from calls to
> Apache::Request::new().
> 


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: File uploads using Apache:;request in mod_perl2

Posted by Joe Schaefer <jo...@sunstarsys.com>.
Kevin Bosak <ke...@bosak.net> writes:

> Thanks for the advice.
> I checked and $upload->link does indeed return false.  I'm guessing
> it's because of something with TEMP_DIR you said, but my lack of
> knowledge is keeping me from getting this resolved.  How do I
> determine what TEMP_DIR has been set to?  

At the moment, grepping Mason's source files for TEMP_DIR or TMPDIR is
probably the only solution.  I don't think the current Apache::Request 
for mp2 exposes enough of the C API to be of any help to you.

> I'm using Mason with ApacheHandler2 that I believe sets up the
> Apache::Request object but I'm still a little unclear on how
> everything fits together.  I could definitely use another "nudge" in
> the right direction.

If you're using glibc, the sledgehammer approach is to have the 
sysadmin set/export the TMPDIR environment variable prior to server 
startup, ie.

  % TMPDIR=/path/to/my/tmpdir apachectl restart

This will override any TEMP_DIR settings coming from calls to
Apache::Request::new().

btw- I'm planning to $upload->link so that it will handle the
cross-device situation more gracefully (by making a full copy 
of the tempfile should the internal PerlLIO_link fail).

-- 
Joe Schaefer


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: File uploads using Apache:;request in mod_perl2

Posted by Kevin Bosak <ke...@bosak.net>.
Thanks for the advice.
I checked and $upload->link does indeed return false.  I'm guessing it's 
because of something with TEMP_DIR you said, but my lack of knowledge is 
keeping me from getting this resolved.  How do I determine what TEMP_DIR 
has been set to?  I'm using Mason with ApacheHandler2 that I believe 
sets up the Apache::Request object but I'm still a little unclear on how 
everything fits together.  I could definitely use another "nudge" in the 
right direction.

Joe Schaefer wrote:
> 
> 
> Three things to check:
> 
>   1) be sure $filename is valid (it really should be marked as tainted),
>   2) be sure "/path/to/local/$filename" is on the same device
>   (filesystem) as your temporary directory (see the docs for 
>   Apache::Request::new regarding TEMP_DIR).
>   3) check the return value of $upload->link, if it's false (undef) then
>      there was a problem- usually the trouble is caused by one of the above.
> 


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: File uploads using Apache:;request in mod_perl2

Posted by Joe Schaefer <jo...@sunstarsys.com>.
Kevin Bosak <ke...@bosak.net> writes:

> I can get the file's name but the upload
> is simply not getting linked/saved.  I'm sure it's probably something
> I'm doing wrong, but I don't know what.  Here's the relevant lines
> from my code: 
> 
>    my $upload = $r->upload('file');
>    my $filename = $upload->filename;
>    $upload->link("/path/to/local/$filename");
> 
> Is there something I can do to troubleshoot this?

Three things to check:

  1) be sure $filename is valid (it really should be marked as tainted),
  2) be sure "/path/to/local/$filename" is on the same device
  (filesystem) as your temporary directory (see the docs for 
  Apache::Request::new regarding TEMP_DIR).
  3) check the return value of $upload->link, if it's false (undef) then
     there was a problem- usually the trouble is caused by one of the above.

-- 
Joe Schaefer


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: File uploads using Apache:;request in mod_perl2

Posted by Kevin Bosak <ke...@bosak.net>.
Thanks for the reply!  But unfortunately I'm not having any luck with 
link either.  I'm using Mason 1.25 which isn't giving any errors and 
there are no errors showing up in the apache logs.  I can get the file's 
name but the upload is simply not getting linked/saved.  I'm sure it's 
probably something I'm doing wrong, but I don't know what.  Here's the 
relevant lines from my code:

   my $upload = $r->upload('file');
   my $filename = $upload->filename;
   $upload->link("/path/to/local/$filename");

Is there something I can do to troubleshoot this?
Any help will be greatly appreciated.

And FYI, I'm using libapreq2-2.02_02-dev.

Joe Schaefer wrote:
> Kevin Bosak <ke...@bosak.net> writes:
> 
> 
>>I too am having issues with file uploads using mod_perl2.  I've gotten
>>the beta of Apache::Request but it looks like from this thread that
>>there's not yet a way to retrieve the uploaded file.  Is this true?
> 
> 
> No, it's not true at all.  If you don't need to read the contents of the
> upload, but just need to store it in a file somewhere, use 
> $upload->link("/path/to/local/file"). If you do need to read the 
> contents, use the APR::Brigade API on $upload->bb. A future version 
> of Apache::Request may have include convenience methods (like slurp(), 
> etc.), but you can certainly get at the uploaded file using the current 
> version.
> 
> The brigade API is a big performance-win for libapreq2, since it allows 
> us to use a zero-copy design on file uploads until the file gets too 
> big to store in memory.  The size limit is currently 256K, but the size
> will be configurable in future versions.
> 


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html


Re: File uploads using Apache:;request in mod_perl2

Posted by Joe Schaefer <jo...@sunstarsys.com>.
Kevin Bosak <ke...@bosak.net> writes:

> I too am having issues with file uploads using mod_perl2.  I've gotten
> the beta of Apache::Request but it looks like from this thread that
> there's not yet a way to retrieve the uploaded file.  Is this true?

No, it's not true at all.  If you don't need to read the contents of the
upload, but just need to store it in a file somewhere, use 
$upload->link("/path/to/local/file"). If you do need to read the 
contents, use the APR::Brigade API on $upload->bb. A future version 
of Apache::Request may have include convenience methods (like slurp(), 
etc.), but you can certainly get at the uploaded file using the current 
version.

The brigade API is a big performance-win for libapreq2, since it allows 
us to use a zero-copy design on file uploads until the file gets too 
big to store in memory.  The size limit is currently 256K, but the size
will be configurable in future versions.

-- 
Joe Schaefer


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html