[Webkit-unassigned] [Bug 5760] Safari hangs when uploading files to certain php scripts

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Sun Jan 7 13:24:42 PST 2007


http://bugs.webkit.org/show_bug.cgi?id=5760





------- Comment #38 from ddkilzer at webkit.org  2007-01-07 13:24 PDT -------
Summary
-------

There are two issues that I discovered while researching Bug 5760.  The first
is an inefficiency in the network layer, and the second is the cause of this
bug which apparently depends upon the first issue.  See the "Notes" section
below for more details on each issue.

Issue #1 - Foundation classes attempt to use a half-closed connection after a
keep-alive connection has expired.

Issue #2 - When an HTML form with a file upload is submitted through Safari and
a half-closed connection is used (Issue #1), the Foundation classes fail to
resend the contents of the file to the web server the second time the form data
is posted.


Setup Instructions
------------------

The following instructions use the local Apache web server installed for
Personal Web Sharing and the current user's ~/Sites/ directory to reproduce the
two issues above.

1. Download the bug-5760-test-files.tar.gz file in Attachment 12286.

2. Extract the tar.gz file to the current user's ~/Sites/ directory.

3. Edit bug-5760.conf to replace "USERNAME" in the <Directory> directive with
the current user's username.

4. Move bug-5760.conf to the /etc/httpd/users/ directory on Tiger, or
/etc/apache2/other/ on Leopard.  (You'll need to use sudo(1) to do this.)

5. Open System Preferences.

6. Click on Sharing under Internet & Network.

7. Start Personal File Sharing.  (If it's already been started, stop and start
it to pick up the new config file.)


Steps to Reproduce
------------------

The following instructions describe how to reproduce Issue #2 above.  It will
also reproduce Issue #1 if no file is specified in the file upload input, but
this is only meaningful if you're capturing a packet trace of the connection(s)
using a tool like Ethereal/Wireshark.

1. Close Safari (or WebKit) if it's currently open.

2. Delete the icon database file, or rename it if you want to keep your prized
collection of favicons.  (This step is a red herring since this bug has nothing
to do with the icon database.  This step is done to guarantee that a keep-alive
connection will be created when Safari attempts to load the favicon.ico file
from the web site.  In real-life scenarios, <img> tags on the page could create
keep-alive connections as well.)

3. Start Safari.

4. Open URL to bug-5760.html (replace "HOSTNAME" with the hostname or IP
address of your Mac, and replace "USERNAME" with the current user's username): 
http://HOSTNAME/~USERNAME/bug-5760.html

5. Quickly pick ANY file to upload in the file upload input before the counter
reaches zero.  (You have less than 19 seconds.)

6. Wait for the countdown to reach zero and the form to submit itself.


Expected Results
----------------

The form should be submitted to the server with the contents of the uploaded
file.


Actual Results
--------------

Submitting the form hangs.  When the web server's connection timeout is reached
(usually 5 minutes), it will return an internal server error.


Regression
----------

These issues have been reproduced with the following software on a PowerBook
G4:

Mac OS X 10.4.8 (8L127) with Safari 2.0.4 (419.3) and Apache/1.3.33 (Darwin).
Mac OS X 10.4.8 (8L127) with ToT WebKit (r18639), Safari 2.0.4 (419.3) and
Apache/1.3.33 (Darwin).
Mac OS X Leopard (9A321) with Safari 3.0 (521.31.1) and Apache/2.2.3 (Unix).

And with the following software on a MacBook Pro Core 2 Duo:

Mac OS X 10.4.8 (8N1037) with Safari 2.0.4 (419.3) and Apache/1.3.33 (Darwin).


Notes
-----

Issue #1 - Foundation classes attempt to use a half-closed connection after a
keep-alive connection has expired.

NOTE: The information below is based on the behavior I saw in packet traces
captured using Ethereal/Wireshark while researching Issue #2.  I did not
attempt to step through, decompile or write test programs for the Foundation
classes to prove or to disprove the following information.

Here is a basic outline of what happens:

1. User uses Safari to request a web page with a form.
2. At least one connection to the server is kept alive after the web page,
resources (images) and favicon are loaded.
3. User fills out the form.
4. User waits just long enough for the server to close it's half of the
kept-alive connection (server sends FIN,ACK; OS X sends ACK), but before OS X
closes its half of the connection.
5. User submits the form in Safari.
6. Safari uses Foundation classes to send form data.
7. Server sends an RST packet to reset the connection.
8. Foundation classes open a new connection to the server and resend the form
data.

The above process works fine in all cases except when a file upload is included
in the form (Issue #2).  However, note that Firefox 2.0.0.1 (running on the
same version of Mac OS X on the same hardware) will close its half of the
connection immediately after the server closes its half of the connection,
thereby avoiding the inefficiencies of attempting to use a half-closed
connection to the server.


Issue #2 - When an HTML form with a file upload is submitted through Safari and
a half-closed connection is used (Issue #1), the Foundation classes fail to
resend the contents of the file to the web server the second time the form data
is posted.

The outline of what happens is essentially identical to Issue #1, except that
(1) a file upload input is included in the form and (2) when the form is
resent, the contents of the uploaded file are not sent the second time the form
data is sent:

1. User uses Safari to request a web page with a form that contains a file
upload input.
2. At least one connection to the server is kept alive after the web page,
resources (images) and favicon are loaded.
3. User fills out the form including the file upload input.
4. User waits just long enough for the server to close it's half of the
kept-alive connection (server sends FIN,ACK; OS X sends ACK), but before OS X
closes its half of the connection.
5. User submits the form in Safari.
6. Safari uses Foundation classes to send form data including the contents of
the uploaded file.
7. Server sends an RST packet to reset the connection.
8. Foundation classes open a new connection to the server and resend the form
data, but the contents of the uploaded file are not sent the second time.
9. If Safari and the server are left alone, the server waits until its
connection timeout expires (commonly 300 seconds for a default Apache
installation; see Timeout directive in httpd.conf), then sends an Internal
Server Error since it never received the contents of the uploaded file in the
second request.

This is the original reason this bug was filed.

Note that I've only been able to reproduce Issue #2 using a local Apache web
server.  When I attempt to duplicate the above steps using an external site
(such as the file upload form on http://validator.w3.org/), there are five RST
packets sent in step 7, and the contents of the uploaded file are sent in Step
8.

Finally, if you have trouble reproducing the issue:

- You can try playing with the 'fudgeFactor' variable in bug-5760.html.  An
integer value from 2 to 5 (seconds) should work for most configurations.

- The easiest way to make sure you're reproducing the bug is to install
Wireshark through fink or MacPorts (formerly DarwinPorts).  While capturing
packets, watch for a tell-tale increase of two in the TCP packet count after
the 15-second keep-alive connection expires, then submit the form manually
immediately after that.  (NOTE: Installing either of these requires installing
Xcode and X11 on your Mac.  I tried building Wireshark using GTK+ for OS X, but
it crashes in font code in Cairo.)

- Sometimes the bug is reproducible repeatedly for a while without stopping
Safari.  However, if it stops becoming repeatable, stop Safari, delete the icon
database, than restart Safari (e.g., follow the instructions provided above).


-- 
Configure bugmail: http://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.



More information about the webkit-unassigned mailing list