new.go (1957B)
1 package server 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "net/http" 7 8 "code.dwrz.net/src/pkg/log" 9 "code.dwrz.net/src/pkg/server/redirect" 10 ) 11 12 type Parameters struct { 13 Config Config 14 Handler http.Handler 15 Log *log.Logger 16 } 17 18 func (p Parameters) Validate() error { 19 if p.Handler == nil { 20 return fmt.Errorf("missing handler") 21 } 22 if p.Log == nil { 23 return fmt.Errorf("missing logger") 24 } 25 26 return nil 27 } 28 29 func New(p Parameters) (*Server, error) { 30 if err := p.Validate(); err != nil { 31 return nil, fmt.Errorf("invalid server parameters: %v", err) 32 } 33 34 var server = &Server{ 35 cfg: &p.Config, 36 log: p.Log, 37 } 38 39 // Load TLS certificates, if provided. 40 var certs tls.Certificate 41 if p.Config.CertPath != "" && p.Config.KeyPath != "" { 42 var err error 43 certs, err = tls.LoadX509KeyPair( 44 p.Config.CertPath, p.Config.KeyPath, 45 ) 46 if err != nil { 47 server.log.Error.Fatalf( 48 "failed to load x509 key pair: %v", err, 49 ) 50 } 51 } 52 53 if p.Config.Ports.HTTPS != "" { 54 server.https = &http.Server{ 55 Addr: fmt.Sprintf( 56 ":%s", p.Config.Ports.HTTPS, 57 ), 58 ErrorLog: p.Log.Error, 59 Handler: p.Handler, 60 ReadTimeout: p.Config.Timeouts.Read, 61 MaxHeaderBytes: p.Config.MaxHeaderBytes, 62 IdleTimeout: p.Config.Timeouts.Idle, 63 TLSConfig: &tls.Config{ 64 Certificates: []tls.Certificate{certs}, 65 }, 66 WriteTimeout: p.Config.Timeouts.Write, 67 } 68 } 69 if p.Config.Ports.HTTP != "" { 70 server.http = &http.Server{ 71 Addr: fmt.Sprintf(":%s", p.Config.Ports.HTTP), 72 ErrorLog: p.Log.Error, 73 ReadTimeout: p.Config.Timeouts.Read, 74 MaxHeaderBytes: p.Config.MaxHeaderBytes, 75 IdleTimeout: p.Config.Timeouts.Idle, 76 WriteTimeout: p.Config.Timeouts.Write, 77 } 78 79 // If serving HTTPS, redirect from HTTP. 80 // Otherwise, serve the passed-in handler over HTTP. 81 if p.Config.Ports.HTTPS != "" { 82 server.http.Handler = &redirect.Handler{} 83 } else { 84 server.http.Handler = p.Handler 85 } 86 } 87 88 return server, nil 89 }