[whatwg/fetch] Clarify semantics of checking done, closed, etc. states of a null body stream (#635)

I'm trying to figure out the semantics of checking the **done**, **closed**, **errored**, **disturbed** statuses of a body's stream, when that stream is null.

### Example 1: Non-303 redirect causes body done check

For an example of where a "null body stream done check" can occur, say we're in a service worker script making a `fetch()` request to a same-origin URL. Suppose that request has a body with or without a source buffer.

```js
let request = new Request(someUrl, { method: 'POST', body: someBodyInitializer })
let response = await fetch(request)
```

The fetch request's body will initially possess a *stream* (and possibly a *source*, irrelevant to this example). By my reading, the stream will be nullified in step 2.2.4 of [HTTP network-or-cache fetch](https://fetch.spec.whatwg.org/#http-network-or-cache-fetch), which is called from [HTTP fetch](https://fetch.spec.whatwg.org/#http-fetch) step 4.3.

Say the response is a non-303 redirect. [HTTP fetch](https://fetch.spec.whatwg.org/#http-fetch) step 5.1 kicks in and checks whether the request's body is **done**, i.e., "body is null or body’s stream is closed or errored." Since the request's body is not null, we must check if body's stream (which *is* null) is closed or errored, i.e., `(null.[[closed]] || null.[[errored]])`. I presume this would throw an error.

### Example 2: Checking request.bodyUsed after fetch()

Assume the same situation as above, but say we receive a non-redirect response. The fetch() will complete with the body's stream remaining null (from step 2.2.4 of HTTP network-or-cache fetch). Now say the user checks `request.bodyUsed` after the `await fetch(request)` completes. Since request's body itself is non-null, the `bodyUsed` accessor checks if body's stream is disturbed, defined as "`IsReadableStreamDisturbed(stream)` is true". But body's stream being null violates `IsReadableStreamDisturbed()`'s precondition (https://streams.spec.whatwg.org/#is-readable-stream-disturbed). I presume this would also throw an error.

### A related issue: bodyUsed is false after 301, 302, 303 redirect

For a second, related issue, consider what happens in the above examples when the response is a 301 or 302. Since the request was a POST, the [HTTP redirect-fetch](https://fetch.spec.whatwg.org/#http-redirect-fetch) algorithm will set request's method to GET and request's body to null in step 9 before passing it off to a recursive call to main fetch. Assume the subsequent GET request completes without incident and the user checks `request.bodyUsed` after the `await fetch(request)` line completes. Since request's entire body is null, it cannot be disturbed, so `bodyUsed` returns false. That seems counterintuitive to me -- the request initially had a body, it was transmitted in the first request, then the request was converted to a GET with a null body when the fetch algorithm hit a redirect. I would expect that `bodyUsed` should return true in this situation.

Note that this situation would also happen for a 303 redirect, assuming some workaround for the "null body stream done check" issue.

I can open a separate issue for this question, but wanted to mention it here, so I could explain it using the same example.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/issues/635

Received on Monday, 20 November 2017 20:30:43 UTC