forked from TrueCloudLab/rclone
serve restic: Print actual listener address
This commit is contained in:
parent
5b8977a053
commit
e13f65b953
5 changed files with 80 additions and 15 deletions
|
@ -72,8 +72,12 @@ func newServer(f fs.Fs, opt *httplib.Options) *server {
|
||||||
|
|
||||||
// serve runs the http server - doesn't return
|
// serve runs the http server - doesn't return
|
||||||
func (s *server) serve() {
|
func (s *server) serve() {
|
||||||
|
err := s.srv.Serve()
|
||||||
|
if err != nil {
|
||||||
|
fs.Errorf(s.f, "Opening listener: %v", err)
|
||||||
|
}
|
||||||
fs.Logf(s.f, "Serving on %s", s.srv.URL())
|
fs.Logf(s.f, "Serving on %s", s.srv.URL())
|
||||||
s.srv.Serve()
|
s.srv.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// handler reads incoming requests and dispatches them
|
// handler reads incoming requests and dispatches them
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -24,10 +25,11 @@ var Help = `
|
||||||
|
|
||||||
Use --addr to specify which IP address and port the server should
|
Use --addr to specify which IP address and port the server should
|
||||||
listen on, eg --addr 1.2.3.4:8000 or --addr :8080 to listen to all
|
listen on, eg --addr 1.2.3.4:8000 or --addr :8080 to listen to all
|
||||||
IPs. By default it only listens on localhost.
|
IPs. By default it only listens on localhost. You can use port
|
||||||
|
:0 to let the OS choose an available port.
|
||||||
|
|
||||||
If you set --addr to listen on a public or LAN accessible IP address
|
If you set --addr to listen on a public or LAN accessible IP address
|
||||||
then using Authentication if advised - see the next section for info.
|
then using Authentication is advised - see the next section for info.
|
||||||
|
|
||||||
--server-read-timeout and --server-write-timeout can be used to
|
--server-read-timeout and --server-write-timeout can be used to
|
||||||
control the timeouts on the server. Note that this is the total time
|
control the timeouts on the server. Note that this is the total time
|
||||||
|
@ -98,6 +100,8 @@ var DefaultOpt = Options{
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Opt Options
|
Opt Options
|
||||||
handler http.Handler // original handler
|
handler http.Handler // original handler
|
||||||
|
listener net.Listener
|
||||||
|
waitChan chan struct{} // for waiting on the listener to close
|
||||||
httpServer *http.Server
|
httpServer *http.Server
|
||||||
basicPassHashed string
|
basicPassHashed string
|
||||||
useSSL bool // if server is configured for SSL/TLS
|
useSSL bool // if server is configured for SSL/TLS
|
||||||
|
@ -178,15 +182,52 @@ func NewServer(handler http.Handler, opt *Options) *Server {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve runs the server - doesn't return
|
// Serve runs the server - returns an error only if
|
||||||
func (s *Server) Serve() {
|
// the listener was not started; does not block, so
|
||||||
|
// use s.Wait() to block on the listener indefinitely.
|
||||||
|
func (s *Server) Serve() error {
|
||||||
|
ln, err := net.Listen("tcp", s.httpServer.Addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.listener = ln
|
||||||
|
s.waitChan = make(chan struct{})
|
||||||
|
go func() {
|
||||||
var err error
|
var err error
|
||||||
if s.useSSL {
|
if s.useSSL {
|
||||||
err = s.httpServer.ListenAndServeTLS(s.Opt.SslCert, s.Opt.SslKey)
|
// hacky hack to get this to work with old Go versions, which
|
||||||
} else {
|
// don't have ServeTLS on http.Server; see PR #2194.
|
||||||
err = s.httpServer.ListenAndServe()
|
type tlsServer interface {
|
||||||
|
ServeTLS(ln net.Listener, cert, key string) error
|
||||||
}
|
}
|
||||||
log.Printf("Error while serving HTTP: %v", err)
|
srvIface := interface{}(s.httpServer)
|
||||||
|
if tlsSrv, ok := srvIface.(tlsServer); ok {
|
||||||
|
// yay -- we get easy TLS support with HTTP/2
|
||||||
|
err = tlsSrv.ServeTLS(s.listener, s.Opt.SslCert, s.Opt.SslKey)
|
||||||
|
} else {
|
||||||
|
// oh well -- we can still do TLS but might not have HTTP/2
|
||||||
|
tlsConfig := new(tls.Config)
|
||||||
|
tlsConfig.Certificates = make([]tls.Certificate, 1)
|
||||||
|
tlsConfig.Certificates[0], err = tls.LoadX509KeyPair(s.Opt.SslCert, s.Opt.SslKey)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error loading key pair: %v", err)
|
||||||
|
}
|
||||||
|
tlsLn := tls.NewListener(s.listener, tlsConfig)
|
||||||
|
err = s.httpServer.Serve(tlsLn)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = s.httpServer.Serve(s.listener)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error on serving HTTP server: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait blocks while the listener is open.
|
||||||
|
func (s *Server) Wait() {
|
||||||
|
<-s.waitChan
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close shuts the running server down
|
// Close shuts the running server down
|
||||||
|
@ -194,7 +235,9 @@ func (s *Server) Close() {
|
||||||
err := closeServer(s.httpServer)
|
err := closeServer(s.httpServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error on closing HTTP server: %v", err)
|
log.Printf("Error on closing HTTP server: %v", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
close(s.waitChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL returns the serving address of this server
|
// URL returns the serving address of this server
|
||||||
|
@ -203,5 +246,11 @@ func (s *Server) URL() string {
|
||||||
if s.useSSL {
|
if s.useSSL {
|
||||||
proto = "https"
|
proto = "https"
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s://%s/", proto, s.Opt.ListenAddr)
|
addr := s.Opt.ListenAddr
|
||||||
|
if s.listener != nil {
|
||||||
|
// prefer actual listener address; required if using 0-port
|
||||||
|
// (i.e. port assigned by operating system)
|
||||||
|
addr = s.listener.Addr().String()
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s://%s/", proto, addr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,8 +169,12 @@ func newServer(f fs.Fs, opt *httplib.Options) *server {
|
||||||
|
|
||||||
// serve runs the http server - doesn't return
|
// serve runs the http server - doesn't return
|
||||||
func (s *server) serve() {
|
func (s *server) serve() {
|
||||||
|
err := s.srv.Serve()
|
||||||
|
if err != nil {
|
||||||
|
fs.Errorf(s.f, "Opening listener: %v", 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.srv.URL())
|
||||||
s.srv.Serve()
|
s.srv.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
var matchData = regexp.MustCompile("(?:^|/)data/([^/]{2,})$")
|
var matchData = regexp.MustCompile("(?:^|/)data/([^/]{2,})$")
|
||||||
|
|
|
@ -88,8 +88,12 @@ func newWebDAV(f fs.Fs, opt *httplib.Options) *WebDAV {
|
||||||
|
|
||||||
// serve runs the http server - doesn't return
|
// serve runs the http server - doesn't return
|
||||||
func (w *WebDAV) serve() {
|
func (w *WebDAV) serve() {
|
||||||
|
err := w.srv.Serve()
|
||||||
|
if err != nil {
|
||||||
|
fs.Errorf(w.f, "Opening listener: %v", err)
|
||||||
|
}
|
||||||
fs.Logf(w.f, "WebDav Server started on %s", w.srv.URL())
|
fs.Logf(w.f, "WebDav Server started on %s", w.srv.URL())
|
||||||
w.srv.Serve()
|
w.srv.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// logRequest is called by the webdav module on every request
|
// logRequest is called by the webdav module on every request
|
||||||
|
|
|
@ -58,8 +58,12 @@ func newServer(opt *Options) *server {
|
||||||
|
|
||||||
// serve runs the http server - doesn't return
|
// serve runs the http server - doesn't return
|
||||||
func (s *server) serve() {
|
func (s *server) serve() {
|
||||||
|
err := s.srv.Serve()
|
||||||
|
if err != nil {
|
||||||
|
fs.Errorf(nil, "Opening listener: %v", err)
|
||||||
|
}
|
||||||
fs.Logf(nil, "Serving remote control on %s", s.srv.URL())
|
fs.Logf(nil, "Serving remote control on %s", s.srv.URL())
|
||||||
s.srv.Serve()
|
s.srv.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// handler reads incoming requests and dispatches them
|
// handler reads incoming requests and dispatches them
|
||||||
|
|
Loading…
Reference in a new issue