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 24072 - Clarify handling of neutered objects
Summary: Clarify handling of neutered objects
Status: RESOLVED WORKSFORME
Alias: None
Product: WHATWG
Classification: Unclassified
Component: Fetch (show other bugs)
Version: unspecified
Hardware: PC Windows NT
: P2 normal
Target Milestone: Unsorted
Assignee: Anne
QA Contact: sideshowbarker+fetchspec
URL:
Whiteboard:
Keywords:
Depends on: 28798 24339
Blocks: 26153
  Show dependency treegraph
 
Reported: 2013-12-12 09:56 UTC by sof
Modified: 2016-08-24 13:04 UTC (History)
6 users (show)

See Also:


Attachments

Description sof 2013-12-12 09:56:20 UTC
A Blob can be transitioned to a neutered state by the close() method,

   http://dev.w3.org/2006/webapi/FileAPI/#close-method

Similarly for ArrayBufferViews, and them being neutered upon transfer.

How should XMLHttpRequest.send() and FormData.append() handle such objects? Throw an exception, considered as "empty" objects? The relevant sections of the XMLHttpRequest specification doesn't make this clear.

It makes some sense to have the error handling be strict and throw upon use of these no-longer-useful objects, but perhaps that's already implicitly covered by the spec text?
Comment 1 Anne 2013-12-12 11:35:43 UTC
Throwing sounds good. I wish we had some kind of generic annotation for this in IDL so everyone accepting ArrayBuffer and Blob and such would not fall in this trap.
Comment 2 Boris Zbarsky 2013-12-12 14:03:37 UTC
The ArrayBuffer story is interesting.  Is a neutered ArrayBuffer in any way distinguishable from the return value of new ArrayBuffer(0)?  It's not in Gecko, afaict, but I'm not sure what the ES spec says.

As far as blobs go:

  var f = new FormData(); f.append("foo", myblob); f.get("foo").close();

so the spec/code needs to deal with a closed blob downstream no matter what.  Whether we want to check for it up front, I don't know...  But even if we had a generic annotation for the up front case, I expect most blob users would need to think about the closed-blob issues due to things like the above.
Comment 3 Boris Zbarsky 2013-12-12 14:06:57 UTC
Looks like per the current ES6 text something like .byteLength on a neutered ArrayBuffer should throw.  

Neither Gecko nor Blink implement that (both return 0), so I'm not sure how web-compatible this spec is, exactly, and whether it will stay the way it is.
Comment 5 sof 2014-01-07 14:13:59 UTC
Any conclusions from the mailing list thread on who gets to define Blob.close() semantics?
Comment 6 Anne 2014-01-08 09:27:24 UTC
No, but I think it's on Arun to define the complete Blob life cycle. And if that turns out to expose states that ought to behave differently in other contexts, it would be up to us to deal with that.
Comment 7 Arun 2014-01-10 16:42:08 UTC
(In reply to Anne from comment #6)
> No, but I think it's on Arun to define the complete Blob life cycle. And if
> that turns out to expose states that ought to behave differently in other
> contexts, it would be up to us to deal with that.

OK; I agree this should be done in File API, and I agree it is therefore on me.

It seems from the list you would also like a rewrite of the FileReader.read* methods in terms of Blob state / model.  This seems fine, but there are some points which I'd like you to clarify your opinion on based on mail list comments:

1. An empty Blob and a Blob of size 0 are not equivalent in your opinion, correct?
2. Should reading an empty Blob be treated as an I/O error, using the existing way we do this in read methods (namely, error event coupled with a DOMError), or simply return a distinct result?  Can this be applied to FormData?
Comment 8 Anne 2014-01-11 15:54:05 UTC
I'm not sure I care about the particulars. I just want the low-level model we need to operate on to be clear. Other than that I suppose we should focus on simplicity for developers.

So a Blob either has an association with a bag of bits or is closed.

A Blob has a size which is the length of the associated bag of bits or 0 if there is no association.

A Blob has a read operation. If there is an associated bag of bits this operation can fail for reasons listed in the specification now that would be better placed as part of this operation I think. If there is no associated bag of bits we could always return the empty byte sequence or return "closed" or some such and let the higher-level API deal with it. Failing might be okay given that the read operation can fail anyway. Some testing on what browsers do today might be worth doing.
Comment 9 Arun 2014-01-20 19:54:17 UTC
(In reply to Anne from comment #8)
> I'm not sure I care about the particulars. I just want the low-level model
> we need to operate on to be clear. Other than that I suppose we should focus
> on simplicity for developers.
> 
> So a Blob either has an association with a bag of bits or is closed.
> 
> A Blob has a size which is the length of the associated bag of bits or 0 if
> there is no association.
> 
> A Blob has a read operation. If there is an associated bag of bits this
> operation can fail for reasons listed in the specification now that would be
> better placed as part of this operation I think. If there is no associated
> bag of bits we could always return the empty byte sequence or return
> "closed" or some such and let the higher-level API deal with it. Failing
> might be okay given that the read operation can fail anyway. Some testing on
> what browsers do today might be worth doing.

Bug 24339 is for this spec fix.
Comment 10 sof 2014-01-22 16:21:31 UTC
The handling of neutered ArrayBuffers (treat them as empty) is currently compatible with the Khronos spec.

Will wait & see where ES6 heads on neutering of ArrayBuffers. 24.1.5 in the current drafts says "will fail" on accessing a neutered object -- guess that will be expanded upon soon enough.
Comment 12 Arun 2014-06-02 20:44:34 UTC
The whiteboard comment says that this is blocked on File API, but I hope that this is now unblocked. File API's "close" is decoupled from neutered objects in the transferable and clonable sense.

The close method on a Blob (namely http://dev.w3.org/2006/webapi/FileAPI/#close-method) sets a state that causes other operations to fail (e.g. FileReader.readAsXXX fails) or propagate the closed status (e.g. Blob.slice spawns a closed slice). Fetching of a closed Blob URL causes a network error.
Comment 13 Anne 2015-09-26 16:41:19 UTC
So in principle throwing seems better to me, but I'm not sure what that means for FormData. I guess FormData's serialization could throw. However, that would also mean FormData's serialization has to make structured clones of the objects it contains since we cannot read those all synchronously and we wouldn't want them to end up being neutered while uploading is happening.

Does that still sound like a reasonable model at that point? Or should we go for silent failures and make detached buffers and closed blobs the same as empty byte sequences?
Comment 14 Anne 2016-08-24 13:04:53 UTC
The ArrayBuffer part of this bug are actually issues with IDL:

  https://github.com/heycam/webidl/issues/151
  https://www.w3.org/Bugs/Public/show_bug.cgi?id=28798

At this point I think we should not throw for detached buffers. That will likely cause breakage.

The Blob's close() method does not appear to be implemented:

  https://github.com/w3c/FileAPI/issues/10

So I'm not sure what we're planning on doing there. But it seems that if it's ever implemented, making all callsites throw is going to be difficult to get right.

With that I'm closing this bug as I don't think there's anything to be done here in Fetch and XMLHttpRequest.