Re: [fetch] Proposed backward-incompatible change: requiring cloning all requests/responses (#61)

@jakearchibald that ignores streams. We need to figure out a model that makes sense with streams.

I have a proposal. We keep the new `offset` feature to figure out if a stream has been used.

In addition, to solve #55, we give `Request` an "obsolete flag", set for requests during `new Request()` for requests with non-null bodies.

In addition we rewrite everything in terms of a high-level "validate the Request/Response stream" algorithm that a) checks for the offset to be 0 b) checks for the obsolete flag to be unset which can be reused by `put()`/`new Request()`.

Here are some examples to show what this means:

```js
req = new Request({body: ""})
assert(req.body !== null)
assert_false(req.bodyUsed)
fetch(req) // success
assert(req.body === null) // due to transfer
assert_true(req.bodyUsed) // due to obsolete flag
assert_reject(fetch(req)) // due to obsolete flag

req = new Request()
assert(req.body === null)
assert_false(req.bodyUsed)
fetch(req) // success, obsolete flag not set due to null body
assert(req.body === null)
assert_false(req.bodyUsed)
fetch(req) // success

req = new Request({body: "Hallo wereld!"})
assert(req.body !== null)
assert_false(req.bodyUsed)
fetch(req) // success
assert(req.body === null) // due to transfer
assert_true(req.bodyUsed) // due to obsolete flag
assert_reject(fetch(req)) // due to obsolete flag

req = new Request({body: "Hallo wereld!"})
req.body.getReader()
assert(req.body !== null)
assert_false(req.bodyUsed)
assert_reject(fetch(req)) // because lock not released

req = new Request({body: "Hallo wereld!"})
reader = req.body.getReader()
reader.releaseLock()
assert(req.body !== null)
assert_false(req.bodyUsed)
fetch(req) // success

req = new Request({body: "Hallo wereld!"})
reader = req.body.getReader()
reader.read().then(() => {
  reader.releaseLock()
  assert(req.body !== null)
  assert_true(req.bodyUsed) // due to offset
  assert_reject(fetch(req)) // due to offset
})

stream = new Pipe()
req = new Request({body: stream})
assert(req.body !== null)
assert_false(req.bodyUsed)
fetch(req) // success
assert(req.body === null) // due to transfer
assert_true(req.bodyUsed) // due to obsolete flag
assert_reject(fetch(req)) // due to obsolete flag
```

So bodyUsed is defined as associated stream's offset being greater than 0 or obsolete flag being set. And we end up treating null differently from the empty string.

I think this would be compatible with what we have today and allow for streams.

---
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/issues/61#issuecomment-115376269

Received on Thursday, 25 June 2015 19:54:35 UTC