mirror of https://github.com/Xhofe/alist
				
				
				
			fix: xunlei upload error (#749)
							parent
							
								
									b21801d505
								
							
						
					
					
						commit
						6db09a2736
					
				| 
						 | 
				
			
			@ -4,12 +4,12 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
 | 
			
		||||
	"github.com/go-resty/resty/v2"
 | 
			
		||||
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/Xhofe/alist/drivers/base"
 | 
			
		||||
| 
						 | 
				
			
			@ -95,12 +95,13 @@ func (driver XunLeiCloud) File(path string, account *model.Account) (*model.File
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (driver XunLeiCloud) Files(path string, account *model.Account) ([]model.File, error) {
 | 
			
		||||
	path = utils.ParsePath(path)
 | 
			
		||||
	cache, err := base.GetCache(path, account)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		files, _ := cache.([]model.File)
 | 
			
		||||
		return files, nil
 | 
			
		||||
	}
 | 
			
		||||
	file, err := driver.File(utils.ParsePath(path), account)
 | 
			
		||||
	file, err := driver.File(path, account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -108,8 +109,16 @@ func (driver XunLeiCloud) Files(path string, account *model.Account) ([]model.Fi
 | 
			
		|||
	files := make([]model.File, 0)
 | 
			
		||||
	for {
 | 
			
		||||
		var fileList FileList
 | 
			
		||||
		u := fmt.Sprintf("https://api-pan.xunlei.com/drive/v1/files?parent_id=%s&page_token=%s&with_audit=true&filters=%s", file.Id, fileList.NextPageToken, url.QueryEscape(`{"phase": {"eq": "PHASE_TYPE_COMPLETE"}, "trashed":{"eq":false}}`))
 | 
			
		||||
		if err = GetState(account).Request("GET", u, nil, &fileList, account); err != nil {
 | 
			
		||||
		_, err = GetState(account).Request("GET", FILE_API_URL, func(r *resty.Request) {
 | 
			
		||||
			r.SetQueryParams(map[string]string{
 | 
			
		||||
				"parent_id":  file.Id,
 | 
			
		||||
				"page_token": fileList.NextPageToken,
 | 
			
		||||
				"with_audit": "true",
 | 
			
		||||
				"filters":    `{"phase": {"eq": "PHASE_TYPE_COMPLETE"}, "trashed":{"eq":false}}`,
 | 
			
		||||
			})
 | 
			
		||||
			r.SetResult(&fileList)
 | 
			
		||||
		}, account)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		for _, file := range fileList.Files {
 | 
			
		||||
| 
						 | 
				
			
			@ -153,7 +162,12 @@ func (driver XunLeiCloud) Link(args base.Args, account *model.Account) (*base.Li
 | 
			
		|||
		return nil, base.ErrNotFile
 | 
			
		||||
	}
 | 
			
		||||
	var lFile Files
 | 
			
		||||
	if err = GetState(account).Request("GET", fmt.Sprintf("https://api-pan.xunlei.com/drive/v1/files/%s?&with_audit=true", file.Id), nil, &lFile, account); err != nil {
 | 
			
		||||
	_, err = GetState(account).Request("GET", FILE_API_URL+"/{id}", func(r *resty.Request) {
 | 
			
		||||
		r.SetPathParam("id", file.Id)
 | 
			
		||||
		r.SetQueryParam("with_audit", "true")
 | 
			
		||||
		r.SetResult(&lFile)
 | 
			
		||||
	}, account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &base.Link{
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +208,14 @@ func (driver XunLeiCloud) MakeDir(path string, account *model.Account) error {
 | 
			
		|||
	if !parentFile.IsDir() {
 | 
			
		||||
		return base.ErrNotFolder
 | 
			
		||||
	}
 | 
			
		||||
	return GetState(account).Request("POST", "https://api-pan.xunlei.com/drive/v1/files", &base.Json{"kind": FOLDER, "name": name, "parent_id": parentFile.Id}, nil, account)
 | 
			
		||||
	_, err = GetState(account).Request("POST", FILE_API_URL, func(r *resty.Request) {
 | 
			
		||||
		r.SetBody(&base.Json{
 | 
			
		||||
			"kind":      FOLDER,
 | 
			
		||||
			"name":      name,
 | 
			
		||||
			"parent_id": parentFile.Id,
 | 
			
		||||
		})
 | 
			
		||||
	}, account)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (driver XunLeiCloud) Move(src string, dst string, account *model.Account) error {
 | 
			
		||||
| 
						 | 
				
			
			@ -207,7 +228,14 @@ func (driver XunLeiCloud) Move(src string, dst string, account *model.Account) e
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return GetState(account).Request("POST", "https://api-pan.xunlei.com/drive/v1/files:batchMove", &base.Json{"to": base.Json{"parent_id": dstDirFile.Id}, "ids": []string{srcFile.Id}}, nil, account)
 | 
			
		||||
 | 
			
		||||
	_, err = GetState(account).Request("POST", FILE_API_URL+":batchMove", func(r *resty.Request) {
 | 
			
		||||
		r.SetBody(&base.Json{
 | 
			
		||||
			"to":  base.Json{"parent_id": dstDirFile.Id},
 | 
			
		||||
			"ids": []string{srcFile.Id},
 | 
			
		||||
		})
 | 
			
		||||
	}, account)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (driver XunLeiCloud) Copy(src string, dst string, account *model.Account) error {
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +248,13 @@ func (driver XunLeiCloud) Copy(src string, dst string, account *model.Account) e
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return GetState(account).Request("POST", "https://api-pan.xunlei.com/drive/v1/files:batchCopy", &base.Json{"to": base.Json{"parent_id": dstDirFile.Id}, "ids": []string{srcFile.Id}}, nil, account)
 | 
			
		||||
	_, err = GetState(account).Request("POST", FILE_API_URL+":batchCopy", func(r *resty.Request) {
 | 
			
		||||
		r.SetBody(&base.Json{
 | 
			
		||||
			"to":  base.Json{"parent_id": dstDirFile.Id},
 | 
			
		||||
			"ids": []string{srcFile.Id},
 | 
			
		||||
		})
 | 
			
		||||
	}, account)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (driver XunLeiCloud) Delete(path string, account *model.Account) error {
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +262,11 @@ func (driver XunLeiCloud) Delete(path string, account *model.Account) error {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return GetState(account).Request("PATCH", fmt.Sprintf("https://api-pan.xunlei.com/drive/v1/files/%s/trash", srcFile.Id), &base.Json{}, nil, account)
 | 
			
		||||
	_, err = GetState(account).Request("PATCH", FILE_API_URL+"/{id}/trash", func(r *resty.Request) {
 | 
			
		||||
		r.SetPathParam("id", srcFile.Id)
 | 
			
		||||
		r.SetBody(&base.Json{})
 | 
			
		||||
	}, account)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (driver XunLeiCloud) Upload(file *model.FileStream, account *model.Account) error {
 | 
			
		||||
| 
						 | 
				
			
			@ -246,7 +284,6 @@ func (driver XunLeiCloud) Upload(file *model.FileStream, account *model.Account)
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer tempFile.Close()
 | 
			
		||||
	defer os.Remove(tempFile.Name())
 | 
			
		||||
 | 
			
		||||
	gcid, err := getGcid(io.TeeReader(file, tempFile), int64(file.Size))
 | 
			
		||||
| 
						 | 
				
			
			@ -254,29 +291,37 @@ func (driver XunLeiCloud) Upload(file *model.FileStream, account *model.Account)
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var rep UploadTaskResponse
 | 
			
		||||
	err = GetState(account).Request("POST", "https://api-pan.xunlei.com/drive/v1/files", &base.Json{
 | 
			
		||||
		"kind":        FILE,
 | 
			
		||||
		"parent_id":   parentFile.Id,
 | 
			
		||||
		"name":        file.Name,
 | 
			
		||||
		"size":        fmt.Sprint(file.Size),
 | 
			
		||||
		"hash":        gcid,
 | 
			
		||||
		"upload_type": UPLOAD_TYPE_RESUMABLE,
 | 
			
		||||
	}, &rep, account)
 | 
			
		||||
	tempFile.Close()
 | 
			
		||||
 | 
			
		||||
	var resp UploadTaskResponse
 | 
			
		||||
	_, err = GetState(account).Request("POST", FILE_API_URL, func(r *resty.Request) {
 | 
			
		||||
		r.SetBody(&base.Json{
 | 
			
		||||
			"kind":        FILE,
 | 
			
		||||
			"parent_id":   parentFile.Id,
 | 
			
		||||
			"name":        file.Name,
 | 
			
		||||
			"size":        fmt.Sprint(file.Size),
 | 
			
		||||
			"hash":        gcid,
 | 
			
		||||
			"upload_type": UPLOAD_TYPE_RESUMABLE,
 | 
			
		||||
		})
 | 
			
		||||
		r.SetResult(&resp)
 | 
			
		||||
	}, account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	param := rep.Resumable.Params
 | 
			
		||||
	client, err := oss.New(param.Endpoint, param.AccessKeyID, param.AccessKeySecret, oss.SecurityToken(param.SecurityToken), oss.EnableMD5(true), oss.HTTPClient(xunleiClient.GetClient()))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	param := resp.Resumable.Params
 | 
			
		||||
	if resp.UploadType == UPLOAD_TYPE_RESUMABLE {
 | 
			
		||||
		client, err := oss.New(param.Endpoint, param.AccessKeyID, param.AccessKeySecret, oss.SecurityToken(param.SecurityToken), oss.EnableMD5(true))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		bucket, err := client.Bucket(param.Bucket)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		return bucket.UploadFile(param.Key, tempFile.Name(), 1<<22, oss.Routines(3), oss.Checkpoint(true, ""), oss.Expires(param.Expiration))
 | 
			
		||||
	}
 | 
			
		||||
	bucket, err := client.Bucket(param.Bucket)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return bucket.UploadFile(param.Key, tempFile.Name(), 4*1024*1024, oss.Routines(3), oss.Checkpoint(true, ""), oss.Expires(param.Expiration))
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (driver XunLeiCloud) Rename(src string, dst string, account *model.Account) error {
 | 
			
		||||
| 
						 | 
				
			
			@ -285,8 +330,11 @@ func (driver XunLeiCloud) Rename(src string, dst string, account *model.Account)
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return GetState(account).Request("PATCH", fmt.Sprintf("https://api-pan.xunlei.com/drive/v1/files/%s", srcFile.Id), &base.Json{"name": dstName}, nil, account)
 | 
			
		||||
	_, err = GetState(account).Request("PATCH", FILE_API_URL+"/{id}", func(r *resty.Request) {
 | 
			
		||||
		r.SetPathParam("id", srcFile.Id)
 | 
			
		||||
		r.SetBody(&base.Json{"name": dstName})
 | 
			
		||||
	}, account)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ base.Driver = (*XunLeiCloud)(nil)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,12 @@ var Algorithms = []string{
 | 
			
		|||
	"T78dnANexYRbiZy",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	API_URL        = "https://api-pan.xunlei.com/drive/v1"
 | 
			
		||||
	FILE_API_URL   = API_URL + "/files"
 | 
			
		||||
	XLUSER_API_URL = "https://xluser-ssl.xunlei.com/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	FOLDER = "drive#folder"
 | 
			
		||||
	FILE   = "drive#file"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ package xunlei
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +13,7 @@ import (
 | 
			
		|||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var xunleiClient = resty.New().SetTimeout(120 * time.Second)
 | 
			
		||||
var xunleiClient = resty.New().SetHeaders(map[string]string{"Accept": "application/json;charset=UTF-8"})
 | 
			
		||||
 | 
			
		||||
// 一个账户只允许登陆一次
 | 
			
		||||
var userStateCache = struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -102,16 +103,16 @@ func (s *State) newCaptchaToken(action string, meta map[string]string, account *
 | 
			
		|||
	var e Erron
 | 
			
		||||
	var resp CaptchaTokenResponse
 | 
			
		||||
	_, err := xunleiClient.R().
 | 
			
		||||
		SetHeader("X-Device-Id", driverID).
 | 
			
		||||
		SetBody(&creq).
 | 
			
		||||
		SetError(&e).
 | 
			
		||||
		SetResult(&resp).
 | 
			
		||||
		Post("https://xluser-ssl.xunlei.com/v1/shield/captcha/init?client_id=" + CLIENT_ID)
 | 
			
		||||
		SetHeader("X-Device-Id", driverID).
 | 
			
		||||
		SetQueryParam("client_id", CLIENT_ID).
 | 
			
		||||
		Post(XLUSER_API_URL + "/shield/captcha/init")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if e.ErrorCode != 0 {
 | 
			
		||||
		log.Debugf("%+v\n %+v", e, account)
 | 
			
		||||
		return "", fmt.Errorf("%s : %s", e.Error, e.ErrorDescription)
 | 
			
		||||
	}
 | 
			
		||||
	if resp.Url != "" {
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +121,6 @@ func (s *State) newCaptchaToken(action string, meta map[string]string, account *
 | 
			
		|||
 | 
			
		||||
	s.captchaTokenExpiresTime = (ctime + resp.ExpiresIn*1000) - 30000
 | 
			
		||||
	s.captchaToken = resp.CaptchaToken
 | 
			
		||||
	log.Debugf("%+v\n %+v", s.captchaToken, account)
 | 
			
		||||
	return s.captchaToken, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ func (s *State) refreshToken_(account *model.Account) error {
 | 
			
		|||
			"client_secret": CLIENT_SECRET,
 | 
			
		||||
		}).
 | 
			
		||||
		SetHeader("X-Device-Id", utils.GetMD5Encode(account.Username)).SetQueryParam("client_id", CLIENT_ID).
 | 
			
		||||
		Post("https://xluser-ssl.xunlei.com/v1/auth/token")
 | 
			
		||||
		Post(XLUSER_API_URL + "/auth/token")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +152,6 @@ func (s *State) refreshToken_(account *model.Account) error {
 | 
			
		|||
		s.userID = resp.UserID
 | 
			
		||||
		return nil
 | 
			
		||||
	default:
 | 
			
		||||
		log.Debugf("%+v\n %+v", e, account)
 | 
			
		||||
		return fmt.Errorf("%s : %s", e.Error, e.ErrorDescription)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +159,7 @@ func (s *State) refreshToken_(account *model.Account) error {
 | 
			
		|||
func (s *State) login(account *model.Account) error {
 | 
			
		||||
	s.init()
 | 
			
		||||
	ctime := time.Now().UnixMilli()
 | 
			
		||||
	url := "https://xluser-ssl.xunlei.com/v1/auth/signin"
 | 
			
		||||
	url := XLUSER_API_URL + "/auth/signin"
 | 
			
		||||
	captchaToken, err := s.newCaptchaToken(getAction("POST", url), map[string]string{"username": account.Username}, account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +189,6 @@ func (s *State) login(account *model.Account) error {
 | 
			
		|||
	defer model.SaveAccount(account)
 | 
			
		||||
	if e.ErrorCode != 0 {
 | 
			
		||||
		account.Status = e.Error
 | 
			
		||||
		log.Debugf("%+v\n %+v", e, account)
 | 
			
		||||
		return fmt.Errorf("%s : %s", e.Error, e.ErrorDescription)
 | 
			
		||||
	}
 | 
			
		||||
	account.Status = "work"
 | 
			
		||||
| 
						 | 
				
			
			@ -199,67 +197,68 @@ func (s *State) login(account *model.Account) error {
 | 
			
		|||
	s.accessToken = resp.AccessToken
 | 
			
		||||
	s.refreshToken = resp.RefreshToken
 | 
			
		||||
	s.userID = resp.UserID
 | 
			
		||||
	log.Debugf("%+v\n %+v", resp, account)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *State) Request(method string, url string, body interface{}, resp interface{}, account *model.Account) error {
 | 
			
		||||
func (s *State) Request(method string, url string, callback func(*resty.Request), account *model.Account) (*resty.Response, error) {
 | 
			
		||||
	s.Lock()
 | 
			
		||||
	token, err := s.getToken(account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	captchaToken, err := s.getCaptchaToken(getAction(method, url), account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	s.Unlock()
 | 
			
		||||
	var e Erron
 | 
			
		||||
 | 
			
		||||
	req := xunleiClient.R().
 | 
			
		||||
		SetError(&e).
 | 
			
		||||
		SetHeader("X-Device-Id", utils.GetMD5Encode(account.Username)).
 | 
			
		||||
		SetHeader("Authorization", token).
 | 
			
		||||
		SetHeader("X-Captcha-Token", captchaToken).
 | 
			
		||||
		SetHeaders(map[string]string{
 | 
			
		||||
			"X-Device-Id":     utils.GetMD5Encode(account.Username),
 | 
			
		||||
			"Authorization":   token,
 | 
			
		||||
			"X-Captcha-Token": captchaToken,
 | 
			
		||||
		}).
 | 
			
		||||
		SetQueryParam("client_id", CLIENT_ID)
 | 
			
		||||
 | 
			
		||||
	if body != nil {
 | 
			
		||||
		req.SetBody(body)
 | 
			
		||||
	}
 | 
			
		||||
	if resp != nil {
 | 
			
		||||
		req.SetResult(resp)
 | 
			
		||||
	}
 | 
			
		||||
	callback(req)
 | 
			
		||||
	s.Unlock()
 | 
			
		||||
 | 
			
		||||
	var res *resty.Response
 | 
			
		||||
	switch method {
 | 
			
		||||
	case "GET":
 | 
			
		||||
		_, err = req.Get(url)
 | 
			
		||||
		res, err = req.Get(url)
 | 
			
		||||
	case "POST":
 | 
			
		||||
		_, err = req.Post(url)
 | 
			
		||||
		res, err = req.Post(url)
 | 
			
		||||
	case "DELETE":
 | 
			
		||||
		_, err = req.Delete(url)
 | 
			
		||||
		res, err = req.Delete(url)
 | 
			
		||||
	case "PATCH":
 | 
			
		||||
		_, err = req.Patch(url)
 | 
			
		||||
		res, err = req.Patch(url)
 | 
			
		||||
	case "PUT":
 | 
			
		||||
		_, err = req.Put(url)
 | 
			
		||||
		res, err = req.Put(url)
 | 
			
		||||
	default:
 | 
			
		||||
		return base.ErrNotSupport
 | 
			
		||||
		return nil, base.ErrNotSupport
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	log.Debug(res.String())
 | 
			
		||||
 | 
			
		||||
	var e Erron
 | 
			
		||||
	utils.Json.Unmarshal(res.Body(), &e)
 | 
			
		||||
	switch e.ErrorCode {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return nil
 | 
			
		||||
	case 9:
 | 
			
		||||
		s.newCaptchaToken(getAction(method, url), nil, account)
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case 4122, 4121:
 | 
			
		||||
		return s.Request(method, url, body, resp, account)
 | 
			
		||||
		return s.Request(method, url, callback, account)
 | 
			
		||||
	case 0:
 | 
			
		||||
		if res.StatusCode() == http.StatusOK {
 | 
			
		||||
			return res, nil
 | 
			
		||||
		}
 | 
			
		||||
		return nil, fmt.Errorf(res.String())
 | 
			
		||||
	default:
 | 
			
		||||
		log.Debugf("%+v\n %+v", e, account)
 | 
			
		||||
		return fmt.Errorf("%s : %s", e.Error, e.ErrorDescription)
 | 
			
		||||
		return nil, fmt.Errorf("%s : %s", e.Error, e.ErrorDescription)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue