This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-go-plugin-runner.git


The following commit(s) were added to refs/heads/master by this push:
     new 1a00a4b  fix: write response header should not break req (#65)
1a00a4b is described below

commit 1a00a4b14f930c4588ede207c18c341336a760fd
Author: 罗泽轩 <[email protected]>
AuthorDate: Mon Feb 14 10:15:33 2022 +0800

    fix: write response header should not break req (#65)
---
 docs/en/latest/getting-started.md |  7 +++++--
 internal/http/response.go         |  4 +++-
 internal/plugin/conf.go           |  4 ++--
 internal/plugin/plugin_test.go    | 42 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/docs/en/latest/getting-started.md 
b/docs/en/latest/getting-started.md
index 78bc87a..ca6e6e1 100644
--- a/docs/en/latest/getting-started.md
+++ b/docs/en/latest/getting-started.md
@@ -128,9 +128,12 @@ func (p *Say) Filter(conf interface{}, w 
http.ResponseWriter, r pkgHTTP.Request)
 }
 ```
 
-We can see that the Filter takes the value of the body set in the 
configuration as the response body. If we respond directly in the plugin, it 
will response directly in the APISIX without touching the upstream.
+We can see that the Filter takes the value of the body set in the 
configuration as the response body. If we call `Write` or `WriteHeader` of the 
`http.ResponseWriter`
+(respond directly in the plugin), it will response directly in the APISIX 
without touching the upstream. As we only support setting headers of local 
response,
+calling `Header` won't take any effects without calling `Write` or 
`WriteHeader`. (TODO: support setting response header separately)
 
-Here you can read the API documentation provided by the Go Runner SDK: 
https://pkg.go.dev/github.com/apache/apisix-go-plugin-runner
+For the `pkgHTTP.Request`, you can refer to the API documentation provided by 
the Go Runner SDK:
+https://pkg.go.dev/github.com/apache/apisix-go-plugin-runner
 
 After building the application (`make build` in the example), we need to set 
some environment variables at runtime:
 
diff --git a/internal/http/response.go b/internal/http/response.go
index acf349e..dcf120a 100644
--- a/internal/http/response.go
+++ b/internal/http/response.go
@@ -45,6 +45,8 @@ func (r *Response) Write(b []byte) (int, error) {
                r.body = &bytes.Buffer{}
        }
 
+       // APISIX will convert code 0 to 200, so we don't need to 
WriteHeader(http.StatusOK)
+       // before writing the data
        return r.body.Write(b)
 }
 
@@ -64,7 +66,7 @@ func (r *Response) Reset() {
 }
 
 func (r *Response) HasChange() bool {
-       return !(r.body == nil && r.code == 0 && len(r.hdr) == 0)
+       return !(r.body == nil && r.code == 0)
 }
 
 func (r *Response) FetchChanges(id uint32, builder *flatbuffers.Builder) bool {
diff --git a/internal/plugin/conf.go b/internal/plugin/conf.go
index 5758f0a..7c2cc6c 100644
--- a/internal/plugin/conf.go
+++ b/internal/plugin/conf.go
@@ -101,8 +101,8 @@ func (cc *ConfCache) Set(req *pc.Req) (uint32, error) {
                        conf, err := plugin.ParseConf(v)
                        if err != nil {
                                log.Errorf(
-                                       "failed to parse configuration for 
plugin %s, configuration: %s",
-                                       name, string(v))
+                                       "failed to parse configuration for 
plugin %s, configuration: %s, err: %v",
+                                       name, string(v), err)
                                continue
                        }
 
diff --git a/internal/plugin/plugin_test.go b/internal/plugin/plugin_test.go
index 9016360..9893fb5 100644
--- a/internal/plugin/plugin_test.go
+++ b/internal/plugin/plugin_test.go
@@ -289,6 +289,7 @@ func TestFilter(t *testing.T) {
        }
        fooFilter := func(conf interface{}, w http.ResponseWriter, r 
pkgHTTP.Request) {
                w.Header().Add("foo", "bar")
+               w.WriteHeader(200)
                assert.Equal(t, "foo", conf.(string))
        }
        barParseConf := func(in []byte) (conf interface{}, err error) {
@@ -333,3 +334,44 @@ func TestFilter(t *testing.T) {
        assert.Equal(t, "bar", resp.Header().Get("foo"))
        assert.Equal(t, "bar", req.Header().Get("foo"))
 }
+
+func TestFilter_SetRespHeaderDoNotBreakReq(t *testing.T) {
+       InitConfCache(1 * time.Millisecond)
+
+       barParseConf := func(in []byte) (conf interface{}, err error) {
+               return "", nil
+       }
+       barFilter := func(conf interface{}, w http.ResponseWriter, r 
pkgHTTP.Request) {
+               r.Header().Set("foo", "bar")
+       }
+       filterSetRespParseConf := func(in []byte) (conf interface{}, err error) 
{
+               return "", nil
+       }
+       filterSetRespFilter := func(conf interface{}, w http.ResponseWriter, r 
pkgHTTP.Request) {
+               w.Header().Add("foo", "baz")
+       }
+       RegisterPlugin("bar", barParseConf, barFilter)
+       RegisterPlugin("filterSetResp", filterSetRespParseConf, 
filterSetRespFilter)
+
+       builder := flatbuffers.NewBuilder(1024)
+       barName := builder.CreateString("bar")
+       barConf := builder.CreateString("a")
+       filterSetRespName := builder.CreateString("filterSetResp")
+       filterSetRespConf := builder.CreateString("a")
+       prepareConfWithData(builder, filterSetRespName, filterSetRespConf, 
barName, barConf)
+
+       res, _ := GetRuleConf(1)
+       hrc.ReqStart(builder)
+       hrc.ReqAddId(builder, 233)
+       hrc.ReqAddConfToken(builder, 1)
+       r := hrc.ReqEnd(builder)
+       builder.Finish(r)
+       out := builder.FinishedBytes()
+
+       req := inHTTP.CreateRequest(out)
+       resp := inHTTP.CreateResponse()
+       filter(res, resp, req)
+
+       assert.Equal(t, "bar", req.Header().Get("foo"))
+       assert.Equal(t, "baz", resp.Header().Get("foo"))
+}

Reply via email to