Re: HTTP Content-Location header usage

Nikita Piskunov <> Mon, 17 October 2016 19:42 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id C4A5612989C for <>; Mon, 17 Oct 2016 12:42:46 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -7.33
X-Spam-Status: No, score=-7.33 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_HI=-5, RP_MATCHES_RCVD=-0.431, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id mZ98eoHwoegv for <>; Mon, 17 Oct 2016 12:42:44 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 85B881297C9 for <>; Mon, 17 Oct 2016 12:42:44 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1bwDjx-0005br-Ft for; Mon, 17 Oct 2016 19:38:29 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bwDjs-0005b3-04 for; Mon, 17 Oct 2016 19:38:24 +0000
Received: from ([]) by with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bwDji-00081d-Q7 for; Mon, 17 Oct 2016 19:38:20 +0000
Received: from ([] helo=[]) by with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from <>) id 1bwDjh-0003iw-RJ for; Mon, 17 Oct 2016 19:38:14 +0000
Mime-Version: 1.0 (Mac OS X Mail 10.0 \(3226\))
Content-Type: multipart/alternative; boundary="Apple-Mail=_C3EFA1C9-7916-40FF-AF1E-96C8C64BB3F8"
From: Nikita Piskunov <>
In-Reply-To: <>
Resent-From: Yves Lafon <>
Date: Mon, 17 Oct 2016 18:42:52 +0000
Cc: HTTP working group mailing list <>
Resent-Date: Mon, 17 Oct 2016 21:38:11 +0200
Message-Id: <>
References: <> <> <> <>
X-Name-Md5: efe3dad792d606410c9cc49cedaffc94
To: Mark Nottingham <>
X-Mailer: Apple Mail (2.3226)
X-W3C-Hub-Spam-Status: No, score=-1.8
X-W3C-Scan-Sig: 1bwDji-00081d-Q7 c1a700b460c3b511fd36e8f0821bce49
Subject: Re: HTTP Content-Location header usage
Archived-At: <>
X-Mailing-List: <> archive/latest/32613
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

Mark, in my opinion, the usage of Content-Location in combination with 204 status code, is a good way (for example in reply to PUT,POST,PATCH). I think, in this way the server response could be interpreted as "Your changes are OK and implemented. You can find the new representation of resource in {VALUE_OF_CONTENT-LOCATION}"  (As you've mentioned in previos letter). As an altenative way, i tried to find information about Location (not Content-Location) header, but according to the RFCs, this header should be used only with redirects and 201 (Created) status codes...

But the worst thing is, that almost all information about the Content-Location header usage is encapsulated inside the RFC 7231, which, in other words, says, that this header describes another link to the representation in current message body. And another argument is, that inside some web-developers communities, this usage is already interpreted in this way (content-location can be applied only to the response payload). For example - the .net MVC.WEB API framework by Microsoft. The HTTP response abstaraction in this library restricts the usage of Content-XXX headers (e.g. Content-Location, Content-Language ...) with 204 status code. So, I think, that this question is quiet important. Hope, this will help in work-group discussion :). Thanks a lot for your attention to this issue.

2016-10-17 6:25 GMT+03:00 Mark Nottingham < <>>:

Sorry for the delay. This one is a bit confusing.

Successful PATCH response to existing text file:

   HTTP/1.1 204 No Content
   Content-Location: /file.txt
   ETag: "e0023aa4f"

The 204 response code is used because the response does not carry a message body (which a response with the 200 code would have).  Note that other success codes could be used as well.
""" - < <>>

At first glance, it seems like this is a bug (assuming that the example isn't about a PATCH that leads to a zero-length response), because Content-Location is defined in terms of the message payload:

If Content-Location is included in a 2xx (Successful) response message and its value refers (after conversion to absolute form) to a URI that is the same as the effective request URI, then the recipient MAY consider the payload to be a current representation of that resource at the time indicated by the message origination date.
"" - < <>>

However, 204 is defined with this clause:

Metadata in the response header fields refer to the target resource and its selected representation after the requested action was applied.

For example, if a 204 status code is received in response to a PUT request and the response contains an ETag header field, then the PUT was successful and the ETag field-value contains the entity-tag for the new representation of that target resource.
""" - < <>>

