Contact emails
Spec
https://streams.spec.whatwg.org/
https://fetch.spec.whatwg.org/
https://github.com/yutakahirano/fetch-with-streams/ (will be merged to https://fetch.spec.whatwg.org/ shortly)
Summary
Body.bodyUsed is used to check if the object (Request or Response)'s body is read. Some customers (e.g. Cache.put) checks before reading the body.
The property was shipped at M40 in part of Fetch API (Notice Fetch API was shipped with ServiceWorker, and exposed to Window after that) and modified when body stream was introduced (M43). Recently we decided to change it again for the better consistency with other APIs (FetchEvent.respondWith, Cache.put, ...).
The change consists of two parts:
1. ReadableStreamReader will not be released when closed or errored.
Currently a reader of Readable[Byte]Stream will be released when the stream is closed or errored. We remove this auto-release mechanism.
var promise = fetch('https://www.example.com/').then(res => res.text().then(() => res.body.getReader()));
The promise will be resolved with the current implementation (because after text() is done the body stream will be closed and the reader will be released), but will be rejected with the new behavior.
2. Body.bodyUsed will be based on 'disturbed' internal property of ReadableStream.
Currently Body.bodyUsed returns true if the body stream is locked. With the new interpretation Body.bodyUsed returns true when someone has read any data from the body stream.
var stream = response.body;
var reader = stream.getReader();
reader.read(() => {
reader.releaseLock();
// Here the stream is no longer locked, but bodyUsed returns true.
assert_true(response.bodyUsed);
});
I'm sorry we change the behavior after shipping, but we believe this change doesn't break user-code largely and the new behavior is stable enough (Fetch / Streams guys held a face-to-face meeting and reached consensus).
Discussion threads:
- https://github.com/yutakahirano/fetch-with-streams/issues/37
- https://github.com/whatwg/streams/issues/378
- https://github.com/whatwg/streams/pull/385
Compatibility Risk
1. Removing auto-release mechanism affects users who try to read data from a stream that is already consumed. We did not find any useful use-cases, and we don't expect this change breaks user-code largely.
2. For the bodyUsed change, reading data partially from ReadableStream and calling other APIs (text(), cache.put, ...) will be disallowed. But currently we don't provide a means to read bytes with specifying byte length, so we think there are little code that will be affected.
We are not planning to investigate use-counters because the body stream itself is not yet so popular.
Ongoing technical constraints
None.
Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?
Yes.
OWP launch tracking bug
None.
Link to entry on the feature dashboard
https://www.chromestatus.com/features/6730533392351232
Requesting approval to ship?
Yes.
1. ReadableStreamReader will not be released when closed or errored.
Currently a reader of Readable[Byte]Stream will be released when the stream is closed or errored. We remove this auto-release mechanism.
var promise = fetch('https://www.example.com/').then(res => res.text().then(() => res.body.getReader()));
The promise will be resolved with the current implementation (because after text() is done the body stream will be closed and the reader will be released), but will be rejected with the new behavior.
I mean, for the uneducated (or not native speaker) me, this sounds backwards... What is a released stream reader?
So currently, the stream is locked during res.text() and once that is done, it gets unlocked and others can read from it, right?
The new behavior keeps it locked so others cannot read it, right?
Sorry for not being clear. I'm not a native speaker, too.I mean, for the uneducated (or not native speaker) me, this sounds backwards... What is a released stream reader?ReadableStream has "getReader" method. When called,- The stream is already locked => Throw an error.- Mark the stream as locked.- Return a ReadableStreamReader.ReadableStreamReader has "releaseLock" method. When called,- The reader is already released => Return and do nothing- Unmark "locked" label on the associated stream.- Mark the reader as released.Currently, when a stream is closed or errored and the stream is locked, the associated reader will be automatically released (i.e. releaseLock is called)."1. ReadableStreamReader will not be released when closed or errored." removes this automatic release.So currently, the stream is locked during res.text() and once that is done, it gets unlocked and others can read from it, right?Yes. Please note that text() reads all data from the body stream and "others" can read only empty data after that.The new behavior keeps it locked so others cannot read it, right?Yes.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.