How do you take a cipher.StreamWriter and pass it to a io.Reader

229 views
Skip to first unread message

Justin C

unread,
Feb 2, 2017, 2:27:09 PM2/2/17
to golang-nuts
I have a encryption function that gives a  cipher.StreamWriter 

    writer := &cipher.StreamWriter{S: stream, W: outFile}

I am trying to upload it to using a library that has a function that is uploadFile that requires a IO.reader is there a way to pass the writer to the io.reader so the file is in crypted then uploaded?

    UploadFile(outputFileName, metadata, io.Reader)

My code looks like this


                writer := &cipher.StreamWriter{S: stream, W: outFile}
// Copy the input file to the output file, encrypting as we go.

metadata := make(map[string]string)
b2h.currentBucket.UploadFile(outputFileName, metadata, writer)

I get this error.
cannot use writer (type *cipher.StreamWriter) as type io.Reader in argument to b2h.currentBucket.UploadFile: *cipher.StreamWriter does not implement io.Reader (missing Read method)

I'm having a little trouble understanding how this is suppose to work together.
Does anyone have any ideas? 
Thank you!

Ilya Kostarev

unread,
Feb 2, 2017, 4:39:19 PM2/2/17
to golan...@googlegroups.com
Try to construct an io.Pipe maybe
    pReader, pWriter := io.Pipe()
    writer := &cipher.StreamWriter{S: stream, W: pWriter}
    UploadFile(outputFileName, metadata, pReader)
    writer.Write(src)
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Justin C

unread,
Feb 2, 2017, 5:18:08 PM2/2/17
to golang-nuts
I think your on the right track I just can't get this to work. It seem like I'm missing something simple to do with GOs readers and writters. 


func (b2h *B2Handler) EncyptandUpload(iv []byte, fileName string, outputFileName string) {
key := []byte("example key 1234")

inFile, err := os.Open(fileName)
if err != nil {
panic(err)
}
defer inFile.Close()

block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}

// If the key is unique for each ciphertext, then it's ok to use a zero
// IV.
//var iv [aes.BlockSize]byte
stream := cipher.NewOFB(block, iv[:])

// outFile, err := os.OpenFile(outputFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
// if err != nil {
// panic(err)
// }
// defer outFile.Close()
pReader, pWriter := io.Pipe()
writer := &cipher.StreamWriter{S: stream, W: pWriter}
// Copy the input file to the output file, encrypting as we go.
// if _, err := io.Copy(writer, inFile); err != nil {
// panic(err)
// }

writer.Write(inFile) // cannot use inFile.Read (type func([]byte) (int, error)) as type []byte in argument to writer.Write
metadata := make(map[string]string)
_, err3 := b2h.currentBucket.UploadFile(outputFileName, metadata, pReader)

if err3 != nil {
fmt.Println(err3.Error)
}

I'm still getting a error on reading the file into the writer.Write().  *cannot use inFile.Read (type func([]byte) (int, error)) as type []byte in argument to writer.Write* It seems like you should be able to write it and upload it but i might have to write it out to a temp file and then upload it. 

Here is the encyption example https://golang.org/pkg/crypto/cipher/#NewOFB
here is the library i am using to upload it https://github.com/kothar/go-backblaze
If that helps. 

Ilya Kostarev

unread,
Feb 2, 2017, 6:33:59 PM2/2/17
to golan...@googlegroups.com
You can  use io.TeeReader to connect them all. Also to simultaneously read from one file, encrypt, and write to another file on the fly you seems to need a bit of concurrency 

func (b2h *B2Handler) EncyptandUpload(iv []byte, fileName string, outputFileName string) {
key := []byte("example key 1234")

inFile, err := os.Open(fileName)
if err != nil {
panic(err)
}
defer inFile.Close()

block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}

// If the key is unique for each ciphertext, then it's ok to use a zero
// IV.
//var iv [aes.BlockSize]byte
stream := cipher.NewOFB(block, iv[:])

// outFile, err := os.OpenFile(outputFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
// if err != nil {
// panic(err)
// }
// defer outFile.Close()
pReader, pWriter := io.Pipe()
writer := &cipher.StreamWriter{S: stream, W: pWriter}
// Copy the input file to the output file, encrypting as we go.
// if _, err := io.Copy(writer, inFile); err != nil {
// panic(err)
// }

//writer.Write(inFile) // cannot use inFile.Read (type func([]byte) (int, error)) as type []byte in argument to writer.Write

        teeReader := io.TeeReader(inFile, writer)  //construct TeeReader
        go ioutil.ReadAll(teeReader)               //use it concurrently, err check omitted for simplicity

        metadata := make(map[string]string)
_, err3 := b2h.currentBucket.UploadFile(outputFileName, metadata, pReader)

if err3 != nil {
fmt.Println(err3.Error)
}
or you can do sequentially allocating in-memory  buffers for data
in, err := ioutil.ReadAll(inFile)
        var buf bytes.Buffer
       
writer := &cipher.StreamWriter{S: stream, W: buf}
        _, err = writer.Write(in)
       
_, err3 := b2h.currentBucket.UploadFile(outputFileName, metadata, buf)

Reply all
Reply to author
Forward
0 new messages