do md5 validation AFTER decompression
This commit is contained in:
@@ -81,6 +81,16 @@ func ParseUpload(r *http.Request, sizeLimit int64) (pu *ParsedUpload, e error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if expectedChecksum := r.Header.Get("Content-MD5"); expectedChecksum != "" {
|
||||||
|
h := md5.New()
|
||||||
|
h.Write(pu.UncompressedData)
|
||||||
|
if receivedChecksum := fmt.Sprintf("%x", h.Sum(nil)); expectedChecksum != receivedChecksum {
|
||||||
|
e = fmt.Errorf("Content-MD5 did not match md5 of file data [%s] != [%s]", expectedChecksum, receivedChecksum)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,21 +106,6 @@ func parsePut(r *http.Request, sizeLimit int64, pu *ParsedUpload) (e error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChecksumReader struct {
|
|
||||||
h hash.Hash
|
|
||||||
r io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cr *ChecksumReader) Read(p []byte) (int, error) {
|
|
||||||
n, err := cr.r.Read(p)
|
|
||||||
cr.h.Write(p[:n])
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cr *ChecksumReader) Checksum() string {
|
|
||||||
return fmt.Sprintf("%x", cr.h.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseMultipart(r *http.Request, sizeLimit int64, pu *ParsedUpload) (e error) {
|
func parseMultipart(r *http.Request, sizeLimit int64, pu *ParsedUpload) (e error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e != nil && r.Body != nil {
|
if e != nil && r.Body != nil {
|
||||||
@@ -138,26 +133,7 @@ func parseMultipart(r *http.Request, sizeLimit int64, pu *ParsedUpload) (e error
|
|||||||
pu.FileName = path.Base(pu.FileName)
|
pu.FileName = path.Base(pu.FileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
reader := io.LimitReader(part, sizeLimit+1)
|
pu.Data, e = ioutil.ReadAll(io.LimitReader(part, sizeLimit+1))
|
||||||
if expectedChecksum := r.Header.Get("Content-MD5"); expectedChecksum != "" {
|
|
||||||
if r.Header.Get("Content-Encoding") == "gzip" {
|
|
||||||
gr, err := gzip.NewReader(reader)
|
|
||||||
if err != nil {
|
|
||||||
e = fmt.Errorf("Content-Encoding == gzip but content was not gzipped: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
reader = gr
|
|
||||||
}
|
|
||||||
cr := &ChecksumReader{md5.New(), reader}
|
|
||||||
pu.Data, e = ioutil.ReadAll(cr)
|
|
||||||
if expectedChecksum != cr.Checksum() {
|
|
||||||
e = fmt.Errorf("Content-MD5 did not match md5 of file data [%s] != [%s]", expectedChecksum, cr.Checksum())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pu.Data, e = ioutil.ReadAll(reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
if e != nil {
|
if e != nil {
|
||||||
glog.V(0).Infoln("Reading Content [ERROR]", e)
|
glog.V(0).Infoln("Reading Content [ERROR]", e)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user