Giving precedence to the higher-level semantics of the status code, the Content-Location now applies to the selected representation (i.e., what the response would have contained, had the response been a 200 -- see < <>>), *not* the payload in the actual message.

Does that make sense?

I think RFC5987 and RFC7231 could be clearer about this, but I'm not sure it merits an errata. We should probably create an issue to track it for the next revision of these documents, though.


> On 28 Sep. 2016, at 7:49 pm, Nikita Piskunov < <>> wrote:
> Mark, thank you for the reply, but my main confusion is about the second part of my letter. I understand, that Content-Location header can be a link to another URL, representing the current resource in the http-response body in this reponse. But, what about the responses with 204 status code (No-Content). They can't have a body in general, so they have no representation of the current resource. But we can find the example of http-response in RFC 5789, which has 204 status and includes Content-Location header. In other words:
> If I perform:
>       PATCH <>,
>       Content-type: appllication/json
>       Body: {"Foo":"Bar"}
> The possible response is:
>       HTTP/1.1 200 Ok
>       Content-Location: <>
>       Content-type: appllication/json
>       Body: {"Foo": "Bar"}
> But, is it possible to respond in this way (how we can see in RFC 5789) - with no body, and Content-Location?
>       HTTP/1.1 204 No Content
>       Content-Location: <>
> In my opinion, the description of Content-Location header usage in RFC 7231 and example in RFC 5789 contradict each other.
> 2016-09-28 9:10 GMT+03:00 Mark Nottingham < <>>:
> > On 21 Sep. 2016, at 10:35 pm, Никита Пискунов < <>> wrote:
> >
> > Hello,
> > i've already posted my comment about ambiguous Content-Location header usage description here as a GitHub Issue. And I've also decided to raise the discussion via email.
> >
> > So, my question is:
> >
> > The RFC 5789 discribes the apropriate usage of Content-Location header in PATCH:
> >
> > A response to this method is only cacheable if it contains explicit freshness information (such as an Expires header or "Cache-Control: max-age" directive) as well as the Content-Location header matching the Request-URI, indicating that the PATCH response body is a resource representation.
> > So, it means, that Content-Location header must appear only if the actual represantation is the part of response body for PATCH.
> No. Content-Location can appear; it indicates a URL for the representation in the message. *If* it matches the request-target, you can deduce that it's a representation of what's currently at that resource (after the PATCH is applied). But if it doesn't match, it can still appear.
> > Also the usage of Content-Location is mentioned in another RFC 7231:
> >
> > For a state-changing request like PUT (Section 4.3.4) or POST (Section 4.3.3), it implies that the server's response contains the new representation of that resource, thereby distinguishing it from representations that might only report about the action (e.g., "It worked!"). This allows authoring applications to update their local copies without the need for a subsequent GET request.
> > So, accordingly to this information in both RFCs, the apropriate usage of Content-Location with state-changing requests are following:
> > Content-Location must appear in response only if response-body contains the new resourse representation.
> >
> > But, there is also an example in RFC 5789:
> >
> > Successful PATCH response to existing text file:
> >
> > HTTP/1.1 204 No Content
> > Content-Location: /file.txt
> > ETag: "e0023aa4f"
> >
> > The 204 response code is used because the response does not carry a message body (which a response with the 200 code would have). Note that other success codes could be used as well.
> >
> > Furthermore, the ETag response header field contains the ETag for the entity created by applying the PATCH, available at <>, as indicated by the Content-Location response header field.
> > How you can see, there is a Content-Location presented in response with 204 status code (No content). Ofcourse, this response doesn't contain any body as well as new resourse representation. This fact adds some ambiguity in Content-Location header description. What is the correct usage of this header?
> >
> --
> Mark Nottingham <>

Mark Nottingham <>