]> git.r.bdr.sh - rbdr/mobius/commitdiff
Fix folder upload hang with resource forks
authorJeff Halter <redacted>
Thu, 9 Jun 2022 03:41:57 +0000 (20:41 -0700)
committerJeff Halter <redacted>
Thu, 9 Jun 2022 03:41:57 +0000 (20:41 -0700)
hotline/file_transfer.go
hotline/server.go
hotline/transfer.go

index 9e86bb8724558164f948bc5a916f6c781cc4fb9c..4a93390457c82a8e9c9f7b1f9f9e4f78f2f24db4 100644 (file)
@@ -38,38 +38,6 @@ func (ft *FileTransfer) ItemCount() int {
        return int(binary.BigEndian.Uint16(ft.FolderItemCount))
 }
 
        return int(binary.BigEndian.Uint16(ft.FolderItemCount))
 }
 
-// 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:      [2]byte{buf[0], buf[1]}, // Size of this structure (not including data size element itself)
-               IsFolder:      [2]byte{buf[2], buf[3]},
-               PathItemCount: [2]byte{buf[4], buf[5]},
-               FileNamePath:  buf[6 : dataLen+2],
-       }
-
-       return fu
-}
-
-func (fu *folderUpload) UnmarshalBinary(b []byte) error {
-       fu.DataSize = [2]byte{b[0], b[1]}
-       fu.IsFolder = [2]byte{b[2], b[3]}
-       fu.PathItemCount = [2]byte{b[4], b[5]}
-
-       return nil
-}
-
 type folderUpload struct {
        DataSize      [2]byte
        IsFolder      [2]byte
 type folderUpload struct {
        DataSize      [2]byte
        IsFolder      [2]byte
index 33888e08f745a92d1f41802603ba2aadb619c3ce..1a6d163fade17544f2065bdf7af72e59bed0ffde 100644 (file)
@@ -978,15 +978,26 @@ func (s *Server) handleFileTransfer(conn io.ReadWriteCloser) error {
                }
 
                fileSize := make([]byte, 4)
                }
 
                fileSize := make([]byte, 4)
-               readBuffer := make([]byte, 1024)
 
                for i := 0; i < fileTransfer.ItemCount(); i++ {
 
                for i := 0; i < fileTransfer.ItemCount(); i++ {
-                       // TODO: fix potential short read with io.ReadFull
-                       _, err := conn.Read(readBuffer)
-                       if err != nil {
+                       s.Stats.UploadCounter += 1
+
+                       var fu folderUpload
+                       if _, err := io.ReadFull(conn, fu.DataSize[:]); err != nil {
+                               return err
+                       }
+
+                       if _, err := io.ReadFull(conn, fu.IsFolder[:]); err != nil {
+                               return err
+                       }
+                       if _, err := io.ReadFull(conn, fu.PathItemCount[:]); err != nil {
+                               return err
+                       }
+                       fu.FileNamePath = make([]byte, binary.BigEndian.Uint16(fu.DataSize[:])-4)
+
+                       if _, err := io.ReadFull(conn, fu.FileNamePath); err != nil {
                                return err
                        }
                                return err
                        }
-                       fu := readFolderUpload(readBuffer)
 
                        s.Logger.Infow(
                                "Folder upload continued",
 
                        s.Logger.Infow(
                                "Folder upload continued",
@@ -1073,7 +1084,7 @@ func (s *Server) handleFileTransfer(conn io.ReadWriteCloser) error {
                                        }
 
                                case dlFldrActionSendFile:
                                        }
 
                                case dlFldrActionSendFile:
-                                       if _, err := conn.Read(fileSize); err != nil {
+                                       if _, err := io.ReadFull(conn, fileSize); err != nil {
                                                return err
                                        }
 
                                                return err
                                        }
 
index 78bd888ccc35e3b27f168fcdc4ab6e7c20b7f0e1..4e6f79f0e3380c4337e6dda59f54a3696a3218b3 100644 (file)
@@ -32,7 +32,7 @@ func (tf *transfer) Write(b []byte) (int, error) {
 const fileCopyBufSize = 524288 // 512k
 func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) error {
        ffhBuf := make([]byte, 24)
 const fileCopyBufSize = 524288 // 512k
 func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) error {
        ffhBuf := make([]byte, 24)
-       if _, err := conn.Read(ffhBuf); err != nil {
+       if _, err := io.ReadFull(conn, ffhBuf); err != nil {
                return err
        }
 
                return err
        }
 
@@ -43,7 +43,7 @@ func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) er
        }
 
        ffifhBuf := make([]byte, 16)
        }
 
        ffifhBuf := make([]byte, 16)
-       if _, err := conn.Read(ffifhBuf); err != nil {
+       if _, err := io.ReadFull(conn, ffifhBuf); err != nil {
                return err
        }
 
                return err
        }
 
@@ -57,7 +57,7 @@ func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) er
 
        dataLen := binary.BigEndian.Uint32(ffifh.DataSize[:])
        ffifBuf := make([]byte, dataLen)
 
        dataLen := binary.BigEndian.Uint32(ffifh.DataSize[:])
        ffifBuf := make([]byte, dataLen)
-       if _, err := conn.Read(ffifBuf); err != nil {
+       if _, err := io.ReadFull(conn, ffifBuf); err != nil {
                return err
        }
        if err := ffif.UnmarshalBinary(ffifBuf); err != nil {
                return err
        }
        if err := ffif.UnmarshalBinary(ffifBuf); err != nil {
@@ -66,7 +66,7 @@ func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) er
 
        var ffdfh FlatFileDataForkHeader
        ffdfhBuf := make([]byte, 16)
 
        var ffdfh FlatFileDataForkHeader
        ffdfhBuf := make([]byte, 16)
-       if _, err := conn.Read(ffdfhBuf); err != nil {
+       if _, err := io.ReadFull(conn, ffdfhBuf); err != nil {
                return err
        }
        err = binary.Read(bytes.NewReader(ffdfhBuf), binary.BigEndian, &ffdfh)
                return err
        }
        err = binary.Read(bytes.NewReader(ffdfhBuf), binary.BigEndian, &ffdfh)
@@ -88,20 +88,24 @@ func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) er
 
        if ffh.ForkCount == [2]byte{0, 3} {
                var resForkHeader FlatFileDataForkHeader
 
        if ffh.ForkCount == [2]byte{0, 3} {
                var resForkHeader FlatFileDataForkHeader
-               resForkBuf := make([]byte, 16)
-               resForkBufWrter := bufio.NewWriterSize(resForkFile, 16)
-               if _, err := io.CopyN(resForkBufWrter, conn, 16); err != nil {
+               if _, err := io.ReadFull(conn, resForkHeader.ForkType[:]); err != nil {
                        return err
                }
                        return err
                }
-               err = binary.Read(bytes.NewReader(resForkBuf), binary.BigEndian, &resForkHeader)
-               if err != nil {
+
+               if _, err := io.ReadFull(conn, resForkHeader.CompressionType[:]); err != nil {
                        return err
                }
 
                        return err
                }
 
-               fileSize = int(binary.BigEndian.Uint32(resForkHeader.DataSize[:]))
+               if _, err := io.ReadFull(conn, resForkHeader.RSVD[:]); err != nil {
+                       return err
+               }
+
+               if _, err := io.ReadFull(conn, resForkHeader.DataSize[:]); err != nil {
+                       return err
+               }
 
                bw = bufio.NewWriterSize(resForkFile, fileCopyBufSize)
 
                bw = bufio.NewWriterSize(resForkFile, fileCopyBufSize)
-               _, err = io.CopyN(resForkFile, conn, int64(fileSize))
+               _, err = io.CopyN(resForkFile, conn, int64(binary.BigEndian.Uint32(resForkHeader.DataSize[:])))
                if err != nil {
                        return err
                }
                if err != nil {
                        return err
                }