| 123 | }) |
| 124 | |
| 125 | function installErrorAndReconnectServer (server, p, { contentLength, trackPostWithPlan }) { |
| 126 | let sawPost = false |
| 127 | let sawGet = false |
| 128 | |
| 129 | server.on('request', (req, res) => { |
| 130 | if (req.method === 'GET') { |
| 131 | if (sawGet) { |
| 132 | req.socket?.destroy() |
| 133 | return |
| 134 | } |
| 135 | |
| 136 | sawGet = true |
| 137 | p.strictEqual('/', req.url) |
| 138 | p.strictEqual('GET', req.method) |
| 139 | res.setHeader('content-type', 'text/plain') |
| 140 | res.end('hello') |
| 141 | return |
| 142 | } |
| 143 | |
| 144 | if (sawPost) { |
| 145 | // Node.js 26 can surface additional POST attempts around the queued GET. |
| 146 | // Tear them down and keep the test focused on the reconnect behavior. |
| 147 | req.resume() |
| 148 | req.socket?.destroy() |
| 149 | return |
| 150 | } |
| 151 | |
| 152 | sawPost = true |
| 153 | |
| 154 | if (trackPostWithPlan) { |
| 155 | p.strictEqual('/', req.url) |
| 156 | p.strictEqual('POST', req.method) |
| 157 | p.strictEqual(req.headers['content-length'], contentLength) |
| 158 | } else { |
| 159 | assert.strictEqual('/', req.url) |
| 160 | assert.strictEqual('POST', req.method) |
| 161 | assert.strictEqual(req.headers['content-length'], contentLength) |
| 162 | } |
| 163 | |
| 164 | const bufs = [] |
| 165 | req.on('data', (buf) => { |
| 166 | bufs.push(buf) |
| 167 | }) |
| 168 | |
| 169 | req.on('aborted', () => { |
| 170 | // we will abruptly close the connection here |
| 171 | // but this will still end |
| 172 | if (trackPostWithPlan) { |
| 173 | p.strictEqual('a string', Buffer.concat(bufs).toString('utf8')) |
| 174 | } else { |
| 175 | assert.strictEqual('a string', Buffer.concat(bufs).toString('utf8')) |
| 176 | } |
| 177 | }) |
| 178 | }) |
| 179 | } |
| 180 | |
| 181 | function errorAndPipelining (type) { |
| 182 | test(`POST with a ${type} that errors and pipelining 1 should reconnect`, async (t) => { |