{"id":17045444,"url":"https://github.com/ballercat/mockttp-multi-header-issue","last_synced_at":"2026-04-11T08:04:16.936Z","repository":{"id":203173536,"uuid":"708997116","full_name":"ballercat/mockttp-multi-header-issue","owner":"ballercat","description":"repro of multiple values in a header (like `set-cookie`)","archived":false,"fork":false,"pushed_at":"2023-10-24T16:50:12.000Z","size":97,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-28T08:48:45.649Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ballercat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-10-23T20:03:19.000Z","updated_at":"2023-10-23T20:03:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"532e2d5f-4824-41c8-814e-fd7d20d4d913","html_url":"https://github.com/ballercat/mockttp-multi-header-issue","commit_stats":null,"previous_names":["ballercat/mockttp-multi-header-issue"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ballercat%2Fmockttp-multi-header-issue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ballercat%2Fmockttp-multi-header-issue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ballercat%2Fmockttp-multi-header-issue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ballercat%2Fmockttp-multi-header-issue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ballercat","download_url":"https://codeload.github.com/ballercat/mockttp-multi-header-issue/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245048275,"owners_count":20552483,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T09:37:26.839Z","updated_at":"2026-04-11T08:04:16.838Z","avatar_url":"https://github.com/ballercat.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Multi Headers issue with CORS enabled\n\n```\nyarn\nyarn test\n```\n\nOne test should pass and one should fail. Both test are identical except that the\nfailing spec is enabling cors via `mockServer.getLocal({ cors: true })`\n\nThe problem is that the way headers are passed to `writeHead` is broken when there\nis already an existing header in the `ServerResponse`. In these cases (like when cors is on),\n`writeHead` will run `setHeader` on each entry and simply mangle headers that are intended to\nbe multi values/arrays.\n\nHere is the failing spec\n\n```js\ntest.serial(\"multi-headers, cors on (this will fail)\", async (t) =\u003e {\n  let serverCookieHeader;\n  const proxy = mockttp.getLocal({ debug: true, cors: true });\n  await proxy.start();\n\n  proxy\n    .forAnyRequest()\n    .forHost(\"multi-headers-mockttp-test.com\")\n    .thenForwardTo(\"http://localhost:42069\", {\n      beforeResponse(res) {\n        serverCookieHeader = res.headers[\"set-cookie\"];\n      },\n    });\n\n  const app = express();\n  app.use((req, res, next) =\u003e {\n    res.cookie(\"bar\", \"bar\");\n    next();\n  });\n  app.get(\"*\", (_, res) =\u003e {\n    res.cookie(\"foo\", \"foo\");\n    res.status(200).send(\"OK\");\n  });\n\n  const server = http.createServer(app);\n  await promise(server.listen.bind(server), 42069);\n\n  const opts = { agent: new HttpsProxyAgent(proxy.url) };\n\n  const res = await fetch(\"http://multi-headers-mockttp-test.com/\", opts);\n  await proxy.stop();\n\n  t.is(res.headers.get(\"set-cookie\"), \"bar=bar; Path=/, foo=foo; Path=/\");\n  t.is(res.headers.get(\"set-cookie\"), serverCookieHeader.join(\", \"));\n\n  await new Promise((res, rej) =\u003e {\n    server.close((error) =\u003e {\n      if (error) {\n        rej(error);\n      } else {\n        server.unref();\n        res();\n      }\n    });\n  });\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fballercat%2Fmockttp-multi-header-issue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fballercat%2Fmockttp-multi-header-issue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fballercat%2Fmockttp-multi-header-issue/lists"}