Welcome to WebmasterWorld Guest from 54.197.94.141

Forum Moderators: coopster & jatar k & phranque

Message Too Old, No Replies

Using PERL to create a file upload script

but it save with original file name

   
2:00 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



I basically copied the upload script out of the CGI.pm book, but in the example it just saved statically to "saved_file.out" and I want to have it remotely save with the original file name. Using pattern matching I can strip the full path down to just the file name, but it wont save to it!
Also, when I change the $filename variable to anything else, it saves fine. There's just something askew with the variable after the pattern matching.

sub upload_file {
my ($data, $filename);
my $file = param( 'upload' );
my $type = uploadInfo($file)->{'Content-Type'};

if (!$file) {
print "No file uploaded!";
return;
}
($filename = $file) =~ s /^\w.+\\//ig;
print $filename, br;
print $file,br,$type,br;
open (SAVE,">./$filename") die $!;
while (read($file,$data,1024)) {
print SAVE $data;
}
close SAVE;
}

Any ideas?
peace,
~Joe Donahue

2:18 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



<$file>

should return the file on the user's computer. the open() function is for opening files on the server.

2:21 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oops, strike that. I thought you were using it to open the file off the user's computer. So, are you trying to open the file off your server with the same filename as the one the user uploaded?
2:27 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



I guess I should have been a little more specific. It is an upload script, so the OPEN actually creates the file on the server, and the file is read from the local source and then saved to the server, 1024 bytes at a time. The trouble lies in naming the file that is created on the server.
peace,
~Joe Donahue

[edited by: donahuej at 2:44 pm (utc) on Dec. 18, 2004]

2:36 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



[edited for content] Sorry!
peace,
Joe Donahue

[edited by: donahuej at 2:43 pm (utc) on Dec. 18, 2004]

2:39 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Posting URL's is against the TOS of this forum ;)
2:45 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



Thanks for the tip! Any ideas on the file upload script though? :o) j/k, I appreciate your help in my forum etiquette.
3:15 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



So, where does the script save the file?
4:07 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



When I force a name ($filename = "test.jpg") it saves it just fine to the cgi-bin directory, but in its current state it doesnt save it anywhere, and actually terminates the script. I added a link to return to the original page after the block, and the script never gets to it when I use a filename that is pulled from $file.

So weird....

4:44 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Are you using use CGI;?


my $file = param( 'upload' );

should be

$q=new CGI;
$file = $q -> param( 'upload' );
4:47 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



I am using use CGI, however I am not using the object-oriented syntax you posted. I have used that before, but this script is simply the function-oriented syntax. Thanks though!

peace,
~Joe Donahue

4:47 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



also, if you are using CGI, the "my" prefixes should be eliminated.
4:49 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



the "my" prefixes are part of Use Strict, and otherwise work fine (and are encouraged to be used) in scripts.

At least, thats my understanding...

4:54 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



in my experience, use strict and use CGI don't go together.
4:57 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I believe that the problem in the filtering of the filename resides in:

my $type = uploadInfo($file)->{'Content-Type'};
/quote]

If you remove it, the filter works. :-D

4:59 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



that line just finds the MIME type of the file...

I tried it without that line and still had no success. Honestly, thanks for all your help in this so far though.

5:16 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I sticked a url to you
5:26 pm on Dec 18, 2004 (gmt 0)

10+ Year Member



Yeah, and I got it.. bit it looks big and scary, and bigger than what I need! My nice little script works great except for this stupid naming issue!
5:51 pm on Dec 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



hehe... it's not, just documented and certain things for security etc.
6:15 pm on Dec 20, 2004 (gmt 0)

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member



This is using CGI.pm, correct?

I may be off on this part, but try changing

while (read($file,$data,1024))

to

while (read($file,$buffer,1024))

I seem to recall finding $buffer being one of the variables used in CGI.pm that if changed it won't work. (This part may be inaccurate, but it's one variable and you can change it back, try it.)

Secondly, you have verified your substitution indeed grabs the right filename, correct? Beware, this is a double-edged sword - Mac paths do not follow the / syntax. I do something like

@fullpath = split (/\\¦\/¦:/,$file); ## \ for win / for linux : for mac
$filename = $fullpath[$#fullpath]; ## or use pop(@fullpath)

Last thing you could look at is

open (SAVE,">./$filename")

./ from where? I've noticed when working with CGI.pm, your location at the time this bit of code runs is not where you think. I've seen my files turn up in the CGI_temp directory, the server root . . . all kinds of places. Try

$filename = /full_virtual_path/to/$filename;

So all together:

@fullpath = split (/\\¦\/¦:/,$file);
$filename = pop(@fullpath);
$filename = /full_virtual_path/to/$filename;

open (SAVE,">$filename") ¦¦ die $!;
while (read($file,$buffer,1024)) {
print SAVE $buffer;
}
close ($file); ##old habit - maybe bad one but it works
close SAVE;

6:48 pm on Dec 20, 2004 (gmt 0)

10+ Year Member



Thanks for the reponses - some very good things that I will have to keep in mind as I continue to work on this. It is indeed CGI.pm, which I am just picking up but so far am a huge fan of.

The client in this script would be a windows machine, and the host is *nix, so there is no need to accomodate for macintosh. I have verified that the filename it grabs is correct, as far as I can see anyway, and the script uploads and saves a file fine when I force a filename, so I don't really see how it could be a server-side path issue either. You clearly know more about this than I do, but the only thing I can think of is that after I grab the filename there is some null character or something in it that I can't see that is affecting the script's capacity to use it as a valid file name.

I did try using the $buffer var, and that did not seem to change anything.

Thanks for looking into this, and again, if you see something I'm missing, let me know!

peace,
~Joe Donahue

8:14 pm on Dec 20, 2004 (gmt 0)

10+ Year Member



kicking myself....

Thank you all for your help, but it turns out the problem the whole time was that I had Taint checking on
(#!/usr/bin/perl -wT is how I was taught to set up the shebang line) for security reasons, and I guess it was so secure it was protecting it from myself! Sounds like something Microsoft would do....

I thought this might have been the issue pretty early on, but dismissed it since I was convinced it was human error.