Skip to content

Unable to read response cookies until onSend #269

@Galienna

Description

@Galienna

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.25.2

Plugin version

9.2.0

Node.js version

20.9.0

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

20.04

Description

Hello,

In my route handler, if I use reply.setCookie to set a response cookie, I'm unable to read it inside my handler by calling reply.getHeader('set-cookie'). However, I can read my resp cookie later in the lifecycle (onSend and onResponse).

I need to read it inside my handler. Maybe it's working as intended or I missed something ?

Steps to Reproduce

Server :

const fastify = require('fastify');
const fastifyCookie = require('@fastify/cookie');

async function testCookiePlugin() {
    const server = fastify();
    server.register(fastifyCookie);

    server.addHook('preSerialization', async function (request, reply) {
        console.log('--------- server preSerialization -------------');
        console.log('Read response cookies through reply.getHeader(\'set-cookie\')', reply.getHeader('set-cookie'));
    });

    server.addHook('onSend', async function (request, reply) {
        console.log('--------- server onSend -------------');
        console.log('Read response cookies through reply.getHeader(\'set-cookie\')', reply.getHeader('set-cookie'));
    });

    server.addHook('onResponse', async function (request, reply) {
        console.log('--------- server onResponse -------------');
        console.log('Read response cookies through reply.getHeader(\'set-cookie\')', reply.getHeader('set-cookie'));
    });

    server.route({
        method: 'GET',
        url: '/',
        handler: async function (request, reply) {
            console.log('--> Set resp cookie through reply.setCookie');
            reply.setCookie('through-plugin', 'cookie set through reply.setCookie');
            console.log('Read response cookies through reply.getHeader(\'set-cookie\')', reply.getHeader('set-cookie'));

            console.log('--> Set resp cookie through reply.header');
            reply.header('set-cookie', 'through-header=cookie set through reply.header; Secure; HttpOnly');
            console.log('Read response cookies through reply.getHeader(\'set-cookie\')', reply.getHeader('set-cookie'));

            return {
                setCookieHeader: reply.getHeader('set-cookie')
            };
        },
        preSerialization: async function (request, reply) {
            console.log('--------- route preSerialization -------------');
            console.log('Read response cookies through reply.getHeader(\'set-cookie\')', reply.getHeader('set-cookie'));
        },
        onSend: async function (request, reply) {
            console.log('--------- route onSend -------------');
            console.log('Read response cookies through reply.getHeader(\'set-cookie\')', reply.getHeader('set-cookie'));
        },
        onResponse: async function (request, reply) {
            console.log('--------- route onResponse -------------');
            console.log('Read response cookies through reply.getHeader(\'set-cookie\')', reply.getHeader('set-cookie'));
        }
    });

    return server.listen({port: 8080, host: '0.0.0.0'});
}

return testCookiePlugin();

The following curl curl -i http://localhost:8080/ gives me this :

HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
set-cookie: through-header=cookie set through reply.header; Secure; HttpOnly
set-cookie: through-plugin=cookie%20set%20through%20reply.setCookie
content-length: 86
Date: Wed, 10 Jan 2024 11:22:13 GMT
Connection: keep-alive
Keep-Alive: timeout=72

{"setCookieHeader":"through-header=cookie set through reply.header; Secure; HttpOnly"}

And server logs :

--> Set resp cookie through reply.setCookie
Read response cookies through reply.getHeader('set-cookie') undefined

--> Set resp cookie through reply.header
Read response cookies through reply.getHeader('set-cookie') through-header=cookie set through reply.header; Secure; HttpOnly

--------- server preSerialization -------------
Read response cookies through reply.getHeader('set-cookie') through-header=cookie set through reply.header; Secure; HttpOnly

--------- route preSerialization -------------
Read response cookies through reply.getHeader('set-cookie') through-header=cookie set through reply.header; Secure; HttpOnly

--------- server onSend -------------
Read response cookies through reply.getHeader('set-cookie') [
  'through-header=cookie set through reply.header; Secure; HttpOnly',
  'through-plugin=cookie%20set%20through%20reply.setCookie'
]

--------- route onSend -------------
Read response cookies through reply.getHeader('set-cookie') [
  'through-header=cookie set through reply.header; Secure; HttpOnly',
  'through-plugin=cookie%20set%20through%20reply.setCookie'
]

--------- server onResponse -------------
Read response cookies through reply.getHeader('set-cookie') [
  'through-header=cookie set through reply.header; Secure; HttpOnly',
  'through-plugin=cookie%20set%20through%20reply.setCookie'
]

--------- route onResponse -------------
Read response cookies through reply.getHeader('set-cookie') [
  'through-header=cookie set through reply.header; Secure; HttpOnly',
  'through-plugin=cookie%20set%20through%20reply.setCookie'
]

Expected Behavior

I expect I can write/read response cookies through the plugin the "same way" I do through reply.header('set-cookie', ...).
I would like the plugin to modify the set-cookie response header as soon as i call the reply.setCookie method.
I find it misleading to "hide" the cookies that will be sent until the onSend lifecycle step.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions