499 errors in IE9 causing order duplicates

We use nginx to reverse proxy to a farm of apache servers. It rocks.
But we’ve noticed that Internet Explorer 9 has been generating duplicate
orders. It does not happen every time, but often enough. It appears to
be an IE 9 issue, but I’m hoping the experts here can confirm my theory:

A request comes from an IE 9 client. Nginx passes the request to an
upstream apache server. For some reason, the IE 9 browser closes the
connection before the apache server returns results with return code
200. Nginx sees a closed connection, and generates a 499 error (client
problem, connection closed). IE 9 sees that, and immediately re-sends
the request. Nginx forwards to apache, receives the response, and
forward to the client, logging a 200. Log results are below

Does this seem correct? Anyone else seeing this behavior? Any
suggestions for a graceful way to handle this? (Duplicate orders BAD)
Thanks,

      -Paleo

On nginx, we see:

XX.XX.XX.XX - - [14/Oct/2010:18:01:31 -0400] “POST /checkout.php
HTTP/1.1” 499 0 “https://www.somesite.com/precheckout.php” “Mozilla/5.0
(compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)” “-”

XX.XX.XX.XX - - [14/Oct/2010:18:01:33 -0400] “POST /checkout.php
HTTP/1.1” 200 6996 “https://www.somesite.com/precheckout.php
“Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)” “-”

And on apache, the same requests log:

XX.XX.XX.XX - - [14/Oct/2010:18:01:30 -0400] “POST /checkout.php
HTTP/1.0” 200 6996 “https://www.somesite.com/precheckout.php
“Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)” google

XX.XX.XX.XX - - [14/Oct/2010:18:01:30 -0400] “POST /checkout.php
HTTP/1.0” 200 6996 “https://www.somesite.com/precheckout.php
“Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)” google

Hello!

On Tue, Oct 26, 2010 at 09:48:23AM -0400, Paleo Tek wrote:

(client problem, connection closed). IE 9 sees that, and
immediately re-sends the request. Nginx forwards to apache,
receives the response, and forward to the client, logging a 200.
Log results are below

IE can’t “see” 499 as it’s logged after client already closed
connection. It’s IE who closed connection (which is logged with
499 fake code) and re-issued request. Most likely reason - user
hit “Submit” button two times (so on second click IE aborted first
request and issued another one).

This problems isn’t nginx and/or IE specific, though may show in
logs slightly differently depending on exact borwser and/or server
behaviour.

Usual methods to prevent it from happening - either use javascript
to disable submit button, or use some token in form and filter
duplicates at server side, see e.g. [1].

[1]

Maxim D.