Pushing the Web Forward with HTTP/308

Recently, the IESG approved publication of a new Internet-Draft defining the HTTP/308 status code (Intended Status: Experimental). This status code is defined as the "Permanent" variant of the existing HTTP/307 status code. Recall that HTTP/307 was defined back in 1999 to remove the ambiguity around the HTTP/301 and HTTP/302 redirection codes, for which many user-agents would change the redirected request's method from POST to GET. HTTP/303 was defined to unambiguously indicate that the UA should change the method to GET, while HTTP/307 was defined to unambiguously indicate that the UA should preserve the current method.

HTTP/308 is pretty much the same as HTTP/307, with two defined deltas:

  1. The status is defined as a "Permanent Redirect".
  2. A client with "link editing" capabilities "ought" to automatically re-link references to the target URL.

These basic properties are inherited from HTTP/301, although there's some subtlety here you might miss. First, despite being defined as permanent, caches explicitly MAY use heuristics to expire the redirection (making "permanence" a bit squishy). That's probably not a bad thing, considering that we’ve found that many real-world sites aren't using HTTP/301 properly, and if a cache truly treats the redirect as permanent, such sites end up in infinite redirect loops. Secondly, I've never seen any client with "link editing" capabilities that automatically updates URIs based on 301. That's most likely due to the security implications of doing so, along with the fact that 301 is often misused as a temporary redirect. We're not terribly likely to see automatic "link editing" based on HTTP/308 responses either.

Despite its practical equivalence to HTTP/307, HTTP/308 has one unique property which makes it very interesting:

As an entirely new status code, no client implemented in the first 21 years of HTTP’s existence supports HTTP/308.

This characteristic is intriguing, because it means that only bleeding-edge browsers (e.g. the latest Firefox nightly) work with the HTTP/308 status. If any of the existing billions of existing web clients encounters a HTTP/308, the client will not perform a same-method redirect as called for in the Internet-Draft.

A server could use User-Agent sniffing to send back a 307 instead of a 308 to a client if it's not on the bleeding edge of standards support; such sniffing is necessary because there's nothing in HTTP request headers that indicates what response codes the client supports. Notably, the draft suggests that the server avoid the use of sniffing to send the 308 only to clients that support it, noting:

Server implementers are advised not to vary the status code based on characteristics of the request, such as the User-Agent header field ("User-Agent Sniffing") -- doing so usually results in both hard to maintain and hard to debug code and would also require special attention to caching

Of course, there are some situations where the server knows a priori that the client supports HTTP/308... for instance, in closed environments where the user is forced to use a particular client, HTTP/308 can reliably deliver its function.

Most clients, however, will simply render the body of the HTTP/308 response as a webpage, which is the "fallback" behavior for unknown 3xx response codes. Unfortunately, if the 308 was being used to redirect a POST, the fallback script or markup in the body will generally not be able to perform the POST to the new target URL, because the POST body is not available to the page... unless the body of the 308 is delivered with a form echoing back the originally-submitted POST body.

So instead, the HTTP/308 response body instead serves as a great way to advertise to the user that their browser isn't at the bleeding-edge of Internet Standards. Such a page could point the user to the nightly build of a browser which does support HTTP/308. For users on legacy devices that are not readily updatable to such browsers (e.g. phones, consoles, tablets after the end of their supported lifetime) links to web stores can be provided to offer the user the ability to purchase devices that support the latest standards experiments.

Fiddler users can simulate HTTP/308 behavior even with non-hip clients by clicking Rules > Customize Rules. Inside the OnPeekAtResponseHeaders method, add the following block:

  if (oSession.responseCode == 308) {
oSession.responseCode = 307;
oSession["ui-backcolor"] = "teal";
}

You can test your browser’s support for HTTP/308 on this test page: https://webdbg.com/test/308/.

-Eric