ufilesdk-dev / ufile-gosdk

UCloud 对象存储官方 SDK
https://www.ucloud.cn/
Apache License 2.0
34 stars 27 forks source link

文件下载时返回token expires错误 #4

Closed clpdyhm closed 6 years ago

clpdyhm commented 6 years ago

hi ,你好!

  1. 使用GetPublicURL并调用函数Download时,服务端返回错误: { "RetCode": -148643, "ErrMsg": "no authorization found" }
  2. 使用GetPrivateURL并调用函数Download时,服务端返回错误: { "RetCode": -148660, "ErrMsg": "token expires" } 函数调用的http接口:https://docs.ucloud.cn/api/ufile-api/get_file 请问,应该怎么排查这个问题? 另外,bucket是私有的。 谢谢!
leyafo commented 6 years ago

GetPrivateURL 你是怎么传参的?发上来看看。

clpdyhm commented 6 years ago

有一个现象需要告诉你一下,使用 GetPrivateURL函数生成url时,第一次可以下载成功,第二次提示 token expires错误。使用GetPublicURL生成url时,直接提示no authorization found错误。 以下是我的代码,只是调用了sdk中的这2个函数。 //DownloadToFile 把文件下载到本地磁盘文件里面 //localPath 下载的文件保存到本地的路径 //localFileName 本地保存的文件名称 //keyName ufile中保存的文件名称 //@return filesize err

func (u UFileRequest) DownloadToFile(localPath, localFileName, keyName string) (int64, error) { // reqURL := u.GetPublicURL(keyName) reqURL := u.GetPrivateURL(keyName, 24 time.Hour) if err := u.Download(reqURL); err != nil { return 0, err }

if u.LastResponseStatus != http.StatusOK {
    return 0, fmt.Errorf("res status:%d, res body: %s, res header: %v",
        u.LastResponseStatus, string(u.LastResponseBody), u.LastResponseHeader)
}

var (
    pathx string
    base  string
)

pathx = localPath
base = localFileName
if dir := filepath.Dir(localFileName); dir != "." {
    pathx = filepath.Join(localPath, dir)
    base = filepath.Base(localFileName)
}

if _, err := os.Stat(pathx); os.IsNotExist(err) {
    err = os.MkdirAll(pathx, os.ModePerm)
    if err != nil {
        return 0, err
    }
}
// 打开文件,将body写入文件中
f, err := os.OpenFile(pathx+string(os.PathSeparator)+base, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0644))
if err != nil {
    return 0, err
}
defer f.Close()

// copy body内容
n, err := io.Copy(f, bytes.NewBuffer(u.LastResponseBody))
if err != nil {
    return 0, err
}

// 计算文件size
contentLenStr := u.LastResponseHeader["Content-Length"][0]
var contentLen int64
if contentLenStr != "" {
    if contentLen, err = strconv.ParseInt(contentLenStr, 10, 64); err != nil {
        return 0, err
    }
} else {
    return 0, fmt.Errorf("get content length from response header fail")
}

if contentLen != n {
    return 0, fmt.Errorf("write to file error, success write: %d, should be: %d", n, contentLen)
}

return contentLen, nil

}

clpdyhm commented 6 years ago

找到原因了。错误原因在于: file.go中方法GetPrivateURL未使用time.Add()之后的值,导致ufile服务器判断时间过期。请及时修正! t = t.Add(expiresDuation)

leyafo commented 6 years ago

感谢指出,马上修正。 已修正 https://github.com/ufilesdk-dev/ufile-gosdk/commit/a6d73aa8044b5ff21a06ddd15388b20e43b56ce9