This is an automated email from the ASF dual-hosted git repository.
gallardot pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
The following commit(s) were added to refs/heads/master by this push:
new e809cfba feat: Allow response header rewrite via Ingress annotations
(#1861)
e809cfba is described below
commit e809cfbaaad6f6c3cbd23f5ec8e93bc1d87f543d
Author: Ashish Tiwari <[email protected]>
AuthorDate: Thu Jun 29 06:55:29 2023 +0530
feat: Allow response header rewrite via Ingress annotations (#1861)
* feat: Allow response header rewrite via Ingress annotations
Signed-off-by: revolyssup <[email protected]>
* Fix lint check
Signed-off-by: Ashish Tiwari <[email protected]>
* add docs
Signed-off-by: revolyssup <[email protected]>
---------
Signed-off-by: revolyssup <[email protected]>
Signed-off-by: Ashish Tiwari <[email protected]>
---
docs/en/latest/concepts/annotations.md | 24 +++++++
.../annotations/plugins/response_rewrite.go | 5 ++
.../annotations/plugins/response_rewrite_test.go | 19 +++--
.../ingress/translation/annotations/types.go | 11 +--
pkg/types/apisix/v1/plugin_types.go | 80 ++++++++++++++++++++++
5 files changed, 129 insertions(+), 10 deletions(-)
diff --git a/docs/en/latest/concepts/annotations.md
b/docs/en/latest/concepts/annotations.md
index 4f0bd93a..26af6a21 100644
--- a/docs/en/latest/concepts/annotations.md
+++ b/docs/en/latest/concepts/annotations.md
@@ -278,6 +278,30 @@ This annotation configures the new body in the response.
k8s.apisix.apache.org/response-rewrite-body: "bar-body"
```
+### Add header
+
+This annotation configures to append the new headers in the response.
+
+```yaml
+k8s.apisix.apache.org/response-rewrite-add-header:
"testkey1:testval1,testkey2:testval2"
+```
+
+### Set header
+
+This annotation configures to rewrite the new headers in the response.
+
+```yaml
+k8s.apisix.apache.org/response-rewrite-set-header:
"testkey1:testval1,testkey2:testval2"
+```
+
+### Remove header
+
+This annotation configures to remove headers in the response.
+
+```yaml
+k8s.apisix.apache.org/response-rewrite-remove-header: "testkey1,testkey2"
+```
+
### Body Base64
When set, the body of the request will be decoded before writing to the client.
diff --git
a/pkg/providers/ingress/translation/annotations/plugins/response_rewrite.go
b/pkg/providers/ingress/translation/annotations/plugins/response_rewrite.go
index 673fc88d..f03a1d94 100644
--- a/pkg/providers/ingress/translation/annotations/plugins/response_rewrite.go
+++ b/pkg/providers/ingress/translation/annotations/plugins/response_rewrite.go
@@ -42,5 +42,10 @@ func (c *responseRewrite) Handle(e annotations.Extractor)
(interface{}, error) {
plugin.StatusCode, _ =
strconv.Atoi(e.GetStringAnnotation(annotations.AnnotationsResponseRewriteStatusCode))
plugin.Body =
e.GetStringAnnotation(annotations.AnnotationsResponseRewriteBody)
plugin.BodyBase64 =
e.GetBoolAnnotation(annotations.AnnotationsResponseRewriteBodyBase64)
+ headers := make(apisixv1.Headers)
+
headers.Add(e.GetStringsAnnotation(annotations.AnnotationsResponseRewriteHeaderAdd))
+
headers.Set(e.GetStringsAnnotation(annotations.AnnotationsResponseRewriteHeaderSet))
+
headers.Remove(e.GetStringsAnnotation(annotations.AnnotationsResponseRewriteHeaderRemove))
+ plugin.Headers = headers
return &plugin, nil
}
diff --git
a/pkg/providers/ingress/translation/annotations/plugins/response_rewrite_test.go
b/pkg/providers/ingress/translation/annotations/plugins/response_rewrite_test.go
index 6682d289..302f7a21 100644
---
a/pkg/providers/ingress/translation/annotations/plugins/response_rewrite_test.go
+++
b/pkg/providers/ingress/translation/annotations/plugins/response_rewrite_test.go
@@ -25,10 +25,13 @@ import (
func TestResponseRewriteHandler(t *testing.T) {
anno := map[string]string{
- annotations.AnnotationsEnableResponseRewrite: "true",
- annotations.AnnotationsResponseRewriteStatusCode: "200",
- annotations.AnnotationsResponseRewriteBody: "bar_body",
- annotations.AnnotationsResponseRewriteBodyBase64: "false",
+ annotations.AnnotationsEnableResponseRewrite: "true",
+ annotations.AnnotationsResponseRewriteStatusCode: "200",
+ annotations.AnnotationsResponseRewriteBody: "bar_body",
+ annotations.AnnotationsResponseRewriteBodyBase64: "false",
+ annotations.AnnotationsResponseRewriteHeaderAdd:
"testkey1:testval1,testkey2:testval2",
+ annotations.AnnotationsResponseRewriteHeaderRemove:
"testkey1,testkey2",
+ annotations.AnnotationsResponseRewriteHeaderSet:
"testkey1:testval1,testkey2:testval2",
}
p := NewResponseRewriteHandler()
out, err := p.Handle(annotations.NewExtractor(anno))
@@ -37,9 +40,13 @@ func TestResponseRewriteHandler(t *testing.T) {
assert.Equal(t, 200, config.StatusCode)
assert.Equal(t, "bar_body", config.Body)
assert.Equal(t, false, config.BodyBase64)
-
assert.Equal(t, "response-rewrite", p.PluginName())
-
+ assert.Equal(t, []string{"testkey1:testval1", "testkey2:testval2"},
config.Headers.GetAddedHeaders())
+ assert.Equal(t, []string{"testkey1", "testkey2"},
config.Headers.GetRemovedHeaders())
+ assert.Equal(t, map[string]string{
+ "testkey1": "testval1",
+ "testkey2": "testval2",
+ }, config.Headers.GetSetHeaders())
anno[annotations.AnnotationsEnableResponseRewrite] = "false"
out, err = p.Handle(annotations.NewExtractor(anno))
assert.Nil(t, err, "checking given error")
diff --git a/pkg/providers/ingress/translation/annotations/types.go
b/pkg/providers/ingress/translation/annotations/types.go
index 56d2b622..503e79b2 100644
--- a/pkg/providers/ingress/translation/annotations/types.go
+++ b/pkg/providers/ingress/translation/annotations/types.go
@@ -53,10 +53,13 @@ const (
AnnotationsRewriteTargetRegexTemplate = AnnotationsPrefix +
"rewrite-target-regex-template"
// response-rewrite plugin
- AnnotationsEnableResponseRewrite = AnnotationsPrefix +
"enable-response-rewrite"
- AnnotationsResponseRewriteStatusCode = AnnotationsPrefix +
"response-rewrite-status-code"
- AnnotationsResponseRewriteBody = AnnotationsPrefix +
"response-rewrite-body"
- AnnotationsResponseRewriteBodyBase64 = AnnotationsPrefix +
"response-rewrite-body-base64"
+ AnnotationsEnableResponseRewrite = AnnotationsPrefix +
"enable-response-rewrite"
+ AnnotationsResponseRewriteStatusCode = AnnotationsPrefix +
"response-rewrite-status-code"
+ AnnotationsResponseRewriteBody = AnnotationsPrefix +
"response-rewrite-body"
+ AnnotationsResponseRewriteBodyBase64 = AnnotationsPrefix +
"response-rewrite-body-base64"
+ AnnotationsResponseRewriteHeaderAdd = AnnotationsPrefix +
"response-rewrite-add-header"
+ AnnotationsResponseRewriteHeaderSet = AnnotationsPrefix +
"response-rewrite-set-header"
+ AnnotationsResponseRewriteHeaderRemove = AnnotationsPrefix +
"response-rewrite-remove-header"
// forward-auth plugin
AnnotationsForwardAuthURI = AnnotationsPrefix + "auth-uri"
diff --git a/pkg/types/apisix/v1/plugin_types.go
b/pkg/types/apisix/v1/plugin_types.go
index dd6bf9b9..d6e611f5 100644
--- a/pkg/types/apisix/v1/plugin_types.go
+++ b/pkg/types/apisix/v1/plugin_types.go
@@ -16,6 +16,8 @@ package v1
import (
"encoding/json"
+ "fmt"
+ "strings"
"github.com/incubator4/go-resty-expr/expr"
)
@@ -199,3 +201,81 @@ func (p *Headers) DeepCopy() *Headers {
p.DeepCopyInto(out)
return out
}
+
+func (p *Headers) Add(headersToAdd []string) {
+ if p == nil {
+ return
+ }
+ if headersToAdd != nil {
+ addedHeader := make([]string, 0)
+ for _, h := range headersToAdd {
+ kv := strings.Split(h, ":")
+ if len(kv) < 2 {
+ continue
+ }
+ addedHeader = append(addedHeader, fmt.Sprintf("%s:%s",
kv[0], kv[1]))
+ }
+ (*p)["add"] = addedHeader
+ }
+}
+
+func (p *Headers) GetAddedHeaders() []string {
+ if p == nil || (*p)["add"] == nil {
+ return nil
+ }
+ addedheaders, ok := (*p)["add"].([]string)
+ if ok {
+ return addedheaders
+ }
+ return nil
+}
+
+func (p *Headers) Set(headersToSet []string) {
+ if p == nil {
+ return
+ }
+ if headersToSet != nil {
+ setHeaders := make(map[string]string, 0)
+ for _, h := range headersToSet {
+ kv := strings.Split(h, ":")
+ if len(kv) < 2 {
+ continue
+ }
+ setHeaders[kv[0]] = kv[1]
+ }
+ (*p)["set"] = setHeaders
+ }
+}
+
+func (p *Headers) GetSetHeaders() map[string]string {
+ if p == nil || (*p)["set"] == nil {
+ return nil
+ }
+ addedheaders, ok := (*p)["set"].(map[string]string)
+ if ok {
+ return addedheaders
+ }
+ return nil
+}
+
+func (p *Headers) Remove(headersToRemove []string) {
+ if p == nil {
+ return
+ }
+ if headersToRemove != nil {
+ removeHeaders := make([]string, 0)
+ removeHeaders = append(removeHeaders, headersToRemove...)
+ (*p)["remove"] = removeHeaders
+ }
+}
+
+func (p *Headers) GetRemovedHeaders() []string {
+ if p == nil || (*p)["remove"] == nil {
+ return nil
+ }
+ removedHeaders, ok := (*p)["remove"].([]string)
+ if ok {
+ return removedHeaders
+ }
+ return nil
+}