Re: File Upload Questions

2002-11-15 Thread Issac Goldstand
So far, I've seen two suggestions; both are very good, and I wanted to try
to offer a combination, based on a real implementation.
The relevant parts of the source code for uploading the content (as related
to writing the actual file on the server):

my $r=shift;
my $q=Apache::Request-instance($r);
[snip]
my $File=$q-upload('fid') || undef;
[snip]
my $hFile=$File-fh || undef;
[snip]
my $fLoc=fqName($hMD5);
open(my $DOUT,$fLoc);
binmode $DOUT;
 [snip]
seek($hFile,0,0);
ps_status(Compressing $fname...);
while ($hFile)
{
($output,$status)=$dStream-deflate($_);
$status == Z_OK or die (Error deflating: $status);
print $DOUT $output;
}
($output,$status)=$dStream-flush();
$status==Z_OK or die (Error flushing: $status);
print $DOUT $output;
close $DOUT;

As you can see, this code uses an interim deflate stream, but the loop would
work just as well without it (eg, simply print $DOUT $_; inside the while
loop).

  Issac

PS.  If you want to see the application, feel free to conatct me off-list
and I'll send you the URL.
- Original Message -
From: Dennis Daupert [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Thursday, November 14, 2002 10:47 PM
Subject: File Upload Questions


 I have gotten file upload working using Apache::Request for
 text files. But binary files seem to have other ideas :-)

 For example, uploading a word doc, I get a success message,
 but when I retrieve the doc after uploading it, and try to open it in
 Word 2000, I get the popup error message:

 The document name or path is not valid... etc

 Do I need to do anything to detect the content type of the file and
 set binary versus ascii transfers? The man page for Apache::Request
 talks about type, but not how to set the transfer.

 In case I have done something silly in my code, here is a section in which
 I untaint the filename, and also remove the leading c:\path\to\file info
 (for windows uploads) or similar /path/to/file for unix uploads:

 # now let's untaint the filename itself
 if ($data{'up_filename'} =~ /^([-\@\/\w\:\\.]+)$/) {
 $data{'up_filename'} = $1;
 my $cleanfile = $data{'up_filename'};
 $cleanfile = $1; # $cleanfile now untainted
 $cleanfile =~ s#\.\.##g;
 $cleanfile =~ s[//][/]g;
  # take out windows backslashes
  if ($cleanfile =~ /\\/) {
   my @parts = split ( /\\/, $cleanfile );
  $cleanfile = pop @parts;
}
# take out unix forward slashes
if ($cleanfile =~ /\//) {
my @parts = split ( /\//, $cleanfile );
   $cleanfile = pop @parts;
}
 $data{'up_filename'} = $cleanfile;
 }

 And then:

 my $fh = $upload-fh;
 my @file = $fh;

 open ( WRITEFILE, $data{'write_dir'}/$data
 {'up_filename'} ) or die couldn't open $data{'up_filename'} for writing:
 $! \n;
  print WRITEFILE @file;
 close (WRITEFILE);

 Any insight greatly appreciated.

 /dennis

 --
-
 Office phone: 817-762-8304

 --
-
  Great leaders never tell people how to do their jobs.
Great leaders tell people what to do and establish a
  framework within which it must be done.
   Then they let people on the front lines,
who know best, figure out how to get it done.
 ~ General H. Norman Schwarzkopf








Re: File Upload Questions

2002-11-15 Thread Dennis Daupert
Thanks all for the suggestions;  I really appreciate the help.
I will tuck BINMODE away for future reference.

Before I got those ideas, while digging around in the mailing
list archives I found a reference to the link function in
Apache::Request that creates a hard symlink to a specified
path from the uploaded temp file, thus:

  my $upload = $apr-upload('file');
  $upload-link(/path/to/newfile) or
  die sprintf link from '%s' failed: $!, $upload-tempname;

I tried that last night, and it works great.

Makes me a believer in checking the archives.

/dennis


---
Office phone: 817-762-8304

---
 Great leaders never tell people how to do their jobs.
   Great leaders tell people what to do and establish a
 framework within which it must be done.
  Then they let people on the front lines,
   who know best, figure out how to get it done.
~ General H. Norman Schwarzkopf







File Upload Questions

2002-11-14 Thread Dennis Daupert
I have gotten file upload working using Apache::Request for
text files. But binary files seem to have other ideas :-)

For example, uploading a word doc, I get a success message,
but when I retrieve the doc after uploading it, and try to open it in
Word 2000, I get the popup error message:

The document name or path is not valid... etc

Do I need to do anything to detect the content type of the file and
set binary versus ascii transfers? The man page for Apache::Request
talks about type, but not how to set the transfer.

In case I have done something silly in my code, here is a section in which
I untaint the filename, and also remove the leading c:\path\to\file info
(for windows uploads) or similar /path/to/file for unix uploads:

# now let's untaint the filename itself
if ($data{'up_filename'} =~ /^([-\\/\w\:\\.]+)$/) {
$data{'up_filename'} = $1;
my $cleanfile = $data{'up_filename'};
$cleanfile = $1; # $cleanfile now untainted
$cleanfile =~ s#\.\.##g;
$cleanfile =~ s[//][/]g;
 # take out windows backslashes
 if ($cleanfile =~ /\\/) {
  my parts = split ( /\\/, $cleanfile );
 $cleanfile = pop parts;
   }
   # take out unix forward slashes
   if ($cleanfile =~ /\//) {
   my parts = split ( /\//, $cleanfile );
  $cleanfile = pop parts;
   }
$data{'up_filename'} = $cleanfile;
}

And then:

my $fh = $upload-fh;
my file = $fh;

open ( WRITEFILE, $data{'write_dir'}/$data
{'up_filename'} ) or die couldn't open $data{'up_filename'} for writing:
$! \n;
 print WRITEFILE file;
close (WRITEFILE);

Any insight greatly appreciated.

/dennis

---
Office phone: 817-762-8304

---
 Great leaders never tell people how to do their jobs.
   Great leaders tell people what to do and establish a
 framework within which it must be done.
  Then they let people on the front lines,
   who know best, figure out how to get it done.
~ General H. Norman Schwarzkopf







Re: File Upload Questions

2002-11-14 Thread Randy Kobes
On Thu, 14 Nov 2002, Dennis Daupert wrote:

 I have gotten file upload working using Apache::Request for
 text files. But binary files seem to have other ideas :-)
 
 For example, uploading a word doc, I get a success message,
 but when I retrieve the doc after uploading it, and try to open it in
 Word 2000, I get the popup error message:
 
 The document name or path is not valid... etc
 
 Do I need to do anything to detect the content type of the file and
 set binary versus ascii transfers? The man page for Apache::Request
 talks about type, but not how to set the transfer.
 
 In case I have done something silly in my code, here is a section in which
 I untaint the filename, and also remove the leading c:\path\to\file info
 (for windows uploads) or similar /path/to/file for unix uploads:
[ .. ] 
 And then:
 my $fh = $upload-fh;
 my file = $fh;
 open ( WRITEFILE, $data{'write_dir'}/$data
 {'up_filename'} ) or die couldn't open $data{'up_filename'} for writing:
 $! \n;
  print WRITEFILE file;
 close (WRITEFILE);

For binary docs, would a
 binmode WRITEFILE;
before the print statement help?

-- 
best regards,
randy kobes




Re: File Upload Questions

2002-11-14 Thread David Kaufman
Dennis Daupert [EMAIL PROTECTED] wrote:

 I have gotten file upload working using Apache::Request for
 text files. But binary files seem to have other ideas :-)

 For example, uploading a word doc, I get a success message,
 but when I retrieve the doc after uploading it, and try to open it in
 Word 2000, I get the popup error message:

 The document name or path is not valid... etc [...]

 In case I have done something silly in my code, [...]

you may have done one silly thing :-)

 my $fh = $upload-fh;
 my @file = $fh;

here you slurp the lines of the text file into the @file array

 print WRITEFILE @file;

and here you put the @file array into double-quotes.  normal string
interpolation of an array is to join together the elements of the array,
separated by a *space*.  this is not what you wanted to do.

for instance, this code:

@a=('a','b','c');
print @a;

prints: a b c instead of abc

while:

@a=('a','b','c');
print @a;

prints: abc

so you should try:

  print WRITEFILE @file;  # without the quotes


instead and see if that works.

hth,

-dave