forked from TrueCloudLab/rclone
serve http, webdav, restic: ensure rclone exits if the port is in use
This commit is contained in:
parent
1f05d5bf4a
commit
bb5637d46a
7 changed files with 65 additions and 40 deletions
|
@ -46,7 +46,11 @@ control the stats printing.
|
||||||
f := cmd.NewFsSrc(args)
|
f := cmd.NewFsSrc(args)
|
||||||
cmd.Run(false, true, command, func() error {
|
cmd.Run(false, true, command, func() error {
|
||||||
s := newServer(f, &httpflags.Opt)
|
s := newServer(f, &httpflags.Opt)
|
||||||
s.serve()
|
err := s.Serve()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Wait()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -54,30 +58,32 @@ control the stats printing.
|
||||||
|
|
||||||
// server contains everything to run the server
|
// server contains everything to run the server
|
||||||
type server struct {
|
type server struct {
|
||||||
|
*httplib.Server
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
vfs *vfs.VFS
|
vfs *vfs.VFS
|
||||||
srv *httplib.Server
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServer(f fs.Fs, opt *httplib.Options) *server {
|
func newServer(f fs.Fs, opt *httplib.Options) *server {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
s := &server{
|
s := &server{
|
||||||
|
Server: httplib.NewServer(mux, opt),
|
||||||
f: f,
|
f: f,
|
||||||
vfs: vfs.New(f, &vfsflags.Opt),
|
vfs: vfs.New(f, &vfsflags.Opt),
|
||||||
srv: httplib.NewServer(mux, opt),
|
|
||||||
}
|
}
|
||||||
mux.HandleFunc("/", s.handler)
|
mux.HandleFunc("/", s.handler)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// serve runs the http server - doesn't return
|
// Serve runs the http server in the background.
|
||||||
func (s *server) serve() {
|
//
|
||||||
err := s.srv.Serve()
|
// Use s.Close() and s.Wait() to shutdown server
|
||||||
|
func (s *server) Serve() error {
|
||||||
|
err := s.Server.Serve()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(s.f, "Opening listener: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
fs.Logf(s.f, "Serving on %s", s.srv.URL())
|
fs.Logf(s.f, "Serving on %s", s.URL())
|
||||||
s.srv.Wait()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handler reads incoming requests and dispatches them
|
// handler reads incoming requests and dispatches them
|
||||||
|
|
|
@ -35,7 +35,7 @@ func startServer(t *testing.T, f fs.Fs) {
|
||||||
opt := httplib.DefaultOpt
|
opt := httplib.DefaultOpt
|
||||||
opt.ListenAddr = testBindAddress
|
opt.ListenAddr = testBindAddress
|
||||||
httpServer = newServer(f, &opt)
|
httpServer = newServer(f, &opt)
|
||||||
go httpServer.serve()
|
assert.NoError(t, httpServer.Serve())
|
||||||
|
|
||||||
// try to connect to the test server
|
// try to connect to the test server
|
||||||
pause := time.Millisecond
|
pause := time.Millisecond
|
||||||
|
@ -233,5 +233,6 @@ func TestAddEntry(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFinalise(t *testing.T) {
|
func TestFinalise(t *testing.T) {
|
||||||
httpServer.srv.Close()
|
httpServer.Close()
|
||||||
|
httpServer.Wait()
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
|
|
||||||
auth "github.com/abbot/go-http-auth"
|
auth "github.com/abbot/go-http-auth"
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
|
@ -188,7 +189,7 @@ func NewServer(handler http.Handler, opt *Options) *Server {
|
||||||
func (s *Server) Serve() error {
|
func (s *Server) Serve() error {
|
||||||
ln, err := net.Listen("tcp", s.httpServer.Addr)
|
ln, err := net.Listen("tcp", s.httpServer.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrapf(err, "start server failed")
|
||||||
}
|
}
|
||||||
s.listener = ln
|
s.listener = ln
|
||||||
s.waitChan = make(chan struct{})
|
s.waitChan = make(chan struct{})
|
||||||
|
|
|
@ -138,8 +138,11 @@ these **must** end with /. Eg
|
||||||
httpSrv.ServeConn(conn, opts)
|
httpSrv.ServeConn(conn, opts)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
err := s.Serve()
|
||||||
s.serve()
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Wait()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -151,28 +154,30 @@ const (
|
||||||
|
|
||||||
// server contains everything to run the server
|
// server contains everything to run the server
|
||||||
type server struct {
|
type server struct {
|
||||||
|
*httplib.Server
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
srv *httplib.Server
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServer(f fs.Fs, opt *httplib.Options) *server {
|
func newServer(f fs.Fs, opt *httplib.Options) *server {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
s := &server{
|
s := &server{
|
||||||
|
Server: httplib.NewServer(mux, opt),
|
||||||
f: f,
|
f: f,
|
||||||
srv: httplib.NewServer(mux, opt),
|
|
||||||
}
|
}
|
||||||
mux.HandleFunc("/", s.handler)
|
mux.HandleFunc("/", s.handler)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// serve runs the http server - doesn't return
|
// Serve runs the http server in the background.
|
||||||
func (s *server) serve() {
|
//
|
||||||
err := s.srv.Serve()
|
// Use s.Close() and s.Wait() to shutdown server
|
||||||
|
func (s *server) Serve() error {
|
||||||
|
err := s.Server.Serve()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(s.f, "Opening listener: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
fs.Logf(s.f, "Serving restic REST API on %s", s.srv.URL())
|
fs.Logf(s.f, "Serving restic REST API on %s", s.URL())
|
||||||
s.srv.Wait()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var matchData = regexp.MustCompile("(?:^|/)data/([^/]{2,})$")
|
var matchData = regexp.MustCompile("(?:^|/)data/([^/]{2,})$")
|
||||||
|
|
|
@ -41,8 +41,11 @@ func TestRestic(t *testing.T) {
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
w := newServer(fremote, &opt)
|
w := newServer(fremote, &opt)
|
||||||
go w.serve()
|
assert.NoError(t, w.Serve())
|
||||||
defer w.srv.Close()
|
defer func() {
|
||||||
|
w.Close()
|
||||||
|
w.Wait()
|
||||||
|
}()
|
||||||
|
|
||||||
// Change directory to run the tests
|
// Change directory to run the tests
|
||||||
err = os.Chdir(resticSource)
|
err = os.Chdir(resticSource)
|
||||||
|
|
|
@ -68,8 +68,12 @@ Use "rclone hashsum" to see the full list.
|
||||||
fs.Debugf(f, "Using hash %v for ETag", hashType)
|
fs.Debugf(f, "Using hash %v for ETag", hashType)
|
||||||
}
|
}
|
||||||
cmd.Run(false, false, command, func() error {
|
cmd.Run(false, false, command, func() error {
|
||||||
w := newWebDAV(f, &httpflags.Opt)
|
s := newWebDAV(f, &httpflags.Opt)
|
||||||
w.serve()
|
err := s.serve()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Wait()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
|
@ -89,9 +93,9 @@ Use "rclone hashsum" to see the full list.
|
||||||
// might apply". In particular, whether or not renaming a file or directory
|
// might apply". In particular, whether or not renaming a file or directory
|
||||||
// overwriting another existing file or directory is an error is OS-dependent.
|
// overwriting another existing file or directory is an error is OS-dependent.
|
||||||
type WebDAV struct {
|
type WebDAV struct {
|
||||||
|
*httplib.Server
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
vfs *vfs.VFS
|
vfs *vfs.VFS
|
||||||
srv *httplib.Server
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check interface
|
// check interface
|
||||||
|
@ -110,18 +114,20 @@ func newWebDAV(f fs.Fs, opt *httplib.Options) *WebDAV {
|
||||||
Logger: w.logRequest, // FIXME
|
Logger: w.logRequest, // FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
w.srv = httplib.NewServer(handler, opt)
|
w.Server = httplib.NewServer(handler, opt)
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
// serve runs the http server - doesn't return
|
// serve runs the http server in the background.
|
||||||
func (w *WebDAV) serve() {
|
//
|
||||||
err := w.srv.Serve()
|
// Use s.Close() and s.Wait() to shutdown server
|
||||||
|
func (w *WebDAV) serve() error {
|
||||||
|
err := w.Serve()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(w.f, "Opening listener: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
fs.Logf(w.f, "WebDav Server started on %s", w.srv.URL())
|
fs.Logf(w.f, "WebDav Server started on %s", w.URL())
|
||||||
w.srv.Wait()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// logRequest is called by the webdav module on every request
|
// logRequest is called by the webdav module on every request
|
||||||
|
|
|
@ -48,8 +48,11 @@ func TestWebDav(t *testing.T) {
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
w := newWebDAV(fremote, &opt)
|
w := newWebDAV(fremote, &opt)
|
||||||
go w.serve()
|
assert.NoError(t, w.serve())
|
||||||
defer w.srv.Close()
|
defer func() {
|
||||||
|
w.Close()
|
||||||
|
w.Wait()
|
||||||
|
}()
|
||||||
|
|
||||||
// Change directory to run the tests
|
// Change directory to run the tests
|
||||||
err = os.Chdir("../../../backend/webdav")
|
err = os.Chdir("../../../backend/webdav")
|
||||||
|
|
Loading…
Reference in a new issue