HTTP statuscode to retry same request

33,102

Solution 1

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.

Solution 2

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.

Share:
33,102
Jeroen Ooms
Author by

Jeroen Ooms

#rstats developer and staff RSE for @ropensci at UC Berkeley.

Updated on July 25, 2022

Comments

  • Jeroen Ooms
    Jeroen Ooms almost 2 years

    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).

  • Jeroen Ooms
    Jeroen Ooms almost 11 years
    I don't think a HTTP redirect allows to modify parameters? Note that 307 must work for any method. So if the original request was a POST with form-data/multipart, I don't think I can just add a retry parameter?
  • Barmar
    Barmar almost 11 years
    You can redirect to any URL, and it can contain parameters, so why couldn't they be different from the original parameters? But you're right that this won't work with a POST -- it won't post the form again to the new URL.
  • akostadinov
    akostadinov over 7 years
    I don't think server error is a correct response here. For me something in the 4xx range would make more sense. I read stackoverflow.com/q/9794696/520567 -- there 423 is a good for for ops use case. Also 202 is good for other use cases.
  • borlafu
    borlafu about 6 years
    You should not use HTTP 307: "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, since this might change the conditions under which the request was issued." Source: 10.3.8 307 Temporary Redirect
  • Barmar
    Barmar about 6 years
    If you're going to use application-specific Javascript, you could use practically any code -- all that matters is that the client and server code agree on how this condition is distinguished from other cases.
  • Barmar
    Barmar about 6 years
    @borlafu As I said in my previous comment, this won't work with POST.
  • Elliott Beach
    Elliott Beach over 4 years
    307 should work. From here: The 307 Temporary Redirect is usually not something that requires much user intervention. All modern browsers will automatically detect the 307 Temporary Redirect response code and process the redirection action to the new URI automatically