Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
5f72b743
Commit
5f72b743
authored
May 21, 2015
by
Matthew Holt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Created app package, and better TLS compatibility with HTTP/2
parent
ea960730
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
242 additions
and
135 deletions
+242
-135
app/app.go
app/app.go
+76
-0
config/config.go
config/config.go
+46
-6
config/setup/tls.go
config/setup/tls.go
+44
-28
config/setup/tls_test.go
config/setup/tls_test.go
+61
-1
main.go
main.go
+14
-93
server/server.go
server/server.go
+1
-7
No files found.
app/app.go
0 → 100644
View file @
5f72b743
// 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
}
config/config.go
View file @
5f72b743
package
config
package
config
import
(
import
(
"errors"
"fmt"
"io"
"io"
"log"
"log"
"net"
"github.com/mholt/caddy/app"
"github.com/mholt/caddy/config/parse"
"github.com/mholt/caddy/config/parse"
"github.com/mholt/caddy/config/setup"
"github.com/mholt/caddy/config/setup"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware"
...
@@ -41,8 +45,8 @@ func Load(filename string, input io.Reader) ([]server.Config, error) {
...
@@ -41,8 +45,8 @@ func Load(filename string, input io.Reader) ([]server.Config, error) {
Root
:
Root
,
Root
:
Root
,
Middleware
:
make
(
map
[
string
][]
middleware
.
Middleware
),
Middleware
:
make
(
map
[
string
][]
middleware
.
Middleware
),
ConfigFile
:
filename
,
ConfigFile
:
filename
,
AppName
:
App
Name
,
AppName
:
app
.
Name
,
AppVersion
:
App
Version
,
AppVersion
:
app
.
Version
,
}
}
// It is crucial that directives are executed in the proper order.
// 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) {
...
@@ -81,6 +85,46 @@ func Load(filename string, input io.Reader) ([]server.Config, error) {
return
configs
,
nil
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
// validDirective returns true if d is a valid
// directive; false otherwise.
// directive; false otherwise.
func
validDirective
(
d
string
)
bool
{
func
validDirective
(
d
string
)
bool
{
...
@@ -109,7 +153,3 @@ var (
...
@@ -109,7 +153,3 @@ var (
Host
=
DefaultHost
Host
=
DefaultHost
Port
=
DefaultPort
Port
=
DefaultPort
)
)
// The application should set these so that various middlewares
// can access the proper information for their own needs.
var
AppName
,
AppVersion
string
config/setup/tls.go
View file @
5f72b743
...
@@ -6,33 +6,10 @@ import (
...
@@ -6,33 +6,10 @@ import (
"strconv"
"strconv"
"strings"
"strings"
"github.com/mholt/caddy/app"
"github.com/mholt/caddy/middleware"
"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
)
{
func
TLS
(
c
*
Controller
)
(
middleware
.
Middleware
,
error
)
{
c
.
TLS
.
Enabled
=
true
c
.
TLS
.
Enabled
=
true
if
c
.
Port
==
"http"
{
if
c
.
Port
==
"http"
{
...
@@ -79,6 +56,9 @@ func TLS(c *Controller) (middleware.Middleware, error) {
...
@@ -79,6 +56,9 @@ func TLS(c *Controller) (middleware.Middleware, error) {
if
!
ok
{
if
!
ok
{
return
nil
,
c
.
Errf
(
"Wrong cipher name or cipher not supported '%s'"
,
c
.
Val
())
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
)
c
.
TLS
.
Ciphers
=
append
(
c
.
TLS
.
Ciphers
,
value
)
}
}
case
"cache"
:
case
"cache"
:
...
@@ -87,7 +67,7 @@ func TLS(c *Controller) (middleware.Middleware, error) {
...
@@ -87,7 +67,7 @@ func TLS(c *Controller) (middleware.Middleware, error) {
}
}
size
,
err
:=
strconv
.
Atoi
(
c
.
Val
())
size
,
err
:=
strconv
.
Atoi
(
c
.
Val
())
if
err
!=
nil
{
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
c
.
TLS
.
CacheSize
=
size
default
:
default
:
...
@@ -96,12 +76,14 @@ func TLS(c *Controller) (middleware.Middleware, error) {
...
@@ -96,12 +76,14 @@ 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
{
if
len
(
c
.
TLS
.
Ciphers
)
==
0
{
for
_
,
v
:=
range
supportedCiphers
{
for
_
,
v
:=
range
supportedCiphers
{
if
_
,
ok
:=
http2CipherSuites
[
v
];
!
app
.
Http2
||
ok
{
c
.
TLS
.
Ciphers
=
append
(
c
.
TLS
.
Ciphers
,
v
)
c
.
TLS
.
Ciphers
=
append
(
c
.
TLS
.
Ciphers
,
v
)
}
}
}
}
}
// If no ProtocolMin provided, set default MinVersion to TLSv1.1 for security reasons
// If no ProtocolMin provided, set default MinVersion to TLSv1.1 for security reasons
if
c
.
TLS
.
ProtocolMinVersion
==
0
{
if
c
.
TLS
.
ProtocolMinVersion
==
0
{
...
@@ -114,9 +96,43 @@ func TLS(c *Controller) (middleware.Middleware, error) {
...
@@ -114,9 +96,43 @@ func TLS(c *Controller) (middleware.Middleware, error) {
}
}
//If no cachesize provided, set default to 64
//If no cachesize provided, set default to 64
if
c
.
TLS
.
CacheSize
=
=
0
{
if
c
.
TLS
.
CacheSize
<
=
0
{
c
.
TLS
.
CacheSize
=
64
c
.
TLS
.
CacheSize
=
64
}
}
return
nil
,
nil
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
{}{},
}
config/setup/tls_test.go
View file @
5f72b743
...
@@ -3,8 +3,29 @@ package setup
...
@@ -3,8 +3,29 @@ package setup
import
(
import
(
"crypto/tls"
"crypto/tls"
"testing"
"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
)
{
func
TestTLSParseNoOptional
(
t
*
testing
.
T
)
{
c
:=
newTestController
(
`tls cert.crt cert.key`
)
c
:=
newTestController
(
`tls cert.crt cert.key`
)
...
@@ -44,7 +65,6 @@ func TestTLSParseIncompleteParams(t *testing.T) {
...
@@ -44,7 +65,6 @@ func TestTLSParseIncompleteParams(t *testing.T) {
if
err
==
nil
{
if
err
==
nil
{
t
.
Errorf
(
"Expected errors, but no error returned"
)
t
.
Errorf
(
"Expected errors, but no error returned"
)
}
}
}
}
func
TestTLSParseWithOptionalParams
(
t
*
testing
.
T
)
{
func
TestTLSParseWithOptionalParams
(
t
*
testing
.
T
)
{
...
@@ -107,3 +127,43 @@ func TestTLSParseWithWrongOptionalParams(t *testing.T) {
...
@@ -107,3 +127,43 @@ func TestTLSParseWithWrongOptionalParams(t *testing.T) {
t
.
Errorf
(
"Expected errors, but no error returned"
)
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
))
}
}
main.go
View file @
5f72b743
...
@@ -2,58 +2,49 @@ package main
...
@@ -2,58 +2,49 @@ package main
import
(
import
(
"bytes"
"bytes"
"errors"
"flag"
"flag"
"fmt"
"fmt"
"io/ioutil"
"io/ioutil"
"log"
"log"
"net"
"os"
"os"
"os/exec"
"os/exec"
"path"
"path"
"runtime"
"runtime"
"strconv"
"strconv"
"strings"
"strings"
"sync"
"github.com/mholt/caddy/app"
"github.com/mholt/caddy/config"
"github.com/mholt/caddy/config"
"github.com/mholt/caddy/server"
"github.com/mholt/caddy/server"
)
)
var
(
var
(
conf
string
conf
string
http2
bool
// TODO: temporary flag until http2 is standard
quiet
bool
cpu
string
cpu
string
version
bool
version
bool
)
)
func
init
()
{
func
init
()
{
flag
.
StringVar
(
&
conf
,
"conf"
,
""
,
"Configuration file to use (default="
+
config
.
DefaultConfigFile
+
")"
)
flag
.
StringVar
(
&
conf
,
"conf"
,
""
,
"Configuration file to use (default="
+
config
.
DefaultConfigFile
+
")"
)
flag
.
BoolVar
(
&
h
ttp2
,
"http2"
,
true
,
"Enable HTTP/2 support"
)
// TODO: temporary flag until http2 merged into std lib
flag
.
BoolVar
(
&
app
.
H
ttp2
,
"http2"
,
true
,
"Enable HTTP/2 support"
)
// TODO: temporary flag until http2 merged into std lib
flag
.
BoolVar
(
&
q
uiet
,
"quiet"
,
false
,
"Quiet mode (no initialization output)"
)
flag
.
BoolVar
(
&
app
.
Q
uiet
,
"quiet"
,
false
,
"Quiet mode (no initialization output)"
)
flag
.
StringVar
(
&
cpu
,
"cpu"
,
"100%"
,
"CPU cap"
)
flag
.
StringVar
(
&
cpu
,
"cpu"
,
"100%"
,
"CPU cap"
)
flag
.
StringVar
(
&
config
.
Root
,
"root"
,
config
.
DefaultRoot
,
"Root path to default site"
)
flag
.
StringVar
(
&
config
.
Root
,
"root"
,
config
.
DefaultRoot
,
"Root path to default site"
)
flag
.
StringVar
(
&
config
.
Host
,
"host"
,
config
.
DefaultHost
,
"Default host"
)
flag
.
StringVar
(
&
config
.
Host
,
"host"
,
config
.
DefaultHost
,
"Default host"
)
flag
.
StringVar
(
&
config
.
Port
,
"port"
,
config
.
DefaultPort
,
"Default port"
)
flag
.
StringVar
(
&
config
.
Port
,
"port"
,
config
.
DefaultPort
,
"Default port"
)
flag
.
BoolVar
(
&
version
,
"version"
,
false
,
"Show version"
)
flag
.
BoolVar
(
&
version
,
"version"
,
false
,
"Show version"
)
config
.
AppName
=
"Caddy"
config
.
AppVersion
=
"0.6.0"
}
}
func
main
()
{
func
main
()
{
flag
.
Parse
()
flag
.
Parse
()
if
version
{
if
version
{
fmt
.
Printf
(
"%s %s
\n
"
,
config
.
AppName
,
config
.
App
Version
)
fmt
.
Printf
(
"%s %s
\n
"
,
app
.
Name
,
app
.
Version
)
os
.
Exit
(
0
)
os
.
Exit
(
0
)
}
}
var
wg
sync
.
WaitGroup
// Set CPU cap
// Set CPU cap
err
:=
s
etCPU
(
cpu
)
err
:=
app
.
S
etCPU
(
cpu
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Fatal
(
err
)
log
.
Fatal
(
err
)
}
}
...
@@ -65,7 +56,7 @@ func main() {
...
@@ -65,7 +56,7 @@ func main() {
}
}
// Group by address (virtual hosts)
// Group by address (virtual hosts)
addresses
,
err
:=
a
rrangeBindings
(
allConfigs
)
addresses
,
err
:=
config
.
A
rrangeBindings
(
allConfigs
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Fatal
(
err
)
log
.
Fatal
(
err
)
}
}
...
@@ -76,18 +67,21 @@ func main() {
...
@@ -76,18 +67,21 @@ func main() {
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Fatal
(
err
)
log
.
Fatal
(
err
)
}
}
s
.
HTTP2
=
h
ttp2
// TODO: This setting is temporary
s
.
HTTP2
=
app
.
H
ttp2
// TODO: This setting is temporary
w
g
.
Add
(
1
)
app
.
W
g
.
Add
(
1
)
go
func
(
s
*
server
.
Server
)
{
go
func
(
s
*
server
.
Server
)
{
defer
w
g
.
Done
()
defer
app
.
W
g
.
Done
()
err
:=
s
.
Serve
()
err
:=
s
.
Serve
()
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Fatal
(
err
)
// kill whole process to avoid a half-alive zombie server
log
.
Fatal
(
err
)
// kill whole process to avoid a half-alive zombie server
}
}
}(
s
)
}(
s
)
if
!
quiet
{
app
.
Servers
=
append
(
app
.
Servers
,
s
)
if
!
app
.
Quiet
{
var
checkedFdLimit
bool
var
checkedFdLimit
bool
for
addr
,
configs
:=
range
addresses
{
for
addr
,
configs
:=
range
addresses
{
for
_
,
conf
:=
range
configs
{
for
_
,
conf
:=
range
configs
{
// Print address of site
// Print address of site
...
@@ -117,7 +111,7 @@ func main() {
...
@@ -117,7 +111,7 @@ func main() {
}
}
}
}
w
g
.
Wait
()
app
.
W
g
.
Wait
()
}
}
func
isLocalhost
(
s
string
)
bool
{
func
isLocalhost
(
s
string
)
bool
{
...
@@ -169,76 +163,3 @@ func loadConfigs() ([]server.Config, error) {
...
@@ -169,76 +163,3 @@ func loadConfigs() ([]server.Config, error) {
return
config
.
Load
(
config
.
DefaultConfigFile
,
file
)
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
}
server/server.go
View file @
5f72b743
...
@@ -132,17 +132,11 @@ func ListenAndServeTLSWithSNI(srv *http.Server, tlsConfigs []TLSConfig) error {
...
@@ -132,17 +132,11 @@ func ListenAndServeTLSWithSNI(srv *http.Server, tlsConfigs []TLSConfig) error {
}
}
config
.
BuildNameToCertificate
()
config
.
BuildNameToCertificate
()
// Here we change some crypto/tls defaults based on caddyfile
// Customize our TLS configuration
// If no config provided, we set defaults focused in security
// Add a session cache LRU algorithm
config
.
ClientSessionCache
=
tls
.
NewLRUClientSessionCache
(
tlsConfigs
[
0
]
.
CacheSize
)
config
.
ClientSessionCache
=
tls
.
NewLRUClientSessionCache
(
tlsConfigs
[
0
]
.
CacheSize
)
config
.
MinVersion
=
tlsConfigs
[
0
]
.
ProtocolMinVersion
config
.
MinVersion
=
tlsConfigs
[
0
]
.
ProtocolMinVersion
config
.
MaxVersion
=
tlsConfigs
[
0
]
.
ProtocolMaxVersion
config
.
MaxVersion
=
tlsConfigs
[
0
]
.
ProtocolMaxVersion
config
.
CipherSuites
=
tlsConfigs
[
0
]
.
Ciphers
config
.
CipherSuites
=
tlsConfigs
[
0
]
.
Ciphers
// Server ciphers have priority over client ciphers
config
.
PreferServerCipherSuites
=
true
config
.
PreferServerCipherSuites
=
true
conn
,
err
:=
net
.
Listen
(
"tcp"
,
addr
)
conn
,
err
:=
net
.
Listen
(
"tcp"
,
addr
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment