otsukare Thoughts after a day of work

Refresh HTTP Header

Through discussions on whatwg, I learned (or I had just forgotten) about the Refresh HTTP header. Let's cut strait to the syntax:

HTTP/1.1 200 OK
Refresh: 5; url=http://www.example.org/fresh-as-a-summer-breeze

where

  • 5 means here 5 seconds.
  • url= gives the destination where the client should head after 5 seconds.

Simon Pieters (Opera) is saying in that mail:

I think Refresh as an HTTP header is not specified anywhere, so per spec
it shouldn't work. However I think browsers all support it, so it would be
good to specify it.

Eric Law (ex-Microsoft) has written about The Performance Impact of META REFRESH. If we express the previous HTTP header in HTML, we get:

<meta http-equiv="refresh" content="5;url=http://www.example.org/fresh-as-a-summer-breeze" />

In his blog post, Eric is talking about people using refresh to… well refresh the page. He means loading the same exact page over and over again. And indeed it means for the browser to create a certain number of "unconditional and conditional HTTP requests to revalidate the page’s resources" for each reload (refresh).

On the Web Compatibility side of things, I see the <meta http-equiv="refresh" …/> used quite often.

<meta http-equiv="refresh" content="0;url=http://example.com/there" />

Note the 0. Probably the result of sysadmins not willing to touch the configuration of the servers, and so front-end developers taking the lead to "fix it", instead of using HTTP 302 or HTTP 301. Anyway, it is something which is being used for most of the time, redirecting to another domain name or uri. Refresh HTTP Header on the other hand, I don't remember seeing it that often.

Should it be documented?

Simon is saying: "it would be good to specify it." I'm not so sure. First things first.

Testing

Let's create a test, by making a page sending a Refresh.

Header set Refresh "0;url=https://www.youtube.com/watch?v=sTJ1XwGDcA4"

which gives

HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Length: 200
Content-Type: text/html; charset=utf-8
Date: Thu, 26 Mar 2015 05:48:57 GMT
ETag: "c8-5122a67ec0240"
Expires: Thu, 02 Apr 2015 05:48:57 GMT
Keep-Alive: timeout=5, max=100
Last-Modified: Thu, 26 Mar 2015 05:37:05 GMT
Refresh: 0;url=https://www.youtube.com/watch?v=sTJ1XwGDcA4

This should redirect to this Fresh page

  • Yes - Firefox 36.0.4
  • Yes - Opera 29.0.1795.26
  • Yes - Safari 8.0.4 (10600.4.10.7)
  • Yes - IE11
  • Yes - Chrome (something) said Hallvord ;)

If someone could test for IE and Chrome at least.

Browser Bugs?

On Mozilla bug tracker, there are a certain number of bugs around refresh. This bug about inline resources is quite interesting and might indeed need to be addressed if there was a documentation. The bug is what the browser should do when the Refresh HTTP header is on an image included in a Web page (this could be another test). For now, the refresh is not done for inline resources. Then what about scripts, stylesheets, JSON files, HTML document in iframes, etc? For the SetupRefreshURIFromHeader code, there are Web Compatibility hacks in the source code of Firefox. We can read:

// Also note that the seconds and URL separator can be either
// a ';' or a ','. The ',' separator should be illegal but CNN
// is using it."

also:

// Note that URI should start with "url=" but we allow omission

and… spaces!

// We've had at least one whitespace so tolerate the mistake
// and drop through.
// e.g. content="10 foo"

Good times…

On Webkit bug tracker, I found another couple of bugs but about meta refresh and not specifically Refresh:. But I'm not sure it's handled by WebCore or if it's handled elsewhere in MacOSX (NSURLRequest, NSURLConnection, …). If someone knows, tell me. I didn't explore yet the source code.

On Chromium bug tracker, another couple of bugs for meta refresh, with some interesting such as this person complaining that a space doesn't work instead of a ;. This is also tracked on WebKit. Something like:

<meta http-equiv="refresh" content="0 url=http://example.com/there" />

Also what should be done with a relative URL.

<meta http-equiv="refresh" content="0;url=/there" />

But for Chromium, I have not found anything really specific to Refresh header. I didn't explore yet the source code.

On Opera bug tracker, it is still closed. We tried to open it when I was working there, and it didn't work.

Competition Of Techniques

Then you can also imagine the hierarchy of commands in a case like this:

HTTP/1.1 301 Permanent Redirect
Refresh: 0;url=http://example.net/refresh-header
Location: http://example.net/location

<!DOCTYPE html>
<html>
<title>Fresh</title>
<meta http-equiv="refresh" content="0;url=http://example.net/meta" />
<body onload="document.location.replace('http://example.net/body')">

</body>
</html>

My guess is the 301 always win with the Location HTTP header, or at least it's what I hope.

History

I can find very early references of meta refresh such as in Netscape Developer documentation.

The earliest mention seems to be An Exploration Of Dynamic Documents I can't find anywhere the documentation for Refresh HTTP header on old Netscape Web sites. (Thanks to SecuriTeam Web site and Amit Klein)

So another thing you obviously want to do, in addition to causing the current document to reload, is to cause another document to be reloaded in n seconds in place of the current document. This is easy. The HTTP response header will look like this:

Refresh: 12; URL=http://foo.bar/blatz.html

In June 1996, Jerry Jongerius posted about HTTP/1.1 Refresh header field comments

My concern with "Refresh" is that I do not want it to be a global concept (a browser can only keep track of one refresh)--it looks to be implemented this way in Netscape 2.x. I would like "Refresh" to apply to individual objects (RE: the message below to netscape).

which Roy T. Fielding replied to:

Refresh is no longer in the HTTP/1.1 document -- it has been deferred to HTTP/1.2 (or later).

Should it be documented? Well, there are plenty of issues, there are plenty of hacks around it. I have just touched the surface of it. Maybe it would be worth to document indeed how it is working as implemented now and how it is supposed to be working when there's no interoperability. If I was silly enough, maybe I would do this. HTTP, Archeology and Web Compatibility issues that seems to be close enough from my vices.

Otsukare!