3

I want to redirect a certain URI to a new one on the same server. This can be done by sending a response with a 3xx code, and a 'Location' header. Now the HTTP/1.1 standard dictates that this should be an 'absolute URI'. (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30)

Now what exactly do they mean by 'absolute URI'? In the example given they included the full URI, with protocol, hostname, and the path. Now I want to redirect to a URI on the same server, and I know the path. It is an absolute URI (it starts at the root), but without hostname and protocol. As a matter of fact, the server might not know its own hostname, and it would be hard to construct a full URI.

Is it also valid, according to the HTTP/1.1 standard, to send a URI without hostname and protocol? I tried this, and every browser I tested seemed to understand it. My question is: is it correct to do this?

An example response:

HTTP/1.1 303 See Other
Location: /path/to/other

Instead of:

HTTP/1.1 303 See Other
Location: https://hostname.com/path/to/other
Ruud
  • 135
  • 7
  • possible duplicate of [Redirect, Change URLs or Redirect HTTP to HTTPS in Apache - Everything You Ever Wanted How to Know about Mod\_Rewrite Rules but Were Afraid to Ask](http://serverfault.com/questions/214512/redirect-change-urls-or-redirect-http-to-https-in-apache-everything-you-ever) – ETL Feb 13 '14 at 15:28

2 Answers2

3

Is it also valid, according to the HTTP/1.1 standard, to send a URI [in a location header] without hostname and protocol?

No, because of how 'absoluteURI' is defined. Since you're looking at an RFC, let's stick to them for this discussion. Backing up:

Now what exactly do they mean by 'absolute URI'?

It's defined elsewhere. This happens often.

Now I want to redirect to a URI on the same server, and I know the path. It is an absolute URI (it starts at the root), but without hostname and protocol.

It might be an absolute path, but that doesn't make it an absolute URI.

From section 3.2.1 of the HTTP/1.1 RFC, General Syntax:

For definitive information on URL syntax and semantics, see "Uniform Resource Identifiers (URI): Generic Syntax and Semantics," RFC 2396 [42] (which replaces RFCs 1738 [4] and RFC 1808 [11]). This specification adopts the definitions of "URI-reference", "absoluteURI", "relativeURI", "port", "host","abs_path", "rel_path", and "authority" from that specification.

Looking at RFC 2396:

   absoluteURI   = scheme ":" ( hier_part | opaque_part )

Even without diving through the BNF, the 'scheme' part (the 'http' or 'https') is required. I'll omit an actual discussion of the rule-building here, but since you need an 'http:' or 'https:' at the beginning of the string, you can't remove the network part of the URI.

I tried this, and every browser I tested seemed to understand it.

Postel's law at work. You did something wrong, but the browser understood it anyway. You should follow it and send a correct absolute URI with your Location: header. If it can't be built easily in your environment, there's something off; I can't think of any web application I've seen where host information is not configurable or retrievable.

Josh Y.
  • 280
  • 1
  • 2
  • 7
  • 1
    So looking at RFC 2396, hier_part is defined as '( net_path | abs_path ) [ "?" query ]', so it would be valid to send a location like https:/path/to/other ? – Ruud Dec 29 '11 at 08:30
  • AFAICT it's valid to construct one without the authority section--I reskimmed both the URI and HTTP RFCs--but I have no idea what the behavior of that would be. I would strongly recommend you avoid that, but I can't give you a standards-based reason from my reading of the RFCs, just that I felt terror when I saw you had constructed that. E: I would guess the browser would assume you forgot a slash and try to GET `/to/other` from the host `path` – Josh Y. Dec 29 '11 at 09:02
  • It looks strange to me as well … I will have to try and see how browsers handle this. Thank you very much for your help! – Ruud Dec 29 '11 at 09:43
2

It seems that they did not say it explicitly whether you should include the server name and protocol. If you know who will use your HTTP service, you can simply test it and see if it goes well.

Also, it is not difficult to know the requested URL in the server and construct an absolute URL that includes the protocol and hostname. For example, you can use $_SERVER array in PHP. Other web languages should have similar predefined variables.

Khaled
  • 35,688
  • 8
  • 69
  • 98
  • For most servers this is easy indeed. Most servers allow you to create redirects without manually having to send headers anyway. The problem is, that I am building my own server. – Ruud Dec 29 '11 at 08:25