in Uncategorized

Location vs. Content-Location

Here is a quick note on the purposes of and differences between Location and Content-Location response headers. The question came up several times, and more recently in Bill Burke's post on Atom too SOAPy for me.

Here is how HTTP 1.1 defines the Location header.

Location:

The Location response-header field is used to redirect the recipient to a Location other than the Request-URI for completion of the request or identification of a new resource.

The use of the Location header is straight-forward. The server can use this header when it creates new resource in response to a POST request, i.e. while returning response code 201. Or, it is can use this header to redirect the client to a different Location with one of the 3xx codes. The use of the Location header otherwise is unspecified. In particular, its use is not defined for GET.

Content-Location, on the other hand, has a much narrower usage.

Content-Location:

The Content-Location entity-header field MAY be used to supply the resource Location for the entity enclosed in the message when that entity is accessible from a Location separate from the requested resource’s URI.

The name of this header could be a bit confusing. One way to understand this is to relate it to other Content-xxx headers such as Content-Type, Content-Language, and Content-Encoding. Just like the way Content-Type header declares the media type of the entity in the response, the Content-Location header declares a URI for the entity in the response. Also note that the Content-Location header is not defined for PUT and POST.

Content-Location header is useful for content-negotiated responses when both server-driven and agent-driven negotiations are in use by the server. Here is an example.

GET /myResource
Accept: application/xml
200 OK
Content-Type: application/xml
Content-Location: http://example.org/myResource?format=xml

...

Here the server is telling the client that the same content (i.e. a variant of media type application/xml) is also available at http://example.org/myResource?format=xml at the time of the request. The client can use that URI in future to directly fetch the negotiated response. Caches can use this URI to associate the requested URI (i.e. http://example.org/myResource) to URIs of variants (such as http://example.org/myResource?format=xml), and flush those variants while flushing the resource, or to flush previously cached representation at the variant URI if that representation is stale.

Finally, neither header is meant for general-purpose linking.

Thanks to my colleague, Mark Nottingham for clarifying some of the finer points over several emails a few months ago.