diff options
-rw-r--r-- | .rr.yaml | 5 | ||||
-rw-r--r-- | service/http/config.go | 28 | ||||
-rw-r--r-- | service/http/config_test.go | 55 | ||||
-rw-r--r-- | service/http/service.go | 15 |
4 files changed, 100 insertions, 3 deletions
@@ -33,6 +33,11 @@ http: # FastCGI connection DSN. Supported TCP and Unix sockets. address: tcp://0.0.0.0:6920 + # HTTP service provides HTTP2 transport + http2: + enabled: true + maxConcurrentStreams: 128 + # max POST request size, including file uploads in MB. maxRequestSize: 200 diff --git a/service/http/config.go b/service/http/config.go index 4b5950b3..5454f124 100644 --- a/service/http/config.go +++ b/service/http/config.go @@ -30,6 +30,9 @@ type Config struct { // Uploads configures uploads configuration. Uploads *UploadsConfig + // HTTP2 configuration + HTTP2 *HTTP2Config + // Workers configures rr server and worker pool. Workers *roadrunner.ServerConfig } @@ -39,6 +42,18 @@ type FCGIConfig struct { Address string } +type HTTP2Config struct { + Enabled bool + MaxConcurrentStreams uint32 +} + +func (cfg *HTTP2Config) InitDefaults() error { + cfg.Enabled = true + cfg.MaxConcurrentStreams = 128 + + return nil +} + // SSLConfig defines https server configuration. type SSLConfig struct { // Port to listen as HTTPS server, defaults to 443. @@ -63,6 +78,10 @@ func (c *Config) EnableTLS() bool { return c.SSL.Key != "" || c.SSL.Cert != "" } +func (c *Config) EnableHTTP2() bool { + return c.HTTP2.Enabled +} + func (c *Config) EnableFCGI() bool { return c.FCGI.Address != "" } @@ -73,6 +92,10 @@ func (c *Config) Hydrate(cfg service.Config) error { c.Workers = &roadrunner.ServerConfig{} } + if c.HTTP2 == nil { + c.HTTP2 = &HTTP2Config{} + } + if c.Uploads == nil { c.Uploads = &UploadsConfig{} } @@ -81,6 +104,7 @@ func (c *Config) Hydrate(cfg service.Config) error { c.SSL.Port = 443 } + c.HTTP2.InitDefaults() c.Uploads.InitDefaults() c.Workers.InitDefaults() @@ -149,6 +173,10 @@ func (c *Config) Valid() error { return errors.New("mailformed uploads config") } + if c.HTTP2 == nil { + return errors.New("mailformed http2 config") + } + if c.Workers == nil { return errors.New("mailformed workers config") } diff --git a/service/http/config_test.go b/service/http/config_test.go index 54e5b27a..6bb314d8 100644 --- a/service/http/config_test.go +++ b/service/http/config_test.go @@ -33,6 +33,9 @@ func Test_Config_Valid(t *testing.T) { cfg := &Config{ Address: ":8080", MaxRequestSize: 1024, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Uploads: &UploadsConfig{ Dir: os.TempDir(), Forbid: []string{".go"}, @@ -59,6 +62,9 @@ func Test_Trusted_Subnets(t *testing.T) { Dir: os.TempDir(), Forbid: []string{".go"}, }, + HTTP2: &HTTP2Config{ + Enabled: true, + }, TrustedSubnets: []string{"200.1.0.0/16"}, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", @@ -85,6 +91,9 @@ func Test_Trusted_Subnets_Err(t *testing.T) { Dir: os.TempDir(), Forbid: []string{".go"}, }, + HTTP2: &HTTP2Config{ + Enabled: true, + }, TrustedSubnets: []string{"200.1.0.0"}, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", @@ -112,6 +121,9 @@ func Test_Config_Valid_SSL(t *testing.T) { Dir: os.TempDir(), Forbid: []string{".go"}, }, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", Relay: "pipes", @@ -141,6 +153,9 @@ func Test_Config_SSL_No_key(t *testing.T) { Dir: os.TempDir(), Forbid: []string{".go"}, }, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", Relay: "pipes", @@ -166,6 +181,9 @@ func Test_Config_SSL_No_Cert(t *testing.T) { Dir: os.TempDir(), Forbid: []string{".go"}, }, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", Relay: "pipes", @@ -184,6 +202,9 @@ func Test_Config_NoUploads(t *testing.T) { cfg := &Config{ Address: ":8080", MaxRequestSize: 1024, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", Relay: "pipes", @@ -198,10 +219,35 @@ func Test_Config_NoUploads(t *testing.T) { assert.Error(t, cfg.Valid()) } +func Test_Config_NoHTTP2(t *testing.T) { + cfg := &Config{ + Address: ":8080", + MaxRequestSize: 1024, + Uploads: &UploadsConfig{ + Dir: os.TempDir(), + Forbid: []string{".go"}, + }, + Workers: &roadrunner.ServerConfig{ + Command: "php tests/client.php echo pipes", + Relay: "pipes", + Pool: &roadrunner.Config{ + NumWorkers: 0, + AllocateTimeout: time.Second, + DestroyTimeout: time.Second, + }, + }, + } + + assert.Error(t, cfg.Valid()) +} + func Test_Config_NoWorkers(t *testing.T) { cfg := &Config{ Address: ":8080", MaxRequestSize: 1024, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Uploads: &UploadsConfig{ Dir: os.TempDir(), Forbid: []string{".go"}, @@ -219,6 +265,9 @@ func Test_Config_NoPool(t *testing.T) { Dir: os.TempDir(), Forbid: []string{".go"}, }, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", Relay: "pipes", @@ -241,6 +290,9 @@ func Test_Config_DeadPool(t *testing.T) { Dir: os.TempDir(), Forbid: []string{".go"}, }, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", Relay: "pipes", @@ -258,6 +310,9 @@ func Test_Config_InvalidAddress(t *testing.T) { Dir: os.TempDir(), Forbid: []string{".go"}, }, + HTTP2: &HTTP2Config{ + Enabled: true, + }, Workers: &roadrunner.ServerConfig{ Command: "php tests/client.php echo pipes", Relay: "pipes", diff --git a/service/http/service.go b/service/http/service.go index b309cd45..00d877ec 100644 --- a/service/http/service.go +++ b/service/http/service.go @@ -104,6 +104,12 @@ func (s *Service) Serve() error { if s.cfg.EnableTLS() { s.https = s.initSSL() + + if s.cfg.EnableHTTP2() { + if err := s.InitHTTP2(); err != nil { + return err + } + } } if s.cfg.EnableFCGI() { @@ -209,12 +215,15 @@ func (s *Service) initSSL() *http.Server { server := &http.Server{Addr: s.tlsAddr(s.cfg.Address, true), Handler: s} s.throw(EventInitSSL, server) - // Enable HTTP/2 support by default - http2.ConfigureServer(server, &http2.Server{}) - return server } +func (s *Service) InitHTTP2() error { + return http2.ConfigureServer(s.https, &http2.Server{ + MaxConcurrentStreams: s.cfg.HTTP2.MaxConcurrentStreams, + }) +} + // throw handles service, server and pool events. func (s *Service) throw(event int, ctx interface{}) { for _, l := range s.lsns { |