W3C home > Mailing lists > Public > public-webapi@w3.org > April 2006

Re: XMLHttpRequest Object feedback

From: Mark Nottingham <mnot@yahoo-inc.com>
Date: Fri, 21 Apr 2006 09:29:06 -0700
Message-Id: <68CAB27E-83BD-4CE5-8EFA-A1E3D4B9F007@yahoo-inc.com>
Cc: "Web APIs WG (public)" <public-webapi@w3.org>
To: Anne van Kesteren <annevk@opera.com>


On 2006/04/21, at 6:34 AM, Anne van Kesteren wrote:
>> * responseText attribute - type the response as an HTTP entity  
>> explicitly (you already do this for the request data); that way,  
>> there's no ambiguity about what level the implementation operates  
>> at. I.e., XHR won't give you direct access to the raw HTTP  
>> bytestream, with transfer-codings like chunked visible.
>
> So what exactly is the right term? I looked up "response entity",  
> "response body" and "request body" and they seem to be used in RFC  
> 2616 but not really properly defined anywhere... I'm probably  
> missing something though, a pointer to a section would be welcome.

See section 7.2.1; something like

"XHR operates across entity bodies, as defined by [RFC2616, section  
7.2.1]; that is, transfer-encodings are applied to request bodies  
submitted to send(), as well as response bodes made available."

>> WRT supported methods, it should support PUT, DELETE, FOO and  
>> anything else that's syntactically correct.
>
> I suggest your partake in ISSUE-74.

Ack. BTW, the issues list isn't obviously linked from the WG's home  
page.

>> WRT URIs, what should happen when I pass it a URI with a fragment  
>> identifier?
>
> Do you perhaps know what implementations do?

I can't imagine that they'd do much, but I'll test and report back.  
Assuming they don't, it might be good to say something to the effect  
that fragment identifiers either
   a) aren't allowed
   b) might not be supported

>> Nit - WRT redirect loops, there's a caveat on it, so it's a  
>> SHOULD, not a MUST.
>
> That caveat is mentioned, I don't really see the problem. (For  
> example, what would be the problem with saying "Imp MUST do A  
> unless B is C."?)

It's a stylistic thing; YMMV.

>> When talking about redirects, it would be really nice to remind  
>> implementers (probably non-normatively) that HTTP has requirements  
>> about method preservation and getting approval for the user for  
>> the various codes; see http://www.mnot.net/javascript/xmlhttprequest/
>
> Suggestions for text? I also wonder what kind of implications it  
> would have for implementations given that currently most seem to  
> ignore it.

"Implementers should note that HTTP places requirements on  
implementations regarding the preservation of the request method  
during redirects, and also requires users to be notified of certain  
kinds of automatic redirections."

WRT how it affects implementers, I think that's a question of whether  
the WG intends to test the requirements it inherits from HTTP (and  
other specs) during the CR phase.

>> Content-coding is a property of the content (entity,  
>> representation, whatever) itself -- just like content-type and  
>> content-language -- and automatically handling it breaks layering  
>> (which is OK, as long as you do it explicitly). This means that if  
>> decoding is handled automagically, the appropriate part of the  
>> Content-Encoding header should probably be stripped, so the app  
>> doesn't get confused.
>
> What do you mean?

In HTTP, Content-* headers are entity headers -- they describe  
properties of the content explicitly. As such, they're not  
transparently handled by the implementations; if I send an entity and  
it's got a gzip encoding, I expect the guy on the other side to get a  
gzip encoding as well.

All that said, many people find it convenient for the implementation  
to handle content-encoding automatically.

I think the implication of this is that *if* the WG decides that  
content-encoding can be handled by the implementation automatically,  
there should be some control offered to the user over whether or not  
it happens.

The real trick for the WG might be in deciding what the default of  
that control is.

>> * setRequestHeader() -  HTTP allows header field-values to contain  
>> linefeeds and cr's; they should be allowed here.
>
> Why? As I understand section 4.2 they don't affect the actual value.

Just don't see any reason to disallow it. This isn't a big deal, though.

>> The specification of concatenation of headers is too simplistic; a  
>> header can be split across multiple lines, or have multiple  
>> entries. Some implementations will do this to avoid header length  
>> limitations out there.
>
> What is wrong with keeping this consistent? I don't really care  
> about making it more loose, but it should probably be discussed  
> first. Perhaps raise this separately?

This is more serious. Implementations are allowed to split outgoing  
headers on commas or whitespace to manage their length; e.g., so that  
they can have a reasonable buffer size for a single header (line). If  
you don't let them split a setRequestHeader() into multiple lines/ 
headers, they may have problems.

See below for suggested text.

>> Also, some headers are specified to have only a single value (not  
>> a list), and some implementations might take advantage of that  
>> knowledge to overwrite them, rather than concatenate new values.  
>> The current language effectively disallows that.

