diff options
author | wppd <[email protected]> | 2019-12-25 10:31:10 +0800 |
---|---|---|
committer | wppd <[email protected]> | 2019-12-25 10:31:10 +0800 |
commit | 081c3708f242a491ddef9733f95f35e70f50c3e7 (patch) | |
tree | e362a8f93f820c95fae91ee7d5f080c870ec83cd /service | |
parent | 75a817edcff22e721dcc3a7fa5590b866f630403 (diff) |
add gzip handler
Diffstat (limited to 'service')
-rw-r--r-- | service/gzip/config.go | 23 | ||||
-rw-r--r-- | service/gzip/config_test.go | 43 | ||||
-rw-r--r-- | service/gzip/service.go | 32 | ||||
-rw-r--r-- | service/gzip/service_test.go | 123 | ||||
-rw-r--r-- | service/static/service_test.go | 4 |
5 files changed, 223 insertions, 2 deletions
diff --git a/service/gzip/config.go b/service/gzip/config.go new file mode 100644 index 00000000..7da48a67 --- /dev/null +++ b/service/gzip/config.go @@ -0,0 +1,23 @@ +package gzip + +import ( + "github.com/spiral/roadrunner/service" +) + +// Config describes file location and controls access to them. +type Config struct { + // Dir contains name of directory to control access to. + Enable bool +} + +// Hydrate must populate Config values using given Config source. Must return error if Config is not valid. +func (c *Config) Hydrate(cfg service.Config) error { + return cfg.Unmarshal(c) +} + +// InitDefaults sets missing values to their default values. +func (c *Config) InitDefaults() error { + c.Enable = true + + return nil +} diff --git a/service/gzip/config_test.go b/service/gzip/config_test.go new file mode 100644 index 00000000..92bb1cb5 --- /dev/null +++ b/service/gzip/config_test.go @@ -0,0 +1,43 @@ +package gzip + +import ( + "encoding/json" + "github.com/spiral/roadrunner/service" + "github.com/stretchr/testify/assert" + "testing" +) + +type mockCfg struct{ cfg string } + +func (cfg *mockCfg) Get(name string) service.Config { return nil } +func (cfg *mockCfg) Unmarshal(out interface{}) error { return json.Unmarshal([]byte(cfg.cfg), out) } + +func Test_Config_Hydrate(t *testing.T) { + cfg := &mockCfg{`{"enable": true}`} + c := &Config{} + + assert.NoError(t, c.Hydrate(cfg)) +} + +func Test_Config_Hydrate_Error(t *testing.T) { + cfg := &mockCfg{`{"enable": "invalid"}`} + c := &Config{} + + assert.Error(t, c.Hydrate(cfg)) +} + +func Test_Config_Hydrate_Error2(t *testing.T) { + cfg := &mockCfg{`{"enable": 1}`} + c := &Config{} + + assert.Error(t, c.Hydrate(cfg)) +} + +func Test_Config_Defaults(t *testing.T) { + c := &Config{} + err := c.InitDefaults() + if err != nil { + t.Errorf("error during the InitDefaults: error %v", err) + } + assert.Equal(t, true, c.Enable) +} diff --git a/service/gzip/service.go b/service/gzip/service.go new file mode 100644 index 00000000..4c6320ad --- /dev/null +++ b/service/gzip/service.go @@ -0,0 +1,32 @@ +package gzip + +import ( + rrhttp "github.com/spiral/roadrunner/service/http" + "github.com/NYTimes/gziphandler" + "net/http" +) + +// ID contains default service name. +const ID = "gzip" + +type Service struct { + cfg *Config +} + +func (s *Service) Init(cfg *Config, r *rrhttp.Service) (bool, error) { + s.cfg = cfg + + if s.cfg.Enable == false { + return false, nil + } + + r.AddMiddleware(s.middleware) + + return true, nil +} + +func (s *Service) middleware(f http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + gziphandler.GzipHandler(f).ServeHTTP(w, r) + } +} diff --git a/service/gzip/service_test.go b/service/gzip/service_test.go new file mode 100644 index 00000000..6f07a1f9 --- /dev/null +++ b/service/gzip/service_test.go @@ -0,0 +1,123 @@ +package gzip + +import ( + "encoding/json" + "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" + "os" + "testing" + "time" +) + +type testCfg struct { + gzip string + httpCfg string + static 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.gzip} + } + return nil +} +func (cfg *testCfg) Unmarshal(out interface{}) error { + return json.Unmarshal([]byte(cfg.target), out) +} + +func get(url string) (string, *http.Response, error) { + r, err := http.Get(url) + if err != nil { + return "", nil, err + } + + b, err := ioutil.ReadAll(r.Body) + if err != nil { + return "", nil, err + } + + err = r.Body.Close() + if err != nil { + return "", nil, err + } + + return string(b), r, err +} + +func Test_Disabled(t *testing.T) { + logger, _ := test.NewNullLogger() + logger.SetLevel(logrus.DebugLevel) + + c := service.NewContainer(logger) + c.Register(ID, &Service{}) + + assert.NoError(t, c.Init(&testCfg{ + gzip: `{"enable":false}`, + })) + + s, st := c.Get(ID) + assert.NotNil(t, s) + assert.Equal(t, service.StatusInactive, st) +} +// func Test_Files(t *testing.T) { +// 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{ +// gzip: `{"enable":true}`, +// static: `{"enable":true, "dir":"../../tests", "forbid":[]}`, +// httpCfg: `{ +// "enable": true, +// "address": ":6029", +// "maxRequestSize": 1024, +// "uploads": { +// "dir": ` + tmpDir() + `, +// "forbid": [] +// }, +// "workers":{ +// "command": "php ../../tests/http/client.php pid pipes", +// "relay": "pipes", +// "pool": { +// "numWorkers": 1, +// "allocateTimeout": 10000000, +// "destroyTimeout": 10000000 +// } +// } +// }`})) + +// go func() { +// err := c.Serve() +// if err != nil { +// t.Errorf("serve error: %v", err) +// } +// }() +// time.Sleep(time.Millisecond * 1000) +// defer c.Stop() + +// b, _, _ := get("http://localhost:6029/sample.txt") +// assert.Equal(t, "sample", b) +// //header should not contain content-encoding:gzip because content-length < gziphandler.DefaultMinSize +// // b, _, _ := get("http://localhost:6029/gzip-large-file.txt") +// //header should contain content-encoding:gzip because content-length > gziphandler.DefaultMinSize +// } + +func tmpDir() string { + p := os.TempDir() + r, _ := json.Marshal(p) + + return string(r) +} diff --git a/service/static/service_test.go b/service/static/service_test.go index 309804cc..4205650d 100644 --- a/service/static/service_test.go +++ b/service/static/service_test.go @@ -77,9 +77,9 @@ func Test_Files(t *testing.T) { "command": "php ../../tests/http/client.php pid pipes", "relay": "pipes", "pool": { - "numWorkers": 1, + "numWorkers": 1, "allocateTimeout": 10000000, - "destroyTimeout": 10000000 + "destroyTimeout": 10000000 } } }`})) |