1
0
mirror of https://github.com/minio/mc.git synced 2025-11-14 23:42:27 +03:00

Filesystem now calculates md5sum and returns

This commit is contained in:
Harshavardhana
2015-04-24 20:15:57 -07:00
parent f8ac1b96d1
commit 9fb94c72a1
5 changed files with 113 additions and 19 deletions

View File

@@ -19,6 +19,9 @@
package fs package fs
import ( import (
"bytes"
"crypto/md5"
"encoding/hex"
"errors" "errors"
"io" "io"
"os" "os"
@@ -57,13 +60,30 @@ func (f *fsClient) Put(md5HexString string, size int64) (io.WriteCloser, error)
blockingWriter.Release(err) blockingWriter.Release(err)
return return
} }
_, err = io.CopyN(fs, r, size) // calculate md5 to verify - incoming md5
h := md5.New()
mw := io.MultiWriter(fs, h)
_, err = io.CopyN(mw, r, size)
if err != nil { if err != nil {
err := iodine.New(err, nil) err := iodine.New(err, nil)
r.CloseWithError(err) r.CloseWithError(err)
blockingWriter.Release(err) blockingWriter.Release(err)
return return
} }
expectedMD5, err := hex.DecodeString(md5HexString)
if err != nil {
err := iodine.New(err, nil)
r.CloseWithError(err)
blockingWriter.Release(err)
return
}
if !bytes.Equal(expectedMD5, h.Sum(nil)) {
err := iodine.New(errors.New("md5sum mismatch"), nil)
r.CloseWithError(err)
blockingWriter.Release(err)
return
}
blockingWriter.Release(nil) blockingWriter.Release(nil)
r.Close() r.Close()
}() }()

View File

@@ -17,6 +17,9 @@
package fs package fs
import ( import (
"bytes"
"crypto/md5"
"encoding/hex"
"errors" "errors"
"io" "io"
"os" "os"
@@ -55,13 +58,30 @@ func (f *fsClient) Put(md5HexString string, size int64) (io.WriteCloser, error)
blockingWriter.Release(err) blockingWriter.Release(err)
return return
} }
_, err = io.CopyN(fs, r, size) // calculate md5 to verify - incoming md5
h := md5.New()
mw := io.MultiWriter(fs, h)
_, err = io.CopyN(mw, r, size)
if err != nil { if err != nil {
err := iodine.New(err, nil) err := iodine.New(err, nil)
r.CloseWithError(err) r.CloseWithError(err)
blockingWriter.Release(err) blockingWriter.Release(err)
return return
} }
expectedMD5, err := hex.DecodeString(md5HexString)
if err != nil {
err := iodine.New(err, nil)
r.CloseWithError(err)
blockingWriter.Release(err)
return
}
if !bytes.Equal(expectedMD5, h.Sum(nil)) {
err := iodine.New(errors.New("md5sum mismatch"), nil)
r.CloseWithError(err)
blockingWriter.Release(err)
return
}
blockingWriter.Release(nil) blockingWriter.Release(nil)
r.Close() r.Close()
}() }()

View File

