X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/72dd37f1abb2b550aaaac48eac677403d5664797..11843c8da176b40093972e9037df3e04b077890b:/hotline/server.go diff --git a/hotline/server.go b/hotline/server.go index 8e0fb50..30121a6 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -1,7 +1,6 @@ package hotline import ( - "bytes" "context" "encoding/binary" "errors" @@ -414,7 +413,7 @@ func (s *Server) loadAccounts(userDir string) error { } for _, file := range matches { - fh, err := os.Open(file) + fh, err := FS.Open(file) if err != nil { return err } @@ -432,7 +431,7 @@ func (s *Server) loadAccounts(userDir string) error { } func (s *Server) loadConfig(path string) error { - fh, err := os.Open(path) + fh, err := FS.Open(path) if err != nil { return err } @@ -543,7 +542,6 @@ func (s *Server) handleNewConnection(conn net.Conn) error { c.Server.Stats.LoginCount += 1 const readBuffSize = 1024000 // 1KB - TODO: what should this be? - const maxTranSize = 1024000 tranBuff := make([]byte, 0) tReadlen := 0 // Infinite loop where take action on incoming client requests until the connection is closed @@ -638,11 +636,15 @@ func (s *Server) TransferFile(conn net.Conn) error { switch fileTransfer.Type { case FileDownload: - fullFilePath := fmt.Sprintf("%v/%v", s.Config.FileRoot+string(fileTransfer.FilePath), string(fileTransfer.FileName)) + fullFilePath, err := readPath(s.Config.FileRoot, fileTransfer.FilePath, fileTransfer.FileName) + if err != nil { + return err + } ffo, err := NewFlattenedFileObject( - s.Config.FileRoot+string(fileTransfer.FilePath), - string(fileTransfer.FileName), + s.Config.FileRoot, + fileTransfer.FilePath, + fileTransfer.FileName, ) if err != nil { return err @@ -651,11 +653,11 @@ func (s *Server) TransferFile(conn net.Conn) error { s.Logger.Infow("File download started", "filePath", fullFilePath, "transactionRef", fileTransfer.ReferenceNumber, "RemoteAddr", conn.RemoteAddr().String()) // Start by sending flat file object to client - if _, err := conn.Write(ffo.Payload()); err != nil { + if _, err := conn.Write(ffo.BinaryMarshal()); err != nil { return err } - file, err := os.Open(fullFilePath) + file, err := FS.Open(fullFilePath) if err != nil { return err } @@ -681,7 +683,7 @@ func (s *Server) TransferFile(conn net.Conn) error { } ffo := ReadFlattenedFileObject(buf) - payloadLen := len(ffo.Payload()) + payloadLen := len(ffo.BinaryMarshal()) fileSize := int(binary.BigEndian.Uint32(ffo.FlatFileDataForkHeader.DataSize)) destinationFile := s.Config.FileRoot + ReadFilePath(fileTransfer.FilePath) + "/" + string(fileTransfer.FileName) @@ -758,9 +760,10 @@ func (s *Server) TransferFile(conn net.Conn) error { // // This notifies the server to send the next item header - var fh FilePath - _ = fh.UnmarshalBinary(fileTransfer.FilePath) - fullFilePath := fmt.Sprintf("%v/%v", s.Config.FileRoot+fh.String(), string(fileTransfer.FileName)) + fullFilePath, err := readPath(s.Config.FileRoot, fileTransfer.FilePath, fileTransfer.FileName) + if err != nil { + return err + } basePathLen := len(fullFilePath) @@ -789,7 +792,6 @@ func (s *Server) TransferFile(conn net.Conn) error { // Read the client's Next Action request //TODO: Remove hardcoded behavior and switch behaviors based on the next action send if _, err := conn.Read(readBuffer); err != nil { - s.Logger.Errorf("error reading next action: %v", err) return err } @@ -800,9 +802,12 @@ func (s *Server) TransferFile(conn net.Conn) error { } splitPath := strings.Split(path, "/") - //strings.Join(splitPath[:len(splitPath)-1], "/") - ffo, err := NewFlattenedFileObject(strings.Join(splitPath[:len(splitPath)-1], "/"), info.Name()) + ffo, err := NewFlattenedFileObject( + strings.Join(splitPath[:len(splitPath)-1], "/"), + nil, + []byte(info.Name()), + ) if err != nil { return err } @@ -820,18 +825,18 @@ func (s *Server) TransferFile(conn net.Conn) error { } // Send file bytes to client - if _, err := conn.Write(ffo.Payload()); err != nil { + if _, err := conn.Write(ffo.BinaryMarshal()); err != nil { s.Logger.Error(err) return err } - file, err := os.Open(path) + file, err := FS.Open(path) if err != nil { return err } sendBuffer := make([]byte, 1048576) - totalBytesSent := len(ffo.Payload()) + totalBytesSent := len(ffo.BinaryMarshal()) for { bytesRead, err := file.Read(sendBuffer) @@ -855,20 +860,23 @@ func (s *Server) TransferFile(conn net.Conn) error { }) case FolderUpload: - dstPath := s.Config.FileRoot + ReadFilePath(fileTransfer.FilePath) + "/" + string(fileTransfer.FileName) + dstPath, err := readPath(s.Config.FileRoot, fileTransfer.FilePath, fileTransfer.FileName) + if err != nil { + return err + } s.Logger.Infow( "Folder upload started", "transactionRef", fileTransfer.ReferenceNumber, "RemoteAddr", conn.RemoteAddr().String(), "dstPath", dstPath, - "TransferSize", fileTransfer.TransferSize, + "TransferSize", fmt.Sprintf("%x", fileTransfer.TransferSize), "FolderItemCount", fileTransfer.FolderItemCount, ) // Check if the target folder exists. If not, create it. - if _, err := os.Stat(dstPath); os.IsNotExist(err) { - s.Logger.Infow("Target path does not exist; Creating...", "dstPath", dstPath) - if err := os.Mkdir(dstPath, 0777); err != nil { + if _, err := FS.Stat(dstPath); os.IsNotExist(err) { + s.Logger.Infow("Creating target path", "dstPath", dstPath) + if err := FS.Mkdir(dstPath, 0777); err != nil { s.Logger.Error(err) } } @@ -895,10 +903,10 @@ func (s *Server) TransferFile(conn net.Conn) error { "RemoteAddr", conn.RemoteAddr().String(), "FormattedPath", fu.FormattedPath(), "IsFolder", fmt.Sprintf("%x", fu.IsFolder), - "PathItemCount", binary.BigEndian.Uint16(fu.PathItemCount), + "PathItemCount", binary.BigEndian.Uint16(fu.PathItemCount[:]), ) - if bytes.Equal(fu.IsFolder, []byte{0, 1}) { + if fu.IsFolder == [2]byte{0, 1} { if _, err := os.Stat(dstPath + "/" + fu.FormattedPath()); os.IsNotExist(err) { s.Logger.Infow("Target path does not exist; Creating...", "dstPath", dstPath) if err := os.Mkdir(dstPath+"/"+fu.FormattedPath(), 0777); err != nil { @@ -957,7 +965,7 @@ func transferFile(conn net.Conn, dst string) error { return err } ffo := ReadFlattenedFileObject(buf) - payloadLen := len(ffo.Payload()) + payloadLen := len(ffo.BinaryMarshal()) fileSize := int(binary.BigEndian.Uint32(ffo.FlatFileDataForkHeader.DataSize)) newFile, err := os.Create(dst) @@ -985,51 +993,6 @@ func transferFile(conn net.Conn, dst string) error { } } -// 00 28 // DataSize -// 00 00 // IsFolder -// 00 02 // PathItemCount -// -// 00 00 -// 09 -// 73 75 62 66 6f 6c 64 65 72 // "subfolder" -// -// 00 00 -// 15 -// 73 75 62 66 6f 6c 64 65 72 2d 74 65 73 74 66 69 6c 65 2d 35 6b // "subfolder-testfile-5k" -func readFolderUpload(buf []byte) folderUpload { - dataLen := binary.BigEndian.Uint16(buf[0:2]) - - fu := folderUpload{ - DataSize: buf[0:2], // Size of this structure (not including data size element itself) - IsFolder: buf[2:4], - PathItemCount: buf[4:6], - FileNamePath: buf[6 : dataLen+2], - } - - return fu -} - -type folderUpload struct { - DataSize []byte - IsFolder []byte - PathItemCount []byte - FileNamePath []byte -} - -func (fu *folderUpload) FormattedPath() string { - pathItemLen := binary.BigEndian.Uint16(fu.PathItemCount) - - var pathSegments []string - pathData := fu.FileNamePath - - for i := uint16(0); i < pathItemLen; i++ { - segLen := pathData[2] - pathSegments = append(pathSegments, string(pathData[3:3+segLen])) - pathData = pathData[3+segLen:] - } - - return strings.Join(pathSegments, pathSeparator) -} // sortedClients is a utility function that takes a map of *ClientConn and returns a sorted slice of the values. // The purpose of this is to ensure that the ordering of client connections is deterministic so that test assertions work.