Browse Source

add x-oss-traffic-limit option

alzhang 6 năm trước cách đây
mục cha
commit
e9c5e0bfbb
4 tập tin đã thay đổi với 174 bổ sung1 xóa
  1. 158 0
      oss/bucket_test.go
  2. 1 1
      oss/conn.go
  3. 1 0
      oss/const.go
  4. 14 0
      oss/option.go

+ 158 - 0
oss/bucket_test.go

@@ -4476,3 +4476,161 @@ func (s *OssBucketSuite) TestOptionsMethod(c *C) {
 	bucket.DeleteObject(objectName)
 	forceDeleteBucket(client, bucketName, c)
 }
+
+func (s *OssBucketSuite) TestBucketTrafficLimit(c *C) {
+	var respHeader http.Header
+	var qosDelayTime string
+	var traffic int64 = 819220 // 100KB
+	maxTraffic := traffic * 120 / 100
+
+	objectName := objectNamePrefix + randStr(8)
+	localFile := "../sample/BingWallpaper-2015-11-07.jpg"
+	fd, err := os.Open(localFile)
+	c.Assert(err, IsNil)
+	defer fd.Close()
+
+	tryGetFileSize := func (f *os.File) int64 {
+		fInfo, _ := f.Stat()
+		return fInfo.Size()
+	}
+	contentLength := tryGetFileSize(fd) * 8
+
+	// put object
+	start := time.Now().UnixNano() / 1000 / 1000
+	err = s.bucket.PutObject(objectName, fd, TrafficLimitHeader(traffic))
+	c.Assert(err, IsNil)
+	endingTime := time.Now().UnixNano() / 1000 / 1000
+	costT := endingTime - start
+	costV := contentLength * 1000 / costT  // bit * 1000 / Millisecond = bit/s
+	c.Assert((costV < maxTraffic), Equals, true)
+
+	// putobject without TrafficLimit
+	//
+	// fd, err = os.Open(localFile)
+	// c.Assert(err, IsNil)
+	// defer fd.Close()
+	// start = time.Now().UnixNano() / 1000 / 1000
+	// err = s.bucket.PutObject(objectName, fd)
+	// c.Assert(err, IsNil)
+	// endingTime = time.Now().UnixNano() / 1000 / 1000
+	// costT = endingTime - start
+	// costV = contentLength * 1000 / costT  // bit * 1000 / Millisecond = bit/s
+	// testLogger.Println(traffic, maxTraffic, contentLength, costT, costV)
+	// c.Assert((costV < maxTraffic), Equals, true)
+
+	// get object to file
+	newFile := "test-file-" + randStr(10)
+	start = time.Now().UnixNano() / 1000 / 1000
+	err = s.bucket.GetObjectToFile(objectName, newFile, TrafficLimitHeader(traffic))
+	c.Assert(err, IsNil)
+	endingTime = time.Now().UnixNano() / 1000 / 1000
+	costT = endingTime - start
+	costV = contentLength * 1000 / costT  // bit * 1000 / Millisecond = bit/s
+	c.Assert((costV < maxTraffic), Equals, true)
+	os.Remove(newFile)
+
+	// append object
+	newFile = "test-file-" + randStr(10)
+	objectKey := objectNamePrefix + randStr(8)
+	var nextPos int64
+	fd, err = os.Open(localFile)
+	c.Assert(err, IsNil)
+	defer fd.Close()
+	start = time.Now().UnixNano() / 1000 / 1000
+	nextPos, err = s.bucket.AppendObject(objectKey, strings.NewReader(randStr(18)), nextPos)
+	c.Assert(err, IsNil)
+	nextPos, err = s.bucket.AppendObject(objectKey, fd, nextPos, TrafficLimitHeader(traffic))
+	c.Assert(err, IsNil)
+	endingTime = time.Now().UnixNano() / 1000 / 1000
+	costT = endingTime - start
+	costV = contentLength * 1000 / costT  // bit * 1000 / Millisecond = bit/s
+	c.Assert((costV < maxTraffic), Equals, true)
+	err = s.bucket.GetObjectToFile(objectKey, newFile, TrafficLimitHeader(traffic))
+	c.Assert(err, IsNil)
+	err = s.bucket.DeleteObject(objectKey)
+	c.Assert(err, IsNil)
+	os.Remove(newFile)
+
+	// put object with url
+	fd, err = os.Open(localFile)
+	c.Assert(err, IsNil)
+	defer fd.Close()
+	strURL, err := s.bucket.SignURL(objectName, HTTPPut, 60, TrafficLimitParam(traffic))
+	start = time.Now().UnixNano() / 1000 / 1000
+	err = s.bucket.PutObjectWithURL(strURL, fd)
+	c.Assert(err, IsNil)
+	endingTime = time.Now().UnixNano() / 1000 / 1000
+	costT = endingTime - start
+	costV = contentLength * 1000 / costT  // bit * 1000 / Millisecond = bit/s
+	c.Assert((costV < maxTraffic), Equals, true)
+
+	// get object with url
+	newFile = "test-file-" + randStr(10)
+	strURL, err = s.bucket.SignURL(objectName, HTTPGet, 60, TrafficLimitParam(traffic), GetResponseHeader(&respHeader))
+	c.Assert(err, IsNil)
+	start = time.Now().UnixNano() / 1000 / 1000
+	err = s.bucket.GetObjectToFileWithURL(strURL, newFile)
+	c.Assert(err, IsNil)
+	endingTime = time.Now().UnixNano() / 1000 / 1000
+	costT = endingTime - start
+	costV = contentLength * 1000 / costT  // bit * 1000 / Millisecond = bit/s
+	c.Assert((costV < maxTraffic), Equals, true)
+	qosDelayTime = GetQosDelayTime(respHeader)
+	c.Assert(len(qosDelayTime) > 0, Equals, true)
+	os.Remove(newFile)
+
+	// copy object
+	destObjectName := objectNamePrefix + randStr(8)
+	_, err = s.bucket.CopyObject(objectName, destObjectName, TrafficLimitHeader(traffic), GetResponseHeader(&respHeader))
+	c.Assert(err, IsNil)
+	qosDelayTime = GetQosDelayTime(respHeader)
+	c.Assert(len(qosDelayTime) > 0, Equals, true)
+	err = s.bucket.DeleteObject(destObjectName)
+	c.Assert(err, IsNil)
+
+	err = s.bucket.DeleteObject(objectName)
+	c.Assert(err, IsNil)
+}
+
+func (s *OssBucketSuite) TestBucketTrafficLimitUpload(c *C) {
+	var traffic int64 = 819220 // 100KB
+	maxTraffic := traffic * 120 / 100
+	contentLength := 500 * 1024
+
+	var fileName = "test-file-" + randStr(8)
+	objectName := objectNamePrefix + randStr(8)
+	content := randStr(contentLength)
+	createFile(fileName, content, c)
+
+	chunks, err := SplitFileByPartNum(fileName, 3)
+	c.Assert(err, IsNil)
+
+	options := []Option{
+		Expires(futureDate), Meta("my", "myprop"),
+	}
+
+	fd, err := os.Open(fileName)
+	c.Assert(err, IsNil)
+	defer fd.Close()
+
+	imur, err := s.bucket.InitiateMultipartUpload(objectName, options...)
+	c.Assert(err, IsNil)
+	var parts []UploadPart
+	start := time.Now().UnixNano() / 1000 / 1000
+	for _, chunk := range chunks {
+		fd.Seek(chunk.Offset, os.SEEK_SET)
+		part, err := s.bucket.UploadPart(imur, fd, chunk.Size, chunk.Number, TrafficLimitHeader(traffic))
+		c.Assert(err, IsNil)
+		parts = append(parts, part)
+	}
+	_, err = s.bucket.CompleteMultipartUpload(imur, parts)
+	c.Assert(err, IsNil)
+	endingTime := time.Now().UnixNano() / 1000 / 1000
+	costT := endingTime - start
+	costV := int64(contentLength) * 8 * 1000 / costT  // B * 8 * 1000 / Millisecond = bit/s
+	c.Assert((costV < maxTraffic), Equals, true)
+	os.Remove(fileName)
+
+	s.bucket.DeleteObject(objectName)
+	c.Assert(err, IsNil)
+}

