github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/varlinkapi/transfers.go (about) 1 // +build varlink 2 3 package varlinkapi 4 5 import ( 6 "bufio" 7 "fmt" 8 "io" 9 "io/ioutil" 10 "os" 11 12 iopodman "github.com/containers/libpod/pkg/varlink" 13 "github.com/sirupsen/logrus" 14 ) 15 16 // SendFile allows a client to send a file to the varlink server 17 func (i *VarlinkAPI) SendFile(call iopodman.VarlinkCall, ftype string, length int64) error { 18 if !call.WantsUpgrade() { 19 return call.ReplyErrorOccurred("client must use upgraded connection to send files") 20 } 21 22 outputFile, err := ioutil.TempFile("", "varlink_send") 23 if err != nil { 24 return call.ReplyErrorOccurred(err.Error()) 25 } 26 defer outputFile.Close() 27 28 if err = call.ReplySendFile(outputFile.Name()); err != nil { 29 // If an error occurs while sending the reply, return the error 30 return err 31 } 32 33 writer := bufio.NewWriter(outputFile) 34 defer writer.Flush() 35 36 reader := call.Call.Reader 37 if _, err := io.CopyN(writer, reader, length); err != nil { 38 return err 39 } 40 41 logrus.Debugf("successfully received %s", outputFile.Name()) 42 // Send an ACK to the client 43 call.Call.Writer.WriteString(fmt.Sprintf("%s:", outputFile.Name())) 44 call.Call.Writer.Flush() 45 return nil 46 47 } 48 49 // ReceiveFile allows the varlink server to send a file to a client 50 func (i *VarlinkAPI) ReceiveFile(call iopodman.VarlinkCall, filepath string, delete bool) error { 51 if !call.WantsUpgrade() { 52 return call.ReplyErrorOccurred("client must use upgraded connection to send files") 53 } 54 fs, err := os.Open(filepath) 55 if err != nil { 56 return call.ReplyErrorOccurred(err.Error()) 57 } 58 fileInfo, err := fs.Stat() 59 if err != nil { 60 return call.ReplyErrorOccurred(err.Error()) 61 } 62 63 // Send the file length down to client 64 // Varlink connection upgraded 65 if err = call.ReplyReceiveFile(fileInfo.Size()); err != nil { 66 // If an error occurs while sending the reply, return the error 67 return err 68 } 69 70 reader := bufio.NewReader(fs) 71 _, err = reader.WriteTo(call.Writer) 72 if err != nil { 73 return err 74 } 75 if delete { 76 if err := os.Remove(filepath); err != nil { 77 return err 78 } 79 } 80 return call.Writer.Flush() 81 }