You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apisix.apache.org by Zexuan Luo <sp...@apache.org> on 2022/08/23 07:12:25 UTC

[DISCUSS] Proposal: Support adding header in response-rewrite

Background

Currently, response-rewrite plugin only supports set / delete headers.
The limitation makes some operations impossible. For example, we can't
add a Set-Cookie header in APISIX as it may override the Set-Cookie
header from the upstream.
Therefore, we need a way to add a header without overriding the existing one.

Solution

We can enrich the headers field and add the operation name to it. Here
is the new configuration schema:

headers = {
    description = "new headers for response",
    anyOf = {
        {
            type = "object",
            minProperties = 1,
            patternProperties = {
                ["^[^:]+$"] = {
                    oneOf = {
                        {type = "string"},
                        {type = "number"},
                    }
                }
            },
        },
        {
            properties = {
                add = {
                    type = "array",
                    minItems = 1,
                    items = {
                        type = "string",
                        -- "Set-Cookie: <cookie-name>=<cookie-value>;
Max-Age=<number>"
                        pattern = "^[^:]+:[^:]+$"
                    }
                },
                set = {
                    type = "object",
                    minProperties = 1,
                    patternProperties = {
                        ["^[^:]+$"] = {
                            oneOf = {
                                {type = "string"},
                                {type = "number"},
                            }
                        }
                    },
                },
                remove = {
                    type = "array",
                    minItems = 1,
                    items = {
                        type = "string",
                        -- "Set-Cookie"
                        pattern = "^[^:]+$"
                    }
                },
            }
        }
    }
},

set means rewriting the headers,
remove means removing the headers,
addmeans appending the new headers.
For set and add, the header format is "name: value", while for remove,
the format is "name".
We use array to represent multiple headers, so the same header can be
used multiple times in the add. For example,

add = {
    "Cache-Control: no-cache",
    "Cache-Control: max-age=0, must-revalidate"
}

The previous configuration can be migrated as part of the new configuration.
The execution order among those operations are ["add", "set", "remove"].

Inspired by:
https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
https://docs.konghq.com/hub/kong-inc/response-transformer/

Re: [DISCUSS] Proposal: Support adding header in response-rewrite

Posted by Nicolas Frankel <ni...@api7.ai>.
I saw this limitation some time ago. Great idea IMHO!

On Tue, Aug 23, 2022 at 9:12 AM Zexuan Luo <sp...@apache.org> wrote:

> Background
>
> Currently, response-rewrite plugin only supports set / delete headers.
> The limitation makes some operations impossible. For example, we can't
> add a Set-Cookie header in APISIX as it may override the Set-Cookie
> header from the upstream.
> Therefore, we need a way to add a header without overriding the existing
> one.
>
> Solution
>
> We can enrich the headers field and add the operation name to it. Here
> is the new configuration schema:
>
> headers = {
>     description = "new headers for response",
>     anyOf = {
>         {
>             type = "object",
>             minProperties = 1,
>             patternProperties = {
>                 ["^[^:]+$"] = {
>                     oneOf = {
>                         {type = "string"},
>                         {type = "number"},
>                     }
>                 }
>             },
>         },
>         {
>             properties = {
>                 add = {
>                     type = "array",
>                     minItems = 1,
>                     items = {
>                         type = "string",
>                         -- "Set-Cookie: <cookie-name>=<cookie-value>;
> Max-Age=<number>"
>                         pattern = "^[^:]+:[^:]+$"
>                     }
>                 },
>                 set = {
>                     type = "object",
>                     minProperties = 1,
>                     patternProperties = {
>                         ["^[^:]+$"] = {
>                             oneOf = {
>                                 {type = "string"},
>                                 {type = "number"},
>                             }
>                         }
>                     },
>                 },
>                 remove = {
>                     type = "array",
>                     minItems = 1,
>                     items = {
>                         type = "string",
>                         -- "Set-Cookie"
>                         pattern = "^[^:]+$"
>                     }
>                 },
>             }
>         }
>     }
> },
>
> set means rewriting the headers,
> remove means removing the headers,
> addmeans appending the new headers.
> For set and add, the header format is "name: value", while for remove,
> the format is "name".
> We use array to represent multiple headers, so the same header can be
> used multiple times in the add. For example,
>
> add = {
>     "Cache-Control: no-cache",
>     "Cache-Control: max-age=0, must-revalidate"
> }
>
> The previous configuration can be migrated as part of the new
> configuration.
> The execution order among those operations are ["add", "set", "remove"].
>
> Inspired by:
>
> https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
> https://docs.konghq.com/hub/kong-inc/response-transformer/
>