summaryrefslogtreecommitdiff
path: root/internal/server/handlers
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2021-10-09 21:10:29 +0300
committerPaul Buetow <paul@buetow.org>2021-10-10 13:36:41 +0300
commit97747ea0f3178f7f5890512d483fdccaa82846b0 (patch)
tree9ff1335ca26afc90e55fd6de416457e252d75a35 /internal/server/handlers
parent7a7169791a64190e1002e38bc9c04ad0d5c1ce1f (diff)
vetting and linting and some code restyling
Diffstat (limited to 'internal/server/handlers')
-rw-r--r--internal/server/handlers/basehandler.go30
-rw-r--r--internal/server/handlers/healthhandler.go11
-rw-r--r--internal/server/handlers/mapcommand.go7
-rw-r--r--internal/server/handlers/readcommand.go41
-rw-r--r--internal/server/handlers/serverhandler.go20
5 files changed, 52 insertions, 57 deletions
diff --git a/internal/server/handlers/basehandler.go b/internal/server/handlers/basehandler.go
index f73f82e..847e8f9 100644
--- a/internal/server/handlers/basehandler.go
+++ b/internal/server/handlers/basehandler.go
@@ -37,7 +37,7 @@ type baseHandler struct {
activeCommands int32
quiet bool
spartan bool
- serverless bool
+ serverless int32
readBuf bytes.Buffer
writeBuf bytes.Buffer
}
@@ -59,16 +59,14 @@ func (h *baseHandler) Read(p []byte) (n int, err error) {
select {
case message := <-h.serverMessages:
if message[0] == '.' {
- // Handle hidden message (don't display to the user, interpreted by dtail client)
+ // Handle hidden message (don't display to the user)
h.readBuf.WriteString(message)
h.readBuf.WriteByte(protocol.MessageDelimiter)
n = copy(p, h.readBuf.Bytes())
return
}
- if h.serverless {
- // In serverless mode we have logged the server message already via the
- // dlog logger, no need to send the message again to the client part.
+ if h.serverless > 0 {
return
}
@@ -132,7 +130,6 @@ func (h *baseHandler) Write(p []byte) (n int, err error) {
h.writeBuf.WriteByte(b)
}
}
-
n = len(p)
return
}
@@ -145,13 +142,11 @@ func (h *baseHandler) handleCommand(commandStr string) {
h.send(h.serverMessages, dlog.Server.Error(h.user, err)+add)
return
}
-
args, argc, err = h.handleBase64(args, argc)
if err != nil {
h.send(h.serverMessages, dlog.Server.Error(h.user, err))
return
}
-
ctx, cancel := context.WithCancel(context.Background())
go func() {
<-h.done.Done()
@@ -160,7 +155,6 @@ func (h *baseHandler) handleCommand(commandStr string) {
splitted := strings.Split(args[0], ":")
commandName := splitted[0]
-
options, err := config.DeserializeOptions(splitted[1:])
if err != nil {
h.send(h.serverMessages, dlog.Server.Error(h.user, err))
@@ -191,8 +185,8 @@ func (h *baseHandler) handleProtocolVersion(args []string) ([]string, int, strin
if clientCompat > serverCompat {
toUpdate = "server"
}
-
- err := fmt.Errorf("DTail server protocol version '%s' does not match client protocol version '%s', please update DTail %s!",
+ err := fmt.Errorf("the DTail server protocol version '%s' does not match "+
+ "client protocol version '%s', please update DTail %s",
protocol.ProtocolCompat, args[1], toUpdate)
return args, argc, add, err
}
@@ -201,8 +195,8 @@ func (h *baseHandler) handleProtocolVersion(args []string) ([]string, int, strin
}
func (h *baseHandler) handleBase64(args []string, argc int) ([]string, int, error) {
- err := errors.New("Unable to decode client message, DTail server and client versions may not be compatible")
-
+ err := errors.New("unable to decode client message, DTail server and client " +
+ "versions may not be compatible")
if argc != 2 || args[0] != "base64" {
return args, argc, err
}
@@ -215,7 +209,8 @@ func (h *baseHandler) handleBase64(args []string, argc int) ([]string, int, erro
args = strings.Split(decodedStr, " ")
argc = len(decodedStr)
- dlog.Server.Trace(h.user, "Base64 decoded received command", decodedStr, argc, args)
+ dlog.Server.Trace(h.user, "Base64 decoded received command",
+ decodedStr, argc, args)
return args, argc, nil
}
@@ -223,7 +218,8 @@ func (h *baseHandler) handleBase64(args []string, argc int) ([]string, int, erro
func (h *baseHandler) handleAckCommand(argc int, args []string) {
if argc < 3 {
if !h.quiet {
- h.send(h.serverMessages, dlog.Server.Warn(h.user, "Unable to parse command", args, argc))
+ h.send(h.serverMessages, dlog.Server.Warn(h.user,
+ "Unable to parse command", args, argc))
}
return
}
@@ -245,11 +241,9 @@ func (h *baseHandler) send(ch chan<- string, message string) {
func (h *baseHandler) flush() {
dlog.Server.Trace(h.user, "flush()")
-
numUnsentMessages := func() int {
return len(h.lines) + len(h.serverMessages) + len(h.maprMessages)
}
-
for i := 0; i < 10; i++ {
if numUnsentMessages() == 0 {
dlog.Server.Debug(h.user, "ALL lines sent", fmt.Sprintf("%p", h))
@@ -258,7 +252,6 @@ func (h *baseHandler) flush() {
dlog.Server.Debug(h.user, "Still lines to be sent")
time.Sleep(time.Millisecond * 10)
}
-
dlog.Server.Warn(h.user, "Some lines remain unsent", numUnsentMessages())
}
@@ -279,7 +272,6 @@ func (h *baseHandler) shutdown() {
dlog.Server.Debug(h.user, "Shutdown timeout reached, enforcing shutdown")
case <-h.done.Done():
}
-
h.done.Shutdown()
}
diff --git a/internal/server/handlers/healthhandler.go b/internal/server/handlers/healthhandler.go
index 347ff66..8d6c400 100644
--- a/internal/server/handlers/healthhandler.go
+++ b/internal/server/handlers/healthhandler.go
@@ -35,24 +35,23 @@ func NewHealthHandler(user *user.User) *HealthHandler {
if err != nil {
dlog.Server.FatalPanic(err)
}
-
s := strings.Split(fqdn, ".")
h.hostname = s[0]
-
return &h
}
-func (h *HealthHandler) handleHealthCommand(ctx context.Context, argc int, args []string,
- commandName string, options map[string]string) {
- dlog.Server.Debug(h.user, "Handling health command", argc, args)
+func (h *HealthHandler) handleHealthCommand(ctx context.Context, argc int,
+ args []string, commandName string, options map[string]string) {
+ dlog.Server.Debug(h.user, "Handling health command", argc, args)
switch commandName {
case "health":
h.send(h.serverMessages, "OK")
case ".ack":
h.handleAckCommand(argc, args)
default:
- h.send(h.serverMessages, dlog.Server.Error(h.user, "Received unknown health command", commandName, argc, args))
+ h.send(h.serverMessages, dlog.Server.Error(h.user,
+ "Received unknown health command", commandName, argc, args))
}
h.shutdown()
}
diff --git a/internal/server/handlers/mapcommand.go b/internal/server/handlers/mapcommand.go
index c3e600e..65e0ed8 100644
--- a/internal/server/handlers/mapcommand.go
+++ b/internal/server/handlers/mapcommand.go
@@ -14,18 +14,17 @@ type mapCommand struct {
}
// NewMapCommand returns a new server side mapreduce command.
-func newMapCommand(serverHandler *ServerHandler, argc int, args []string) (mapCommand, *server.Aggregate, error) {
- m := mapCommand{server: serverHandler}
+func newMapCommand(serverHandler *ServerHandler, argc int,
+ args []string) (mapCommand, *server.Aggregate, error) {
+ m := mapCommand{server: serverHandler}
queryStr := strings.Join(args[1:], " ")
aggregate, err := server.NewAggregate(queryStr)
if err != nil {
return m, nil, err
}
-
m.aggregate = aggregate
return m, aggregate, nil
-
}
func (m mapCommand) Start(ctx context.Context, aggregatedMessages chan<- string) {
diff --git a/internal/server/handlers/readcommand.go b/internal/server/handlers/readcommand.go
index abc44c7..384e966 100644
--- a/internal/server/handlers/readcommand.go
+++ b/internal/server/handlers/readcommand.go
@@ -26,25 +26,30 @@ func newReadCommand(server *ServerHandler, mode omode.Mode) *readCommand {
}
}
-func (r *readCommand) Start(ctx context.Context, argc int, args []string, retries int) {
- re := regex.NewNoop()
+func (r *readCommand) Start(ctx context.Context, argc int, args []string,
+ retries int) {
+ re := regex.NewNoop()
if argc >= 4 {
deserializedRegex, err := regex.Deserialize(strings.Join(args[2:], " "))
if err != nil {
- r.server.send(r.server.serverMessages, dlog.Server.Error(r.server.user, "Unable to parse command", err))
+ r.server.send(r.server.serverMessages, dlog.Server.Error(r.server.user,
+ "Unable to parse command", err))
return
}
re = deserializedRegex
}
if argc < 3 {
- r.server.send(r.server.serverMessages, dlog.Server.Warn(r.server.user, "Unable to parse command", args, argc))
+ r.server.send(r.server.serverMessages, dlog.Server.Warn(r.server.user,
+ "Unable to parse command", args, argc))
return
}
r.readGlob(ctx, args[1], re, retries)
}
-func (r *readCommand) readGlob(ctx context.Context, glob string, re regex.Regex, retries int) {
+func (r *readCommand) readGlob(ctx context.Context, glob string, re regex.Regex,
+ retries int) {
+
retryInterval := time.Second * 5
glob = filepath.Clean(glob)
@@ -58,7 +63,8 @@ func (r *readCommand) readGlob(ctx context.Context, glob string, re regex.Regex,
if numPaths := len(paths); numPaths == 0 {
dlog.Server.Error(r.server.user, "No such file(s) to read", glob)
- r.server.send(r.server.serverMessages, dlog.Server.Warn(r.server.user, "Unable to read file(s), check server logs"))
+ r.server.send(r.server.serverMessages, dlog.Server.Warn(r.server.user,
+ "Unable to read file(s), check server logs"))
select {
case <-ctx.Done():
return
@@ -72,31 +78,33 @@ func (r *readCommand) readGlob(ctx context.Context, glob string, re regex.Regex,
return
}
- r.server.send(r.server.serverMessages, dlog.Server.Warn(r.server.user, "Giving up to read file(s)"))
+ r.server.send(r.server.serverMessages, dlog.Server.Warn(r.server.user,
+ "Giving up to read file(s)"))
return
}
-func (r *readCommand) readFiles(ctx context.Context, paths []string, glob string, re regex.Regex, retryInterval time.Duration) {
+func (r *readCommand) readFiles(ctx context.Context, paths []string, glob string,
+ re regex.Regex, retryInterval time.Duration) {
+
var wg sync.WaitGroup
wg.Add(len(paths))
-
for _, path := range paths {
go r.readFileIfPermissions(ctx, &wg, path, glob, re)
}
-
wg.Wait()
}
-func (r *readCommand) readFileIfPermissions(ctx context.Context, wg *sync.WaitGroup, path, glob string, re regex.Regex) {
+func (r *readCommand) readFileIfPermissions(ctx context.Context,
+ wg *sync.WaitGroup, path, glob string, re regex.Regex) {
+
defer wg.Done()
globID := r.makeGlobID(path, glob)
-
if !r.server.user.HasFilePermission(path, "readfiles") {
dlog.Server.Error(r.server.user, "No permission to read file", path, globID)
- r.server.send(r.server.serverMessages, dlog.Server.Warn(r.server.user, "Unable to read file(s), check server logs"))
+ r.server.send(r.server.serverMessages, dlog.Server.Warn(r.server.user,
+ "Unable to read file(s), check server logs"))
return
}
-
r.readFile(ctx, path, globID, re)
}
@@ -137,7 +145,6 @@ func (r *readCommand) readFile(ctx context.Context, path, globID string, re rege
return
}
}
-
time.Sleep(time.Second * 2)
dlog.Server.Info(path, globID, "Reading file again")
}
@@ -156,11 +163,11 @@ func (r *readCommand) makeGlobID(path, glob string) string {
if len(idParts) > 0 {
return strings.Join(idParts, "/")
}
-
if len(pathParts) > 0 {
return pathParts[len(pathParts)-1]
}
- r.server.send(r.server.serverMessages, dlog.Server.Warn("Empty file path given?", path, glob))
+ r.server.send(r.server.serverMessages,
+ dlog.Server.Warn("Empty file path given?", path, glob))
return ""
}
diff --git a/internal/server/handlers/serverhandler.go b/internal/server/handlers/serverhandler.go
index aed8956..f12d590 100644
--- a/internal/server/handlers/serverhandler.go
+++ b/internal/server/handlers/serverhandler.go
@@ -4,6 +4,7 @@ import (
"context"
"os"
"strings"
+ "sync/atomic"
"github.com/mimecast/dtail/internal"
"github.com/mimecast/dtail/internal/io/dlog"
@@ -23,7 +24,9 @@ type ServerHandler struct {
}
// NewServerHandler returns the server handler.
-func NewServerHandler(user *user.User, catLimiter, tailLimiter chan struct{}) *ServerHandler {
+func NewServerHandler(user *user.User, catLimiter,
+ tailLimiter chan struct{}) *ServerHandler {
+
dlog.Server.Debug(user, "Creating new server handler")
h := ServerHandler{
baseHandler: baseHandler{
@@ -51,11 +54,10 @@ func NewServerHandler(user *user.User, catLimiter, tailLimiter chan struct{}) *S
return &h
}
-func (h *ServerHandler) handleUserCommand(ctx context.Context, argc int, args []string,
- commandName string, options map[string]string) {
+func (h *ServerHandler) handleUserCommand(ctx context.Context, argc int,
+ args []string, commandName string, options map[string]string) {
dlog.Server.Debug(h.user, "Handling user command", argc, args)
-
h.incrementActiveCommands()
commandFinished := func() {
if h.decrementActiveCommands() == 0 {
@@ -73,7 +75,7 @@ func (h *ServerHandler) handleUserCommand(ctx context.Context, argc int, args []
}
if serverless, _ := options["serverless"]; serverless == "true" {
dlog.Server.Debug(h.user, "Enabling serverless mode")
- h.serverless = true
+ atomic.AddInt32(&h.serverless, 1)
}
switch commandName {
@@ -83,14 +85,12 @@ func (h *ServerHandler) handleUserCommand(ctx context.Context, argc int, args []
command.Start(ctx, argc, args, 1)
commandFinished()
}()
-
case "tail":
command := newReadCommand(h, omode.TailClient)
go func() {
command.Start(ctx, argc, args, 10)
commandFinished()
}()
-
case "map":
command, aggregate, err := newMapCommand(h, argc, args)
if err != nil {
@@ -99,19 +99,17 @@ func (h *ServerHandler) handleUserCommand(ctx context.Context, argc int, args []
commandFinished()
return
}
-
h.aggregate = aggregate
go func() {
command.Start(ctx, h.maprMessages)
commandFinished()
}()
-
case ".ack":
h.handleAckCommand(argc, args)
commandFinished()
-
default:
- h.send(h.serverMessages, dlog.Server.Error(h.user, "Received unknown user command", commandName, argc, args, options))
+ h.send(h.serverMessages, dlog.Server.Error(h.user,
+ "Received unknown user command", commandName, argc, args, options))
commandFinished()
}
}