Skip to content

Commit

Permalink
improve upload
Browse files Browse the repository at this point in the history
rewrite download
  • Loading branch information
JojiiOfficial committed Apr 12, 2020
1 parent eece806 commit a82508b
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 133 deletions.
28 changes: 24 additions & 4 deletions Crypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ func IsValidCipher(c string) bool {
return false
}

// Encrypt encrypts input stream and writes it to out
func Encrypt(in io.Reader, out io.Writer, keyAes, buff []byte) (err error) {
// EncryptAES encrypts input stream and writes it to out
func EncryptAES(in io.Reader, out io.Writer, keyAes, buff []byte) (err error) {
iv := make([]byte, 16)

// Create random iv
_, err = rand.Read(iv)
if err != nil {
return err
Expand All @@ -86,8 +88,12 @@ func Encrypt(in io.Reader, out io.Writer, keyAes, buff []byte) (err error) {
}

ctr := cipher.NewCTR(aes, iv)

// First 16 bytes of ciphertext will
// be the iv, so write it!
out.Write(iv)

// Encrypt file
for {
n, err := in.Read(buff)
if err != nil && err != io.EOF {
Expand All @@ -108,27 +114,38 @@ func Encrypt(in io.Reader, out io.Writer, keyAes, buff []byte) (err error) {
return nil
}

// Decrypt decrypt stuff
func Decrypt(in io.Reader, out, hashwriter io.Writer, keyAes, buff []byte) (err error) {
// DecryptAES decrypt stuff
func DecryptAES(in io.Reader, out, hashwriter io.Writer, keyAes, buff []byte, cancenChan chan bool) (err error) {
// Iv is always 16 bytes
iv := make([]byte, 16)

aes, err := aes.NewCipher(keyAes)
if err != nil {
return err
}

// Read first 16 bytes to iv
n, err := in.Read(iv)
if err != nil {
return err
}

// If not 16 bytes were written, there
// is a big problem
if n != 16 {
return errors.New("reading aes iv")
}

// Write iv to hasher cause the servers
// hash is built on it too
hashwriter.Write(iv)
ctr := cipher.NewCTR(aes, iv)

// Decrypt using xor keystream the
// cipher input text is written to the
// hashwriter since the servers has no
// key and built it's hash using the
// encrypted text
for {
n, err := in.Read(buff)
if err != nil && err != io.EOF {
Expand All @@ -138,10 +155,13 @@ func Decrypt(in io.Reader, out, hashwriter io.Writer, keyAes, buff []byte) (err
if n != 0 {
outBuf := make([]byte, n)
ctr.XORKeyStream(outBuf, buff[:n])

out.Write(outBuf)
hashwriter.Write(buff[:n])
}

// Treat eof as stop condition, not as
// an error
if err == io.EOF {
break
}
Expand Down
110 changes: 12 additions & 98 deletions File.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
package libdatamanager

import (
"encoding/hex"
"hash/crc32"
"io"
"net/http"
"os"
"path/filepath"
"strconv"
"time"

"github.com/pkg/errors"
)

// FileAttributes attributes for a file
Expand Down Expand Up @@ -53,6 +47,17 @@ type FileChanges struct {
SetPublic, SetPrivate bool
}

const (
// DefaultBuffersize The default buffersize for filestreams
DefaultBuffersize = 10 * 1024
)

// WriterProxy proxy writing
type WriterProxy func(io.Writer) io.Writer

// FileSizeCallback gets called if the filesize is known
type FileSizeCallback func(int64)

// DeleteFile deletes the desired file(s)
func (libdm LibDM) DeleteFile(name string, id uint, all bool, attributes FileAttributes) (*IDsResponse, error) {
var response IDsResponse
Expand Down Expand Up @@ -119,98 +124,6 @@ func (libdm LibDM) PublishFile(name string, id uint, publicName string, all bool
return resp, nil
}

// GetFile requests a filedownload and returns the response
// -> response, serverfilename, checksum, error
// The response body must be closed
func (libdm LibDM) GetFile(name string, id uint, namespace string) (*http.Response, string, string, error) {
resp, err := libdm.NewRequest(EPFileGet, &FileRequest{
Name: name,
FileID: id,
Attributes: FileAttributes{
Namespace: namespace,
},
}).WithAuthFromConfig().DoHTTPRequest()

// Check for error
if err != nil {
return nil, "", "", &ResponseErr{
Err: err,
}
}

// Check response headers
if resp.Header.Get(HeaderStatus) == strconv.Itoa(int(ResponseError)) {
return nil, "", "", &ResponseErr{
Response: &RestRequestResponse{
HTTPCode: resp.StatusCode,
Headers: &resp.Header,
Message: resp.Header.Get(HeaderStatusMessage),
Status: ResponseError,
},
}
}

// Get filename from headers
serverFileName := resp.Header.Get(HeaderFileName)
// Get file checksum from headers
checksum := resp.Header.Get(HeaderChecksum)

// Check headers
if len(serverFileName) == 0 {
return nil, "", "", &ResponseErr{
Err: ErrResponseFilenameInvalid,
}
}

return resp, serverFileName, checksum, nil
}

var (
// ErrChecksumNotMatch error if the checksum of the downloaded
// file doesn't match with the checksum of the remote file
ErrChecksumNotMatch = errors.New("generated checksum not match")
)

// DownloadFile downloads and saves a file to the given localFilePath. If the file exists, it will be overwritten
func (libdm LibDM) DownloadFile(name string, id uint, namespace, localFilePath string, appendFilename ...bool) error {
// Download file from server
resp, name, checksum, err := libdm.GetFile(name, id, namespace)
if err != nil {
return err
}
defer resp.Body.Close()

hash := crc32.NewIEEE()

// Append remote filename if desired
if len(appendFilename) > 0 && appendFilename[0] {
localFilePath = filepath.Join(localFilePath, name)
}

// Create loal file
f, err := os.Create(localFilePath)
defer f.Close()
if err != nil {
return err
}

w := io.MultiWriter(hash, f)

// Save file to local file
buff := make([]byte, 10*1024)
_, err = io.CopyBuffer(w, resp.Body, buff)
if err != nil {
return err
}

// Check if the checksums are equal, if not return an error
if hex.EncodeToString(hash.Sum(nil)) != checksum {
return ErrChecksumNotMatch
}

return nil
}

// UpdateFile updates a file on the server
func (libdm LibDM) UpdateFile(name string, id uint, namespace string, all bool, changes FileChanges) (*CountResponse, error) {
// Set attributes
Expand Down Expand Up @@ -239,6 +152,7 @@ func (libdm LibDM) UpdateFile(name string, id uint, namespace string, all bool,

var response CountResponse

// Do request
if _, err := libdm.Request(EPFileUpdate, &FileRequest{
Name: name,
FileID: id,
Expand Down
Loading

0 comments on commit a82508b

Please sign in to comment.