aboutsummaryrefslogtreecommitdiff
path: root/hotline
diff options
context:
space:
mode:
authorJeff Halter <868228+jhalter@users.noreply.github.com>2022-06-08 20:41:57 -0700
committerJeff Halter <868228+jhalter@users.noreply.github.com>2022-06-08 20:41:57 -0700
commitba29c43bb23de83c7715271e0830cb9f00e9e1c1 (patch)
tree40adf0940e4a7f2d1c1a4a55e159e21a4e07f951 /hotline
parentb196a50a44a5c72fc43df39fce4407d05ec8863b (diff)
Fix folder upload hang with resource forks
Diffstat (limited to 'hotline')
-rw-r--r--hotline/file_transfer.go32
-rw-r--r--hotline/server.go23
-rw-r--r--hotline/transfer.go26
3 files changed, 32 insertions, 49 deletions
diff --git a/hotline/file_transfer.go b/hotline/file_transfer.go
index 9e86bb8..4a93390 100644
--- a/hotline/file_transfer.go
+++ b/hotline/file_transfer.go
@@ -38,38 +38,6 @@ func (ft *FileTransfer) ItemCount() int {
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
diff --git a/hotline/server.go b/hotline/server.go
index 33888e0..1a6d163 100644
--- a/hotline/server.go
+++ b/hotline/server.go
@@ -978,15 +978,26 @@ func (s *Server) handleFileTransfer(conn io.ReadWriteCloser) error {
}
fileSize := make([]byte, 4)
- readBuffer := make([]byte, 1024)
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
}
- fu := readFolderUpload(readBuffer)
s.Logger.Infow(
"Folder upload continued",
@@ -1073,7 +1084,7 @@ func (s *Server) handleFileTransfer(conn io.ReadWriteCloser) error {
}
case dlFldrActionSendFile:
- if _, err := conn.Read(fileSize); err != nil {
+ if _, err := io.ReadFull(conn, fileSize); err != nil {
return err
}
diff --git a/hotline/transfer.go b/hotline/transfer.go
index 78bd888..4e6f79f 100644
--- a/hotline/transfer.go
+++ b/hotline/transfer.go
@@ -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)
- if _, err := conn.Read(ffhBuf); err != nil {
+ if _, err := io.ReadFull(conn, ffhBuf); err != nil {
return err
}
@@ -43,7 +43,7 @@ func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) er
}
ffifhBuf := make([]byte, 16)
- if _, err := conn.Read(ffifhBuf); err != nil {
+ if _, err := io.ReadFull(conn, ffifhBuf); err != nil {
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)
- if _, err := conn.Read(ffifBuf); err != nil {
+ if _, err := io.ReadFull(conn, 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)
- 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)
@@ -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
- 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
}
- err = binary.Read(bytes.NewReader(resForkBuf), binary.BigEndian, &resForkHeader)
- if err != nil {
+
+ if _, err := io.ReadFull(conn, resForkHeader.CompressionType[:]); err != nil {
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)
- _, err = io.CopyN(resForkFile, conn, int64(fileSize))
+ _, err = io.CopyN(resForkFile, conn, int64(binary.BigEndian.Uint32(resForkHeader.DataSize[:])))
if err != nil {
return err
}