"Otherwise, the request header header must be set to value. If the  
request header header had already been set, then the new value must  
be concatenated to the existing value using a U+002C COMMA followed  
by a U+0020 SPACE for separation."

->

"Otherwise, the nominated request header field value MUST be set to  
value. If the nominated request header field already has a value, the  
new value SHOULD be combined with the existing value, as specified by  
[RFC2616 Section 4.2]. Implementations MAY replace an existing value  
(instead of combining it with the new value) if the nominated request  
header field value is not specified as a comma-separated list."

>> Say something to the effect that if the UA has a cache, it MUST  
>> honour Cache-Control request headers sent with setRequestHeader().  
>> This allows the application to control the cache.
>
> So we need more text besides "In particular, UAs MUST NOT  
> automatically set the <code>Cache-Control</code> or <code>Pragma</ 
> code> headers to defeat caching [RFC2616]."?

Yes. Something like "UAs that implement a cache should honour request  
cache-control headers." Note the lower-case SHOULD; HTTP already  
requires them to be honoured.

Based on my testing, implementations don't do this today. It would be  
very good if they do; as it is, developers don't have any control of  
the local cache.

>> The wording around Connection and Keep-Alive leads developers to  
>> believe that they always have to set these headers; that's not the  
>> case.
>
> Why? It specifically mentions UAs...

The text reads as if persistent connection support is required, when  
HTTP does not require it. It also normatively re-states the  
requirements of HTTP, which isn't good specification practice.

It should just be:

"UAs MUST NOT allow the Connection, Keep-Alive and Content-Length  
headers to be overridden."

Using the same logic, the requirement about the Host header should be

"UAs MUST NOT allow the Host header to be overridden."

>> "set" should probably be "use", and Content-Length should be in  
>> there too. In fact, I'd require UAs to set Content-Length; while  
>> theoretically you can chunk a request body, there are some  
>> practical interop problems with doing so.
>
> Could you elaborate on that?

Not applicable any more -- see above.

>> What about automatically setting headers to do with delta encoding  
>> (RFC3229)? TE (for transfer encoding negotiation)? Content-MD5  
>> (for request body integrity)? Meter (HTTP hit metering from  
>> caches)? The UA-* request headers? MUST NOT is too strong a  
>> prohibition for automatically-set headers; I'd suggest SHOULD NOT.  
>> (The response shown in the "Manipulating response headers" example  
>> is actually impossible for conforming implementations to see; you  
>> need to send TE to get a Transfer-Encoding back).
>
> Would it work if I removed "Transfer-Encoding: chunked" from the  
> example? And what are your suggestions for those other headers?

My suggestion would be to weaken "User agents MUST NOT set any  
headers other than the headers set by the author using this method"  
to SHOULD NOT.

Also, add TE to the list of headers that UAs MAY add.

>> * In open(), send() and setRequestHeader(), it says that the  
>> userinfo MUST be used. This is too simplistic; a naive  
>> implementation will send them optimistically as HTTP Basic  
>> authentication, which is the wrong thing to do from a security  
>> perspective. If they're supplied, the UA needs to wait for a 401  
>> Unauthenticated response, so it can learn that a) credentials are  
>> required and b) what scheme (and details thereof) to use.
>
> So "request to uri using method method, authenticating using user   
> and password as appropriate is sent" should have some addition?
>
>    Otherwise, the readyState attribute MUST be set to 2 (Sent)
>    and a request to uri using method method, authenticating
>    using user  and password as appropriate is sent. UAs MUST NOT
>    use HTTP Basic authentication when doing so, instead they
>    MUST wait for a 401 Unauthenticated response and use its
>    details to perform the request.
>
> Something like the above?

Hmm. The text in question is;

open()
   "If the URI given to this method contains a user name and a  
password (the latter potentially being the empty string), then these  
must be used if the user and password arguments are omitted"

send()
   "authenticating using user and password as appropriate"

setRequestHeader()
   "UAs must set the Authorization header according to the values  
passed to the open() method (but must allow calls to setRequestHeader 
() to append values to it)."

Of the three, the text around open() and send() isn't too bad; in send 
() I'd perhaps say "...be used for the purposes of authentication as  
appropriate."

setRequestHeader() is the problem. Something like this would improve it;

"UAs MAY set the Authorization header, based upon the operation of  
HTTP Authentication [RFC2617 ref]. If a challenge from the server is  
encountered, credentials SHOULD be generated based upon the values of  
the username and password specified by open(). UAs MUST NOT set the  
Authorization header solely because open() contains a username/ 
password; it should only be set as part of the protocol described by  
HTTP Authentication [RFC2617 ref]."

That probably needs some massaging to take account of the precedence  
rules for sourcing username and password. It's tricky, because the UA  
can optimistically send Authorization, based upon previous challenges  
sent; you just don't want the UA sending it without having seen a  
challenge.


Thanks!

--
Mark Nottingham
mnot@yahoo-inc.com
Received on Friday, 21 April 2006 16:30:00 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 8 January 2008 14:18:54 GMT