ID: 26788
Updated by: [EMAIL PROTECTED]
Reported By: d-alvarez at gmx dot de
-Status: Open
+Status: Feedback
-Bug Type: Reproducible crash
+Bug Type: *General Issues
Operating System: GNU/Linux 2.4.21-144-default
PHP Version: 4.3.4
New Comment:
What apache version?
Previous Comments:
------------------------------------------------------------------------
[2004-01-04 18:18:40] d-alvarez at gmx dot de
Description:
------------
Take any html page that uploads a file using HTTP post.
It does not matter what the receiving script does, because
this issue is only related to the interpreter. A page as
simple as the following suffices to reproduce the problem:
<html><body>
<form method="post" enctype="multipart/form-data"
action="http://www.somesite.org/somescript.php">
<input name="somefile" type=file><input type="submit">
</form>
</body>
</html>
Change the form's action to some script on a php server.
I have placed an echo in it, so I can see more easily if
the script is run. And, of course, it should use the file
posted, so that we can get an error if it does not find
it. You can use this:
<?php
echo "the script has been started";
is_uploaded_file ($somefile);
?>
Now use the html page to upload a file sufficiently large
enough for the upload to take several seconds to complete.
While the data is being submitted, load the script a second
time in another instance of your browser, and post the same
file again (in parallel to the first post running in the
background). I use a file 824 kb in size. Transmitted over
ISDN, the two posts take like two minutes of time to
complete. The file was a zip archive.
Now, while the server is handling the two uploads concurrently, get a
listing of the directory it uses to
store the temporary files. You can watch the two
uploading files growing until both uploads complete.
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 228
-rw------- 1 wwwrun www 114688 2004-01-04 23:09 phpHh9HQ9
-rw------- 1 wwwrun www 110592 2004-01-04 23:09 phpp9QIDj
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 360
-rw------- 1 wwwrun www 180224 2004-01-04 23:10 phpHh9HQ9
-rw------- 1 wwwrun www 180224 2004-01-04 23:10 phpp9QIDj
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 572
-rw------- 1 wwwrun www 299008 2004-01-04 23:10 phpHh9HQ9
-rw------- 1 wwwrun www 278528 2004-01-04 23:10 phpp9QIDj
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 1528
-rw------- 1 wwwrun www 790528 2004-01-04 23:12 phpHh9HQ9
-rw------- 1 wwwrun www 765952 2004-01-04 23:12 phpp9QIDj
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 1664
-rw------- 1 wwwrun www 844067 2004-01-04 23:13 phpHh9HQ9
-rw------- 1 wwwrun www 844067 2004-01-04 23:13 phpp9QIDj
Now, with both files being uploaded, two scripts begin
to execute, one for each file. Subsequent directory
listings will show the temporary files being deleted
as the php scripts complete.
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 832
-rw------- 1 wwwrun www 844067 2004-01-04 23:13 phpp9QIDj
(first file has been deleted automatically,
because script started first has completed processing)
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 0
(second file has been deleted automatically,
because script started last has completed processing)
This is the situation as it should be. Now place an .htaccess file into
a directoy above the directory
containing your script. The .htaccess file should usually
cause your browser to ask you for some realm and password,
and then ask you to commit, e.g. by clicking an OK button.
Again, start two posts in parallel, but do not yet
commit the authorization dialogue shown to you in
response to the .htaccess file.
The files are uploaded, probably to some temporary
location in memory. While the files get uploaded, get
some listings of your temporary directory, as before.
Neither the system-global /tmp directory, nor the location
used to store temporary php files have any entries, but
the line is busy for exactly as much time as during the
post when there was no .htaccess file yet.
Probably the upload is handled differently by Apache.
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 0
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l /tmp
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch>
Now confirm the authorization dialogue in your browser.
In Internet Explorer, you are shown a single dialogue
for both html pages. Maybe the .htaccess file per se is
irellevant here. I guess the point is that by committing
the dialogue, processing continues synchronously for both
posts. Anyway, by committing, you trigger something on
the server that causes two scripts to execute at exactly
the same time, one for each upload.
Quickly after committing, get some directory listings, as
before. You'll get something along the lines of:
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 32
--w------- 1 wwwrun www 32768 2004-01-05 00:02 phpu7oZqm
The bottom line is: one file instead of two. You can
watch it growing as in the first example, but there is
no second temporary file. Furthermore, one of the scripts
has been started immediately, without waiting for the
upload to complete. If you tried to use the file within
the script, it will barf out some error.
Ocassionally, even the second script will not complete
properly, complaining about the uploaded file being
corrupted. Probably this script is also started without
waiting for the upload to complete.
Reproduce code:
---------------
See above.
Expected result:
----------------
Two files being uploaded, and two instances of the script
being run after the uploads have completed.
Actual result:
--------------
Only a single file being uploaded, and one instance of
the script being run before the upload is completed.
Sometimes even the second instance of the script is run
while the upload is still in progress.
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=26788&edit=1