Multiple content length headers and multiple transfer encoding headers - http

If there are multiple content length headers, should I
fail (I don't think so?)
use the first one,
use the last one
Then I have the same question for transfer_encoding header too. I think with transfer_encoding we are supposed to use the last one.
then, same question for 'Host' header as well.
thanks,
Dean

Content-Length is a single-value header. Usually the last header would have authority; however RFC 7230, section 3.3.2 states:
If a message is received that has multiple Content-Length header fields with field-values consisting of the same decimal value, or a single Content-Length header field with a field value containing a list of identical decimal values (e.g., "Content-Length: 42, 42"), indicating that duplicate Content-Length header fields have been generated or combined by an upstream message processor, then the recipient MUST either reject the message as invalid or replace the duplicated field-values with a single valid Content-Length field containing that decimal value prior to determining the message body length or forwarding the message.
Transfer-Encoding is a different matter as it is containing a list. There can be multiple ones and all are valid. The important thing here is that applied encodings have to be listed in the order in which they have been applied. E.g. if content has been gzipped and then chunk-encoded, the headers have to look like
Transfer-Encoding: gzip, chunked
or
Transfer-Encoding: gzip
Transfer-Encoding: chunked

WRT Content-Length: yes, you actually MUST fail (unless both values are the same, in which case you MAY pick one). See RFC 7230.
"Transfer-Encoding" is different in that it allows multiple values; so you'll have to process them all in order.

Related

Possible types of a HTTP header value

The type of a value passed through a query string is always a string. When a HTTP client need to send a number, let's say 42, in is actually "42". Everything inside the query string is actually a string.
Is it the same for the type of values passed through a header ?
In other words, if we send an HTTP request with a "FooBar" header with the value of 42, and another request where the value of the header set to "42", will the server perceive the two received values as of the same type and value (i.e. "42")?
It's always a string, even in HTTP/2
tldr; Headers are text, sometimes ISO 8859, but usually just US-ASCII.
According to the 2014 RFC7230 (last paragraph), HTTP fields have used to be text and new headers should continue to do so, restricting the values to consist of US-ASCII octets.
The 1982 RFC822 specifies ASCII as the format of the header body.
References (found through List of HTTP Headers):
Section 3.2 of RFC822
RFC7230

HTTP multirange requests - headers in response

I'm using multirange http requests like this
"curl --range 1-2,2-3 http://some.url"
The response is like
--00000000000000030705 Content-Type: text/html; charset=utf-8 Content-Range: bytes 1-2/13882393
il
--00000000000000030705 Content-Type: text/html; charset=utf-8 Content-Range: bytes 2-3/13882393
le
--00000000000000030705--
How can I remove fields Content-Type and Content-Range from response to get a raw data from server (without parsing on client side)?
I want to get response like:
"ille"
Thanks a lot!
You probably can't. The server is conforming to the spec, as described by the RFC.
If multiple parts are being transferred, the server generating the 206 response must generate a "multipart/byteranges" payload, as defined in Appendix A, and a Content-Type header field containing the multipart/byteranges media type and its required boundary parameter. To avoid confusion with single-part responses, a server must not generate a Content-Range header field in the HTTP header section of a multiple part response (this field will be sent in each part instead).
In the case of contiguous multi ranges the server may send the response without the multipart boundaries but this is optional.
When multiple ranges are requested, a server may coalesce any of the ranges that overlap, or that are separated by a gap that is smaller than the overhead of sending multiple parts, regardless of the order in which the corresponding byte-range-spec appeared in the received Range header field. Since the typical overhead between parts of a multipart/byteranges payload is around 80 bytes, depending on the selected representation's media type and the chosen boundary parameter length, it can be less efficient to transfer many small disjoint parts than it is to transfer the entire selected representation.
Within the header area of each body part in the multipart payload, the server must generate a Content-Range header field corresponding to the range being enclosed in that body part. If the selected representation would have had a Content-Type header field in a 200 (OK) response, the server should generate that same Content-Type field in the header area of each body part. For example:
Assuming your server conforms to the spec, sending a single range 1-3 you will get a single body.

Can I separate ALL HTTP headers with a comma? Even Authorization?

I am reading through the HTTP 1.1 RFCs and I am not able to answer the following question.
We have this header:
Authorization: Basic Qmxvb21iZXJnOnRjbG1lU1JT, Basic
which is causing troubles because Rails 3 authorization parser incorrectly decodes the string because of the "," character. This is very uncommon I know, but we add this using this Apache httpd configuration:
RequestHeader append Authorization "Basic" early
The Apache mod_header documentation says:
The response header is appended to any existing header of the same
name. When a new value is merged onto an existing header it is
separated from the existing header with a comma. This is the HTTP
standard way of giving a header multiple values.
But I don't think it is correct for this Authorization header. The RFC definition does not allow this. But some headers permit comma-separated list. I am not sure if this is a general rule for all HTTP headers.
I am looking for a paragraph in the HTTP 1.1 RFC that prooves my idea this is not correct. I have already found something that is saying "this is valid only for headers that can be separated", but this is not a proof.
Multiple message-header fields with the same field-name MAY be present
in a message if and only if the entire field-value for that header
field is defined as a comma-separated list [i.e., #(values)]. It MUST
be possible to combine the multiple header fields into one
"field-name: field-value" pair, without changing the semantics of the
message, by appending each subsequent field-value to the first, each
separated by a comma. The order in which header fields with the same
field-name are received is therefore significant to the interpretation
of the combined field value, and thus a proxy MUST NOT change the
order of these field values when a message is forwarded.
It really does not make sense, but I am looking for a clear proof.
The answer is in the text you quoted:
"Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]."
This is not the case for "Authorization".

Set more than one HTTP header with the same name?

As far as I know it is allowed by the HTTP spec to set more than one HTTP header with the same name. Is there any use case to do so (from client to server and vice versa)?
HTTP 1.1 Section 4.2:
Multiple message-header fields with
the same field-name MAY be present in
a message if and only if the entire
field-value for that header field is
defined as a comma-separated list
[i.e., #(values)]. It MUST be possible
to combine the multiple header fields
into one "field-name: field-value"
pair, without changing the semantics
of the message, by appending each
subsequent field-value to the first,
each separated by a comma. The order
in which header fields with the same
field-name are received is therefore
significant to the interpretation of
the combined field value, and thus a
proxy MUST NOT change the order of
these field values when a message is
forwarded.
If I'm not wrong there is no case where multiple headers with the same name are needed.
It's commonly used for Set-Cookie:. Many servers set more than one cookie.
Of course, you can always set them all in a single header.
Actually, I think you cannot set multiple cookies in one header. So that's a necessary use-case.
The Cookie spec (RFC 2109) does claim that you can combine multiple cookies in one header the same way other headers can be combined (comma-separated), but it also points out that non-conforming syntaxes (like the Expires parameter, which has ,s in its value) are still common and must be dealt with by implementations.
So, if you use Expires params in your Set-Cookie headers and you don't want all your cookies to expire at the same time, you probably need to use multiple headers.
Update: Evolution of the Cookie spec
RFC 2109 has been obsoleted by RFC 2965 that in turn got obsoleted by RFC 6265, which is stricter on the issue:
Origin servers SHOULD NOT fold multiple Set-Cookie header fields into a single header field. The usual mechanism for folding HTTP headers fields (i.e., as defined in [RFC2616]) might change the semantics of the Set-Cookie header field because the %x2C (",") character is used by Set-Cookie in a way that conflicts with such folding.
Side note
RFC 6265 uses the verb "folding" when it refers to combining multiple header fields into one, which is ambiguous in the context of the HTTP/1 specs (both by RFC2616, and its successor, RFC 7230) where:
"folding" consistently refers to line folding, and
the verb "combine" is used to describe merging same headers.
Combining header fields:
See RFC 2616, Section 4.2, Message Headers (quoted in the question), but searching for the for the word "combine" will bring up special cases.
The above item obsoleted by RFC 7230, Section 3.2.2, Field Order:
A recipient MAY combine multiple header fields with the same field name into one field-name: field-value pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma. The order in which header fields with the same field name are received is therefore significant to the interpretation of the combined field value; a proxy MUST NOT change the order of these field values when forwarding a message.
Note: In practice, the "Set-Cookie" header field (RFC6265) often appears multiple times in a response message and does not use the list syntax, violating the above requirements on multiple header fields with the same name. Since it cannot be combined into a single field-value, recipients ought to handle Set-Cookie as a special case while processing header fields. (See Appendix A.2.3 of [Kri2001] for details.)
Line folding:
From RFC 2616, Section 2.2, Basic Rules:
HTTP/1.1 header field values can be folded onto multiple lines if the continuation line begins with a space or horizontal tab. All linear white space, including folding, has the same semantics as SP. A recipient MAY replace any linear white space with a single SP before interpreting the field value or forwarding the message downstream.
The above section obsoleted by RFC 7230, Section 3.2.4, Field Parsing:
Historically, HTTP header field values could be extended over multiple lines by preceding each extra line with at least one space or horizontal tab (obs-fold). This specification deprecates such line folding except within the message/http media type (Section 8.3.1). A sender MUST NOT generate a message that includes line folding (i.e., that has any field-value that contains a match to the obs-fold rule) unless the message is intended for packaging within the message/http media type.
A server that receives an obs-fold in a request message that is not within a message/http container MUST either reject the message by sending a 400 (Bad Request), preferably with a representation explaining that obsolete line folding is unacceptable, or replace each received obs-fold with one or more SP octets prior to interpreting the field value or forwarding the message downstream.
A proxy or gateway that receives an obs-fold in a response message that is not within a message/http container MUST either discard the message and replace it with a 502 (Bad Gateway) response, preferably with a representation explaining that unacceptable line folding was received, or replace each received obs-fold with one or more SP octets prior to interpreting the field value or forwarding the message downstream.
A user agent that receives an obs-fold in a response message that is not within a message/http container MUST replace each received obs-fold with one or more SP octets prior to interpreting the field value.
Since duplicate headers can cause issues with various web-servers and APIs (regardless of what the spec says), I doubt there is any general purpose use case where this is best practice. That's not to say someone somewhere isn't doing it, of course.
As you're looking for use-cases, maybe Accept would be a valid one.
Accept: application/json
Accept: application/xml
It's only allowed for headers using a very specific format, see RFC 2616, Section 4.2.
Old thread, but I was looking into this same issue. Anyway, the Accept and Accept-Encoding headers are typical examples that uses multiple values, comma separated. Even if these are request specific header, the specs do not differentiate between request and response at this level. Check the one from this page.
What the spec says is that if you have commas as character in the value of the header, you cannot use multiple headers of the same name, unless you disambiguate the use of the comma.

Standard for adding multiple values of a single HTTP Header to a request or response

If I want to add a list of values as an HTTP Header, is there a standard way to do this? I couldn't find anything (that I could easily understand) in RFC 822. For example, is
comma separated values standard or semi-colon separated values. Is there a standard at all?
Example:
Key: value1;value2;value3
You'll want to take a look at the HTTP spec RFC 2616 where it says:
Multiple message-header fields with
the same field-name MAY be present in
a message if and only if the entire
field-value for that header field is
defined as a comma-separated list
[i.e., #(values)]. It MUST be possible
to combine the multiple header fields
into one "field-name: field-value"
pair, without changing the semantics
of the message, by appending each
subsequent field-value to the first,
each separated by a comma. The order
in which header fields with the same
field-name are received is therefore
significant to the interpretation of
the combined field value, and thus a
proxy MUST NOT change the order of
these field values when a message is
forwarded.
What this means is that you can send the same header multiple times in a response with different values, as long as those values can be appended to each other using a comma. This also means that you can send multiple values in a single header by concatenating them with commas.
So in your case it will be:
Key: value1,value2,value3
by all means #marc-novakowski you narrowing the "problem" :)
normally (per HTTP spec) we delimit each value from the other using a comma ','
but we will examine a simple case:
Cookie-set: language=pl; expires=Sat, 15-Jul-2017 23:58:22 GMT; path=/; domain=x.com
Cookie-set: id=123 expires=Sat, 15-Jul-2017 23:58:22 GMT; path=/; domain=x.com; httponly
how do you join such headers when the values one from another are delimited with commas - case when coma can appear ???
then the "client" responsibility is to choose and decide the strategy eg drop, merg (if merg how)?
pleas take look at Mozilla implementation of nsHttpHeaderArray
https://github.com/bnoordhuis/mozilla-central/blob/master/netwerk/protocol/http/nsHttpHeaderArray.h#L185
mozilla choose to use a newline delimiter '\n' in this case (for certain header fields names)
I encourage when you face a such situation to search in common existing solutions - as they providing familiar scheme
flags explanations:
Cookies are no part of the HTTP standard. Cookies are defined in an
own RFC, 6265 (formally 2965 and 2109). Even the HTTP 2 RFC only
mentions cookies but does not define them as part of the standard. –
#mecki Aug 25 at 18:56
please look one more time for sentence:
per HTTP spec we delimit each value from other using a comma ',' - there is no word cookie here :)
maybe we need to precise we talk here about HEADER FIELD(s - when repeating them) "Cookie-set" is a header field and it has value .. those value we consider to be a "COOKIE/S" - thus client/server implementation should handle such "COOKIE/S"
SEE VALUES OR NAME PAIRS :) IN HTTP 1/1 SPEC
https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.2
However not all values with the same field name may be combined into field values list. For example, in RFC 7230 we may read
Note: In practice, the "Set-Cookie" header field ([RFC6265]) often
appears multiple times in a response message and does not use the
list syntax, violating the above requirements on multiple header
fields with the same name. Since it cannot be combined into a
single field-value, recipients ought to handle "Set-Cookie" as a
special case while processing header fields. (See Appendix A.2.3
of [Kri2001] for details.)

Resources