@@ -20,6 +20,7 @@ import (
"bytes" "bytes"
"crypto/md5" "crypto/md5"
"encoding/base64" "encoding/base64"
"encoding/hex"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
@@ -130,7 +131,7 @@ func (s *MySuite) TestGetObject(c *C) {
data := "hello" data := "hello"
binarySum := md5.Sum([]byte(data)) binarySum := md5.Sum([]byte(data))
etag := base64.StdEncoding.EncodeToString(binarySum[:]) etag := hex.EncodeToString(binarySum[:])
dataLen := int64(len(data)) dataLen := int64(len(data))
writer, err := fsc.Put(etag, dataLen) writer, err := fsc.Put(etag, dataLen)
@@ -139,10 +140,10 @@ func (s *MySuite) TestGetObject(c *C) {
_, err = io.CopyN(writer, bytes.NewBufferString(data), dataLen) _, err = io.CopyN(writer, bytes.NewBufferString(data), dataLen)
c.Assert(err, IsNil) c.Assert(err, IsNil)
reader, size, _, err := fsc.Get() reader, size, md5Sum, err := fsc.Get()
c.Assert(err, IsNil) c.Assert(err, IsNil)
var results bytes.Buffer var results bytes.Buffer
c.Assert(etag, Equals, md5Sum)
_, err = io.CopyN(&results, reader, size) _, err = io.CopyN(&results, reader, size)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert([]byte(data), DeepEquals, results.Bytes()) c.Assert([]byte(data), DeepEquals, results.Bytes())

View File

@@ -19,6 +19,8 @@
package fs package fs
import ( import (
"crypto/md5"
"encoding/hex"
"errors" "errors"
"io" "io"
"os" "os"
@@ -58,7 +60,7 @@ func (f *fsClient) fsStat() (os.FileInfo, error) {
} }
// Get - download an object from bucket // Get - download an object from bucket
func (f *fsClient) Get() (body io.ReadCloser, size int64, md5 string, err error) { func (f *fsClient) Get() (io.ReadCloser, int64, string, error) {
item, err := f.getFSMetadata() item, err := f.getFSMetadata()
if err != nil { if err != nil {
return nil, 0, "", iodine.New(err, nil) return nil, 0, "", iodine.New(err, nil)
@@ -66,17 +68,27 @@ func (f *fsClient) Get() (body io.ReadCloser, size int64, md5 string, err error)
if item.FileType.IsDir() { if item.FileType.IsDir() {
return nil, 0, "", iodine.New(FileISDir{path: f.path}, nil) return nil, 0, "", iodine.New(FileISDir{path: f.path}, nil)
} }
body, err = os.Open(f.path) body, err := os.Open(f.path)
if err != nil { if err != nil {
return nil, 0, "", iodine.New(err, nil) return nil, 0, "", iodine.New(err, nil)
} }
// TODO: support md5sum - there is no easier way to do it right now without temporary buffer h := md5.New()
// so avoiding it to ensure no out of memory situations // calculate md5sum
return body, item.Size, "", nil _, err = io.Copy(h, body)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
// seek back
_, err = body.Seek(0, 0)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
md5Str := hex.EncodeToString(h.Sum(nil))
return body, item.Size, md5Str, nil
} }
// GetPartial - download a partial object from bucket // GetPartial - download a partial object from bucket
func (f *fsClient) GetPartial(offset, length int64) (body io.ReadCloser, size int64, md5 string, err error) { func (f *fsClient) GetPartial(offset, length int64) (io.ReadCloser, int64, string, error) {
if offset < 0 { if offset < 0 {
return nil, 0, "", iodine.New(client.InvalidRange{Offset: offset}, nil) return nil, 0, "", iodine.New(client.InvalidRange{Offset: offset}, nil)
} }
@@ -90,11 +102,27 @@ func (f *fsClient) GetPartial(offset, length int64) (body io.ReadCloser, size in
if offset > item.Size || (offset+length-1) > item.Size { if offset > item.Size || (offset+length-1) > item.Size {
return nil, 0, "", iodine.New(client.InvalidRange{Offset: offset}, nil) return nil, 0, "", iodine.New(client.InvalidRange{Offset: offset}, nil)
} }
body, err := os.Open(f.path)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
_, err = io.CopyN(ioutil.Discard, body, offset) _, err = io.CopyN(ioutil.Discard, body, offset)
if err != nil { if err != nil {
return nil, 0, "", iodine.New(err, nil) return nil, 0, "", iodine.New(err, nil)
} }
return body, length, "", nil h := md5.New()
// calculate md5sum
_, err = io.Copy(h, body)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
// seek back
_, err = body.Seek(0, 0)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
md5Str := hex.EncodeToString(h.Sum(nil))
return body, length, md5Str, nil
} }
func (f *fsClient) List() <-chan client.ItemOnChannel { func (f *fsClient) List() <-chan client.ItemOnChannel {

View File

@@ -17,6 +17,8 @@
package fs package fs
import ( import (
"crypto/md5"
"encoding/hex"
"errors" "errors"
"io" "io"
"os" "os"
@@ -54,7 +56,7 @@ func (f *fsClient) fsStat() (os.FileInfo, error) {
} }
// Get - download an object from bucket // Get - download an object from bucket
func (f *fsClient) Get() (body io.ReadCloser, size int64, md5 string, err error) { func (f *fsClient) Get() (io.ReadCloser, int64, string, error) {
item, err := f.getFSMetadata() item, err := f.getFSMetadata()
if err != nil { if err != nil {
return nil, 0, "", iodine.New(err, nil) return nil, 0, "", iodine.New(err, nil)
@@ -62,16 +64,27 @@ func (f *fsClient) Get() (body io.ReadCloser, size int64, md5 string, err error)
if item.FileType.IsDir() { if item.FileType.IsDir() {
return nil, 0, "", iodine.New(FileISDir{path: f.path}, nil) return nil, 0, "", iodine.New(FileISDir{path: f.path}, nil)
} }
body, err = os.Open(f.path) body, err := os.Open(f.path)
if err != nil { if err != nil {
return nil, 0, "", iodine.New(err, nil) return nil, 0, "", iodine.New(err, nil)
} }
// TODO: support md5sum - h := md5.New()
return body, st.Size(), "", nil // calculate md5sum
_, err = io.Copy(h, body)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
// seek back
_, err = body.Seek(0, 0)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
md5Str := hex.EncodeToString(h.Sum(nil))
return body, item.Size, md5Str, nil
} }
// GetPartial - download a partial object from bucket // GetPartial - download a partial object from bucket
func (f *fsClient) GetPartial(offset, length int64) (body io.ReadCloser, size int64, md5 string, err error) { func (f *fsClient) GetPartial(offset, length int64) (io.ReadCloser, int64, string, error) {
if offset < 0 { if offset < 0 {
return nil, 0, "", iodine.New(client.InvalidRange{Offset: offset}, nil) return nil, 0, "", iodine.New(client.InvalidRange{Offset: offset}, nil)
} }
@@ -82,7 +95,7 @@ func (f *fsClient) GetPartial(offset, length int64) (body io.ReadCloser, size in
if item.FileType.IsDir() { if item.FileType.IsDir() {
return nil, 0, "", iodine.New(FileISDir{path: f.path}, nil) return nil, 0, "", iodine.New(FileISDir{path: f.path}, nil)
} }
body, err = os.Open(f.path) body, err := os.Open(f.path)
if err != nil { if err != nil {
return nil, 0, "", iodine.New(err, nil) return nil, 0, "", iodine.New(err, nil)
} }
@@ -93,7 +106,19 @@ func (f *fsClient) GetPartial(offset, length int64) (body io.ReadCloser, size in
if err != nil { if err != nil {
return nil, 0, "", iodine.New(err, nil) return nil, 0, "", iodine.New(err, nil)
} }
return body, length, "", nil h := md5.New()
// calculate md5sum
_, err = io.Copy(h, body)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
// seek back
_, err = body.Seek(0, 0)
if err != nil {
return nil, 0, "", iodine.New(err, nil)
}
md5Str := hex.EncodeToString(h.Sum(nil))
return body, length, md5Str, nil
} }
/// Bucket operations /// Bucket operations