mirror of
https://github.com/mmatczuk/go-http-tunnel.git
synced 2026-05-15 14:16:17 -06:00
Upd client list can now be a client folder
This commit is contained in:
parent
51e9f199e5
commit
c93916810b
5 changed files with 90 additions and 28 deletions
28
client.go
28
client.go
|
|
@ -14,6 +14,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff"
|
||||
"golang.org/x/net/http2"
|
||||
|
||||
"github.com/hons82/go-http-tunnel/connection"
|
||||
|
|
@ -98,7 +99,7 @@ func (c *Client) Start() error {
|
|||
"level", 1,
|
||||
"action", "start",
|
||||
)
|
||||
|
||||
b := backoff.NewExponentialBackOff()
|
||||
for {
|
||||
conn, err := c.connect()
|
||||
if err != nil {
|
||||
|
|
@ -115,17 +116,36 @@ func (c *Client) Start() error {
|
|||
)
|
||||
|
||||
c.connMu.Lock()
|
||||
now := time.Now()
|
||||
err = c.serverErr
|
||||
|
||||
// detect disconnect hiccup
|
||||
if err == nil && now.Sub(c.lastDisconnect).Seconds() < 5 {
|
||||
if err == nil && time.Since(c.lastDisconnect).Seconds() < 5 {
|
||||
err = fmt.Errorf("connection is being cut")
|
||||
}
|
||||
|
||||
// Backoff
|
||||
if b != nil {
|
||||
if err != nil {
|
||||
d := b.NextBackOff()
|
||||
if d > 0 {
|
||||
// backoff
|
||||
c.logger.Log(
|
||||
"level", 1,
|
||||
"action", "backoff",
|
||||
"sleep", d,
|
||||
"err", err,
|
||||
)
|
||||
time.Sleep(d)
|
||||
err = nil
|
||||
}
|
||||
} else {
|
||||
b.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
c.conn = nil
|
||||
c.serverErr = nil
|
||||
c.lastDisconnect = now
|
||||
c.lastDisconnect = time.Now()
|
||||
c.connMu.Unlock()
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -71,12 +71,11 @@ func main() {
|
|||
|
||||
if !autoSubscribe {
|
||||
// First load immediatly
|
||||
server.LoadAllowedTunnels(opts.clients)
|
||||
server.ReloadTunnels(opts.clients)
|
||||
|
||||
// Watch for the file to change
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
fatal("NewWatcher failed: %s", err)
|
||||
logger.Log(
|
||||
"level", 1,
|
||||
"action", "could not create file watcher",
|
||||
|
|
@ -98,9 +97,11 @@ func main() {
|
|||
"file", event.Name,
|
||||
"action", event.Op.String(),
|
||||
)
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
if event.Op&fsnotify.Write == fsnotify.Write ||
|
||||
event.Op&fsnotify.Create == fsnotify.Create ||
|
||||
event.Op&fsnotify.Remove == fsnotify.Remove {
|
||||
server.Clear()
|
||||
server.LoadAllowedTunnels(event.Name)
|
||||
server.ReloadTunnels(opts.clients)
|
||||
}
|
||||
case err, ok := <-watcher.Errors:
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package fileutil
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -17,7 +16,6 @@ func ReadPropertiesFile(filename string) (AppConfigProperties, error) {
|
|||
}
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
|
@ -25,7 +23,7 @@ func ReadPropertiesFile(filename string) (AppConfigProperties, error) {
|
|||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if equal := strings.Index(line, "="); equal >= 0 {
|
||||
if equal := strings.Index(line, ";"); equal >= 0 {
|
||||
if key := strings.TrimSpace(line[:equal]); len(key) > 0 {
|
||||
value := ""
|
||||
if len(line) > equal {
|
||||
|
|
@ -37,9 +35,17 @@ func ReadPropertiesFile(filename string) (AppConfigProperties, error) {
|
|||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// IsDirectory determines if a file represented by `path` is a directory or not
|
||||
func IsDirectory(path string) (bool, error) {
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return fileInfo.IsDir(), err
|
||||
}
|
||||
|
|
|
|||
13
registry.go
13
registry.go
|
|
@ -118,13 +118,12 @@ func (r *registry) Unsubscribe(identifier id.ID, autoSubscribe bool) *RegistryIt
|
|||
"identifier", identifier,
|
||||
)
|
||||
|
||||
if i.Hosts != nil {
|
||||
for _, h := range i.Hosts {
|
||||
delete(r.hosts, h.Host)
|
||||
}
|
||||
}
|
||||
|
||||
if autoSubscribe {
|
||||
if i.Hosts != nil {
|
||||
for _, h := range i.Hosts {
|
||||
delete(r.hosts, h.Host)
|
||||
}
|
||||
}
|
||||
delete(r.items, identifier)
|
||||
} else {
|
||||
r.items[identifier] = voidRegistryItem
|
||||
|
|
@ -174,7 +173,7 @@ func (r *registry) set(i *RegistryItem, identifier id.ID) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *registry) RegisterTunnel(host string, client string) error {
|
||||
func (r *registry) registerTunnel(host string, client string) error {
|
||||
identifier := id.New([]byte(client))
|
||||
|
||||
r.logger.Log(
|
||||
|
|
|
|||
54
server.go
54
server.go
|
|
@ -14,6 +14,8 @@ import (
|
|||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -410,11 +412,10 @@ func (s *Server) handleClient(conn net.Conn) {
|
|||
}
|
||||
|
||||
if len(tunnels) == 0 {
|
||||
err = fmt.Errorf("no tunnels")
|
||||
logger.Log(
|
||||
"level", 2,
|
||||
"msg", "handshake failed",
|
||||
"err", err,
|
||||
"level", 1,
|
||||
"msg", "configuration error",
|
||||
"err", fmt.Errorf("no tunnels"),
|
||||
)
|
||||
goto reject
|
||||
}
|
||||
|
|
@ -431,7 +432,7 @@ func (s *Server) handleClient(conn net.Conn) {
|
|||
if err = s.addTunnels(tunnels, identifier, IDInfo); err != nil {
|
||||
logger.Log(
|
||||
"level", 2,
|
||||
"msg", "handshake failed",
|
||||
"msg", "add tunnel failed",
|
||||
"err", err,
|
||||
)
|
||||
goto reject
|
||||
|
|
@ -467,8 +468,8 @@ reject:
|
|||
conn.Close()
|
||||
}
|
||||
|
||||
// LoadAllowedTunnels registers allowed tunnels from a file
|
||||
func (s *Server) LoadAllowedTunnels(propertiesFile string) {
|
||||
// loadAllowedTunnels registers allowed tunnels from a file
|
||||
func (s *Server) loadAllowedTunnels(propertiesFile string) {
|
||||
clients, err := fileutil.ReadPropertiesFile(propertiesFile)
|
||||
if err != nil {
|
||||
s.logger.Log(
|
||||
|
|
@ -480,7 +481,7 @@ func (s *Server) LoadAllowedTunnels(propertiesFile string) {
|
|||
}
|
||||
|
||||
for host, value := range clients {
|
||||
if err := s.RegisterTunnel(host, value); err != nil {
|
||||
if err := s.registerTunnel(host, value); err != nil {
|
||||
s.logger.Log(
|
||||
"level", 2,
|
||||
"action", "failed to load tunnel",
|
||||
|
|
@ -491,6 +492,41 @@ func (s *Server) LoadAllowedTunnels(propertiesFile string) {
|
|||
}
|
||||
}
|
||||
|
||||
// ReloadTunnels registers allowed tunnels from a file
|
||||
func (s *Server) ReloadTunnels(path string) {
|
||||
directory, err := fileutil.IsDirectory(path)
|
||||
if err != nil {
|
||||
s.logger.Log(
|
||||
"level", 3,
|
||||
"action", "could not determine if path is a directory",
|
||||
"err", err,
|
||||
)
|
||||
}
|
||||
if directory {
|
||||
files, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
s.logger.Log(
|
||||
"level", 2,
|
||||
"action", "could not read directory",
|
||||
"err", err,
|
||||
)
|
||||
}
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
s.logger.Log(
|
||||
"level", 3,
|
||||
"action", "skip directory",
|
||||
"file", file.Name(),
|
||||
)
|
||||
} else {
|
||||
s.loadAllowedTunnels(filepath.Join(path, file.Name()))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s.loadAllowedTunnels(path)
|
||||
}
|
||||
}
|
||||
|
||||
// notifyError tries to send error to client.
|
||||
func (s *Server) notifyError(serverError error, identifier id.ID) {
|
||||
if serverError == nil {
|
||||
|
|
@ -523,7 +559,7 @@ func (s *Server) hasTunnels(tunnels map[string]*proto.Tunnel, identifier id.ID)
|
|||
// AutoSubscribe --> Tunnel not yet registered (means that it isn't already opened)
|
||||
// !AutoSubscribe -> Tunnel has to be already registered, and therefore allowed to be opened
|
||||
if s.config.AutoSubscribe == s.HasTunnel(t.Host, identifier) {
|
||||
err = fmt.Errorf("tunnel %s not allowed for %s", name, identifier)
|
||||
err = fmt.Errorf("tunnel %s (%s) not allowed for %s", name, t.Host, identifier)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue