summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rr.yaml5
-rw-r--r--service/http/config.go28
-rw-r--r--service/http/config_test.go55
-rw-r--r--service/http/service.go15
4 files changed, 100 insertions, 3 deletions
diff --git a/.rr.yaml b/.rr.yaml
index 973bc03f..198f777b 100644
--- a/.rr.yaml
+++ b/.rr.yaml
@@ -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 {