You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.1 KiB
138 lines
3.1 KiB
/* |
|
------------------------------------------------------------------------------------------------------------------------ |
|
####### kong ####### Copyright (c) 2021-2022 losyme ################################################ MIT License ####### |
|
------------------------------------------------------------------------------------------------------------------------ |
|
*/ |
|
|
|
package server |
|
|
|
import ( |
|
"crypto/tls" |
|
"crypto/x509" |
|
"log" |
|
"os" |
|
"time" |
|
|
|
"forge.chapril.org/losyme/errors" |
|
"forge.chapril.org/losyme/util" |
|
) |
|
|
|
type Options struct { |
|
Addr string |
|
IdleTimeout time.Duration |
|
ReadTimeout time.Duration |
|
WriteTimeout time.Duration |
|
CertFile string |
|
KeyFile string |
|
CAFile string |
|
logger *log.Logger |
|
tls bool |
|
} |
|
|
|
type Option func(*Options) |
|
|
|
func WithOptions(options *Options) Option { |
|
return func(o *Options) { |
|
if options != nil { |
|
*o = *options |
|
} |
|
} |
|
} |
|
|
|
func WithAddr(addr string) Option { |
|
return func(o *Options) { |
|
o.Addr = addr |
|
} |
|
} |
|
|
|
func WithIdleTimeout(idleTimeout time.Duration) Option { |
|
return func(o *Options) { |
|
o.IdleTimeout = idleTimeout |
|
} |
|
} |
|
|
|
func WithReadTimeout(readTimeout time.Duration) Option { |
|
return func(o *Options) { |
|
o.ReadTimeout = readTimeout |
|
} |
|
} |
|
|
|
func WithWriteTimeout(writeTimeout time.Duration) Option { |
|
return func(o *Options) { |
|
o.WriteTimeout = writeTimeout |
|
} |
|
} |
|
|
|
func WithCertKeyFiles(certFile, keyFile string) Option { |
|
return func(o *Options) { |
|
o.CertFile = certFile |
|
o.KeyFile = keyFile |
|
} |
|
} |
|
|
|
func WithCAFile(caFile string) Option { |
|
return func(o *Options) { |
|
o.CAFile = caFile |
|
} |
|
} |
|
|
|
func WithLogger(logger *log.Logger) Option { |
|
return func(o *Options) { |
|
o.logger = logger |
|
} |
|
} |
|
|
|
func (po *Options) tlsConfig() (*tls.Config, error) { |
|
if po.CertFile == "" && po.KeyFile == "" { |
|
return nil, nil |
|
} |
|
|
|
po.tls = true |
|
|
|
if po.CertFile == "" { |
|
return nil, errors.New("certificate file name cannot be empty") //////////////////////////////////////////////// |
|
} |
|
|
|
if ok, err := util.FileExists(po.CertFile); err != nil { |
|
return nil, err |
|
} else if !ok { |
|
return nil, errors.New("this file doesn't exist", "name", po.CertFile) ///////////////////////////////////////// |
|
} |
|
|
|
if po.KeyFile == "" { |
|
return nil, errors.New("key file name cannot be empty") //////////////////////////////////////////////////////// |
|
} |
|
|
|
if ok, err := util.FileExists(po.KeyFile); err != nil { |
|
return nil, err |
|
} else if !ok { |
|
return nil, errors.New("this file doesn't exist", "name", po.KeyFile) ////////////////////////////////////////// |
|
} |
|
|
|
var certPool *x509.CertPool |
|
authType := tls.NoClientCert |
|
|
|
if po.CAFile != "" { |
|
authType = tls.RequireAndVerifyClientCert |
|
|
|
buf, err := os.ReadFile(po.CAFile) |
|
if err != nil { |
|
return nil, errors.WithMessage(err, "unable to read this file", "file", po.CAFile) ///////////////////////// |
|
} |
|
|
|
certPool = x509.NewCertPool() |
|
certPool.AppendCertsFromPEM(buf) |
|
} |
|
|
|
cfg := &tls.Config{ |
|
ClientAuth: authType, |
|
ClientCAs: certPool, |
|
MinVersion: tls.VersionTLS12, |
|
} |
|
|
|
return cfg, nil |
|
} |
|
|
|
/* |
|
######################################################################################################## @(°_°)@ ####### |
|
*/
|
|
|