浏览代码

Merge pull request #62 from aliyun/fix-sign-url

fix url encoding
baiyubin 8 年之前
父节点
当前提交
13545534a8
共有 10 个文件被更改,包括 159 次插入24 次删除
  1. 1 1
      .travis.yml
  2. 5 0
      CHANGELOG.md
  3. 2 2
      README-CN.md
  4. 2 2
      README.md
  5. 134 0
      oss/bucket_test.go
  6. 8 14
      oss/conn.go
  7. 2 0
      oss/conn_test.go
  8. 1 1
      oss/const.go
  9. 2 2
      oss/download_test.go
  10. 2 2
      oss/upload_test.go

+ 1 - 1
.travis.yml

@@ -1,9 +1,9 @@
 language: go
 go:
-- 1.4
 - 1.5
 - 1.6
 - 1.7
+- 1.8
 install:
 - go get golang.org/x/tools/cmd/cover
 - go get github.com/mattn/goveralls

+ 5 - 0
CHANGELOG.md

@@ -1,5 +1,10 @@
 # ChangeLog - Aliyun OSS SDK for Go
 
+## 版本号:1.6.0 日期:2017-09-01
+### 变更内容
+ - 修复:URL中特殊字符的编码问题
+ - 变更:不再支持Golang 1.4
+ 
 ## 版本号:1.5.1 日期:2017-08-04
 ### 变更内容
  - 修复:SignURL中Key编码的问题

+ 2 - 2
README-CN.md

@@ -13,10 +13,10 @@
 > - 使用此SDK,用户可以方便地在任何应用、任何时间、任何地点上传,下载和管理数据。
 
 ## 版本
-> - 当前版本:1.5.1
+> - 当前版本:1.6.0
 
 ## 运行环境
-> - 推荐使用Go 1.4及以上。
+> - 推荐使用Go 1.5及以上。
 
 ## 安装方法
 ### GitHub安装

+ 2 - 2
README.md

@@ -13,10 +13,10 @@
 > - With this SDK, you can upload, download and manage data on any app anytime and anywhere conveniently. 
 
 ## Version
-> - Current version: 1.5.1. 
+> - Current version: 1.6.0. 
 
 ## Running Environment
-> - Go 1.4 or above is recommended. 
+> - Go 1.5 or above is recommended. 
 
 ## Installing
 ### Install the SDK through GitHub

+ 134 - 0
oss/bucket_test.go