+ 1 - 1
oss/conn.go

@@ -36,7 +36,7 @@ var signKeyList = []string{"acl", "uploads", "location", "cors",
 	"replicationLocation", "cname", "bucketInfo",
 	"comp", "qos", "live", "status", "vod",
 	"startTime", "endTime", "symlink",
-	"x-oss-process", "response-content-type",
+	"x-oss-process", "response-content-type", "x-oss-traffic-limit",
 	"response-content-language", "response-expires",
 	"response-cache-control", "response-content-disposition",
 	"response-content-encoding", "udf", "udfName", "udfImage",

+ 1 - 0
oss/const.go

@@ -156,6 +156,7 @@ const (
 	HTTPHeaderOssRequester                   = "X-Oss-Request-Payer"
 	HTTPHeaderOssTagging                     = "X-Oss-Tagging"
 	HTTPHeaderOssTaggingDirective            = "X-Oss-Tagging-Directive"
+	HTTPHeaderOssTrafficLimit                = "X-Oss-Traffic-Limit"
 )
 
 // HTTP Param

+ 14 - 0
oss/option.go

@@ -240,6 +240,11 @@ func ACReqHeaders(value string) Option {
 	return setHeader(HTTPHeaderACReqHeaders, value)
 }
 
+// TrafficLimitHeader is an option to set X-Oss-Traffic-Limit
+func TrafficLimitHeader(value int64) Option {
+	return setHeader(HTTPHeaderOssTrafficLimit, strconv.FormatInt(value, 10))
+}
+
 // Delimiter is an option to set delimiler parameter
 func Delimiter(value string) Option {
 	return addParam("delimiter", value)
@@ -392,6 +397,11 @@ func Process(value string) Option {
 	return addParam("x-oss-process", value)
 }
 
+// TrafficLimitParam is a option to set x-oss-traffic-limit
+func TrafficLimitParam(value int64) Option {
+	return addParam("x-oss-traffic-limit", strconv.FormatInt(value, 10))
+}
+
 func setHeader(key string, value interface{}) Option {
 	return func(params map[string]optionValue) error {
 		if value == nil {
@@ -531,3 +541,7 @@ func GetDeleteMark(header http.Header) bool {
 	}
 	return false
 }
+
+func GetQosDelayTime(header http.Header) string {
+	return header.Get("x-oss-qos-delay-time")
+}