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
Łukasz Nowak
caddy
Commits
2fbfafc4
Commit
2fbfafc4
authored
Mar 26, 2015
by
Matthew Holt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New startup and shutdown directives
parent
b5dc1dde
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
144 additions
and
63 deletions
+144
-63
config/config.go
config/config.go
+45
-40
config/directives.go
config/directives.go
+53
-0
middleware/commands.go
middleware/commands.go
+27
-0
middleware/websockets/websockets.go
middleware/websockets/websockets.go
+1
-23
server/server.go
server/server.go
+18
-0
No files found.
config/config.go
View file @
2fbfafc4
...
...
@@ -14,6 +14,51 @@ const (
defaultRoot
=
"."
)
// config represents a server configuration. It
// is populated by parsing a config file (via the
// Load function).
type
Config
struct
{
// The hostname or IP to which to bind the server
Host
string
// The port to listen on
Port
string
// The directory from which to serve files
Root
string
// HTTPS configuration
TLS
TLSConfig
// Middleware stack
Middleware
map
[
string
][]
middleware
.
Middleware
// Functions (or methods) to execute at server start; these
// are executed before any parts of the server are configured,
// and the functions are blocking
Startup
[]
func
()
error
// Functions (or methods) to execute when the server quits;
// these are executed in response to SIGINT and are blocking
Shutdown
[]
func
()
error
// MaxCPU is the maximum number of cores for the whole process to use
MaxCPU
int
}
// Address returns the host:port of c as a string.
func
(
c
Config
)
Address
()
string
{
return
c
.
Host
+
":"
+
c
.
Port
}
// TLSConfig describes how TLS should be configured and used,
// if at all. A certificate and key are both required.
type
TLSConfig
struct
{
Enabled
bool
Certificate
string
Key
string
}
// Load loads a configuration file, parses it,
// and returns a slice of Config structs which
// can be used to create and configure server
...
...
@@ -54,43 +99,3 @@ func Default() []Config {
}
return
cfg
}
// config represents a server configuration. It
// is populated by parsing a config file (via the
// Load function).
type
Config
struct
{
// The hostname or IP to which to bind the server
Host
string
// The port to listen on
Port
string
// The directory from which to serve files
Root
string
// HTTPS configuration
TLS
TLSConfig
// Middleware stack
Middleware
map
[
string
][]
middleware
.
Middleware
// Functions (or methods) to execute at server start; these
// are executed before any parts of the server are configured
Startup
[]
func
()
error
// MaxCPU is the maximum number of cores for the whole process to use
MaxCPU
int
}
// Address returns the host:port of c as a string.
func
(
c
Config
)
Address
()
string
{
return
c
.
Host
+
":"
+
c
.
Port
}
// TLSConfig describes how TLS should be configured and used,
// if at all. At least a certificate and key are required.
type
TLSConfig
struct
{
Enabled
bool
Certificate
string
Key
string
}
config/directives.go
View file @
2fbfafc4
...
...
@@ -2,9 +2,12 @@ package config
import
(
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"github.com/mholt/caddy/middleware"
)
// dirFunc is a type of parsing function which processes
...
...
@@ -111,5 +114,55 @@ func init() {
}
return
nil
},
"startup"
:
func
(
p
*
parser
)
error
{
// TODO: This code is duplicated with the shutdown directive below
if
!
p
.
nextArg
()
{
return
p
.
argErr
()
}
command
,
args
,
err
:=
middleware
.
SplitCommandAndArgs
(
p
.
tkn
())
if
err
!=
nil
{
return
p
.
err
(
"Parse"
,
err
.
Error
())
}
startupfn
:=
func
()
error
{
cmd
:=
exec
.
Command
(
command
,
args
...
)
cmd
.
Stdout
=
os
.
Stdout
cmd
.
Stderr
=
os
.
Stderr
err
:=
cmd
.
Run
()
if
err
!=
nil
{
return
err
}
return
nil
}
p
.
cfg
.
Startup
=
append
(
p
.
cfg
.
Startup
,
startupfn
)
return
nil
},
"shutdown"
:
func
(
p
*
parser
)
error
{
if
!
p
.
nextArg
()
{
return
p
.
argErr
()
}
command
,
args
,
err
:=
middleware
.
SplitCommandAndArgs
(
p
.
tkn
())
if
err
!=
nil
{
return
p
.
err
(
"Parse"
,
err
.
Error
())
}
shutdownfn
:=
func
()
error
{
cmd
:=
exec
.
Command
(
command
,
args
...
)
cmd
.
Stdout
=
os
.
Stdout
cmd
.
Stderr
=
os
.
Stderr
err
:=
cmd
.
Run
()
if
err
!=
nil
{
return
err
}
return
nil
}
p
.
cfg
.
Shutdown
=
append
(
p
.
cfg
.
Shutdown
,
shutdownfn
)
return
nil
},
}
}
middleware/commands.go
0 → 100644
View file @
2fbfafc4
package
middleware
import
(
"errors"
"github.com/flynn/go-shlex"
)
// SplitCommandAndArgs takes a command string and parses it
// shell-style into the command and its separate arguments.
func
SplitCommandAndArgs
(
command
string
)
(
cmd
string
,
args
[]
string
,
err
error
)
{
parts
,
err
:=
shlex
.
Split
(
command
)
if
err
!=
nil
{
err
=
errors
.
New
(
"Error parsing command: "
+
err
.
Error
())
return
}
else
if
len
(
parts
)
==
0
{
err
=
errors
.
New
(
"No command contained in '"
+
command
+
"'"
)
return
}
cmd
=
parts
[
0
]
if
len
(
parts
)
>
1
{
args
=
parts
[
1
:
]
}
return
}
middleware/websockets/websockets.go
View file @
2fbfafc4
...
...
@@ -4,10 +4,8 @@
package
websockets
import
(
"errors"
"net/http"
"github.com/flynn/go-shlex"
"github.com/mholt/caddy/middleware"
"golang.org/x/net/websocket"
)
...
...
@@ -101,7 +99,7 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
}
// Split command into the actual command and its arguments
cmd
,
args
,
err
:=
parse
CommandAndArgs
(
command
)
cmd
,
args
,
err
:=
middleware
.
Split
CommandAndArgs
(
command
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -122,26 +120,6 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
},
nil
}
// parseCommandAndArgs takes a command string and parses it
// shell-style into the command and its separate arguments.
func
parseCommandAndArgs
(
command
string
)
(
cmd
string
,
args
[]
string
,
err
error
)
{
parts
,
err
:=
shlex
.
Split
(
command
)
if
err
!=
nil
{
err
=
errors
.
New
(
"Error parsing command for websocket: "
+
err
.
Error
())
return
}
else
if
len
(
parts
)
==
0
{
err
=
errors
.
New
(
"No command found for use by websocket"
)
return
}
cmd
=
parts
[
0
]
if
len
(
parts
)
>
1
{
args
=
parts
[
1
:
]
}
return
}
var
(
// See CGI spec, 4.1.4
GatewayInterface
string
...
...
server/server.go
View file @
2fbfafc4
...
...
@@ -7,6 +7,8 @@ import (
"errors"
"log"
"net/http"
"os"
"os/signal"
"runtime"
"github.com/bradfitz/http2"
...
...
@@ -75,6 +77,21 @@ func (s *Server) Serve() error {
http2
.
ConfigureServer
(
server
,
nil
)
// TODO: This may not be necessary after HTTP/2 merged into std lib
// Execute shutdown commands on exit
// TODO: Is graceful net/http shutdown necessary?
go
func
()
{
interrupt
:=
make
(
chan
os
.
Signal
,
1
)
signal
.
Notify
(
interrupt
,
os
.
Interrupt
,
os
.
Kill
)
// TODO: syscall.SIGQUIT? (Ctrl+\, Unix-only)
<-
interrupt
for
_
,
shutdownFunc
:=
range
s
.
config
.
Shutdown
{
err
:=
shutdownFunc
()
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
}
os
.
Exit
(
0
)
}()
if
s
.
config
.
TLS
.
Enabled
{
return
server
.
ListenAndServeTLS
(
s
.
config
.
TLS
.
Certificate
,
s
.
config
.
TLS
.
Key
)
}
else
{
...
...
@@ -103,6 +120,7 @@ func (s *Server) Log(v ...interface{}) {
func
(
s
*
Server
)
buildStack
()
error
{
s
.
fileServer
=
FileServer
(
http
.
Dir
(
s
.
config
.
Root
))
// Execute startup functions
for
_
,
start
:=
range
s
.
config
.
Startup
{
err
:=
start
()
if
err
!=
nil
{
...
...
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