This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 16297 - combining multiple author request headers
Summary: combining multiple author request headers
Status: CLOSED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: XHR (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Target Milestone: ---
Assignee: Anne
QA Contact: public-webapps-bugzilla
URL: http://dvcs.w3.org/hg/xhr/raw-file/8d...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-10 00:19 UTC by Glenn Adams
Modified: 2012-03-26 21:23 UTC (History)
3 users (show)

See Also:


Attachments

Description Glenn Adams 2012-03-10 00:19:41 UTC
section 4.7.2 step 7 is ambiguous or non-testable or both; i.e., as defined, consistent behavior cannot be predicted... the current language says:

"If header is in the author request headers list either use multiple headers, combine the values or use a combination of those (section 4.2, RFC 2616)."

in order to reliably implement the rules cited in HTTP, namely

"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."

one must have a priori knowledge of which headers satisfy this constraint and which headers do not

while it is possible to determine this information at a fixed point in time, e.g., the date 2616 was published (June 1999), it is not possible to know this information for headers defined in the future

given this ambiguity, I wonder if the implementation of XHR should make any decisions about combining headers?? perhaps it is better to allow the JS client code to make this determination... that is, to have the implementation *always* use multiple headers (in the order added)
Comment 1 Julian Reschke 2012-03-10 10:04:17 UTC
Setting a header multiple times when the header syntax does not allow this is a case of "garbage in garbage out", so this is fine.

Optimally, there were ways to remove headers, so the caller can make sure that it doesn't set a header twice when it doesn't want to.
Comment 2 Glenn Adams 2012-03-10 19:21:20 UTC
(In reply to comment #1)
> Setting a header multiple times when the header syntax does not allow this is a
> case of "garbage in garbage out", so this is fine.
> 
> Optimally, there were ways to remove headers, so the caller can make sure that
> it doesn't set a header twice when it doesn't want to.

are you agreeing with me to have the application code handle this rather than the UA? or are you suggesting the UA should implement the "combine" function as currently specified, and that the results are indeterminate?
Comment 3 Julian Reschke 2012-03-10 19:34:20 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > Setting a header multiple times when the header syntax does not allow this is a
> > case of "garbage in garbage out", so this is fine.
> > 
> > Optimally, there were ways to remove headers, so the caller can make sure that
> > it doesn't set a header twice when it doesn't want to.
> 
> are you agreeing with me to have the application code handle this rather than
> the UA? or are you suggesting the UA should implement the "combine" function as
> currently specified, and that the results are indeterminate?

Neither.

I don't think the results are indeterminate. They may be *undesirable* in some cases, but that's a different problem.

The core problem is not this rule, but the lack of control for the caller (who should be able to reliably *replace* a header field). This issue has been raised again and again, but we still have no API for that.
Comment 4 Glenn Adams 2012-03-10 19:44:52 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > (In reply to comment #1)
> > > Setting a header multiple times when the header syntax does not allow this is a
> > > case of "garbage in garbage out", so this is fine.
> > > 
> > > Optimally, there were ways to remove headers, so the caller can make sure that
> > > it doesn't set a header twice when it doesn't want to.
> > 
> > are you agreeing with me to have the application code handle this rather than
> > the UA? or are you suggesting the UA should implement the "combine" function as
> > currently specified, and that the results are indeterminate?
> 
> Neither.
> 
> I don't think the results are indeterminate. They may be *undesirable* in some
> cases, but that's a different problem.

How can a UA implement the combine rule in a determinate, testable manner in the presence of future header fields for which it is unknown whether combination would change the semantics or not?

> 
> The core problem is not this rule, but the lack of control for the caller (who
> should be able to reliably *replace* a header field). This issue has been
> raised again and again, but we still have no API for that.

I'm suggesting the punt on having the UA perform *any* combination, and let the app be responsible for producing garbage (or not).
Comment 5 Julian Reschke 2012-03-10 19:51:33 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > (In reply to comment #2)
> > > (In reply to comment #1)
> > > > Setting a header multiple times when the header syntax does not allow this is a
> > > > case of "garbage in garbage out", so this is fine.
> > > > 
> > > > Optimally, there were ways to remove headers, so the caller can make sure that
> > > > it doesn't set a header twice when it doesn't want to.
> > > 
> > > are you agreeing with me to have the application code handle this rather than
> > > the UA? or are you suggesting the UA should implement the "combine" function as
> > > currently specified, and that the results are indeterminate?
> > 
> > Neither.
> > 
> > I don't think the results are indeterminate. They may be *undesirable* in some
> > cases, but that's a different problem.
> 
> How can a UA implement the combine rule in a determinate, testable manner in
> the presence of future header fields for which it is unknown whether
> combination would change the semantics or not?

It does exactly what the spec says.

I agree that the outcome might be undesirable if the header field doesn't use list syntax, but that is different from "indeterminate".

> > The core problem is not this rule, but the lack of control for the caller (who
> > should be able to reliably *replace* a header field). This issue has been
> > raised again and again, but we still have no API for that.
> 
> I'm suggesting the punt on having the UA perform *any* combination, and let the
> app be responsible for producing garbage (or not).

XHR implementations currently *do* implement combination, so specifying something else without good reason makes little sense to me.

What's needed is something that allows the caller to reliably set the header field no matter whether it was set before or not.
Comment 6 Glenn Adams 2012-03-10 20:14:48 UTC
(In reply to comment #5)
> (In reply to comment #4)
> > How can a UA implement the combine rule in a determinate, testable manner in
> > the presence of future header fields for which it is unknown whether
> > combination would change the semantics or not?
> 
> It does exactly what the spec says.
> 
> I agree that the outcome might be undesirable if the header field doesn't use
> list syntax, but that is different from "indeterminate".

my contention is that the spec says either too little (doesn't prescribe a reliable, future-proof combination rule) or too much (defines combination be performed by UA behind the back of the app).

XHR says:

"If header is in the author request headers list either use multiple headers, combine the values or use a combination of those (section 4.2, RFC 2616)."

my problem is with the use of "either"; the choice is left up to the UA; looking at 2616 4.2 does not resolve this into a concrete answer without knowledge of the future;

> > I'm suggesting the punt on having the UA perform *any* combination, and let the
> > app be responsible for producing garbage (or not).
> 
> XHR implementations currently *do* implement combination, so specifying
> something else without good reason makes little sense to me.

ok, you're making a backwards compatibility argument here (though one might argue that the spec is still in WD and subject to any change), but in this case the spec should be more specific and align with implemented behavior; e.g.,

it might say to perform combination in all cases on the assumption that the field value syntax is #(values)

or

it might say that, unless it is known that a given header's value syntax is not #(values), then perform combination on the assumption that it is #values

either of these would be an improvement over the current language (IMO)

> What's needed is something that allows the caller to reliably set the header
> field no matter whether it was set before or not.

ok, but that is an orthogonal problem, yes?
Comment 7 Julian Reschke 2012-03-10 21:33:37 UTC
(In reply to comment #6)
> (In reply to comment #5)
> > (In reply to comment #4)
> > > How can a UA implement the combine rule in a determinate, testable manner in
> > > the presence of future header fields for which it is unknown whether
> > > combination would change the semantics or not?
> > 
> > It does exactly what the spec says.
> > 
> > I agree that the outcome might be undesirable if the header field doesn't use
> > list syntax, but that is different from "indeterminate".
> 
> my contention is that the spec says either too little (doesn't prescribe a
> reliable, future-proof combination rule) or too much (defines combination be
> performed by UA behind the back of the app).
> 
> XHR says:
> 
> "If header is in the author request headers list either use multiple headers,
> combine the values or use a combination of those (section 4.2, RFC 2616)."
> 
> my problem is with the use of "either"; the choice is left up to the UA;
> looking at 2616 4.2 does not resolve this into a concrete answer without
> knowledge of the future;

Why is that a problem? Both forms are allowed.

> > > I'm suggesting the punt on having the UA perform *any* combination, and let the
> > > app be responsible for producing garbage (or not).
> > 
> > XHR implementations currently *do* implement combination, so specifying
> > something else without good reason makes little sense to me.
> 
> ok, you're making a backwards compatibility argument here (though one might
> argue that the spec is still in WD and subject to any change), but in this case
> the spec should be more specific and align with implemented behavior; e.g.,
> 
> it might say to perform combination in all cases on the assumption that the
> field value syntax is #(values)
> 
> or
> 
> it might say that, unless it is known that a given header's value syntax is not
> #(values), then perform combination on the assumption that it is #values
> 
> either of these would be an improvement over the current language (IMO)

I don't see how. Right now implementations can do both, and there's nothing wrong with it.

> > What's needed is something that allows the caller to reliably set the header
> > field no matter whether it was set before or not.
> 
> ok, but that is an orthogonal problem, yes?

It's orthogonal, but if it was solved, the whole issue we're discussing here would be less important from an application's point of view (because the case of having to recombine values would happen less frequently)
Comment 8 Glenn Adams 2012-03-10 21:40:53 UTC
(In reply to comment #7)
> (In reply to comment #6)
> > "If header is in the author request headers list either use multiple headers,
> > combine the values or use a combination of those (section 4.2, RFC 2616)."
> > 
> > my problem is with the use of "either"; the choice is left up to the UA;
> > looking at 2616 4.2 does not resolve this into a concrete answer without
> > knowledge of the future;
> 
> Why is that a problem? Both forms are allowed.

that's what produces intedeterminate behavior; that's what causes non-interoperability, when one UA does X and another UA does Y;

the point in standardization is not just writing down arbitrary complicated rules rather, it is creating greater interoperability and consistency
Comment 9 Julian Reschke 2012-03-10 21:47:37 UTC
(In reply to comment #8)
> ...
> that's what produces intedeterminate behavior; that's what causes
> non-interoperability, when one UA does X and another UA does Y;
> 
> the point in standardization is not just writing down arbitrary complicated
> rules rather, it is creating greater interoperability and consistency

HTTP says both forms are allowed. XHR requiring one with no good reason would be a layering violation.
Comment 10 Glenn Adams 2012-03-11 01:17:30 UTC
(In reply to comment #9)
> (In reply to comment #8)
> > ...
> > that's what produces intedeterminate behavior; that's what causes
> > non-interoperability, when one UA does X and another UA does Y;
> > 
> > the point in standardization is not just writing down arbitrary complicated
> > rules rather, it is creating greater interoperability and consistency
> 
> HTTP says both forms are allowed. XHR requiring one with no good reason would
> be a layering violation.

we seem to be talking past each other... let me try again

the current XHR spec says:

"If header is in the author request headers list either use multiple headers, combine the values or use a combination of those (section 4.2, RFC 2616)."

this means that a UA has three choices:

(1) use multiple headers
(2) combine all values into one header
(3) use multiple headers *and* combine *some* values

it also cites 2616 4.2, but does not specify what if any part of 4.2 applies, so the reference to 2616 is effectively informative only

the application (JS author) has no idea which of these three options are chosen by a given UA

the UA implementer has no idea (other than the tangential reference to 2616 4.2) what rules to apply to determine which of these three cases apply

to me, this means the behavior is indeterminate for the app (JS author) and is arbitrary for the UA implementer

in contrast, the language in 2616 4.2 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."

Firstly, the language "MAY be present" makes it optional whether or not *any* combination occurs. It is up to the HTTP client, in the present case, the UA implementation of XHR to choose whether to perform combination or not. It need not even perform combination to be compatible with 2616.

If combination is performed, however, it must be the case that the "header field is defined as a comma-separated list [i.e., #(values)]."

Now this is already different from what XHR says, since XHR does not say that this rule applies. It only cites 2616 4.2 without specifying what (if any) aspect of it normatively applies.

Also, 2616 4.2 does not mention the case where some combination of using multiple headers and combining into one header occurs (for a given header name). So that is yet another difference in XHR.

I believe this leaves the current text in a state where it does not match 2616 and also does not improve (but instead diminishes) interoperability.

What I believe XHR should say is the following:

"If header is in the author request headers list, then perform the sub-steps:
(1) if header is known by the UA to be defined as a comma-separated list [i.e., #(values)], then it must combine the values into a single header;
(2) otherwise, use multiple headers."

Even better, would be introducing a new boolean attribute combineHeaders [or a hidden variable initialized by a combineHeaders argument to open(), or an additional combineHeaders argument on setRequestHeader()], then change the XHR language to:

"If header is in the author request headers list, then perform the sub-steps:
(1) if header is known by the UA to be defined as a comma-separated list [i.e., #(values)] and the combineHeaders flag is set, then it must combine the values into a single header;
(2) otherwise, use multiple headers."
Comment 11 Julian Reschke 2012-03-11 10:42:37 UTC
(In reply to comment #10)
> ...
> to me, this means the behavior is indeterminate for the app (JS author) and is
> arbitrary for the UA implementer

You say "indeterminate", I say "there are multiple ways to do it". The outcome shouldn't matter.

> in contrast, the language in 2616 4.2 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."
> 
> Firstly, the language "MAY be present" makes it optional whether or not *any*
> combination occurs. It is up to the HTTP client, in the present case, the UA
> implementation of XHR to choose whether to perform combination or not. It need
> not even perform combination to be compatible with 2616.
> 
> If combination is performed, however, it must be the case that the "header
> field is defined as a comma-separated list [i.e., #(values)]."

This just says that *if* you have multiple header fields, and you *want* to combine them, they need to use a certain syntax.

Consider Content-Type, which does not use that syntax.

The point of the time the problem occurs is when you have multiple values to combine. It does not matter whether you combine them or not, the HTTP message will be invalid in both cases (no matter whether you combine the values or not).

> Now this is already different from what XHR says, since XHR does not say that
> this rule applies. It only cites 2616 4.2 without specifying what (if any)
> aspect of it normatively applies.
> 
> Also, 2616 4.2 does not mention the case where some combination of using
> multiple headers and combining into one header occurs (for a given header
> name). So that is yet another difference in XHR.
> 
> I believe this leaves the current text in a state where it does not match 2616
> and also does not improve (but instead diminishes) interoperability.

The text doesn't need to "match". Actually, it shouldn't define anything that is already defined by HTTP, and it also shouldn't define anything that doesn't need to be defined.
 
> What I believe XHR should say is the following:
> 
> "If header is in the author request headers list, then perform the sub-steps:
> (1) if header is known by the UA to be defined as a comma-separated list [i.e.,
> #(values)], then it must combine the values into a single header;
> (2) otherwise, use multiple headers."

It could say that, but I don't see how that helps. XHR usually is implemented on top of a network stack, and that stack might not give you the option. Furthermore, what the UA sends may not be what the server receives, because intermediates are allowed to recombine header fields.

> Even better, would be introducing a new boolean attribute combineHeaders [or a
> hidden variable initialized by a combineHeaders argument to open(), or an
> additional combineHeaders argument on setRequestHeader()], then change the XHR
> language to:
> 
> "If header is in the author request headers list, then perform the sub-steps:
> (1) if header is known by the UA to be defined as a comma-separated list [i.e.,
> #(values)] and the combineHeaders flag is set, then it must combine the values
> into a single header;
> (2) otherwise, use multiple headers."

I have no idea how this helps.

Maybe you could give a concrete example where the current definition is a problem, and then we can start from there?
Comment 12 Glenn Adams 2012-03-11 13:39:46 UTC
(In reply to comment #11)
> (In reply to comment #10)
> > ...
> > to me, this means the behavior is indeterminate for the app (JS author) and is
> > arbitrary for the UA implementer
> 
> You say "indeterminate", I say "there are multiple ways to do it". The outcome
> shouldn't matter.
> 
> > in contrast, the language in 2616 4.2 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."
> > 
> > Firstly, the language "MAY be present" makes it optional whether or not *any*
> > combination occurs. It is up to the HTTP client, in the present case, the UA
> > implementation of XHR to choose whether to perform combination or not. It need
> > not even perform combination to be compatible with 2616.
> > 
> > If combination is performed, however, it must be the case that the "header
> > field is defined as a comma-separated list [i.e., #(values)]."
> 
> This just says that *if* you have multiple header fields, and you *want* to
> combine them, they need to use a certain syntax.

no, it defines the condition under which combination can occur; it precludes combinations when a header is not defined as #(values);

> Consider Content-Type, which does not use that syntax.
> 
> The point of the time the problem occurs is when you have multiple values to
> combine. It does not matter whether you combine them or not, the HTTP message
> will be invalid in both cases (no matter whether you combine the values or
> not).
> 
> > Now this is already different from what XHR says, since XHR does not say that
> > this rule applies. It only cites 2616 4.2 without specifying what (if any)
> > aspect of it normatively applies.
> > 
> > Also, 2616 4.2 does not mention the case where some combination of using
> > multiple headers and combining into one header occurs (for a given header
> > name). So that is yet another difference in XHR.
> > 
> > I believe this leaves the current text in a state where it does not match 2616
> > and also does not improve (but instead diminishes) interoperability.
> 
> The text doesn't need to "match". Actually, it shouldn't define anything that
> is already defined by HTTP, and it also shouldn't define anything that doesn't
> need to be defined.
> 
> > What I believe XHR should say is the following:
> > 
> > "If header is in the author request headers list, then perform the sub-steps:
> > (1) if header is known by the UA to be defined as a comma-separated list [i.e.,
> > #(values)], then it must combine the values into a single header;
> > (2) otherwise, use multiple headers."
> 
> It could say that, but I don't see how that helps. XHR usually is implemented
> on top of a network stack, and that stack might not give you the option.
> Furthermore, what the UA sends may not be what the server receives, because
> intermediates are allowed to recombine header fields.

irrelevant; the first is an implementation detail; the second is outside the scope of the UA, and is not true in general [1] as I'm sure you know

[1] http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-18.html#non-modifiable.header-fields

> > Even better, would be introducing a new boolean attribute combineHeaders [or a
> > hidden variable initialized by a combineHeaders argument to open(), or an
> > additional combineHeaders argument on setRequestHeader()], then change the XHR
> > language to:
> > 
> > "If header is in the author request headers list, then perform the sub-steps:
> > (1) if header is known by the UA to be defined as a comma-separated list [i.e.,
> > #(values)] and the combineHeaders flag is set, then it must combine the values
> > into a single header;
> > (2) otherwise, use multiple headers."
> 
> I have no idea how this helps.
> 
> Maybe you could give a concrete example where the current definition is a
> problem, and then we can start from there?

because it is ambiguous

ambiguous:
adjective
(of language) open to more than one interpretation; having a double meaning
• unclear or inexact because a choice between alternatives has not been made

because ambiguity is a barrier to interoperability [2]

[2] http://en.wikipedia.org/wiki/Semantic_interoperability

by analogy, a similar problem was reported in SOAP JMS Binding [3], and resolved by qualifying when to apply a specific choice (of results)

[3] http://www.w3.org/2002/ws/soapjms/tracker/issues/69
Comment 13 Anne 2012-03-26 20:24:23 UTC
I actually had an XXX on fixing this. Thanks for reminding me! http://dvcs.w3.org/hg/xhr/rev/0746d35a2068
Comment 14 Glenn Adams 2012-03-26 21:23:45 UTC
thanks