mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-28 11:16:37 +08:00
0aff87c69d
优化
98 lines
2.8 KiB
Go
98 lines
2.8 KiB
Go
// 115 开放平台常量与错误类型。
|
||
package cloud115
|
||
|
||
import (
|
||
"crypto/sha256"
|
||
"encoding/base64"
|
||
"errors"
|
||
"fmt"
|
||
)
|
||
|
||
func sha256Sum(data []byte) [32]byte { return sha256.Sum256(data) }
|
||
func base64StdEncode(data []byte) string { return base64.StdEncoding.EncodeToString(data) }
|
||
|
||
// 115 开放平台 API 地址(变量便于测试注入 mock server)
|
||
var (
|
||
ProAPIBase = "https://proapi.115.com"
|
||
PassportAPIBase = "https://passportapi.115.com"
|
||
QRCodeAPIBase = "https://qrcodeapi.115.com"
|
||
FSPIsAPIBase = "https://fsapi.115.com"
|
||
)
|
||
|
||
const (
|
||
// 业务错误码
|
||
AccessTokenAuthFail = 40140126 // 访问过期,需刷新
|
||
AccessTokenExpiryCode = 40140125 // 访问过期,需刷新
|
||
AccessAuthInvalid = 40140124 // 访问无效,需刷新
|
||
RefreshTokenInvalid = 40140116 // 需重新授权
|
||
TokenRefreshFail = 40140121 // 刷新失败,可重试
|
||
RequestMaxLimitCode = 770004 // 访问频率过高
|
||
RequestRateLimitCode = 406 // 达到访问上限
|
||
|
||
// 刷新 token 的错误码
|
||
RefreshTokenFormatInvalid = 40140114
|
||
RefreshTokenSignInvalid = 40140115
|
||
RefreshTooFrequent = 40140117
|
||
RefreshTokenExpired = 40140119
|
||
RefreshTokenCheckFailed = 40140120
|
||
)
|
||
|
||
// DefaultUA 请求 UA(标准 API 客户端格式,避免伪装浏览器触发 115 WAF 拦截与 405 错误)。
|
||
const DefaultUA = "MMTL-115-GoClient/1.0"
|
||
|
||
// OpenAPIError 保留 115 开放平台返回的原始错误信息。
|
||
type OpenAPIError struct {
|
||
Code int
|
||
Message string
|
||
}
|
||
|
||
func (e *OpenAPIError) Error() string {
|
||
if e.Code == 0 {
|
||
return fmt.Sprintf("115 接口错误:%s", e.Message)
|
||
}
|
||
return fmt.Sprintf("115 接口错误(%d):%s", e.Code, e.Message)
|
||
}
|
||
|
||
// NewOpenAPIResponseError 组装接口错误。
|
||
func NewOpenAPIResponseError(code, errno int, message, errorText, fallback string) error {
|
||
if code == 0 {
|
||
code = errno
|
||
}
|
||
if message == "" {
|
||
message = errorText
|
||
}
|
||
if code == 0 && message == "" {
|
||
return fmt.Errorf("%s", fallback)
|
||
}
|
||
return NewOpenAPIError(code, message)
|
||
}
|
||
|
||
// NewOpenAPIError 构造接口错误。
|
||
func NewOpenAPIError(code int, message string) *OpenAPIError {
|
||
if message == "" {
|
||
message = "未知错误"
|
||
}
|
||
return &OpenAPIError{Code: code, Message: message}
|
||
}
|
||
|
||
// IsRefreshTokenDead 判断 refresh_token 是否已无法继续使用。
|
||
func IsRefreshTokenDead(err error) bool {
|
||
if err == nil {
|
||
return false
|
||
}
|
||
var apiErr *OpenAPIError
|
||
if errors.As(err, &apiErr) {
|
||
switch apiErr.Code {
|
||
case RefreshTokenFormatInvalid, RefreshTokenSignInvalid, RefreshTokenInvalid, RefreshTokenExpired, RefreshTokenCheckFailed:
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// genCodeChallenge 生成 PKCE code_challenge(sha256(codeVerifier) base64)。
|
||
func genCodeChallenge(codeVerifier string) string {
|
||
sum := sha256Sum([]byte(codeVerifier))
|
||
return base64StdEncode(sum[:])
|
||
}
|