mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-01 00:23:48 +03:00
Created app package, and better TLS compatibility with HTTP/2
This commit is contained in:
parent
ea9607302a
commit
5f72b7438a
6 changed files with 242 additions and 135 deletions
76
app/app.go
Normal file
76
app/app.go
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Package app holds application-global state to make it accessible
|
||||
// by other packages in the application.
|
||||
//
|
||||
// This package differs from config in that the things in app aren't
|
||||
// really related to server configuration.
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mholt/caddy/server"
|
||||
)
|
||||
|
||||
const (
|
||||
// Program name
|
||||
Name = "Caddy"
|
||||
|
||||
// Program version
|
||||
Version = "0.6.0"
|
||||
)
|
||||
|
||||
var (
|
||||
// Servers is a list of all the currently-listening servers
|
||||
Servers []*server.Server
|
||||
|
||||
// This mutex protects the Servers slice during changes
|
||||
ServersMutex sync.Mutex
|
||||
|
||||
// Waiting on Wg will block until all listeners have shut down.
|
||||
Wg sync.WaitGroup
|
||||
|
||||
// Whether HTTP2 is enabled or not
|
||||
Http2 bool // TODO: temporary flag until http2 is standard
|
||||
|
||||
// Quiet mode hides non-error initialization output
|
||||
Quiet bool
|
||||
)
|
||||
|
||||
// SetCPU parses string cpu and sets GOMAXPROCS
|
||||
// according to its value. It accepts either
|
||||
// a number (e.g. 3) or a percent (e.g. 50%).
|
||||
func SetCPU(cpu string) error {
|
||||
var numCPU int
|
||||
|
||||
availCPU := runtime.NumCPU()
|
||||
|
||||
if strings.HasSuffix(cpu, "%") {
|
||||
// Percent
|
||||
var percent float32
|
||||
pctStr := cpu[:len(cpu)-1]
|
||||
pctInt, err := strconv.Atoi(pctStr)
|
||||
if err != nil || pctInt < 1 || pctInt > 100 {
|
||||
return errors.New("Invalid CPU value: percentage must be between 1-100")
|
||||
}
|
||||
percent = float32(pctInt) / 100
|
||||
numCPU = int(float32(availCPU) * percent)
|
||||
} else {
|
||||
// Number
|
||||
num, err := strconv.Atoi(cpu)
|
||||
if err != nil || num < 1 {
|
||||
return errors.New("Invalid CPU value: provide a number or percent greater than 0")
|
||||
}
|
||||
numCPU = num
|
||||
}
|
||||
|
||||
if numCPU > availCPU {
|
||||
numCPU = availCPU
|
||||
}
|
||||
|
||||
runtime.GOMAXPROCS(numCPU)
|
||||
return nil
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/mholt/caddy/app"
|
||||
"github.com/mholt/caddy/config/parse"
|
||||
"github.com/mholt/caddy/config/setup"
|
||||
"github.com/mholt/caddy/middleware"
|
||||
|
@ -41,8 +45,8 @@ func Load(filename string, input io.Reader) ([]server.Config, error) {
|
|||
Root: Root,
|
||||
Middleware: make(map[string][]middleware.Middleware),
|
||||
ConfigFile: filename,
|
||||
AppName: AppName,
|
||||
AppVersion: AppVersion,
|
||||
AppName: app.Name,
|
||||
AppVersion: app.Version,
|
||||
}
|
||||
|
||||
// It is crucial that directives are executed in the proper order.
|
||||
|
@ -81,6 +85,46 @@ func Load(filename string, input io.Reader) ([]server.Config, error) {
|
|||
return configs, nil
|
||||
}
|
||||
|
||||
// ArrangeBindings groups configurations by their bind address. For example,
|
||||
// a server that should listen on localhost and another on 127.0.0.1 will
|
||||
// be grouped into the same address: 127.0.0.1. It will return an error
|
||||
// if the address lookup fails or if a TLS listener is configured on the
|
||||
// same address as a plaintext HTTP listener. The return value is a map of
|
||||
// bind address to list of configs that would become VirtualHosts on that
|
||||
// server.
|
||||
func ArrangeBindings(allConfigs []server.Config) (map[*net.TCPAddr][]server.Config, error) {
|
||||
addresses := make(map[*net.TCPAddr][]server.Config)
|
||||
|
||||
// Group configs by bind address
|
||||
for _, conf := range allConfigs {
|
||||
addr, err := net.ResolveTCPAddr("tcp", conf.Address())
|
||||
if err != nil {
|
||||
return addresses, errors.New("Could not serve " + conf.Address() + " - " + err.Error())
|
||||
}
|
||||
addresses[addr] = append(addresses[addr], conf)
|
||||
}
|
||||
|
||||
// Don't allow HTTP and HTTPS to be served on the same address
|
||||
for _, configs := range addresses {
|
||||
isTLS := configs[0].TLS.Enabled
|
||||
for _, config := range configs {
|
||||
if config.TLS.Enabled != isTLS {
|
||||
thisConfigProto, otherConfigProto := "HTTP", "HTTP"
|
||||
if config.TLS.Enabled {
|
||||
thisConfigProto = "HTTPS"
|
||||
}
|
||||
if configs[0].TLS.Enabled {
|
||||
otherConfigProto = "HTTPS"
|
||||
}
|
||||
return addresses, fmt.Errorf("Configuration error: Cannot multiplex %s (%s) and %s (%s) on same address",
|
||||
configs[0].Address(), otherConfigProto, config.Address(), thisConfigProto)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return addresses, nil
|
||||
}
|
||||
|
||||
// validDirective returns true if d is a valid
|
||||
// directive; false otherwise.
|
||||
func validDirective(d string) bool {
|
||||
|
@ -109,7 +153,3 @@ var (
|
|||
Host = DefaultHost
|
||||
Port = DefaultPort
|
||||
)
|
||||
|
||||
// The application should set these so that various middlewares
|
||||
// can access the proper information for their own needs.
|
||||
var AppName, AppVersion string
|
||||
|
|
|
@ -6,33 +6,10 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mholt/caddy/app"
|
||||
"github.com/mholt/caddy/middleware"
|
||||
)
|
||||
|
||||
// Map of supported protocols
|
||||
// SSLv3 will be not supported in next release
|
||||
var supportedProtocols = map[string]uint16{
|
||||
"ssl3.0": tls.VersionSSL30,
|
||||
"tls1.0": tls.VersionTLS10,
|
||||
"tls1.1": tls.VersionTLS11,
|
||||
"tls1.2": tls.VersionTLS12,
|
||||
}
|
||||
|
||||
// Map of supported ciphers
|
||||
// For security reasons caddy will not support RC4 ciphers
|
||||
var supportedCiphers = map[string]uint16{
|
||||
"ECDHE-RSA-AES128-GCM-SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
"ECDHE-RSA-AES128-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
"ECDHE-RSA-AES256-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
"ECDHE-ECDSA-AES256-CBC-SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
"ECDHE-ECDSA-AES128-CBC-SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
"RSA-AES128-CBC-SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
"RSA-AES256-CBC-SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
"ECDHE-RSA-3DES-EDE-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
"RSA-3DES-EDE-CBC-SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
}
|
||||
|
||||
func TLS(c *Controller) (middleware.Middleware, error) {
|
||||
c.TLS.Enabled = true
|
||||
if c.Port == "http" {
|
||||
|
@ -79,6 +56,9 @@ func TLS(c *Controller) (middleware.Middleware, error) {
|
|||
if !ok {
|
||||
return nil, c.Errf("Wrong cipher name or cipher not supported '%s'", c.Val())
|
||||
}
|
||||
if _, ok := http2CipherSuites[value]; app.Http2 && !ok {
|
||||
return nil, c.Errf("Cipher suite %s is not allowed for HTTP/2", c.Val())
|
||||
}
|
||||
c.TLS.Ciphers = append(c.TLS.Ciphers, value)
|
||||
}
|
||||
case "cache":
|
||||
|
@ -87,7 +67,7 @@ func TLS(c *Controller) (middleware.Middleware, error) {
|
|||
}
|
||||
size, err := strconv.Atoi(c.Val())
|
||||
if err != nil {
|
||||
return nil, c.Errf("Cache parameter should be an number '%s': %v", c.Val(), err)
|
||||
return nil, c.Errf("Cache parameter must be an number '%s': %v", c.Val(), err)
|
||||
}
|
||||
c.TLS.CacheSize = size
|
||||
default:
|
||||
|
@ -96,10 +76,12 @@ func TLS(c *Controller) (middleware.Middleware, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// If no Ciphers provided, use all caddy supportedCiphers
|
||||
// If no ciphers provided, use all that Caddy supports for the protocol
|
||||
if len(c.TLS.Ciphers) == 0 {
|
||||
for _, v := range supportedCiphers {
|
||||
c.TLS.Ciphers = append(c.TLS.Ciphers, v)
|
||||
if _, ok := http2CipherSuites[v]; !app.Http2 || ok {
|
||||
c.TLS.Ciphers = append(c.TLS.Ciphers, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,9 +96,43 @@ func TLS(c *Controller) (middleware.Middleware, error) {
|
|||
}
|
||||
|
||||
//If no cachesize provided, set default to 64
|
||||
if c.TLS.CacheSize == 0 {
|
||||
if c.TLS.CacheSize <= 0 {
|
||||
c.TLS.CacheSize = 64
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Map of supported protocols
|
||||
// SSLv3 will be not supported in next release
|
||||
// HTTP/2 only supports TLS 1.2 and higher
|
||||
var supportedProtocols = map[string]uint16{
|
||||
"ssl3.0": tls.VersionSSL30,
|
||||
"tls1.0": tls.VersionTLS10,
|
||||
"tls1.1": tls.VersionTLS11,
|
||||
"tls1.2": tls.VersionTLS12,
|
||||
}
|
||||
|
||||
// Map of supported ciphers.
|
||||
//
|
||||
// Note that, at time of writing, HTTP/2 blacklists 276 cipher suites,
|
||||
// including all but two of the suites below (the two GCM suites).
|
||||
var supportedCiphers = map[string]uint16{
|
||||
"ECDHE-RSA-AES128-GCM-SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
"ECDHE-RSA-AES128-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
"ECDHE-RSA-AES256-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
"ECDHE-ECDSA-AES256-CBC-SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
"ECDHE-ECDSA-AES128-CBC-SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
"RSA-AES128-CBC-SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
"RSA-AES256-CBC-SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
"ECDHE-RSA-3DES-EDE-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
"RSA-3DES-EDE-CBC-SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
}
|
||||
|
||||
// Set of cipher suites not blacklisted by HTTP/2 spec.
|
||||
// See https://http2.github.io/http2-spec/#BadCipherSuites
|
||||
var http2CipherSuites = map[uint16]struct{}{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: struct{}{},
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: struct{}{},
|
||||
}
|
||||
|
|
|
@ -3,8 +3,29 @@ package setup
|
|||
import (
|
||||
"crypto/tls"
|
||||
"testing"
|
||||
|
||||
"github.com/mholt/caddy/app"
|
||||
)
|
||||
|
||||
func TestTLSParseBasic(t *testing.T) {
|
||||
c := newTestController(`tls cert.pem key.pem`)
|
||||
|
||||
_, err := TLS(c)
|
||||
if err != nil {
|
||||
t.Error("Expected no errors, but had an error")
|
||||
}
|
||||
|
||||
if c.TLS.Certificate != "cert.pem" {
|
||||
t.Errorf("Expected certificate arg to be 'cert.pem', was '%s'", c.TLS.Certificate)
|
||||
}
|
||||
if c.TLS.Key != "key.pem" {
|
||||
t.Errorf("Expected key arg to be 'key.pem', was '%s'", c.TLS.Key)
|
||||
}
|
||||
if !c.TLS.Enabled {
|
||||
t.Error("Expected TLS Enabled=true, but was false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTLSParseNoOptional(t *testing.T) {
|
||||
c := newTestController(`tls cert.crt cert.key`)
|
||||
|
||||
|
@ -44,7 +65,6 @@ func TestTLSParseIncompleteParams(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Errorf("Expected errors, but no error returned")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTLSParseWithOptionalParams(t *testing.T) {
|
||||
|
@ -107,3 +127,43 @@ func TestTLSParseWithWrongOptionalParams(t *testing.T) {
|
|||
t.Errorf("Expected errors, but no error returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTLSParseWithHTTP2Requirements(t *testing.T) {
|
||||
params := `tls cert.crt cert.key`
|
||||
c := newTestController(params)
|
||||
|
||||
// With HTTP2, cipher suites should be limited
|
||||
app.Http2 = true
|
||||
_, err := TLS(c)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no errors, got: %v", err)
|
||||
}
|
||||
if len(c.TLS.Ciphers) != len(http2CipherSuites) {
|
||||
t.Errorf("With HTTP/2 on, expected %d supported ciphers, got %d",
|
||||
len(http2CipherSuites), len(c.TLS.Ciphers))
|
||||
}
|
||||
|
||||
params = `tls cert.crt cert.key {
|
||||
ciphers RSA-AES128-CBC-SHA
|
||||
}`
|
||||
c = newTestController(params)
|
||||
// Should not be able to specify a blacklisted cipher suite with HTTP2 on
|
||||
_, err = TLS(c)
|
||||
if err == nil {
|
||||
t.Error("Expected an error because cipher suite is invalid for HTTP/2")
|
||||
}
|
||||
|
||||
params = `tls cert.crt cert.key`
|
||||
c = newTestController(params)
|
||||
|
||||
// Without HTTP2, cipher suites should not be as restricted
|
||||
app.Http2 = false
|
||||
_, err = TLS(c)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no errors, got: %v", err)
|
||||
}
|
||||
if len(c.TLS.Ciphers) != len(supportedCiphers) {
|
||||
t.Errorf("With HTTP/2 off, expected %d supported ciphers, got %d",
|
||||
len(supportedCiphers), len(c.TLS.Ciphers))
|
||||
}
|
||||
}
|
||||
|
|
107
main.go
107
main.go
|
@ -2,58 +2,49 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mholt/caddy/app"
|
||||
"github.com/mholt/caddy/config"
|
||||
"github.com/mholt/caddy/server"
|
||||
)
|
||||
|
||||
var (
|
||||
conf string
|
||||
http2 bool // TODO: temporary flag until http2 is standard
|
||||
quiet bool
|
||||
cpu string
|
||||
version bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&conf, "conf", "", "Configuration file to use (default="+config.DefaultConfigFile+")")
|
||||
flag.BoolVar(&http2, "http2", true, "Enable HTTP/2 support") // TODO: temporary flag until http2 merged into std lib
|
||||
flag.BoolVar(&quiet, "quiet", false, "Quiet mode (no initialization output)")
|
||||
flag.BoolVar(&app.Http2, "http2", true, "Enable HTTP/2 support") // TODO: temporary flag until http2 merged into std lib
|
||||
flag.BoolVar(&app.Quiet, "quiet", false, "Quiet mode (no initialization output)")
|
||||
flag.StringVar(&cpu, "cpu", "100%", "CPU cap")
|
||||
flag.StringVar(&config.Root, "root", config.DefaultRoot, "Root path to default site")
|
||||
flag.StringVar(&config.Host, "host", config.DefaultHost, "Default host")
|
||||
flag.StringVar(&config.Port, "port", config.DefaultPort, "Default port")
|
||||
flag.BoolVar(&version, "version", false, "Show version")
|
||||
|
||||
config.AppName = "Caddy"
|
||||
config.AppVersion = "0.6.0"
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if version {
|
||||
fmt.Printf("%s %s\n", config.AppName, config.AppVersion)
|
||||
fmt.Printf("%s %s\n", app.Name, app.Version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// Set CPU cap
|
||||
err := setCPU(cpu)
|
||||
err := app.SetCPU(cpu)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -65,7 +56,7 @@ func main() {
|
|||
}
|
||||
|
||||
// Group by address (virtual hosts)
|
||||
addresses, err := arrangeBindings(allConfigs)
|
||||
addresses, err := config.ArrangeBindings(allConfigs)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -76,18 +67,21 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
s.HTTP2 = http2 // TODO: This setting is temporary
|
||||
wg.Add(1)
|
||||
s.HTTP2 = app.Http2 // TODO: This setting is temporary
|
||||
app.Wg.Add(1)
|
||||
go func(s *server.Server) {
|
||||
defer wg.Done()
|
||||
defer app.Wg.Done()
|
||||
err := s.Serve()
|
||||
if err != nil {
|
||||
log.Fatal(err) // kill whole process to avoid a half-alive zombie server
|
||||
}
|
||||
}(s)
|
||||
|
||||
if !quiet {
|
||||
app.Servers = append(app.Servers, s)
|
||||
|
||||
if !app.Quiet {
|
||||
var checkedFdLimit bool
|
||||
|
||||
for addr, configs := range addresses {
|
||||
for _, conf := range configs {
|
||||
// Print address of site
|
||||
|
@ -117,7 +111,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
app.Wg.Wait()
|
||||
}
|
||||
|
||||
func isLocalhost(s string) bool {
|
||||
|
@ -169,76 +163,3 @@ func loadConfigs() ([]server.Config, error) {
|
|||
|
||||
return config.Load(config.DefaultConfigFile, file)
|
||||
}
|
||||
|
||||
// arrangeBindings groups configurations by their bind address. For example,
|
||||
// a server that should listen on localhost and another on 127.0.0.1 will
|
||||
// be grouped into the same address: 127.0.0.1. It will return an error
|
||||
// if the address lookup fails or if a TLS listener is configured on the
|
||||
// same address as a plaintext HTTP listener.
|
||||
func arrangeBindings(allConfigs []server.Config) (map[*net.TCPAddr][]server.Config, error) {
|
||||
addresses := make(map[*net.TCPAddr][]server.Config)
|
||||
|
||||
// Group configs by bind address
|
||||
for _, conf := range allConfigs {
|
||||
addr, err := net.ResolveTCPAddr("tcp", conf.Address())
|
||||
if err != nil {
|
||||
return addresses, errors.New("Could not serve " + conf.Address() + " - " + err.Error())
|
||||
}
|
||||
addresses[addr] = append(addresses[addr], conf)
|
||||
}
|
||||
|
||||
// Don't allow HTTP and HTTPS to be served on the same address
|
||||
for _, configs := range addresses {
|
||||
isTLS := configs[0].TLS.Enabled
|
||||
for _, config := range configs {
|
||||
if config.TLS.Enabled != isTLS {
|
||||
thisConfigProto, otherConfigProto := "HTTP", "HTTP"
|
||||
if config.TLS.Enabled {
|
||||
thisConfigProto = "HTTPS"
|
||||
}
|
||||
if configs[0].TLS.Enabled {
|
||||
otherConfigProto = "HTTPS"
|
||||
}
|
||||
return addresses, fmt.Errorf("Configuration error: Cannot multiplex %s (%s) and %s (%s) on same address",
|
||||
configs[0].Address(), otherConfigProto, config.Address(), thisConfigProto)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return addresses, nil
|
||||
}
|
||||
|
||||
// setCPU parses string cpu and sets GOMAXPROCS
|
||||
// according to its value. It accepts either
|
||||
// a number (e.g. 3) or a percent (e.g. 50%).
|
||||
func setCPU(cpu string) error {
|
||||
var numCPU int
|
||||
|
||||
availCPU := runtime.NumCPU()
|
||||
|
||||
if strings.HasSuffix(cpu, "%") {
|
||||
// Percent
|
||||
var percent float32
|
||||
pctStr := cpu[:len(cpu)-1]
|
||||
pctInt, err := strconv.Atoi(pctStr)
|
||||
if err != nil || pctInt < 1 || pctInt > 100 {
|
||||
return errors.New("Invalid CPU value: percentage must be between 1-100")
|
||||
}
|
||||
percent = float32(pctInt) / 100
|
||||
numCPU = int(float32(availCPU) * percent)
|
||||
} else {
|
||||
// Number
|
||||
num, err := strconv.Atoi(cpu)
|
||||
if err != nil || num < 1 {
|
||||
return errors.New("Invalid CPU value: provide a number or percent greater than 0")
|
||||
}
|
||||
numCPU = num
|
||||
}
|
||||
|
||||
if numCPU > availCPU {
|
||||
numCPU = availCPU
|
||||
}
|
||||
|
||||
runtime.GOMAXPROCS(numCPU)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -132,17 +132,11 @@ func ListenAndServeTLSWithSNI(srv *http.Server, tlsConfigs []TLSConfig) error {
|
|||
}
|
||||
config.BuildNameToCertificate()
|
||||
|
||||
// Here we change some crypto/tls defaults based on caddyfile
|
||||
// If no config provided, we set defaults focused in security
|
||||
|
||||
// Add a session cache LRU algorithm
|
||||
// Customize our TLS configuration
|
||||
config.ClientSessionCache = tls.NewLRUClientSessionCache(tlsConfigs[0].CacheSize)
|
||||
|
||||
config.MinVersion = tlsConfigs[0].ProtocolMinVersion
|
||||
config.MaxVersion = tlsConfigs[0].ProtocolMaxVersion
|
||||
config.CipherSuites = tlsConfigs[0].Ciphers
|
||||
|
||||
// Server ciphers have priority over client ciphers
|
||||
config.PreferServerCipherSuites = true
|
||||
|
||||
conn, err := net.Listen("tcp", addr)
|
||||
|
|
Loading…
Reference in a new issue