Is there an HTTP status code to instruct a client to perform the same request again?
I am facing a situation where the server has to "wait" for a lock to disappear when processing a request. But by the time the lock disappears, the requests might be close to its timeout limit. So instead, once the lock clears, I would like to instruct the client to just perform the same request again.
The best I an come up with is a HTTP 307 to the same location, but I'm worried that some browsers might not buy into this (redirect loop detection).
The correct response, when a server is unable to handle a request, is 503 Service Unavailable. When the condition is temporary, as it is in your case, you can set the Retry-After
header to let the client know how long it should wait before trying again.
However, this will not force the browser to perform the request again - this is something you would need to handle yourself in javascript. For example, here is how you might perform a retrying ajax POST request in jquery:
function postData() {
$.ajax({
type: 'POST',
url: '503.php',
success: function() {
/*
Do whatever you need to do here when successful.
*/
},
statusCode: {
503: function(jqXHR) {
var retryAfter = jqXHR.getResponseHeader('Retry-After');
retryAfter = parseInt(retryAfter, 10);
if (!retryAfter) retryAfter = 5;
setTimeout(postData, retryAfter * 1000);
}
}
});
}
Note that the above code only supports a Retry-After
header where the retry delay is specified in seconds. If you want to support dates that would require a little more work. In production code I would also recommend a counter of some sort to make sure you don't keep retrying forever.
As for using a 307 status code to repeat the request automatically, I don't think that is a good idea. Even if you add a retry parameter to get around the browser loop detection (which feels like a horrible hack), it's still not going to work on a POST request. From RFC2616:
If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user.
While some browsers are known to ignore this requirement, it's definitely not correct, and isn't something you would want to rely on.
And if you're not using a POST request, you almost certainly should be. Remember that a GET request should not have any side effects, and by default the response will be cached. From the description of your problem, it sounds very much like your request is likely to be doing something that has side-effects.
Use the 307 redirect, but add a retry counter:
http://path/to/server?retry=3
This will make the URL different on each retry, preventing loop detection. And the server could check for retry hitting a limit, and abort with an error when that happens, so the user doesn't wait forever.