joes 2004/07/26 14:08:04
Modified: glue/perl/docs Upload.pod
glue/perl/xsbuilder/Apache/Cookie Apache__Cookie.h
glue/perl/xsbuilder/Apache/Request Apache__Request.h
glue/perl/xsbuilder/Apache/Upload Apache__Upload.h Upload_pm
glue/perl/xsbuilder/maps apreq_functions.map
Log:
Write Upload.pod tests using Apache::Upload::new to create an ad-hoc upload.
The Upload.pod tests may fail on Windows because we rely on POSIX::close(0) to
close fd 0 (ie. stdin).
Revision Changes Path
1.4 +75 -37 httpd-apreq-2/glue/perl/docs/Upload.pod
Index: Upload.pod
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/docs/Upload.pod,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Upload.pod 26 Jul 2004 00:16:01 -0000 1.3
+++ Upload.pod 26 Jul 2004 21:08:04 -0000 1.4
@@ -3,31 +3,46 @@
Apache::Upload - Methods for dealing with file uploads.
=for testing
-ok 1;
-
-=for future testing
+ use POSIX;
use Apache2;
use APR::Pool;
use Apache::Upload;
$r = APR::Pool->new;
$req = Apache::Request->new($r);
- $upload = Apache::Upload->new($r, name => "foo", value => __FILE__);
- $req->body->add($upload);
+ $u = Apache::Upload->new($r, name => "foo", file => __FILE__);
+ eval { POSIX::close(0); $req->parse };
+ $req->body->add($u);
+ $data = do { local (@ARGV, $/) = __FILE__; <> };
=head1 SYNOPSIS
+=for example begin
+
use Apache::Upload;
- my $req = Apache::Request->new($r); # $r is an Apache::RequestRec
- my $upload_table = $req->upload;
- my $upload = $req->upload("file_field"); # same as
$upload_table->{file_field}
- my $size = $upload->size;
- $upload->slurp(my $file_contents);
- my $fh = $upload->fh;
- print while <$fh>;
+ $req = Apache::Request->new($r);
+ $upload = $req->upload("foo");
+ $size = $upload->size;
+
+ # three methods to get at the upload's contents ... slurp, fh, io
+
+ $upload->slurp($slurp_data);
+
+ read $upload->fh, $fh_data, $size;
+
+ $io = $upload->io;
+ print while <$io>;
+
+=for example end
+
+=for example_testing
+ ok $upload->bb->length == $size;
+ is $_STDOUT_, $data;
+ is $fh_data, $data;
+ is $slurp_data, $data;
@@ -59,7 +74,8 @@
The name of the HTML form element which generated the upload.
- my $name = $upload->name;
+=for example_testing
+ is $upload->name, "foo";
@@ -68,9 +84,12 @@
$upload->filename()
-The filename of the uploaded file:
+The (client-side) filename as submitted in the HTML form. Note:
+some agents will submit the file's full pathname, while others
+may submit just the basename.
- my $filename = $upload->filename;
+=for example_testing
+ is $upload->filename, __FILE__;
@@ -100,9 +119,15 @@
syntactic sugar for the underlying C<READ> and C<READLINE> methods from
Apache::Upload::Brigade.
+=for example begin
+
$io = $upload->io;
print while $io->read($_); # equivalent to: tied(*$io)->READ($_)
+=for example end
+
+=for example_testing
+ is $_STDOUT_, $data;
See L<READ|read> and L<READLINE|readline> below for additional notes
on their usage.
@@ -114,10 +139,7 @@
$upload->bb()
$upload->bb($set)
-Returns an I<APR::Brigade> which represents the upload's contents.
-Passing an optional I<APR::Brigade> argument will reassign the
-brigade, which effectively replaces the original contents of the
-upload.
+Get/set the APR::Brigade which represents the upload's contents.
@@ -126,10 +148,10 @@
$upload->size()
+Returns the size of the upload in bytes.
-The size of the upload in bytes:
-
- my $size = $upload->size;
+=for example_testing
+ is $upload->size, -s __FILE__;
@@ -139,24 +161,27 @@
$upload->info()
$upload->info($set)
-The additional header information for the uploaded file.
+Get/set the additional header information table for the
+uploaded file.
Returns a hash reference tied to the I<APR::Table> class.
An optional C<$table> argument can be passed to reassign
the upload's internal (apr_table_t) info table to the one
C<$table> represents.
-Examples:
+=for example begin
my $info = $upload->info;
- while (my($key, $val) = each %$info) {
- ...
+ while (my($hdr_name, $hdr_value) = each %$info) {
+ # ...
}
# fetch upload's Content-Type header
my $type = $upload->info->{"Content-type"};
- #reassign table
- $upload->info($apr_table_object);
+=for example end
+
+=for example_testing
+ is $type, "application/octet-stream";
@@ -167,11 +192,18 @@
Returns the MIME type of the given I<Apache::Upload> object.
+=for example begin
+
my $type = $upload->type;
#same as
- my $type = $upload->info->{"Content-Type"};
- $type =~ s/;.*$//ms;
+ my $content_type = $upload->info->{"Content-Type"};
+ $content_type =~ s/;.*$//ms;
+
+=for example end
+
+=for example_testing
+ is $type, $content_type;
@@ -183,10 +215,14 @@
To avoid recopying the upload's internal tempfile brigade on a
*nix-like system, I<link> will create a hard link to it:
- my $upload = $req->upload('file');
+=for example begin
+
+ my $upload = $req->upload('foo');
$upload->link("/path/to/newfile") or
die sprintf "link from '%s' failed: $!", $upload->tempname;
+=for example end
+
Typically the new name must lie on the same device and partition
as the brigade's tempfile. If this or any other reason prevents
the OS from linking the files, C<link()> will instead
@@ -203,9 +239,9 @@
Reads the full contents of a file upload into the scalar argument.
The return value is the length of the file.
- # print out the upload file
- $upload->slurp(my $contents);
- print $contents;
+=for example_testing
+ is $upload->slurp($contents), -s __FILE__;
+ is $contents, $data;
@@ -216,6 +252,9 @@
Provides the name of the spool file.
+=for example_testing
+ like $upload->tempname, qr/apreq.{6}$/;
+
@@ -231,6 +270,7 @@
+
=head2 TIEHANDLE
Apache::Upload::Brigade->TIEHANDLE($bb)
@@ -273,13 +313,11 @@
-
-
=head1 PORTING from 1.X
=over 4
-=item * C<info($header)> is replaced by C<info($table)>.
+=item * C<info($header_name)> is replaced by C<info($set)>.
=item * C<type()> returns only the MIME-type portion of the Content-Type
header.
1.33 +0 -2
httpd-apreq-2/glue/perl/xsbuilder/Apache/Cookie/Apache__Cookie.h
Index: Apache__Cookie.h
===================================================================
RCS file:
/home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Cookie/Apache__Cookie.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- Apache__Cookie.h 25 Jul 2004 00:30:49 -0000 1.32
+++ Apache__Cookie.h 26 Jul 2004 21:08:04 -0000 1.33
@@ -92,8 +92,6 @@
APREQ_XS_DEFINE_TABLE_GET(table, TABLE_PKG, cookie, COOKIE_PKG, 1);
APREQ_XS_DEFINE_TABLE_FETCH(table, cookie, COOKIE_PKG);
APREQ_XS_DEFINE_TABLE_DO(table, cookie, COOKIE_PKG);
-APREQ_XS_DEFINE_POOL(jar);
-APREQ_XS_DEFINE_POOL(table);
APREQ_XS_DEFINE_TABLE_MAKE(jar, COOKIE_PKG);
APREQ_XS_DEFINE_TABLE_METHOD_N(cookie,set);
1.49 +3 -3
httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Apache__Request.h
Index: Apache__Request.h
===================================================================
RCS file:
/home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Apache__Request.h,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- Apache__Request.h 22 Jul 2004 03:29:09 -0000 1.48
+++ Apache__Request.h 26 Jul 2004 21:08:04 -0000 1.49
@@ -161,9 +161,6 @@
APREQ_XS_DEFINE_TABLE_DO(table, param, NULL);
APREQ_XS_DEFINE_TABLE_NEXTKEY(table);
-APREQ_XS_DEFINE_POOL(request);
-APREQ_XS_DEFINE_POOL(table);
-
APREQ_XS_DEFINE_TABLE_MAKE(request, NULL);
APREQ_XS_DEFINE_TABLE_METHOD_N(param,set);
APREQ_XS_DEFINE_TABLE_METHOD_N(param,add);
@@ -406,6 +403,9 @@
do s = apreq_env_read(req->env, APR_BLOCK_READ, READ_BLOCK_SIZE);
while (s == APR_INCOMPLETE);
+
+ if (req->body == NULL)
+ req->body = apr_table_make(req->env, APREQ_NELTS);
if (GIMME_V != G_VOID)
XSRETURN_IV(s);
1.31 +67 -2
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.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- Apache__Upload.h 25 Jul 2004 05:25:38 -0000 1.30
+++ Apache__Upload.h 26 Jul 2004 21:08:04 -0000 1.31
@@ -108,12 +108,77 @@
APREQ_XS_DEFINE_TABLE_DO(upload_table, param, UPLOAD_PKG);
APREQ_XS_DEFINE_ENV(upload);
-APREQ_XS_DEFINE_POOL(upload_table);
-
APREQ_XS_DEFINE_TABLE_MAKE(request, UPLOAD_PKG);
APREQ_XS_DEFINE_TABLE_METHOD_N(param,add);
APREQ_XS_DEFINE_TABLE_METHOD_N(param,set);
APREQ_XS_DEFINE_TABLE_NEXTKEY(upload_table);
+
+
+
+static XS(apreq_xs_upload_make)
+{
+ dXSARGS;
+ void *env;
+ const char *class, *name, *value, *filename;
+ STRLEN nlen, vlen;
+ apreq_param_t *upload;
+ apr_bucket *b;
+ apr_status_t s;
+ apr_pool_t *p;
+ apr_file_t *f;
+ apr_finfo_t finfo;
+ SV *sv, *obj;
+
+
+ if (items != 5 || SvROK(ST(0)) || !SvROK(ST(1)))
+ Perl_croak(aTHX_ "Usage: Apache::Upload->"
+ "make($env, $name, $value, $filename)");
+
+ class = SvPV_nolen(ST(0));
+ obj = SvRV(ST(1));
+ env = (void *)SvIVX(obj);
+ name = SvPV(ST(2), nlen);
+ value = SvPV(ST(3), vlen);
+ filename = SvPV_nolen(ST(4));
+
+ p = apreq_env_pool(env);
+
+ s = apr_file_open(&f, filename, APR_READ | APR_BINARY, APR_OS_DEFAULT,
p);
+
+ if (s != APR_SUCCESS)
+ goto make_error;
+
+ s = apr_file_info_get(&finfo, APR_FINFO_SIZE, f);
+
+ if (s != APR_SUCCESS)
+ goto make_error;
+
+ upload = apreq_make_param(p, name, nlen, value, vlen);
+
+ upload->bb = apr_brigade_create(p, apr_bucket_alloc_create(p));
+ b = apr_bucket_file_create(f, 0, finfo.size, p,
upload->bb->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(upload->bb, b);
+ b = apr_bucket_immortal_create("", 0, upload->bb->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(upload->bb, b);
+
+ upload->info = apr_table_make(p, APREQ_NELTS);
+ apr_table_addn(upload->info, "Content-Disposition",
+ apr_psprintf(p, "form-data; name=\"%s\"; filename=\"%s\"",
+ name, value));
+ apr_table_addn(upload->info, "Content-Type", "application/octet-stream");
+
+ sv = apreq_xs_2sv(upload, class, obj);
+ ST(0) = sv_2mortal(sv);
+ XSRETURN(1);
+
+ make_error:
+ apreq_xs_croak(aTHX_ newHV(), s,
+ "Apache::Upload::make",
+ "APR::Error");
+
+ XSRETURN_UNDEF;
+}
+
static XS(apreq_xs_upload_link)
1.15 +20 -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.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- Upload_pm 24 Jul 2004 15:10:12 -0000 1.14
+++ Upload_pm 26 Jul 2004 21:08:04 -0000 1.15
@@ -7,6 +7,26 @@
package Apache::Upload;
+# XXX argument wrapper for apreq_xs_upload_make
+sub new {
+ my ($class, $env, %attrs) = @_;
+ my $name = delete $attrs{name};
+ my $value = delete $attrs{value};
+ my $file = delete $attrs{file};
+
+ $name = delete $attrs{-name} unless defined $name;
+ $value = delete $attrs{-value} unless defined $value;
+ $file = delete $attrs{-file} unless defined $name;
+
+ $value = $file unless defined $value;
+
+ die "Usage: Apache::Upload->new($env, name => $name, file=>$file)"
+ unless defined $name and defined $file;
+
+ return $class->make($env, $name, $value, $file);
+}
+
+
sub io {
tie local (*FH), "Apache::Upload::Brigade", shift->bb;
return bless *FH{IO}, "Apache::Upload::IO";
1.36 +2 -7
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.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- apreq_functions.map 24 Jul 2004 15:10:13 -0000 1.35
+++ apreq_functions.map 26 Jul 2004 21:08:04 -0000 1.36
@@ -10,13 +10,12 @@
DEFINE_body | apreq_xs_request_body_get |
DEFINE_config | apreq_xs_request_config |
DEFINE_parse | apreq_xs_request_parse |
- DEFINE_pool | apreq_xs_request_pool |
+
apr_status_t:DEFINE_body_status |
apreq_parse_request(apreq_xs_sv2(request,sv),NULL) | SV *:sv
MODULE=Apache::Request PACKAGE=Apache::Request::Table
PREFIX=Apache__Request__Table_
DEFINE_get | apreq_xs_table_get |
DEFINE_FETCH | apreq_xs_table_FETCH |
- DEFINE_pool | apreq_xs_table_pool |
DEFINE_set | apreq_xs_table_param_set |
DEFINE_STORE | apreq_xs_table_param_set |
DEFINE_add | apreq_xs_table_param_add |
@@ -36,12 +35,11 @@
DEFINE_size | apreq_xs_upload_size |
DEFINE_type | apreq_xs_upload_type |
DEFINE_tempname | apreq_xs_upload_tempname |
- DEFINE_pool | apreq_xs_upload_table_pool |
+ DEFINE_make | apreq_xs_upload_make |
MODULE=Apache::Upload PACKAGE=Apache::Upload::Table
PREFIX=Apache__Upload__Table_
DEFINE_get | apreq_xs_upload_table_get |
DEFINE_FETCH | apreq_xs_upload_table_FETCH |
- DEFINE_pool | apreq_xs_upload_table_pool |
DEFINE_set | apreq_xs_table_param_set |
DEFINE_STORE | apreq_xs_table_param_set |
DEFINE_add | apreq_xs_table_param_add |
@@ -73,7 +71,6 @@
DEFINE_env | apreq_xs_cookie_env |
DEFINE_encode | apreq_xs_encode |
DEFINE_decode | apreq_xs_decode |
- DEFINE_pool | apreq_xs_table_pool |
const char *:DEFINE_name | apreq_cookie_name(c) | apreq_cookie_t *:c
const char *:DEFINE_raw_value| apreq_cookie_value(c) | apreq_cookie_t *:c
apr_status_t:DEFINE_bake | apreq_cookie_bake (apreq_xs_sv2cookie(c),
apreq_xs_sv2env(SvRV(c))) | SV *:c
@@ -84,13 +81,11 @@
DEFINE_env | apreq_xs_jar_env |
DEFINE_cookies | apreq_xs_jar_get |
DEFINE_get | apreq_xs_jar_get |
- DEFINE_pool | apreq_xs_jar_pool |
DEFINE_config | apreq_xs_jar_config |
MODULE=Apache::Cookie PACKAGE=Apache::Cookie::Table
PREFIX=Apache__Cookie__Table_
DEFINE_get | apreq_xs_table_get |
DEFINE_FETCH | apreq_xs_table_FETCH |
- DEFINE_pool | apreq_xs_table_pool |
DEFINE_set | apreq_xs_table_cookie_set |
DEFINE_STORE | apreq_xs_table_cookie_set |
DEFINE_add | apreq_xs_table_cookie_add |