]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/server.go
Use client logger
[rbdr/mobius] / hotline / server.go
index 9df89f2b219ac0a7f24e57c48cbc8a6b2a967cb0..a91e1c817b5f0b2656d0c22704f8544704626eb3 100644 (file)
@@ -17,7 +17,6 @@ import (
        "math/rand"
        "net"
        "os"
-       "path"
        "path/filepath"
        "runtime/debug"
        "strings"
@@ -168,25 +167,31 @@ func (s *Server) sendTransaction(t Transaction) error {
        return nil
 }
 
+func (s *Server) processOutbox() {
+       for {
+               t := <-s.outbox
+               go func() {
+                       if err := s.sendTransaction(t); err != nil {
+                               s.Logger.Errorw("error sending transaction", "err", err)
+                       }
+               }()
+       }
+}
+
 func (s *Server) Serve(ctx context.Context, ln net.Listener) error {
+       go s.processOutbox()
+
        for {
                conn, err := ln.Accept()
                if err != nil {
                        s.Logger.Errorw("error accepting connection", "err", err)
                }
+               connCtx := context.WithValue(ctx, contextKeyReq, requestCtx{
+                       remoteAddr: conn.RemoteAddr().String(),
+               })
 
                go func() {
-                       for {
-                               t := <-s.outbox
-                               go func() {
-                                       if err := s.sendTransaction(t); err != nil {
-                                               s.Logger.Errorw("error sending transaction", "err", err)
-                                       }
-                               }()
-                       }
-               }()
-               go func() {
-                       if err := s.handleNewConnection(ctx, conn, conn.RemoteAddr().String()); err != nil {
+                       if err := s.handleNewConnection(connCtx, conn, conn.RemoteAddr().String()); err != nil {
                                s.Logger.Infow("New client connection established", "RemoteAddr", conn.RemoteAddr())
                                if err == io.EOF {
                                        s.Logger.Infow("Client disconnected", "RemoteAddr", conn.RemoteAddr())
@@ -227,28 +232,28 @@ func NewServer(configDir string, netPort int, logger *zap.SugaredLogger, FS File
                return nil, err
        }
 
-       server.Agreement, err = os.ReadFile(configDir + agreementFile)
+       server.Agreement, err = os.ReadFile(filepath.Join(configDir, agreementFile))
        if err != nil {
                return nil, err
        }
 
-       if server.FlatNews, err = os.ReadFile(configDir + "MessageBoard.txt"); err != nil {
+       if server.FlatNews, err = os.ReadFile(filepath.Join(configDir, "MessageBoard.txt")); err != nil {
                return nil, err
        }
 
-       if err := server.loadThreadedNews(configDir + "ThreadedNews.yaml"); err != nil {
+       if err := server.loadThreadedNews(filepath.Join(configDir, "ThreadedNews.yaml")); err != nil {
                return nil, err
        }
 
-       if err := server.loadConfig(configDir + "config.yaml"); err != nil {
+       if err := server.loadConfig(filepath.Join(configDir, "config.yaml")); err != nil {
                return nil, err
        }
 
-       if err := server.loadAccounts(configDir + "Users/"); err != nil {
+       if err := server.loadAccounts(filepath.Join(configDir, "Users/")); err != nil {
                return nil, err
        }
 
-       server.Config.FileRoot = configDir + "Files/"
+       server.Config.FileRoot = filepath.Join(configDir, "Files")
 
        *server.NextGuestID = 1
 
@@ -329,14 +334,14 @@ func (s *Server) writeThreadedNews() error {
                return err
        }
        err = ioutil.WriteFile(
-               s.ConfigDir+"ThreadedNews.yaml",
+               filepath.Join(s.ConfigDir, "ThreadedNews.yaml"),
                out,
                0666,
        )
        return err
 }
 
-func (s *Server) NewClientConn(conn net.Conn, remoteAddr string) *ClientConn {
+func (s *Server) NewClientConn(conn io.ReadWriteCloser, remoteAddr string) *ClientConn {
        s.mux.Lock()
        defer s.mux.Unlock()
 
@@ -379,7 +384,7 @@ func (s *Server) NewUser(login, name, password string, access []byte) error {
        }
        s.Accounts[login] = &account
 
-       return s.FS.WriteFile(s.ConfigDir+"Users/"+login+".yaml", out, 0666)
+       return s.FS.WriteFile(filepath.Join(s.ConfigDir, "Users", login+".yaml"), out, 0666)
 }
 
 func (s *Server) UpdateUser(login, newLogin, name, password string, access []byte) error {
@@ -388,7 +393,7 @@ func (s *Server) UpdateUser(login, newLogin, name, password string, access []byt
 
        // update renames the user login
        if login != newLogin {
-               err := os.Rename(s.ConfigDir+"Users/"+login+".yaml", s.ConfigDir+"Users/"+newLogin+".yaml")
+               err := os.Rename(filepath.Join(s.ConfigDir, "Users", login+".yaml"), filepath.Join(s.ConfigDir, "Users", newLogin+".yaml"))
                if err != nil {
                        return err
                }
@@ -405,7 +410,8 @@ func (s *Server) UpdateUser(login, newLogin, name, password string, access []byt
        if err != nil {
                return err
        }
-       if err := os.WriteFile(s.ConfigDir+"Users/"+newLogin+".yaml", out, 0666); err != nil {
+
+       if err := os.WriteFile(filepath.Join(s.ConfigDir, "Users", newLogin+".yaml"), out, 0666); err != nil {
                return err
        }
 
@@ -419,7 +425,7 @@ func (s *Server) DeleteUser(login string) error {
 
        delete(s.Accounts, login)
 
-       return s.FS.Remove(s.ConfigDir + "Users/" + login + ".yaml")
+       return s.FS.Remove(filepath.Join(s.ConfigDir, "Users", login+".yaml"))
 }
 
 func (s *Server) connectedUsers() []Field {
@@ -455,7 +461,7 @@ func (s *Server) loadThreadedNews(threadedNewsPath string) error {
 
 // loadAccounts loads account data from disk
 func (s *Server) loadAccounts(userDir string) error {
-       matches, err := filepath.Glob(path.Join(userDir, "*.yaml"))
+       matches, err := filepath.Glob(filepath.Join(userDir, "*.yaml"))
        if err != nil {
                return err
        }
@@ -579,7 +585,9 @@ func (s *Server) handleNewConnection(ctx context.Context, conn net.Conn, remoteA
                *c.Flags = []byte{0, 2}
        }
 
-       s.Logger.Infow("Client connection received", "login", login, "version", *c.Version, "RemoteAddr", remoteAddr)
+       c.logger = s.Logger.With("remoteAddr", remoteAddr, "login", login)
+
+       c.logger.Infow("Client connection received", "version", fmt.Sprintf("%x", *c.Version))
 
        s.outbox <- c.NewReply(clientLogin,
                NewField(fieldVersion, []byte{0x00, 0xbe}),
@@ -597,6 +605,8 @@ func (s *Server) handleNewConnection(ctx context.Context, conn net.Conn, remoteA
        if *c.Version == nil || bytes.Equal(*c.Version, nostalgiaVersion) {
                c.Agreed = true
 
+               c.logger = c.logger.With("name", string(c.UserName))
+
                c.notifyOthers(
                        *NewTransaction(
                                tranNotifyChangeUser, nil,
@@ -628,7 +638,7 @@ func (s *Server) handleNewConnection(ctx context.Context, conn net.Conn, remoteA
                // into a slice of transactions
                var transactions []Transaction
                if transactions, tReadlen, err = readTransactions(tranBuff); err != nil {
-                       c.Server.Logger.Errorw("Error handling transaction", "err", err)
+                       c.logger.Errorw("Error handling transaction", "err", err)
                }
 
                // iterate over all the transactions that were parsed from the byte slice and handle them
@@ -765,6 +775,9 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                }
 
                err = sendFile(wr, rFile, int(dataOffset))
+               if err != nil {
+                       return err
+               }
 
                if err := wr.Flush(); err != nil {
                        return err
@@ -808,8 +821,6 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        return err
                }
 
-               defer func() { _ = file.Close() }()
-
                s.Logger.Infow("File upload started", "transactionRef", fileTransfer.ReferenceNumber, "dstFile", destinationFile)
 
                rForkWriter := io.Discard
@@ -830,6 +841,10 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        return err
                }
 
+               if err := file.Close(); err != nil {
+                       return err
+               }
+
                if err := s.FS.Rename(destinationFile+".incomplete", destinationFile); err != nil {
                        return err
                }
@@ -1002,6 +1017,10 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        return nil
                })
 
+               if err != nil {
+                       return err
+               }
+
        case FolderUpload:
                dstPath, err := readPath(s.Config.FileRoot, fileTransfer.FilePath, fileTransfer.FileName)
                if err != nil {
@@ -1059,8 +1078,8 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        )
 
                        if fu.IsFolder == [2]byte{0, 1} {
-                               if _, err := os.Stat(dstPath + "/" + fu.FormattedPath()); os.IsNotExist(err) {
-                                       if err := os.Mkdir(dstPath+"/"+fu.FormattedPath(), 0777); err != nil {
+                               if _, err := os.Stat(filepath.Join(dstPath, fu.FormattedPath())); os.IsNotExist(err) {
+                                       if err := os.Mkdir(filepath.Join(dstPath, fu.FormattedPath()), 0777); err != nil {
                                                return err
                                        }
                                }
@@ -1073,7 +1092,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                nextAction := dlFldrActionSendFile
 
                                // Check if we have the full file already.  If so, send dlFldrAction_NextFile to client to skip.
-                               _, err = os.Stat(dstPath + "/" + fu.FormattedPath())
+                               _, err = os.Stat(filepath.Join(dstPath, fu.FormattedPath()))
                                if err != nil && !errors.Is(err, fs.ErrNotExist) {
                                        return err
                                }
@@ -1082,7 +1101,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                }
 
                                //  Check if we have a partial file already.  If so, send dlFldrAction_ResumeFile to client to resume upload.
-                               incompleteFile, err := os.Stat(dstPath + "/" + fu.FormattedPath() + incompleteFileSuffix)
+                               incompleteFile, err := os.Stat(filepath.Join(dstPath, fu.FormattedPath()+incompleteFileSuffix))
                                if err != nil && !errors.Is(err, fs.ErrNotExist) {
                                        return err
                                }
@@ -1135,7 +1154,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                                return err
                                        }
 
-                                       filePath := dstPath + "/" + fu.FormattedPath()
+                                       filePath := filepath.Join(dstPath, fu.FormattedPath())
 
                                        hlFile, err := newFileWrapper(s.FS, filePath, 0)
                                        if err != nil {