Skip to content

Error occurred while processing headers when request http2 #2329

@binsee

Description

@binsee

Bug Description

When requesting http2 continuously, an error will occur when the headers contain the Content-Type field and other headers.

When requesting http2, the first request will actually use Request[kHTTP1BuildRequest] instead of Request[kHTTP2BuildRequest], so this issue will not be triggered. Related:
#2326

Reproducible By

test code:

import { Pool, request } from 'undici'
import { setTimeout as sleep } from 'timers/promises'
import { createSecureServer } from 'http2'
import pem from 'https-pem'
import { AddressInfo } from 'net'

async function main() {
  const server = createSecureServer({ ...pem, allowHTTP1: false })
  server
    .on('request', (req, rsp) => {
      console.log('server receive request:', req.method, req.url.toString())
      rsp.setHeader('Content-Type', 'text/html; charset=utf-8')
      rsp.write('hello')
      rsp.end()
    })
    .listen(0)

  const host = `https://localhost:${(server.address() as AddressInfo).port}`
  const client = new Pool(host, {
    allowH2: true,
    connections: 1,
    connect: { rejectUnauthorized: false },
  })

  for (let i = 0; i < 5; i++) {
    console.log(`before request [${i}]`)
    const rsp = await request(`${host}/test`, {
      method: 'GET',
      dispatcher: client,
      headers: {
        'Content-Type': 'application/text',
        otherHeader: 'test',
      },
    })

    console.log('client receive response:', rsp.statusCode)
    console.log(`after request [${i}]\n`)
  }

  await sleep(5e3)
}

void main()

Expected Behavior

No error occurs

Logs & Screenshots

I added some logs in undici to track the behavior of the code

before request [0]
[undici] client[kDispatch] kHTTPConnVersion h1
[undici] request processHeader { key: 'Content-Type', val: 'application/text', skipAppend: false }
[undici] request processHeader { key: 'name', val: '111', skipAppend: false }
[undici] client.connect() socket.alpnProtocol h2 Error
    at connect (/Users/test/node_modules/undici/lib/client.js:1231:87)
(node:40259) [UNDICI-H2] Warning: H2 support is experimental, expect them to change at any time.
(Use `node --trace-warnings ...` to show where the warning was created)
server receive request: POST /test
client receive response: 200
after request [0]

before request [1]
[undici] client[kDispatch] kHTTPConnVersion h2
[undici] request processHeader { key: 'Content-Type', val: 'application/text', skipAppend: true }
[undici] request processHeader { key: 'name', val: '111', skipAppend: true }
/Users/test/node_modules/undici/lib/core/request.js:434
      if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend)
                                           ^
TypeError: Cannot create property 'name' on string '[object Object]Content-Type: application/text
'
    at processHeader (/Users/test/node_modules/undici/lib/core/request.js:434:44)
    at Function.[http2 build request] (/Users/test/node_modules/undici/lib/core/request.js:314:9)
    at Client.[dispatch] (/Users/test/node_modules/undici/lib/client.js:361:36)
    at Client.Intercept (/Users/test/node_modules/undici/lib/interceptor/redirectInterceptor.js:11:16)
    at Client.dispatch (/Users/test/node_modules/undici/lib/dispatcher-base.js:179:40)
    at Pool.[dispatch] (/Users/test/node_modules/undici/lib/pool-base.js:143:28)
    at Pool.dispatch (/Users/test/node_modules/undici/lib/dispatcher-base.js:179:40)
    at Pool.request (/Users/test/node_modules/undici/lib/api/api-request.js:169:10)
    at /Users/test/node_modules/undici/lib/api/api-request.js:162:15
    at new Promise (<anonymous>)

Environment

  • MacOS 14.0
  • Nodejs 16.19.0
  • undici 5.25.4

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions