diff options
author | Wolfy-J <[email protected]> | 2019-06-24 13:35:04 +0300 |
---|---|---|
committer | Wolfy-J <[email protected]> | 2019-06-24 13:35:04 +0300 |
commit | 5dc7dd6b231ccea05ffbec0df47ecaa866192308 (patch) | |
tree | 7959b582590bfbe15205480e64de2f14de2d6b47 /service/http | |
parent | 464baf2eb7bd87ed80332280e8f73faa2d495746 (diff) |
polishing fastcgi integration, polishing headers service (splitted from http)
Diffstat (limited to 'service/http')
-rw-r--r-- | service/http/config.go | 61 | ||||
-rw-r--r-- | service/http/service.go | 106 |
2 files changed, 25 insertions, 142 deletions
diff --git a/service/http/config.go b/service/http/config.go index e2f42626..b5b18c23 100644 --- a/service/http/config.go +++ b/service/http/config.go @@ -18,7 +18,11 @@ type Config struct { // SSL defines https server options. SSL SSLConfig - FCGI FCGIConfig + // FCGI configuration. You can use FastCGI without HTTP server. + FCGI *FCGIConfig + + // HTTP2 configuration + HTTP2 *HTTP2Config // MaxRequestSize specified max size for payload body in megabytes, set 0 to unlimited. MaxRequestSize int64 @@ -30,50 +34,22 @@ type Config struct { // Uploads configures uploads configuration. Uploads *UploadsConfig - // HTTP2 configuration - HTTP2 *HTTP2Config - - // Middlewares - Middlewares *MiddlewaresConfig - // Workers configures rr server and worker pool. Workers *roadrunner.ServerConfig } -type MiddlewaresConfig struct { - Headers *HeaderMiddlewareConfig - CORS *CORSMiddlewareConfig -} - -type CORSMiddlewareConfig struct { - AllowedOrigin string - AllowedMethods string - AllowedHeaders string - AllowCredentials *bool - ExposedHeaders string - MaxAge int -} - -type HeaderMiddlewareConfig struct { - CustomRequestHeaders map[string]string - CustomResponseHeaders map[string]string -} - -func (c *MiddlewaresConfig) EnableCORS() bool { - return c.CORS != nil -} - -func (c *MiddlewaresConfig) EnableHeaders() bool { - return c.Headers.CustomRequestHeaders != nil || c.Headers.CustomResponseHeaders != nil -} - +// FCGIConfig for FastCGI server. type FCGIConfig struct { - // Port and port to handle as http server. + // Address and port to handle as http server. Address string } +// HTTP2Config HTTP/2 server customizations. type HTTP2Config struct { + // Enable or disable HTTP/2 extension, default enable. Enabled bool + + // MaxConcurrentStreams defaults to 128. MaxConcurrentStreams uint32 } @@ -99,23 +75,22 @@ type SSLConfig struct { Cert string } +// EnableHTTP is true when http server must run. func (c *Config) EnableHTTP() bool { return c.Address != "" } -func (c *Config) EnableMiddlewares() bool { - return c.Middlewares != nil -} - // EnableTLS returns true if rr must listen TLS connections. func (c *Config) EnableTLS() bool { return c.SSL.Key != "" || c.SSL.Cert != "" } +// EnableHTTP2 when HTTP/2 extension must be enabled (only with TSL). func (c *Config) EnableHTTP2() bool { return c.HTTP2.Enabled } +// EnableFCGI is true when FastCGI server must be enabled. func (c *Config) EnableFCGI() bool { return c.FCGI.Address != "" } @@ -130,6 +105,10 @@ func (c *Config) Hydrate(cfg service.Config) error { c.HTTP2 = &HTTP2Config{} } + if c.FCGI == nil { + c.FCGI = &FCGIConfig{} + } + if c.Uploads == nil { c.Uploads = &UploadsConfig{} } @@ -223,6 +202,10 @@ func (c *Config) Valid() error { return err } + if !c.EnableHTTP() && !c.EnableTLS() && !c.EnableFCGI() { + return errors.New("unable to run http service, no method has been specified (http, https, http/2 or FastCGI)") + } + if c.Address != "" && !strings.Contains(c.Address, ":") { return errors.New("mailformed http server address") } diff --git a/service/http/service.go b/service/http/service.go index f394f6af..b3f56480 100644 --- a/service/http/service.go +++ b/service/http/service.go @@ -12,13 +12,12 @@ import ( "net/http" "net/http/fcgi" "net/url" - "strconv" "strings" "sync" ) const ( - // ID contains default svc name. + // ID contains default service name. ID = "http" // EventInitSSL thrown at moment of https initialization. SSL server passed as context. @@ -40,7 +39,7 @@ type Service struct { handler *Handler http *http.Server https *http.Server - fcgi *http.Server + fcgi *http.Server } // Attach attaches controller. Currently only one controller is supported. @@ -96,10 +95,6 @@ func (s *Service) Serve() error { s.rr.Attach(s.controller) } - if s.cfg.EnableMiddlewares() { - s.initMiddlewares() - } - s.handler = &Handler{cfg: s.cfg, rr: s.rr} s.handler.Listen(s.throw) @@ -178,7 +173,7 @@ func (s *Service) Server() *roadrunner.Server { } func (s *Service) ListenAndServeFCGI() error { - l, err := util.CreateListener(s.cfg.FCGI.Address); + l, err := util.CreateListener(s.cfg.FCGI.Address) if err != nil { return err } @@ -252,98 +247,3 @@ func (s *Service) tlsAddr(host string, forcePort bool) string { return host } - -func (s *Service) headersMiddleware(f http.HandlerFunc) http.HandlerFunc { - // Define the http.HandlerFunc - return func(w http.ResponseWriter, r *http.Request) { - if s.cfg.Middlewares.Headers.CustomRequestHeaders != nil { - for k, v := range s.cfg.Middlewares.Headers.CustomRequestHeaders { - r.Header.Add(k, v) - } - } - - if s.cfg.Middlewares.Headers.CustomResponseHeaders != nil { - for k, v := range s.cfg.Middlewares.Headers.CustomResponseHeaders { - w.Header().Set(k, v) - } - } - - f(w, r) - } -} - -func handlePreflightRequest(w http.ResponseWriter, r *http.Request, options *CORSMiddlewareConfig) { - headers := w.Header() - - headers.Add("Vary", "Origin") - headers.Add("Vary", "Access-Control-Request-Method") - headers.Add("Vary", "Access-Control-Request-Headers") - - if options.AllowedOrigin != "" { - headers.Set("Access-Control-Allow-Origin", options.AllowedOrigin) - } - - if options.AllowedHeaders != "" { - headers.Set("Access-Control-Allow-Headers", options.AllowedHeaders) - } - - if options.AllowedMethods != "" { - headers.Set("Access-Control-Allow-Methods", options.AllowedMethods) - } - - if options.AllowCredentials != nil { - headers.Set("Access-Control-Allow-Credentials", strconv.FormatBool(*options.AllowCredentials)) - } - - if options.MaxAge > 0 { - headers.Set("Access-Control-Max-Age", strconv.Itoa(options.MaxAge)) - } - - w.WriteHeader(http.StatusOK); -} - -func addCORSHeaders(w http.ResponseWriter, r *http.Request, options *CORSMiddlewareConfig) { - headers := w.Header() - - headers.Add("Vary", "Origin") - - if options.AllowedOrigin != "" { - headers.Set("Access-Control-Allow-Origin", options.AllowedOrigin) - } - - if options.AllowedHeaders != "" { - headers.Set("Access-Control-Allow-Headers", options.AllowedHeaders) - } - - if options.ExposedHeaders != "" { - headers.Set("Access-Control-Expose-Headers", options.ExposedHeaders) - } - - if options.AllowCredentials != nil { - headers.Set("Access-Control-Allow-Credentials", strconv.FormatBool(*options.AllowCredentials)) - } -} - -func (s *Service) corsMiddleware(f http.HandlerFunc) http.HandlerFunc { - // Define the http.HandlerFunc - return func(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodOptions { - handlePreflightRequest(w, r, s.cfg.Middlewares.CORS) - } else { - addCORSHeaders(w, r, s.cfg.Middlewares.CORS) - f(w, r) - } - } -} - -func (s *Service) initMiddlewares() error { - if s.cfg.Middlewares.EnableHeaders() { - s.AddMiddleware(s.headersMiddleware) - } - - if s.cfg.Middlewares.EnableCORS() { - s.AddMiddleware(s.corsMiddleware) - } - - return nil -} |