Skip to content

Commit

Permalink
fix issue 2898 (#2900)
Browse files Browse the repository at this point in the history
* fix issue 2898
  • Loading branch information
KhafraDev authored Mar 2, 2024
1 parent dde9dcb commit 28b2df8
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 13 deletions.
6 changes: 1 addition & 5 deletions lib/web/fetch/body.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,17 +275,13 @@ function cloneBody (body) {

// 1. Let « out1, out2 » be the result of teeing body’s stream.
const [out1, out2] = body.stream.tee()
const out2Clone = structuredClone(out2, { transfer: [out2] })
// This, for whatever reasons, unrefs out2Clone which allows
// the process to exit by itself.
const [, finalClone] = out2Clone.tee()

// 2. Set body’s stream to out1.
body.stream = out1

// 3. Return a body whose stream is out2 and other members are copied from body.
return {
stream: finalClone,
stream: out2,
length: body.length,
source: body.source
}
Expand Down
6 changes: 3 additions & 3 deletions lib/web/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const {
fromInnerResponse
} = require('./response')
const { HeadersList } = require('./headers')
const { Request, makeRequest } = require('./request')
const { Request, cloneRequest } = require('./request')
const zlib = require('node:zlib')
const {
bytesMatch,
Expand Down Expand Up @@ -1405,7 +1405,7 @@ async function httpNetworkOrCacheFetch (
// Otherwise:

// 1. Set httpRequest to a clone of request.
httpRequest = makeRequest(request)
httpRequest = cloneRequest(request)

// 2. Set httpFetchParams to a copy of fetchParams.
httpFetchParams = { ...fetchParams }
Expand Down Expand Up @@ -1942,7 +1942,7 @@ async function httpNetworkFetch (
// 17. Run these steps, but abort when the ongoing fetch is terminated:

// 1. Set response’s body to a new body whose stream is stream.
response.body = { stream }
response.body = { stream, source: null, length: null }

// 2. If response is not a network error and request’s cache mode is
// not "no-store", then update response in httpCache for request.
Expand Down
2 changes: 1 addition & 1 deletion lib/web/fetch/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -990,4 +990,4 @@ webidl.converters.RequestInit = webidl.dictionaryConverter([
}
])

module.exports = { Request, makeRequest, fromInnerRequest }
module.exports = { Request, makeRequest, fromInnerRequest, cloneRequest }
33 changes: 33 additions & 0 deletions test/fetch/issue-2898.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict'

const assert = require('node:assert')
const { once } = require('node:events')
const { createServer } = require('node:http')
const { test } = require('node:test')
const { fetch } = require('../..')

// https://github.com/nodejs/undici/issues/2898
test('421 requests with a body work as expected', async (t) => {
const expected = 'This is a 421 Misdirected Request response.'

const server = createServer((req, res) => {
res.statusCode = 421
res.end(expected)
}).listen(0)

t.after(server.close.bind(server))
await once(server, 'listening')

for (const body of [
'hello',
new Uint8Array(Buffer.from('helloworld', 'utf-8'))
]) {
const response = await fetch(`http://localhost:${server.address().port}`, {
method: 'POST',
body
})

assert.deepStrictEqual(response.status, 421)
assert.deepStrictEqual(await response.text(), expected)
}
})
6 changes: 2 additions & 4 deletions test/wpt/status/fetch.status.json
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,8 @@
},
"response": {
"response-clone.any.js": {
"fail": [
"Check response clone use structureClone for teed ReadableStreams (ArrayBufferchunk)",
"Check response clone use structureClone for teed ReadableStreams (DataViewchunk)"
]
"note": "Node streams are too buggy currently.",
"skip": true
},
"response-consume-empty.any.js": {
"fail": [
Expand Down

0 comments on commit 28b2df8

Please sign in to comment.