Inconsistent browser retry behaviour for timed out POST requests
Browsers retry requests (including POSTs) when the connection is closed before receiving a response from the server. This is defined in the HTTP 1.1 Spec Section 8.2.4.
Jay Kumar
Cloud & DevOps Specialist github, twitter, linkedin
Updated on June 06, 2022Comments
-
Jay Kumar almost 2 years
I am experiencing occasional retries for a POST request, when there is no response from server due to timeout. All modern browsers have retry logic for idempotent requests (GET, HEAD, etc) but I am unable to reason out why it happens for a POST request.
I am testing this case using a simple node.js server with 3 routes and chrome browser .
/ : gives a html page with jquery and code snippets to fire ajax requests /hi : gives a text response 'hello' /sleep : request will timeout without any response
By default, node.js http server times out a request after 2 minutes.
retry.js
var http = require('http'); var server = http.createServer(); server.on('request', function(req, res) { console.log(new Date() + ' ' + req.method + ' request on ' + req.url); if (req.url === '/sleep') { console.log('!!! sleeping'); } else if (req.url === '/') { html = "$.post('/hi', {'for':'server'}, function() { console.log(arguments) } ).error(function() { console.log(arguments) })"; html += "<br><br>"; html += "$.post('/sleep', {'for':'infinite'}, function() { console.log(arguments) } ).error(function() { console.log(arguments) })"; html += '<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>'; res.writeHead(200, {'Content-Type': 'text/html'}); res.end(html); } else { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('hello'); } }); server.listen(2020); console.log('server listening on port 2020');
run it
$ node retry.js server listening on port 2020
1
Load this page in browser http://localhost:2020 Fri Mar 01 2013 12:21:59 GMT+0530 (IST) GET request on / Fri Mar 01 2013 12:21:59 GMT+0530 (IST) GET request on /favicon.ico
2
From Dev console, fire an ajax POST request to /hi using jquery
$.post('/hi', {'for':'server'}, function() { console.log(arguments) } ).error(function() { console.log(arguments) })
Fri Mar 01 2013 12:22:05 GMT+0530 (IST) POST request on /hi
3
Fire a POST request to /sleep, results in a retry after 2 mins and errors out after 4 mins.
$.post('/sleep', {'for':'infinite'}, function() { console.log(arguments) } ).error(function() { console.log(arguments) })
server logs shows 2 requests
Fri Mar 01 2013 12:22:21 GMT+0530 (IST) POST request on /sleep !!! sleeping Fri Mar 01 2013 12:24:21 GMT+0530 (IST) POST request on /sleep !!! sleeping
Firing it again, errors out in 2 mins without any retry.
Fri Mar 01 2013 12:30:01 GMT+0530 (IST) POST request on /sleep !!! sleeping ?
It's not getting retried until we fire a request to /hi (or any other url) that results in a response. And retry happens for just one subsequent request to /sleep.
In browser, the network tab shows the pattern like
/hi - success /sleep - cancelled - 4 mins (retry happens) /sleep - cancelled - 2 mins (no retry) /sleep - cancelled - 2 mins (no retry) /hi - success /sleep - cancelled - 4 mins (retry happens) /sleep - cancelled - 2 mins (no retry) /sleep - cancelled - 2 mins (no retry)
Question
Though we need to design our web app to tolerate these extra requests (either by browsers or any other intermediaries), this inconsistent browser retries looks weird. I had observed this behaviour in chrome (v16 & v24) & firefox.
Can someone help me to understand the browser retry logic behind timed out non-idempotent requests ?
Other relevant stackoverflow questions
What happens when no response is received for a request? I'm seeing retries
-
Jay Kumar over 10 yearsThis answers the scenario. And we made our app resilient to intermediary retries. Thank you.
-
robsonrosa about 9 yearsAnd what can close a connection before receiving a response? I have a process that last about 10 minutes. Testing here, in my machine, it works fine. But in another machine (both with windows/chrome), a POST retry is triggered after 2 or 3 minutes. I dont have any idea about what is happening. I can only think about browser timeout, but why it doesn't happen in my machine?
-
Tyree Jackson almost 6 years@robsonrosa A reverse proxy or a web application firewall in between the client and the server could potentially close the connection depending on how it is configured.