Forráskód Böngészése

fix memory leak as the close function of NopCloser do nothing

hangzws 7 éve
szülő
commit
cb15f13536
3 módosított fájl, 17 hozzáadás és 10 törlés
  1. 7 8
      oss/bucket.go
  2. 1 1
      oss/conn.go
  3. 9 1
      oss/progress.go

+ 7 - 8
oss/bucket.go

@@ -9,7 +9,6 @@ import (
 	"hash"
 	"hash/crc64"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/url"
 	"os"
@@ -208,7 +207,7 @@ func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*
 	listener := getProgressListener(options)
 
 	contentLen, _ := strconv.ParseInt(resp.Headers.Get(HTTPHeaderContentLength), 10, 64)
-	resp.Body = ioutil.NopCloser(TeeReader(resp.Body, crcCalc, contentLen, listener, nil))
+	resp.Body = TeeReader(resp.Body, crcCalc, contentLen, listener, nil)
 
 	return result, nil
 }
@@ -219,7 +218,7 @@ func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*
 // destObjectKey    the target object to copy.
 // options    options for copying an object. You can specify the conditions of copy. The valid conditions are CopySourceIfMatch,
 //            CopySourceIfNoneMatch, CopySourceIfModifiedSince, CopySourceIfUnmodifiedSince, MetadataDirective.
-//            Also you can specify the target object's attributes, such as CacheControl, ContentDisposition, ContentEncoding, Expires, 
+//            Also you can specify the target object's attributes, such as CacheControl, ContentDisposition, ContentEncoding, Expires,
 //            ServerSideEncryption, ObjectACL, Meta. Refer to the link below for more details :
 //            https://help.aliyun.com/document_detail/oss/api-reference/object/CopyObject.html
 //
@@ -303,7 +302,7 @@ func (bucket Bucket) copy(srcObjectKey, destBucketName, destObjectKey string, op
 // reader    io.Reader. The read instance for reading the data to append.
 // appendPosition    the start position to append.
 // destObjectProperties    the options for the first appending, such as CacheControl, ContentDisposition, ContentEncoding,
-//                         Expires, ServerSideEncryption, ObjectACL. 
+//                         Expires, ServerSideEncryption, ObjectACL.
 //
 // int64    the next append position, it's valid when error is nil.
 // error    it's nil if no error, otherwise it's an error object.
@@ -464,7 +463,7 @@ func (bucket Bucket) IsObjectExist(objectKey string) (bool, error) {
 // options    it contains all the filters for listing objects.
 //            It could specify a prefix filter on object keys,  the max keys count to return and the object key marker and the delimiter for grouping object names.
 //            The key marker means the returned objects' key must be greater than it in lexicographic order.
-// 
+//
 //            For example, if the bucket has 8 objects, my-object-1, my-object-11, my-object-2, my-object-21,
 //            my-object-22, my-object-3, my-object-31, my-object-32. If the prefix is my-object-2 (no other filters), then it returns
 //            my-object-2, my-object-21, my-object-22 three objects. If the marker is my-object-22 (no other filters), then it returns
@@ -474,9 +473,9 @@ func (bucket Bucket) IsObjectExist(objectKey string) (bool, error) {
 //            But if the delimiter is specified with '/', then it only returns that folder's files (no subfolder's files). The direct subfolders are in the commonPrefixes properties.
 //            For example, if the bucket has three objects fun/test.jpg, fun/movie/001.avi, fun/movie/007.avi. And if the prefix is "fun/", then it returns all three objects.
 //            But if the delimiter is '/', then only "fun/test.jpg" is returned as files and fun/movie/ is returned as common prefix.
-// 
+//
 //            For common usage scenario, check out sample/list_object.go.
-// 
+//
 // ListObjectsResponse    the return value after operation succeeds (only valid when error is nil).
 //
 func (bucket Bucket) ListObjects(options ...Option) (ListObjectsResult, error) {
@@ -882,7 +881,7 @@ func (bucket Bucket) DoGetObjectWithURL(signedURL string, options []Option) (*Ge
 	listener := getProgressListener(options)
 
 	contentLen, _ := strconv.ParseInt(resp.Headers.Get(HTTPHeaderContentLength), 10, 64)
-	resp.Body = ioutil.NopCloser(TeeReader(resp.Body, crcCalc, contentLen, listener, nil))
+	resp.Body = TeeReader(resp.Body, crcCalc, contentLen, listener, nil)
 
 	return result, nil
 }

+ 1 - 1
oss/conn.go

@@ -591,7 +591,7 @@ func (um urlMaker) buildURL(bucket, object string) (string, string) {
 	return host, path
 }
 
-// getResource gets canonicalized resource 
+// getResource gets canonicalized resource
 func (um urlMaker) getResource(bucketName, objectName, subResource string) string {
 	if subResource != "" {
 		subResource = "?" + subResource

+ 9 - 1
oss/progress.go

@@ -62,7 +62,7 @@ type teeReader struct {
 // corresponding writes to w.  There is no internal buffering -
 // the write must complete before the read completes.
 // Any error encountered while writing is reported as a read error.
-func TeeReader(reader io.Reader, writer io.Writer, totalBytes int64, listener ProgressListener, tracker *readerTracker) io.Reader {
+func TeeReader(reader io.Reader, writer io.Writer, totalBytes int64, listener ProgressListener, tracker *readerTracker) io.ReadCloser {
 	return &teeReader{
 		reader:        reader,
 		writer:        writer,
@@ -103,3 +103,11 @@ func (t *teeReader) Read(p []byte) (n int, err error) {
 
 	return
 }
+
+func (t *teeReader) Close() error {
+	rc, ok := t.reader.(io.ReadCloser)
+	if ok {
+		return rc.Close()
+	}
+	return nil
+}