[whatwg/fetch] Inconsistency in Request constructor when rewriting a used body (#674)

Script authors sometimes have a need to rewrite a Request's body, e.g. a service worker that transforms POST messages. There is currently no easy way to do this if the original body must first be read. Currently, the following code will throw:

```javascript
let request = new Request("https://example.com/", {
  method: "POST",
  body: "an old body"
})

// Disturb the request's body.
let body = await request.text()

// Throws in Request ctor, step 7
let newRequest = new Request(request, {
  body: "a new body"
})
```

The last line throws, because Request's constructor is supposed to check that its first parameter is not disturbed (step 7) *before* it checks if its initialization dictionary contains a `body` property that will override the old body (steps 38-44).

This seems like a bug in the spec, because if we were to comment out the `await request.text()` line, the code snippet would work as intended: `newRequest` would have `"a new body"` as its body. That tells me that the intent was probably to allow authors to concisely rewrite bodies in just this way.

Note that even if step 7's check were modified or moved after the body extraction steps, there remains some ambiguity: if `Request()`'s first parameter is another Request object, step 43 unconditionally creates a new ReadableStream object from the old request's body, which I would expect to throw if the body were disturbed. Perhaps #463 will resolve that ambiguity.

/cc @kentonv

-- 
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/674

Received on Monday, 26 February 2018 19:06:59 UTC