saving an (web) uploaded file in binary format on NT

I am using netscapes (4.04)  file upload form element with the multipart/form-data encoding type to send a file from the client to a directory on the webserver (IIS).  Works great for text files, but binary files (exe, jpg, gif, etc) get 100-200 bytes tacked onto them, cause a network error message to pop up on the client.  Copy actually happens, but file is a wee bit bigger and no longer valid.  I have seen the binmode() function used when the server is sending a binary to the client (like with the FLY graphic program), but I dont know if there is an equivalent for the servers STDIN and the output file on the server.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

as in binmode(STDIN)?
dsweeneyAuthor Commented:
yes, but I suck at all that (better at chopping out sections of code that work and then figuring it our once i've seen it work once).  I gave it a stab on my own binmode(STDIN)
and binmode(OUTFILE) but there is a chunk size parametaer or something that I couldnt get to work.  A working example code would be great, thats why I put up so many points...  Here is my current code, which works great for uploading text files but doesnt work for binary files.  Also tried it first without the binmode statements, that didnt work either.


$upload_dir = "d:\\temp\\incoming\\";
$cgiurl = "/cgi-bin";

#---------------read network input
$len = 0;
$input = '';
while ($len != $ENV{'CONTENT_LENGTH'}) {
      $buf = '';
      $len += sysread(STDIN, $buf, $ENV{'CONTENT_LENGTH'});
      $input .= $buf;

if ($ENV{'CONTENT_TYPE'} =~ /multipart\/form-data; boundary=(.+)$/) {
      $boundary = '--' . $1;
      @list = split(/$boundary/, $input);
      $header_body = $list[1];
      $header_body =~ /\r\n\r\n|\n\n/;  #sep header and body
      $header = $`;
      $body = $';
      $body =~ s/\r\n$//;
      $GLOBAL{'FILE_CONTENT'} = $body;
      #---------------parse header
      $header =~ /filename=\"(.+)\"/;
      $GLOBAL{'FILE_NAME'} = $1;
      $GLOBAL{'FILE_NAME'} =~ s/\"//g;

} #----- end if
#-----------------handle upload
$filename = $GLOBAL{'FILE_NAME'};
$filename =~ s/.+\\([^\\]+)$|.+\/([^\/]+)$/\1/;
$filename =~ tr/A-Z/a-z/;
$write_file = $upload_dir . $filename;

open (OUTFILE, ">$write_file");
close (OUTFILE);

# --------------Send upload complete message
print "Content-type: text/html\n\n";
print <<"endofhtml";
<title>Upload Complete</title>
<font size="3">
<b>Your file <font color=blue>"$filename"<font color=black><br>
has been uploaded.</b>


} else {
#if this page was not the result of a post, just show the form only
print "Content-type: text/html\n\n";
print <<"endofhtml";

<TITLE>File Upload</TITLE>

<FORM NAME="upload" ACTION="$cgiurl/" METHOD=POST enctype="multipart/form-data">
<INPUT TYPE="file" NAME="filename">



Your script worked perfectly for me (IIS 1.0, NS 4.03)... perhaps there's something about your environment. Bug in your perl version? Unlikely, but...
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Wonder if your particular server isn't trying to parse response headers into the file being uploaded? 100 - 200 bytes would be about the size of these.
dsweeneyAuthor Commented:
I am using IIS 3.0, Netscape 4.01.
dsweeneyAuthor Commented:
also same result with IE 4.0.  Sombody has to have the same problem!!
dsweeneyAuthor Commented:
Also I did a view of the binary file in a text editor and there was no "text data" of any sort
so I dont think it is the response header being tacked on
So what were the extra bytes tacked on, and where in the file were they?
I set up your upload script. Access it on my server with the below URL and upload the file you been testing. Then, take the file that has been corrupeted and upload it as "bad.exe" and I'll open it and compare it line by line with the good copy.

dsweeneyAuthor Commented:
Ozo:  I am not that good of a programmer that I understand the binary files and how to compare or what im looking for

Biffo:  wont both versions I upload end up with the extra data since i am using the same script?
dsweeney, I (and everyone else) who has tried your script has reported it works as-is. Therefore it *has* to be something with your system. The most likely culprit is a perl which doesn't implement binmode properly - essentially the questions about the differences and the request to upload the files for someone else to check are attempts to verify this.

You missed my question about which perl version you are using... so what is it? If it's an old version (off the resource kit cdrom, for example) you should get and install the latest from I don't remember hearing of such a bug, but something is strange with your system and a reinstall of perl might help.
dsweeneyAuthor Commented:
alamo:  I am using build 313 (pw32i313) I think, of Activestates 5.003, as well as the IIS DLL (thats whats is associated), same build.  I will try downloading the latest build tonight and reinstall.
>Biffo:  wont both versions I upload end up with the extra data since i am
 > using the same script?

No, the script is on my end and not yours. Just upload the bad file that got corrupted and the clean version of it. I want to see the good and the bad copy. I have a binary file comparison program.  
dsweeneyAuthor Commented:
alamo:  Upgrading to 316 from 313 solved the problem.  I am very grateful.  I would like to split the points 60-40 between alamo/biffo (alamo solved, biffo made a great effort) but I dont even know how to award the points.  There is no placew to click to say "this person solved my problem"....  can I split the points?  Where do I say "xxxx solved it"????

About awarding points:

The way E-E works is that someone must post as an answer (which I am doing) and that is the only person who gets points (normally). They have talked about adding the ability to choose to split points when grading, but for now you must ask to split points in the Customer Service topic area Post the URL of this question and E-E's Linda will answer within a couple of days.

What I expect to happen (what usually happens) then is:

- Linda will add 200 points to your account, with which you can add a new question with "for Biffo" in the title. Biffo will then answer that question, and you'll grade him an A. This will get him 800 quality points, 40% of this question's quality points.

- You'd then grade me a "B" which would give me 75% of the total quality points for this question (it's either 75% or 50%, no way to do 60% unless Linda changes the point amout for this question, which I don't think she can do).

Thanks for making the effort to be fair to everyone, it's always nice when someone appreciates the efforts an expert makes!

Experts Exchange Solution brought to you by ConnectWise

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.