@@ -402,6 +402,34 @@ func (s *OssBucketSuite) TestSignURLWithEscapedKey(c *C) {
 	c.Assert(err, IsNil)
 	c.Assert(str, Equals, objectValue)
 
+	// key with escaped chars
+	objectName = "<>[]()`?.,!@#$%^&'/*-_=+~:;"
+
+	// sign url for put
+	str, err = s.bucket.SignURL(objectName, HTTPPut, 60)
+	c.Assert(err, IsNil)
+	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
+	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
+	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
+
+	// put object with url
+	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
+	c.Assert(err, IsNil)
+
+	// sign url for get object
+	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
+	c.Assert(err, IsNil)
+	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
+	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
+	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
+
+	// get object with url
+	body, err = s.bucket.GetObjectWithURL(str)
+	c.Assert(err, IsNil)
+	str, err = readBody(body)
+	c.Assert(err, IsNil)
+	c.Assert(str, Equals, objectValue)
+
 	// key with Chinese chars
 	objectName = "风吹柳花满店香,吴姬压酒劝客尝。金陵子弟来相送,欲行不行各尽觞。请君试问东流水,别意与之谁短长。"
 
@@ -430,10 +458,116 @@ func (s *OssBucketSuite) TestSignURLWithEscapedKey(c *C) {
 	c.Assert(err, IsNil)
 	c.Assert(str, Equals, objectValue)
 
+	// key
+	objectName = "test/此情无计可消除/才下眉头/却上 心头/。,;:‘’“”?()『』【】《》!@#¥%……&×/test+ =-_*&^%$#@!`~[]{}()<>|\\/?.,;.txt"
+
+	// sign url for put
+	str, err = s.bucket.SignURL(objectName, HTTPPut, 60)
+	c.Assert(err, IsNil)
+
+	// put object with url
+	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
+	c.Assert(err, IsNil)
+
+	// sign url for get object
+	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
+	c.Assert(err, IsNil)
+
+	// get object with url
+	body, err = s.bucket.GetObjectWithURL(str)
+	c.Assert(err, IsNil)
+	str, err = readBody(body)
+	c.Assert(err, IsNil)
+	c.Assert(str, Equals, objectValue)
+
+	// put object
+	err = s.bucket.PutObject(objectName, bytes.NewReader([]byte(objectValue)))
+	c.Assert(err, IsNil)
+
+	// get object
+	body, err = s.bucket.GetObject(objectName)
+	c.Assert(err, IsNil)
+	str, err = readBody(body)
+	c.Assert(err, IsNil)
+	c.Assert(str, Equals, objectValue)
+
+	// delete object
 	err = s.bucket.DeleteObject(objectName)
 	c.Assert(err, IsNil)
 }
 
+func (s *OssBucketSuite) TestSignURLWithEscapedKeyAndPorxy(c *C) {
+	// key with '/'
+	objectName := "zyimg/86/e8/653b5dc97bb0022051a84c632bc4"
+	objectValue := "弃我去者,昨日之日不可留;乱我心者,今日之日多烦忧。长风万里送秋雁,对此可以酣高楼。蓬莱文章建安骨,中间小谢又清发。" +
+		"俱怀逸兴壮思飞,欲上青天揽明月。抽刀断水水更流,举杯销愁愁更愁。人生在世不称意,明朝散发弄扁舟。"
+
+	client, err := New(endpoint, accessID, accessKey, AuthProxy(proxyHost, proxyUser, proxyPasswd))
+	bucket, err := client.Bucket(bucketName)
+
+	// sign url for put
+	str, err := bucket.SignURL(objectName, HTTPPut, 60)
+	c.Assert(err, IsNil)
+	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
+	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
+	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
+
+	// put object with url
+	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
+	c.Assert(err, IsNil)
+
+	// sign url for get object
+	str, err = bucket.SignURL(objectName, HTTPGet, 60)
+	c.Assert(err, IsNil)
+	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
+	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
+	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
+
+	// get object with url
+	body, err := bucket.GetObjectWithURL(str)
+	c.Assert(err, IsNil)
+	str, err = readBody(body)
+	c.Assert(err, IsNil)
+	c.Assert(str, Equals, objectValue)
+
+	// key with Chinese chars
+	objectName = "test/此情无计可消除/才下眉头/却上 心头/。,;:‘’“”?()『』【】《》!@#¥%……&×/test+ =-_*&^%$#@!`~[]{}()<>|\\/?.,;.txt"
+
+	// sign url for put
+	str, err = bucket.SignURL(objectName, HTTPPut, 60)
+	c.Assert(err, IsNil)
+
+	// put object with url
+	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
+	c.Assert(err, IsNil)
+
+	// sign url for get object
+	str, err = bucket.SignURL(objectName, HTTPGet, 60)
+	c.Assert(err, IsNil)
+
+	// get object with url
+	body, err = bucket.GetObjectWithURL(str)
+	c.Assert(err, IsNil)
+	str, err = readBody(body)
+	c.Assert(err, IsNil)
+	c.Assert(str, Equals, objectValue)
+
+	// put object
+	err = bucket.PutObject(objectName, bytes.NewReader([]byte(objectValue)))
+	c.Assert(err, IsNil)
+
+	// get object
+	body, err = bucket.GetObject(objectName)
+	c.Assert(err, IsNil)
+	str, err = readBody(body)
+	c.Assert(err, IsNil)
+	c.Assert(str, Equals, objectValue)
+
+	// delete object
+	err = bucket.DeleteObject(objectName)
+	c.Assert(err, IsNil)
+}
+
 // TestPutObjectType
 func (s *OssBucketSuite) TestPutObjectType(c *C) {
 	objectName := objectNamePrefix + "tptt"

+ 8 - 14
oss/conn.go

@@ -80,9 +80,6 @@ func (conn Conn) DoURL(method HTTPMethod, signedURL string, headers map[string]s
 	}
 
 	m := strings.ToUpper(string(method))
-	if !conn.config.IsUseProxy {
-		uri.Opaque = uri.Path
-	}
 	req := &http.Request{
 		Method:     m,
 		URL:        uri,
@@ -196,9 +193,6 @@ func (conn Conn) isParamSign(paramKey string) bool {
 func (conn Conn) doRequest(method string, uri *url.URL, canonicalizedResource string, headers map[string]string,
 	data io.Reader, initCRC uint64, listener ProgressListener) (*Response, error) {
 	method = strings.ToUpper(method)
-	if !conn.config.IsUseProxy {
-		uri.Opaque = uri.Path
-	}
 	req := &http.Request{
 		Method:     method,
 		URL:        uri,
@@ -556,12 +550,13 @@ func (um *urlMaker) Init(endpoint string, isCname bool, isProxy bool) {
 // Build URL
 func (um urlMaker) getURL(bucket, object, params string) *url.URL {
 	host, path := um.buildURL(bucket, object)
-	uri := &url.URL{
-		Scheme:   um.Scheme,
-		Host:     host,
-		Path:     path,
-		RawQuery: params,
+	addr := ""
+	if params == "" {
+		addr = fmt.Sprintf("%s://%s%s", um.Scheme, host, path)
+	} else {
+		addr = fmt.Sprintf("%s://%s%s?%s", um.Scheme, host, path, params)
 	}
+	uri, _ := url.ParseRequestURI(addr)
 	return uri
 }
 
@@ -576,9 +571,8 @@ func (um urlMaker) buildURL(bucket, object string) (string, string) {
 	var host = ""
 	var path = ""
 
-	if !um.IsProxy {
-		object = url.QueryEscape(object)
-	}
+	object = url.QueryEscape(object)
+	object = strings.Replace(object, "+", "%20", -1)
 
 	if um.Type == urlTypeCname {
 		host = um.NetLoc

+ 2 - 0
oss/conn_test.go

@@ -60,6 +60,8 @@ func (s *OssConnSuite) TestURLMarker(c *C) {
 	c.Assert(um.Type, Equals, urlTypeIP)
 	c.Assert(um.Scheme, Equals, "http")
 	c.Assert(um.NetLoc, Equals, "127.0.0.1")
+	c.Assert(um.getURL("bucket", "object", "params").String(), Equals, "http://127.0.0.1/bucket/object?params")
+	c.Assert(um.getURL("", "object", "params").String(), Equals, "http://127.0.0.1/?params")
 
 	um.Init("https://127.0.0.1:8080", false, false)
 	c.Assert(um.Type, Equals, urlTypeIP)

+ 1 - 1
oss/const.go

@@ -128,5 +128,5 @@ const (
 
 	CheckpointFileSuffix = ".cp" // Checkpoint文件后缀
 
-	Version = "1.5.1" // Go sdk版本
+	Version = "1.6.0" // Go sdk版本
 )

+ 2 - 2
oss/download_test.go

@@ -159,7 +159,7 @@ func (s *OssDownloadSuite) TestDownloadRoutineWithRecovery(c *C) {
 	c.Assert(len(dcp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ=="))
 	c.Assert(dcp.FilePath, Equals, newFile)
 	c.Assert(dcp.ObjStat.Size, Equals, int64(482048))
-	c.Assert(len(dcp.ObjStat.LastModified), Equals, len("2015-12-17 18:43:03 +0800 CST"))
+	c.Assert(len(dcp.ObjStat.LastModified) > 0, Equals, true)
 	c.Assert(dcp.ObjStat.Etag, Equals, "\"2351E662233817A7AE974D8C5B0876DD-5\"")
 	c.Assert(dcp.Object, Equals, objectName)
 	c.Assert(len(dcp.Parts), Equals, 5)
@@ -191,7 +191,7 @@ func (s *OssDownloadSuite) TestDownloadRoutineWithRecovery(c *C) {
 	c.Assert(len(dcp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ=="))
 	c.Assert(dcp.FilePath, Equals, newFile)
 	c.Assert(dcp.ObjStat.Size, Equals, int64(482048))
-	c.Assert(len(dcp.ObjStat.LastModified), Equals, len("2015-12-17 18:43:03 +0800 CST"))
+	c.Assert(len(dcp.ObjStat.LastModified) > 0, Equals, true)
 	c.Assert(dcp.ObjStat.Etag, Equals, "\"2351E662233817A7AE974D8C5B0876DD-5\"")
 	c.Assert(dcp.Object, Equals, objectName)
 	c.Assert(len(dcp.Parts), Equals, 5)

+ 2 - 2
oss/upload_test.go

@@ -250,7 +250,7 @@ func (s *OssUploadSuite) TestUploadRoutineWithRecovery(c *C) {
 	c.Assert(len(ucp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ=="))
 	c.Assert(ucp.FilePath, Equals, fileName)
 	c.Assert(ucp.FileStat.Size, Equals, int64(482048))
-	c.Assert(len(ucp.FileStat.LastModified.String()), Equals, len("2015-12-17 18:43:03 +0800 CST"))
+	c.Assert(len(ucp.FileStat.LastModified.String()) > 0, Equals, true)
 	c.Assert(ucp.FileStat.MD5, Equals, "")
 	c.Assert(ucp.ObjectKey, Equals, objectName)
 	c.Assert(len(ucp.UploadID), Equals, len("3F79722737D1469980DACEDCA325BB52"))
@@ -291,7 +291,7 @@ func (s *OssUploadSuite) TestUploadRoutineWithRecovery(c *C) {
 	c.Assert(len(ucp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ=="))
 	c.Assert(ucp.FilePath, Equals, fileName)
 	c.Assert(ucp.FileStat.Size, Equals, int64(482048))
-	c.Assert(len(ucp.FileStat.LastModified.String()), Equals, len("2015-12-17 18:43:03 +0800 CST"))
+	c.Assert(len(ucp.FileStat.LastModified.String()) > 0, Equals, true)
 	c.Assert(ucp.FileStat.MD5, Equals, "")
 	c.Assert(ucp.ObjectKey, Equals, objectName)
 	c.Assert(len(ucp.UploadID), Equals, len("3F79722737D1469980DACEDCA325BB52"))