diff options
author | Valery Piashchynski <[email protected]> | 2020-12-01 18:36:26 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2020-12-01 18:36:26 +0300 |
commit | 509db1b16de783819932e34703dec42bd99b51c9 (patch) | |
tree | d0b61be0ee53e793d7350c7805db18c31f7af3c4 /plugins | |
parent | f77ddd3109c300d0429e50bde19f86ea8c4883f8 (diff) |
Finish Headers plugin tests
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/headers/plugin.go | 3 | ||||
-rw-r--r-- | plugins/headers/tests/configs/.rr-cors-headers.yaml | 37 | ||||
-rw-r--r-- | plugins/headers/tests/configs/.rr-headers-init.yaml | 6 | ||||
-rw-r--r-- | plugins/headers/tests/configs/.rr-req-headers.yaml | 30 | ||||
-rw-r--r-- | plugins/headers/tests/configs/.rr-res-headers.yaml | 30 | ||||
-rw-r--r-- | plugins/headers/tests/headers_plugin_test.go | 277 | ||||
-rw-r--r-- | plugins/headers/tests/old.go | 362 |
7 files changed, 376 insertions, 369 deletions
diff --git a/plugins/headers/plugin.go b/plugins/headers/plugin.go index dc0aab5a..f1c6e6f3 100644 --- a/plugins/headers/plugin.go +++ b/plugins/headers/plugin.go @@ -24,7 +24,7 @@ func (s *Plugin) Init(cfg config.Configurer) error { const op = errors.Op("headers plugin init") err := cfg.UnmarshalKey(RootPluginName, &s.cfg) if err != nil { - return errors.E(op, err) + return errors.E(op, errors.Disabled, err) } return nil @@ -51,7 +51,6 @@ func (s *Plugin) Middleware(next http.Handler) http.HandlerFunc { s.preflightRequest(w) return } - s.corsHeaders(w) } diff --git a/plugins/headers/tests/configs/.rr-cors-headers.yaml b/plugins/headers/tests/configs/.rr-cors-headers.yaml new file mode 100644 index 00000000..5c1a200b --- /dev/null +++ b/plugins/headers/tests/configs/.rr-cors-headers.yaml @@ -0,0 +1,37 @@ +server: + command: "php ../../../tests/http/client.php headers pipes" + user: "" + group: "" + env: + "RR_HTTP": "true" + relay: "pipes" + relayTimeout: "20s" + +http: + debug: true + address: 127.0.0.1:22855 + maxRequestSize: 1024 + middleware: [ "headers" ] + uploads: + forbid: [ ".php", ".exe", ".bat" ] + trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] + # Additional HTTP headers and CORS control. + headers: + cors: + allowedOrigin: "*" + allowedHeaders: "*" + allowedMethods: "GET,POST,PUT,DELETE" + allowCredentials: true + exposedHeaders: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma" + maxAge: 600 + request: + "input": "custom-header" + response: + "output": "output-header" + pool: + numWorkers: 2 + maxJobs: 0 + allocateTimeout: 60s + destroyTimeout: 60s + + diff --git a/plugins/headers/tests/configs/.rr-headers-init.yaml b/plugins/headers/tests/configs/.rr-headers-init.yaml index cd5d4f9c..252fe8f3 100644 --- a/plugins/headers/tests/configs/.rr-headers-init.yaml +++ b/plugins/headers/tests/configs/.rr-headers-init.yaml @@ -1,7 +1,3 @@ -rpc: - listen: tcp://127.0.0.1:6001 - disabled: false - server: command: "php ../../../tests/http/client.php echo pipes" user: "" @@ -13,7 +9,7 @@ server: http: debug: true - address: 127.0.0.1:18903 + address: 127.0.0.1:33453 maxRequestSize: 1024 middleware: [ "headers" ] uploads: diff --git a/plugins/headers/tests/configs/.rr-req-headers.yaml b/plugins/headers/tests/configs/.rr-req-headers.yaml new file mode 100644 index 00000000..9256e98d --- /dev/null +++ b/plugins/headers/tests/configs/.rr-req-headers.yaml @@ -0,0 +1,30 @@ +server: + command: "php ../../../tests/http/client.php header pipes" + user: "" + group: "" + env: + "RR_HTTP": "true" + relay: "pipes" + relayTimeout: "20s" + +http: + debug: true + address: 127.0.0.1:22655 + maxRequestSize: 1024 + middleware: [ "headers" ] + uploads: + forbid: [ ".php", ".exe", ".bat" ] + trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] + # Additional HTTP headers and CORS control. + headers: + request: + "input": "custom-header" + response: + "output": "output-header" + pool: + numWorkers: 2 + maxJobs: 0 + allocateTimeout: 60s + destroyTimeout: 60s + + diff --git a/plugins/headers/tests/configs/.rr-res-headers.yaml b/plugins/headers/tests/configs/.rr-res-headers.yaml new file mode 100644 index 00000000..1bca2c3d --- /dev/null +++ b/plugins/headers/tests/configs/.rr-res-headers.yaml @@ -0,0 +1,30 @@ +server: + command: "php ../../../tests/http/client.php header pipes" + user: "" + group: "" + env: + "RR_HTTP": "true" + relay: "pipes" + relayTimeout: "20s" + +http: + debug: true + address: 127.0.0.1:22455 + maxRequestSize: 1024 + middleware: [ "headers" ] + uploads: + forbid: [ ".php", ".exe", ".bat" ] + trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] + # Additional HTTP headers and CORS control. + headers: + request: + "input": "custom-header" + response: + "output": "output-header" + pool: + numWorkers: 2 + maxJobs: 0 + allocateTimeout: 60s + destroyTimeout: 60s + + diff --git a/plugins/headers/tests/headers_plugin_test.go b/plugins/headers/tests/headers_plugin_test.go index a0feed81..f1de8cb9 100644 --- a/plugins/headers/tests/headers_plugin_test.go +++ b/plugins/headers/tests/headers_plugin_test.go @@ -1,6 +1,8 @@ package tests import ( + "io/ioutil" + "net/http" "os" "os/signal" "sync" @@ -77,6 +79,281 @@ func TestHeadersInit(t *testing.T) { } } }() + wg.Wait() +} + +func TestRequestHeaders(t *testing.T) { + cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.DebugLevel)) + assert.NoError(t, err) + + cfg := &config.Viper{ + Path: "configs/.rr-req-headers.yaml", + Prefix: "rr", + } + + err = cont.RegisterAll( + cfg, + &logger.ZapLogger{}, + &server.Plugin{}, + &httpPlugin.Plugin{}, + &headers.Plugin{}, + ) + assert.NoError(t, err) + + err = cont.Init() + if err != nil { + t.Fatal(err) + } + + ch, err := cont.Serve() + assert.NoError(t, err) + + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + wg := &sync.WaitGroup{} + wg.Add(1) + + tt := time.NewTimer(time.Second * 10) + + go func() { + defer wg.Done() + for { + select { + case e := <-ch: + assert.Fail(t, "error", e.Error.Error()) + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + case <-sig: + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + case <-tt.C: + // timeout + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + } + } + }() + + time.Sleep(time.Second) + t.Run("RequestHeaders", reqHeaders) + wg.Wait() +} + +func reqHeaders(t *testing.T) { + req, err := http.NewRequest("GET", "http://localhost:22655?hello=value", nil) + assert.NoError(t, err) + + r, err := http.DefaultClient.Do(req) + assert.NoError(t, err) + + b, err := ioutil.ReadAll(r.Body) + assert.NoError(t, err) + + assert.Equal(t, 200, r.StatusCode) + assert.Equal(t, "CUSTOM-HEADER", string(b)) + + err = r.Body.Close() + assert.NoError(t, err) +} + +func TestResponseHeaders(t *testing.T) { + cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.DebugLevel)) + assert.NoError(t, err) + + cfg := &config.Viper{ + Path: "configs/.rr-res-headers.yaml", + Prefix: "rr", + } + + err = cont.RegisterAll( + cfg, + &logger.ZapLogger{}, + &server.Plugin{}, + &httpPlugin.Plugin{}, + &headers.Plugin{}, + ) + assert.NoError(t, err) + + err = cont.Init() + if err != nil { + t.Fatal(err) + } + + ch, err := cont.Serve() + assert.NoError(t, err) + + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + wg := &sync.WaitGroup{} + wg.Add(1) + + tt := time.NewTimer(time.Second * 10) + + go func() { + defer wg.Done() + for { + select { + case e := <-ch: + assert.Fail(t, "error", e.Error.Error()) + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + case <-sig: + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + case <-tt.C: + // timeout + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + } + } + }() + time.Sleep(time.Second) + t.Run("ResponseHeaders", resHeaders) wg.Wait() } + +func resHeaders(t *testing.T) { + req, err := http.NewRequest("GET", "http://localhost:22455?hello=value", nil) + assert.NoError(t, err) + + r, err := http.DefaultClient.Do(req) + assert.NoError(t, err) + + assert.Equal(t, "output-header", r.Header.Get("output")) + + b, err := ioutil.ReadAll(r.Body) + assert.NoError(t, err) + assert.Equal(t, 200, r.StatusCode) + assert.Equal(t, "CUSTOM-HEADER", string(b)) + + err = r.Body.Close() + assert.NoError(t, err) +} + +func TestCORSHeaders(t *testing.T) { + cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.DebugLevel)) + assert.NoError(t, err) + + cfg := &config.Viper{ + Path: "configs/.rr-cors-headers.yaml", + Prefix: "rr", + } + + err = cont.RegisterAll( + cfg, + &logger.ZapLogger{}, + &server.Plugin{}, + &httpPlugin.Plugin{}, + &headers.Plugin{}, + ) + assert.NoError(t, err) + + err = cont.Init() + if err != nil { + t.Fatal(err) + } + + ch, err := cont.Serve() + assert.NoError(t, err) + + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + wg := &sync.WaitGroup{} + wg.Add(1) + + tt := time.NewTimer(time.Second * 10) + + go func() { + defer wg.Done() + for { + select { + case e := <-ch: + assert.Fail(t, "error", e.Error.Error()) + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + case <-sig: + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + case <-tt.C: + // timeout + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + } + } + }() + + time.Sleep(time.Second) + t.Run("CORSHeaders", corsHeaders) + t.Run("CORSHeadersPass", corsHeadersPass) + wg.Wait() +} + +func corsHeadersPass(t *testing.T) { + req, err := http.NewRequest("GET", "http://localhost:22855", nil) + assert.NoError(t, err) + + r, err := http.DefaultClient.Do(req) + assert.NoError(t, err) + + assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) + assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Headers")) + assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Origin")) + assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) + + _, err = ioutil.ReadAll(r.Body) + assert.NoError(t, err) + assert.Equal(t, 200, r.StatusCode) + + err = r.Body.Close() + assert.NoError(t, err) +} + +func corsHeaders(t *testing.T) { + req, err := http.NewRequest("OPTIONS", "http://localhost:22855", nil) + assert.NoError(t, err) + + r, err := http.DefaultClient.Do(req) + assert.NoError(t, err) + + assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) + assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Headers")) + assert.Equal(t, "GET,POST,PUT,DELETE", r.Header.Get("Access-Control-Allow-Methods")) + assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Origin")) + assert.Equal(t, "600", r.Header.Get("Access-Control-Max-Age")) + assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) + + _, err = ioutil.ReadAll(r.Body) + assert.NoError(t, err) + assert.Equal(t, 200, r.StatusCode) + + err = r.Body.Close() + assert.NoError(t, err) +} diff --git a/plugins/headers/tests/old.go b/plugins/headers/tests/old.go deleted file mode 100644 index b3d95aa5..00000000 --- a/plugins/headers/tests/old.go +++ /dev/null @@ -1,362 +0,0 @@ -package tests - -//type mockCfg struct{ cfg string } -// -//func (cfg *mockCfg) Get(name string) service.Config { return nil } -//func (cfg *mockCfg) Unmarshal(out interface{}) error { -// j := json.ConfigCompatibleWithStandardLibrary -// return j.Unmarshal([]byte(cfg.cfg), out) -//} -// -//func Test_Config_Hydrate_Error1(t *testing.T) { -// cfg := &mockCfg{`{"request": {"From": "Something"}}`} -// c := &Config{} -// -// assert.NoError(t, c.Hydrate(cfg)) -//} -// -//func Test_Config_Hydrate_Error2(t *testing.T) { -// cfg := &mockCfg{`{"dir": "/dir/"`} -// c := &Config{} -// -// assert.Error(t, c.Hydrate(cfg)) -//} -//------------------------------------------------------------------------------- -//import ( -// "github.com/cenkalti/backoff/v4" -// json "github.com/json-iterator/go" -// "github.com/sirupsen/logrus" -// "github.com/sirupsen/logrus/hooks/test" -// "github.com/spiral/roadrunner/service" -// rrhttp "github.com/spiral/roadrunner/service/http" -// "github.com/stretchr/testify/assert" -// "io/ioutil" -// "net/http" -// "testing" -// "time" -//) -// -//type testCfg struct { -// httpCfg string -// headers string -// target string -//} -// -//func (cfg *testCfg) Get(name string) service.Config { -// if name == rrhttp.ID { -// return &testCfg{target: cfg.httpCfg} -// } -// -// if name == ID { -// return &testCfg{target: cfg.headers} -// } -// return nil -//} -// -//func (cfg *testCfg) Unmarshal(out interface{}) error { -// return json.Unmarshal([]byte(cfg.target), out) -//} -// -//func Test_RequestHeaders(t *testing.T) { -// bkoff := backoff.NewExponentialBackOff() -// bkoff.MaxElapsedTime = time.Second * 15 -// -// err := backoff.Retry(func() error { -// logger, _ := test.NewNullLogger() -// logger.SetLevel(logrus.DebugLevel) -// -// c := service.NewContainer(logger) -// c.Register(rrhttp.ID, &rrhttp.Service{}) -// c.Register(ID, &Service{}) -// -// assert.NoError(t, c.Init(&testCfg{ -// headers: `{"request":{"input": "custom-header"}}`, -// httpCfg: `{ -// "enable": true, -// "address": ":6078", -// "maxRequestSize": 1024, -// "workers":{ -// "command": "php ../../tests/http/client.php header pipes", -// "relay": "pipes", -// "pool": { -// "numWorkers": 1, -// "allocateTimeout": 10000000, -// "destroyTimeout": 10000000 -// } -// } -// }`})) -// -// go func() { -// err := c.Serve() -// if err != nil { -// t.Errorf("error during Serve: error %v", err) -// } -// }() -// -// time.Sleep(time.Millisecond * 100) -// defer c.Stop() -// -// req, err := http.NewRequest("GET", "http://localhost:6078?hello=value", nil) -// if err != nil { -// return err -// } -// -// r, err := http.DefaultClient.Do(req) -// if err != nil { -// return err -// } -// -// b, err := ioutil.ReadAll(r.Body) -// if err != nil { -// return err -// } -// -// assert.Equal(t, 200, r.StatusCode) -// assert.Equal(t, "CUSTOM-HEADER", string(b)) -// -// err = r.Body.Close() -// if err != nil { -// return err -// } -// -// return nil -// }, bkoff) -// -// if err != nil { -// t.Fatal(err) -// } -//} -// -//func Test_ResponseHeaders(t *testing.T) { -// bkoff := backoff.NewExponentialBackOff() -// bkoff.MaxElapsedTime = time.Second * 15 -// -// err := backoff.Retry(func() error { -// logger, _ := test.NewNullLogger() -// logger.SetLevel(logrus.DebugLevel) -// -// c := service.NewContainer(logger) -// c.Register(rrhttp.ID, &rrhttp.Service{}) -// c.Register(ID, &Service{}) -// -// assert.NoError(t, c.Init(&testCfg{ -// headers: `{"response":{"output": "output-header"},"request":{"input": "custom-header"}}`, -// httpCfg: `{ -// "enable": true, -// "address": ":6079", -// "maxRequestSize": 1024, -// "workers":{ -// "command": "php ../../tests/http/client.php header pipes", -// "relay": "pipes", -// "pool": { -// "numWorkers": 1, -// "allocateTimeout": 10000000, -// "destroyTimeout": 10000000 -// } -// } -// }`})) -// -// go func() { -// err := c.Serve() -// if err != nil { -// t.Errorf("error during the Serve: error %v", err) -// } -// }() -// time.Sleep(time.Millisecond * 100) -// defer c.Stop() -// -// req, err := http.NewRequest("GET", "http://localhost:6079?hello=value", nil) -// if err != nil { -// return err -// } -// -// r, err := http.DefaultClient.Do(req) -// if err != nil { -// return err -// } -// -// assert.Equal(t, "output-header", r.Header.Get("output")) -// -// b, err := ioutil.ReadAll(r.Body) -// if err != nil { -// return err -// } -// assert.Equal(t, 200, r.StatusCode) -// assert.Equal(t, "CUSTOM-HEADER", string(b)) -// -// err = r.Body.Close() -// if err != nil { -// return err -// } -// -// return nil -// }, bkoff) -// -// if err != nil { -// t.Fatal(err) -// } -//} -// -//func TestCORS_OPTIONS(t *testing.T) { -// bkoff := backoff.NewExponentialBackOff() -// bkoff.MaxElapsedTime = time.Second * 15 -// -// err := backoff.Retry(func() error { -// logger, _ := test.NewNullLogger() -// logger.SetLevel(logrus.DebugLevel) -// -// c := service.NewContainer(logger) -// c.Register(rrhttp.ID, &rrhttp.Service{}) -// c.Register(ID, &Service{}) -// -// assert.NoError(t, c.Init(&testCfg{ -// headers: `{ -//"cors":{ -// "allowedOrigin": "*", -// "allowedHeaders": "*", -// "allowedMethods": "GET,POST,PUT,DELETE", -// "allowCredentials": true, -// "exposedHeaders": "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma", -// "maxAge": 600 -//} -//}`, -// httpCfg: `{ -// "enable": true, -// "address": ":16379", -// "maxRequestSize": 1024, -// "workers":{ -// "command": "php ../../tests/http/client.php headers pipes", -// "relay": "pipes", -// "pool": { -// "numWorkers": 1, -// "allocateTimeout": 10000000, -// "destroyTimeout": 10000000 -// } -// } -// }`})) -// -// go func() { -// err := c.Serve() -// if err != nil { -// t.Errorf("error during the Serve: error %v", err) -// } -// }() -// time.Sleep(time.Millisecond * 100) -// defer c.Stop() -// -// req, err := http.NewRequest("OPTIONS", "http://localhost:16379", nil) -// if err != nil { -// return err -// } -// -// r, err := http.DefaultClient.Do(req) -// if err != nil { -// return err -// } -// -// assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) -// assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Headers")) -// assert.Equal(t, "GET,POST,PUT,DELETE", r.Header.Get("Access-Control-Allow-Methods")) -// assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Origin")) -// assert.Equal(t, "600", r.Header.Get("Access-Control-Max-Age")) -// assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) -// -// _, err = ioutil.ReadAll(r.Body) -// if err != nil { -// return err -// } -// assert.Equal(t, 200, r.StatusCode) -// -// err = r.Body.Close() -// if err != nil { -// return err -// } -// -// return nil -// }, bkoff) -// -// if err != nil { -// t.Fatal(err) -// } -//} -// -//func TestCORS_Pass(t *testing.T) { -// bkoff := backoff.NewExponentialBackOff() -// bkoff.MaxElapsedTime = time.Second * 15 -// -// err := backoff.Retry(func() error { -// logger, _ := test.NewNullLogger() -// logger.SetLevel(logrus.DebugLevel) -// -// c := service.NewContainer(logger) -// c.Register(rrhttp.ID, &rrhttp.Service{}) -// c.Register(ID, &Service{}) -// -// assert.NoError(t, c.Init(&testCfg{ -// headers: `{ -//"cors":{ -// "allowedOrigin": "*", -// "allowedHeaders": "*", -// "allowedMethods": "GET,POST,PUT,DELETE", -// "allowCredentials": true, -// "exposedHeaders": "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma", -// "maxAge": 600 -//} -//}`, -// httpCfg: `{ -// "enable": true, -// "address": ":6672", -// "maxRequestSize": 1024, -// "workers":{ -// "command": "php ../../tests/http/client.php headers pipes", -// "relay": "pipes", -// "pool": { -// "numWorkers": 1, -// "allocateTimeout": 10000000, -// "destroyTimeout": 10000000 -// } -// } -// }`})) -// -// go func() { -// err := c.Serve() -// if err != nil { -// t.Errorf("error during the Serve: error %v", err) -// } -// }() -// time.Sleep(time.Millisecond * 100) -// defer c.Stop() -// -// req, err := http.NewRequest("GET", "http://localhost:6672", nil) -// if err != nil { -// return err -// } -// -// r, err := http.DefaultClient.Do(req) -// if err != nil { -// return err -// } -// -// assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) -// assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Headers")) -// assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Origin")) -// assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) -// -// _, err = ioutil.ReadAll(r.Body) -// if err != nil { -// return err -// } -// assert.Equal(t, 200, r.StatusCode) -// -// err = r.Body.Close() -// if err != nil { -// return err -// } -// -// return nil -// }, bkoff) -// -// if err != nil { -// t.Fatal(err) -// } -//}
\ No newline at end of file |