mirror of
https://github.com/eiblog/eiblog.git
synced 2026-03-01 00:34:58 +08:00
release v1.20
This commit is contained in:
41
vendor/qiniupkg.com/api.v7/cdn/anti_leech.go
generated
vendored
Normal file
41
vendor/qiniupkg.com/api.v7/cdn/anti_leech.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
package cdn
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CreateTimestampAntileechURL 构建带时间戳防盗链的链接
|
||||
// host需要加上 "http://" 或 "https://"
|
||||
// encryptKey 七牛防盗链key
|
||||
func CreateTimestampAntileechURL(host, fileName string, queryStr url.Values, encryptKey string, durationInSeconds int64) (antileechURL string, err error) {
|
||||
|
||||
var urlStr string
|
||||
if queryStr != nil {
|
||||
urlStr = fmt.Sprintf("%s/%s?%s", host, fileName, queryStr.Encode())
|
||||
} else {
|
||||
urlStr = fmt.Sprintf("%s/%s", host, fileName)
|
||||
}
|
||||
|
||||
u, parseErr := url.Parse(urlStr)
|
||||
if parseErr != nil {
|
||||
err = parseErr
|
||||
return
|
||||
}
|
||||
|
||||
expireTime := time.Now().Add(time.Second * time.Duration(durationInSeconds)).Unix()
|
||||
toSignStr := fmt.Sprintf("%s%s%x", encryptKey, u.EscapedPath(), expireTime)
|
||||
signedStr := fmt.Sprintf("%x", md5.Sum([]byte(toSignStr)))
|
||||
|
||||
q := u.Query()
|
||||
q.Add("sign", signedStr)
|
||||
q.Add("t", fmt.Sprintf("%x", expireTime))
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
antileechURL = fmt.Sprintf("%s://%s%s?%s", u.Scheme, u.Host, u.EscapedPath(), u.Query().Encode())
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
44
vendor/qiniupkg.com/api.v7/cdn/anti_leech_test.go
generated
vendored
Normal file
44
vendor/qiniupkg.com/api.v7/cdn/anti_leech_test.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package cdn
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCreateTimestampAntiLeech(t *testing.T) {
|
||||
type args struct {
|
||||
host string
|
||||
fileName string
|
||||
queryStr url.Values
|
||||
encryptKey string
|
||||
durationInSeconds int64
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "antileech_1",
|
||||
args: args{
|
||||
host: "http://www.abc.com",
|
||||
fileName: "abc.jpg",
|
||||
queryStr: url.Values{
|
||||
"x": {"9"},
|
||||
},
|
||||
encryptKey: "abc",
|
||||
durationInSeconds: 20,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := CreateTimestampAntileechURL(tt.args.host, tt.args.fileName, tt.args.queryStr, tt.args.encryptKey, tt.args.durationInSeconds)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("CreateTimestampAntiLeech() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
260
vendor/qiniupkg.com/api.v7/cdn/api.go
generated
vendored
Normal file
260
vendor/qiniupkg.com/api.v7/cdn/api.go
generated
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
package cdn
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"qiniupkg.com/api.v7/auth/qbox"
|
||||
. "qiniupkg.com/api.v7/conf"
|
||||
)
|
||||
|
||||
var (
|
||||
FUSION_HOST = "http://fusion.qiniuapi.com"
|
||||
)
|
||||
|
||||
/* TrafficReqBody
|
||||
|
||||
批量查询带宽/流量 请求内容
|
||||
|
||||
StartDate string 开始日期,例如:2016-07-01
|
||||
EndDate string 结束日期,例如:2016-07-03
|
||||
Granularity string 粒度,取值:5min / hour /day
|
||||
Domains string 域名列表,以 ;分割
|
||||
*/
|
||||
type TrafficReqBody struct {
|
||||
StartDate string `json:"startDate"`
|
||||
EndDate string `json:"endDate"`
|
||||
Granularity string `json:"granularity"`
|
||||
Domains string `json:"domains"`
|
||||
}
|
||||
|
||||
// TrafficResp
|
||||
// 带宽/流量查询响应内容
|
||||
type TrafficResp struct {
|
||||
Code int `json:"code"`
|
||||
Error string `json:"error"`
|
||||
Time []string `json:"time,omitempty"`
|
||||
Data map[string]TrafficRespData `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// TrafficRespData
|
||||
// 带宽/流量数据
|
||||
type TrafficRespData struct {
|
||||
DomainChina []int `json:"china"`
|
||||
DomainOversea []int `json:"oversea"`
|
||||
}
|
||||
|
||||
/*
|
||||
// BandWidth
|
||||
|
||||
获取域名访问带宽数据
|
||||
http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
|
||||
|
||||
StartDate string 必须 开始日期,例如:2016-07-01
|
||||
EndDate string 必须 结束日期,例如:2016-07-03
|
||||
Granularity string 必须 粒度,取值:5min / hour /day
|
||||
Domains []string 必须 域名列表
|
||||
*/
|
||||
func GetBandWidthData(startDate, endDate, granularity string, domainList []string) (bandwidthData TrafficResp, err error) {
|
||||
|
||||
domains := strings.Join(domainList, ";")
|
||||
reqBody := TrafficReqBody{
|
||||
StartDate: startDate,
|
||||
EndDate: endDate,
|
||||
Granularity: granularity,
|
||||
Domains: domains,
|
||||
}
|
||||
|
||||
resData, reqErr := postRequest("v2/tune/bandwidth", reqBody)
|
||||
if reqErr != nil {
|
||||
err = reqErr
|
||||
return
|
||||
}
|
||||
umErr := json.Unmarshal(resData, &bandwidthData)
|
||||
if umErr != nil {
|
||||
err = umErr
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/* Flux
|
||||
|
||||
获取域名访问流量数据
|
||||
http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
|
||||
|
||||
StartDate string 必须 开始日期,例如:2016-07-01
|
||||
EndDate string 必须 结束日期,例如:2016-07-03
|
||||
Granularity string 必须 粒度,取值:5min / hour /day
|
||||
Domains []string 必须 域名列表
|
||||
*/
|
||||
func GetFluxData(startDate, endDate, granularity string, domainList []string) (fluxData TrafficResp, err error) {
|
||||
|
||||
domains := strings.Join(domainList, ";")
|
||||
reqBody := TrafficReqBody{
|
||||
StartDate: startDate,
|
||||
EndDate: endDate,
|
||||
Granularity: granularity,
|
||||
Domains: domains,
|
||||
}
|
||||
|
||||
resData, reqErr := postRequest("v2/tune/flux", reqBody)
|
||||
if reqErr != nil {
|
||||
err = reqErr
|
||||
return
|
||||
}
|
||||
|
||||
umErr := json.Unmarshal(resData, &fluxData)
|
||||
if umErr != nil {
|
||||
err = umErr
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RefreshReq
|
||||
// 缓存刷新请求内容
|
||||
type RefreshReq struct {
|
||||
Urls []string `json:"urls"`
|
||||
Dirs []string `json:"dirs"`
|
||||
}
|
||||
|
||||
// RefreshResp
|
||||
// 缓存刷新响应内容
|
||||
type RefreshResp struct {
|
||||
Code int `json:"code"`
|
||||
Error string `json:"error"`
|
||||
RequestID string `json:"requestId,omitempty"`
|
||||
InvalidUrls []string `json:"invalidUrls,omitempty"`
|
||||
InvalidDirs []string `json:"invalidDirs,omitempty"`
|
||||
UrlQuotaDay int `json:"urlQuotaDay,omitempty"`
|
||||
UrlSurplusDay int `json:"urlSurplusDay,omitempty"`
|
||||
DirQuotaDay int `json:"dirQuotaDay,omitempty"`
|
||||
DirSurplusDay int `json:"dirSurplusDay,omitempty"`
|
||||
}
|
||||
|
||||
/* RefreshUrlsAndDirs
|
||||
|
||||
刷新链接列表,每次最多不可以超过100条链接
|
||||
http://developer.qiniu.com/article/fusion/api/refresh.html
|
||||
|
||||
urls 要刷新的单个url列表,总数不超过100条;单个url,即一个具体的url,例如:http://bar.foo.com/index.html
|
||||
dirs 要刷新的目录url列表,总数不超过10条;目录dir,即表示一个目录级的url,例如:http://bar.foo.com/dir/,也支持在尾部使用通配符,例如:http://bar.foo.com/dir/*
|
||||
*/
|
||||
func RefreshUrlsAndDirs(urls, dirs []string) (result RefreshResp, err error) {
|
||||
|
||||
reqBody := RefreshReq{
|
||||
Urls: urls,
|
||||
Dirs: dirs,
|
||||
}
|
||||
|
||||
resData, reqErr := postRequest("v2/tune/refresh", reqBody)
|
||||
if reqErr != nil {
|
||||
err = reqErr
|
||||
return
|
||||
}
|
||||
umErr := json.Unmarshal(resData, &result)
|
||||
if umErr != nil {
|
||||
err = reqErr
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RefreshUrls
|
||||
// 刷新文件
|
||||
func RefreshUrls(urls []string) (result RefreshResp, err error) {
|
||||
return RefreshUrlsAndDirs(urls, nil)
|
||||
}
|
||||
|
||||
// RefreshDirs
|
||||
// 刷新目录
|
||||
func RefreshDirs(dirs []string) (result RefreshResp, err error) {
|
||||
return RefreshUrlsAndDirs(nil, dirs)
|
||||
}
|
||||
|
||||
// PrefetchReq
|
||||
// 文件预取请求内容
|
||||
type PrefetchReq struct {
|
||||
Urls []string `json:"urls"`
|
||||
}
|
||||
|
||||
// PrefetchResp
|
||||
// 文件预取响应内容
|
||||
type PrefetchResp struct {
|
||||
Code int `json:"code"`
|
||||
Error string `json:"error"`
|
||||
RequestID string `json:"requestId,omitempty"`
|
||||
InvalidUrls []string `json:"invalidUrls,omitempty"`
|
||||
QuotaDay int `json:"quotaDay,omitempty"`
|
||||
SurplusDay int `json:"surplusDay,omitempty"`
|
||||
}
|
||||
|
||||
// PrefetchUrls
|
||||
// 预取文件链接,每次最多不可以超过100条
|
||||
// http://developer.qiniu.com/article/fusion/api/prefetch.html
|
||||
func PrefetchUrls(urls []string) (result PrefetchResp, err error) {
|
||||
|
||||
reqBody := PrefetchReq{
|
||||
Urls: urls,
|
||||
}
|
||||
|
||||
resData, reqErr := postRequest("v2/tune/prefetch", reqBody)
|
||||
if reqErr != nil {
|
||||
err = reqErr
|
||||
return
|
||||
}
|
||||
|
||||
umErr := json.Unmarshal(resData, &result)
|
||||
if umErr != nil {
|
||||
err = umErr
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RequestWithBody
|
||||
// 带body对api发出请求并且返回response body
|
||||
func postRequest(path string, body interface{}) (resData []byte, err error) {
|
||||
|
||||
urlStr := fmt.Sprintf("%s/%s", FUSION_HOST, path)
|
||||
|
||||
reqData, _ := json.Marshal(body)
|
||||
req, reqErr := http.NewRequest("POST", urlStr, bytes.NewReader(reqData))
|
||||
if reqErr != nil {
|
||||
err = reqErr
|
||||
return
|
||||
}
|
||||
|
||||
mac := qbox.NewMac(ACCESS_KEY, SECRET_KEY)
|
||||
accessToken, signErr := mac.SignRequest(req, false)
|
||||
if signErr != nil {
|
||||
err = signErr
|
||||
return
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", "QBox "+accessToken)
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
resp, httpErr := http.DefaultClient.Do(req)
|
||||
if httpErr != nil {
|
||||
err = httpErr
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
resData, ioErr := ioutil.ReadAll(resp.Body)
|
||||
if ioErr != nil {
|
||||
err = ioErr
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
243
vendor/qiniupkg.com/api.v7/cdn/api_test.go
generated
vendored
Normal file
243
vendor/qiniupkg.com/api.v7/cdn/api_test.go
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
package cdn
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"time"
|
||||
|
||||
"qiniupkg.com/api.v7/kodo"
|
||||
)
|
||||
|
||||
var (
|
||||
ak = os.Getenv("QINIU_ACCESS_KEY")
|
||||
sk = os.Getenv("QINIU_SECRET_KEY")
|
||||
domain = os.Getenv("QINIU_TEST_DOMAIN")
|
||||
testBucketName = os.Getenv("QINIU_TEST_BUCKET")
|
||||
|
||||
testDate = time.Now().AddDate(0, 0, -3).Format("2006-01-02")
|
||||
bucket = newBucket()
|
||||
client *kodo.Client
|
||||
testKey = "fusionTest"
|
||||
testURL string
|
||||
)
|
||||
|
||||
func init() {
|
||||
kodo.SetMac(ak, sk)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
testKey += strconv.Itoa(rand.Int())
|
||||
bucket.PutFile(nil, nil, testKey, "doc.go", nil)
|
||||
testURL = domain + "/" + testKey
|
||||
|
||||
}
|
||||
|
||||
func TestGetBandWidthData(t *testing.T) {
|
||||
type args struct {
|
||||
startDate string
|
||||
endDate string
|
||||
granularity string
|
||||
domainList []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantTraffic TrafficResp
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "BandWidthTest_1",
|
||||
args: args{
|
||||
testDate,
|
||||
testDate,
|
||||
"5min",
|
||||
[]string{domain},
|
||||
},
|
||||
},
|
||||
}
|
||||
kodo.SetMac(ak, sk)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := GetBandWidthData(tt.args.startDate, tt.args.endDate, tt.args.granularity, tt.args.domainList)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetBandWidthData() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFluxData(t *testing.T) {
|
||||
type args struct {
|
||||
startDate string
|
||||
endDate string
|
||||
granularity string
|
||||
domainList []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantTraffic TrafficResp
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "BandWidthTest_1",
|
||||
args: args{
|
||||
testDate,
|
||||
testDate,
|
||||
"5min",
|
||||
[]string{domain},
|
||||
},
|
||||
},
|
||||
}
|
||||
kodo.SetMac(ak, sk)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := GetFluxData(tt.args.startDate, tt.args.endDate, tt.args.granularity, tt.args.domainList)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetFluxData() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshUrlsAndDirs(t *testing.T) {
|
||||
kodo.SetMac(ak, sk)
|
||||
|
||||
type args struct {
|
||||
urls []string
|
||||
dirs []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantResult RefreshResp
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "refresh_test_1",
|
||||
args: args{
|
||||
urls: []string{testURL},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := RefreshUrlsAndDirs(tt.args.urls, tt.args.dirs)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("RefreshUrlsAndDirs() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshUrls(t *testing.T) {
|
||||
type args struct {
|
||||
urls []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantResult RefreshResp
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "refresh_test_1",
|
||||
args: args{
|
||||
urls: []string{testURL},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := RefreshUrls(tt.args.urls)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("RefreshUrls() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshDirs(t *testing.T) {
|
||||
type args struct {
|
||||
dirs []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantResult RefreshResp
|
||||
wantErr bool
|
||||
}{}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotResult, err := RefreshDirs(tt.args.dirs)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("RefreshDirs() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(gotResult, tt.wantResult) {
|
||||
t.Errorf("RefreshDirs() = %v, want %v", gotResult, tt.wantResult)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrefetchUrls(t *testing.T) {
|
||||
type args struct {
|
||||
urls []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantResult PrefetchResp
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "refresh_test_1",
|
||||
args: args{
|
||||
urls: []string{testURL},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
kodo.SetMac(ak, sk)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := PrefetchUrls(tt.args.urls)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("PrefetchUrls() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newBucket() (bucket kodo.Bucket) {
|
||||
|
||||
ak := os.Getenv("QINIU_ACCESS_KEY")
|
||||
sk := os.Getenv("QINIU_SECRET_KEY")
|
||||
if ak == "" || sk == "" {
|
||||
panic("require ACCESS_KEY & SECRET_KEY")
|
||||
}
|
||||
kodo.SetMac(ak, sk)
|
||||
|
||||
testBucketName = os.Getenv("QINIU_TEST_BUCKET")
|
||||
domain = os.Getenv("QINIU_TEST_DOMAIN")
|
||||
if testBucketName == "" || domain == "" {
|
||||
panic("require test env")
|
||||
}
|
||||
client = kodo.NewWithoutZone(nil)
|
||||
|
||||
return client.Bucket(testBucketName)
|
||||
}
|
||||
25
vendor/qiniupkg.com/api.v7/cdn/doc.go
generated
vendored
Normal file
25
vendor/qiniupkg.com/api.v7/cdn/doc.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
包qiniupkg.com/api.v7/fusion提供了七牛CDN的API功能
|
||||
首先,我们要配置下 AccessKey/SecretKey,
|
||||
import "qiniupkg.com/api.v7/kodo"
|
||||
|
||||
kodo.SetMac("ak", "sk")
|
||||
设置了AccessKey/SecretKey 就可以使用cdn的各类功能
|
||||
|
||||
比如我们要生成一个带时间戳防盗链的链接:
|
||||
q :=url.Values{}// url.Values 请求参数
|
||||
link, err := cdn.CreateTimestampAntiLeechUrl("http://www.qiniu.com", "abc/bcc/aa-s.mp4", nil, "encryptedkey", 20)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(link)
|
||||
|
||||
又或者我们要列出CDN日志及其下载地址:
|
||||
resp, err := cdn.GetLogOfDomain("2016-12-26", "x-mas.com")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(resp)
|
||||
|
||||
*/
|
||||
package cdn
|
||||
92
vendor/qiniupkg.com/api.v7/cdn/logs.go
generated
vendored
Normal file
92
vendor/qiniupkg.com/api.v7/cdn/logs.go
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
package cdn
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"qiniupkg.com/api.v7/auth/qbox"
|
||||
)
|
||||
|
||||
const (
|
||||
LIST_LOG_API = "http://fusion.qiniuapi.com/v2/tune/log/list"
|
||||
)
|
||||
|
||||
// ListLogRequest 日志下载请求内容
|
||||
type ListLogRequest struct {
|
||||
Day string `json:"day"`
|
||||
Domains string `json:"domains"`
|
||||
}
|
||||
|
||||
// ListLogResult 日志下载相应内容
|
||||
type ListLogResult struct {
|
||||
Code int `json:"code"`
|
||||
Error string `json:"error"`
|
||||
Data map[string][]LogDomainInfo `json:"data"`
|
||||
}
|
||||
|
||||
// LogDomainInfo 日志下载信息
|
||||
type LogDomainInfo struct {
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
ModifiedTime int64 `json:"mtime"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// GetCdnLogList 获取CDN域名访问日志的下载链接
|
||||
// http://developer.qiniu.com/article/fusion/api/log.html
|
||||
func GetCdnLogList(date, domains string) (domainLogs []LogDomainInfo, err error) {
|
||||
|
||||
//new log query request
|
||||
logReq := ListLogRequest{
|
||||
Day: date,
|
||||
Domains: domains,
|
||||
}
|
||||
|
||||
logReqBytes, _ := json.Marshal(&logReq)
|
||||
req, reqErr := http.NewRequest("POST", LIST_LOG_API, bytes.NewReader(logReqBytes))
|
||||
if reqErr != nil {
|
||||
err = fmt.Errorf("New request error, %s", reqErr)
|
||||
return
|
||||
}
|
||||
|
||||
mac := qbox.NewMac("", "")
|
||||
token, signErr := mac.SignRequest(req, false)
|
||||
if signErr != nil {
|
||||
err = signErr
|
||||
return
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", "QBox "+token)
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
resp, respErr := http.DefaultClient.Do(req)
|
||||
if respErr != nil {
|
||||
err = fmt.Errorf("Get response error, %s", respErr)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
listLogResult := ListLogResult{}
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
if decodeErr := decoder.Decode(&listLogResult); decodeErr != nil {
|
||||
err = fmt.Errorf("Parse response error, %s", decodeErr)
|
||||
return
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
err = fmt.Errorf("Get log list error, %d %s", listLogResult.Code, listLogResult.Error)
|
||||
return
|
||||
}
|
||||
|
||||
domainItems := strings.Split(domains, ";")
|
||||
|
||||
for _, domain := range domainItems {
|
||||
for _, v := range listLogResult.Data[domain] {
|
||||
domainLogs = append(domainLogs, v)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
48
vendor/qiniupkg.com/api.v7/cdn/logs_test.go
generated
vendored
Normal file
48
vendor/qiniupkg.com/api.v7/cdn/logs_test.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
package cdn
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"qiniupkg.com/api.v7/kodo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
kodo.SetMac(ak, sk)
|
||||
}
|
||||
|
||||
func TestGetCdnLogList(t *testing.T) {
|
||||
type args struct {
|
||||
date string
|
||||
domains string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantDomainLogs []LogDomainInfo
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "getCdnLogListTest",
|
||||
args: args{
|
||||
date: testDate,
|
||||
domains: domain,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotDomainLogs, err := GetCdnLogList(tt.args.date, tt.args.domains)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetCdnLogList() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
fmt.Println(domain, gotDomainLogs)
|
||||
if !reflect.DeepEqual(gotDomainLogs, tt.wantDomainLogs) {
|
||||
t.Errorf("GetCdnLogList() = %v, want %v", gotDomainLogs, tt.wantDomainLogs)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
30
vendor/qiniupkg.com/api.v7/kodo/bucket.go
generated
vendored
30
vendor/qiniupkg.com/api.v7/kodo/bucket.go
generated
vendored
@@ -2,6 +2,7 @@ package kodo
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -60,6 +61,7 @@ type Entry struct {
|
||||
Fsize int64 `json:"fsize"`
|
||||
PutTime int64 `json:"putTime"`
|
||||
MimeType string `json:"mimeType"`
|
||||
Type int `json:"type"`
|
||||
EndUser string `json:"endUser"`
|
||||
}
|
||||
|
||||
@@ -123,6 +125,16 @@ func (p Bucket) ChangeMime(ctx Context, key, mime string) (err error) {
|
||||
return p.Conn.Call(ctx, nil, "POST", p.Conn.RSHost+URIChangeMime(p.Name, key, mime))
|
||||
}
|
||||
|
||||
// 修改文件的存储类型。
|
||||
//
|
||||
// ctx 是请求的上下文。
|
||||
// key 是要修改的文件的访问路径。
|
||||
// fileType 是要设置的新存储类型。
|
||||
//
|
||||
func (p Bucket) ChangeType(ctx Context, key string, fileType int) (err error) {
|
||||
return p.Conn.Call(ctx, nil, "POST", p.Conn.RSHost+URIChangeType(p.Name, key, fileType))
|
||||
}
|
||||
|
||||
// 从网上抓取一个资源并存储到七牛空间(bucket)中。
|
||||
//
|
||||
// ctx 是请求的上下文。
|
||||
@@ -133,6 +145,16 @@ func (p Bucket) Fetch(ctx Context, key string, url string) (err error) {
|
||||
return p.Conn.Call(ctx, nil, "POST", p.IoHost+uriFetch(p.Name, key, url))
|
||||
}
|
||||
|
||||
// 更新文件生命周期
|
||||
//
|
||||
// ctx 是请求的上下文。
|
||||
// key 是要更新的文件的访问路径。
|
||||
// deleteAfterDays 设置为0表示取消 lifecycle
|
||||
//
|
||||
func (p Bucket) DeleteAfterDays(ctx Context, key string, days int) (err error) {
|
||||
return p.Conn.Call(ctx, nil, "POST", p.Conn.RSHost+URIDeleteAfterDays(p.Name, key, days))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
type ListItem struct {
|
||||
@@ -275,4 +297,12 @@ func URIChangeMime(bucket, key, mime string) string {
|
||||
return "/chgm/" + encodeURI(bucket+":"+key) + "/mime/" + encodeURI(mime)
|
||||
}
|
||||
|
||||
func URIChangeType(bucket, key string, fileType int) string {
|
||||
return "/chtype/" + encodeURI(bucket+":"+key) + "/type/" + strconv.Itoa(fileType)
|
||||
}
|
||||
|
||||
func URIDeleteAfterDays(bucket, key string, days int) string {
|
||||
return fmt.Sprintf("/deleteAfterDays/%s/%d", encodeURI(bucket+":"+key), days)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
78
vendor/qiniupkg.com/api.v7/kodo/bucket_test.go
generated
vendored
78
vendor/qiniupkg.com/api.v7/kodo/bucket_test.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package kodo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
@@ -8,9 +9,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
bkey = "abatch"
|
||||
bnewkey1 = "abatch/newkey1"
|
||||
bnewkey2 = "abatch/newkey2"
|
||||
batchTestKey = "abatch"
|
||||
batchTestNewKey1 = "abatch/newkey1"
|
||||
batchTestNewKey2 = "abatch/newkey2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -20,11 +21,11 @@ func init() {
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
bkey += strconv.Itoa(rand.Int())
|
||||
bnewkey1 += strconv.Itoa(rand.Int())
|
||||
bnewkey2 += strconv.Itoa(rand.Int())
|
||||
batchTestKey += strconv.Itoa(rand.Int())
|
||||
batchTestNewKey1 += strconv.Itoa(rand.Int())
|
||||
batchTestNewKey2 += strconv.Itoa(rand.Int())
|
||||
// 删除 可能存在的 key
|
||||
bucket.BatchDelete(nil, bkey, bnewkey1, bnewkey2)
|
||||
bucket.BatchDelete(nil, batchTestKey, batchTestNewKey1, batchTestNewKey2)
|
||||
}
|
||||
|
||||
func TestAll(t *testing.T) {
|
||||
@@ -34,11 +35,11 @@ func TestAll(t *testing.T) {
|
||||
}
|
||||
|
||||
//上传一个文件用用于测试
|
||||
err := upFile("bucket_test.go", bkey)
|
||||
err := upFile("bucket_test.go", batchTestKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer bucket.Delete(nil, bkey)
|
||||
defer bucket.Delete(nil, batchTestKey)
|
||||
|
||||
testBatchStat(t)
|
||||
testBatchCopy(t)
|
||||
@@ -46,11 +47,12 @@ func TestAll(t *testing.T) {
|
||||
testBatchDelete(t)
|
||||
testBatch(t)
|
||||
testClient_MakeUptokenBucket(t)
|
||||
testDeleteAfterDays(t)
|
||||
}
|
||||
|
||||
func testBatchStat(t *testing.T) {
|
||||
|
||||
rets, err := bucket.BatchStat(nil, bkey, bkey, bkey)
|
||||
rets, err := bucket.BatchStat(nil, batchTestKey, batchTestKey, batchTestKey)
|
||||
if err != nil {
|
||||
t.Fatal("bucket.BatchStat failed:", err)
|
||||
}
|
||||
@@ -59,7 +61,7 @@ func testBatchStat(t *testing.T) {
|
||||
t.Fatal("BatchStat failed: len(rets) = ", 3)
|
||||
}
|
||||
|
||||
stat, err := bucket.Stat(nil, bkey)
|
||||
stat, err := bucket.Stat(nil, batchTestKey)
|
||||
if err != nil {
|
||||
t.Fatal("bucket.Stat failed:", err)
|
||||
}
|
||||
@@ -71,18 +73,18 @@ func testBatchStat(t *testing.T) {
|
||||
|
||||
func testBatchMove(t *testing.T) {
|
||||
|
||||
stat0, err := bucket.Stat(nil, bkey)
|
||||
stat0, err := bucket.Stat(nil, batchTestKey)
|
||||
if err != nil {
|
||||
t.Fatal("BathMove get stat failed:", err)
|
||||
}
|
||||
|
||||
_, err = bucket.BatchMove(nil, KeyPair{bkey, bnewkey1}, KeyPair{bnewkey1, bnewkey2})
|
||||
_, err = bucket.BatchMove(nil, KeyPair{batchTestKey, batchTestNewKey1}, KeyPair{batchTestNewKey1, batchTestNewKey2})
|
||||
if err != nil {
|
||||
t.Fatal("bucket.BatchMove failed:", err)
|
||||
}
|
||||
defer bucket.Move(nil, bnewkey2, bkey)
|
||||
defer bucket.Move(nil, batchTestNewKey2, batchTestKey)
|
||||
|
||||
stat1, err := bucket.Stat(nil, bnewkey2)
|
||||
stat1, err := bucket.Stat(nil, batchTestNewKey2)
|
||||
if err != nil {
|
||||
t.Fatal("BathMove get stat failed:", err)
|
||||
}
|
||||
@@ -94,16 +96,16 @@ func testBatchMove(t *testing.T) {
|
||||
|
||||
func testBatchCopy(t *testing.T) {
|
||||
|
||||
_, err := bucket.BatchCopy(nil, KeyPair{bkey, bnewkey1}, KeyPair{bkey, bnewkey2})
|
||||
_, err := bucket.BatchCopy(nil, KeyPair{batchTestKey, batchTestNewKey1}, KeyPair{batchTestKey, batchTestNewKey2})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer bucket.Delete(nil, bnewkey1)
|
||||
defer bucket.Delete(nil, bnewkey2)
|
||||
defer bucket.Delete(nil, batchTestNewKey1)
|
||||
defer bucket.Delete(nil, batchTestNewKey2)
|
||||
|
||||
stat0, _ := bucket.Stat(nil, bkey)
|
||||
stat1, _ := bucket.Stat(nil, bnewkey1)
|
||||
stat2, _ := bucket.Stat(nil, bnewkey2)
|
||||
stat0, _ := bucket.Stat(nil, batchTestKey)
|
||||
stat1, _ := bucket.Stat(nil, batchTestNewKey1)
|
||||
stat2, _ := bucket.Stat(nil, batchTestNewKey2)
|
||||
if stat0.Hash != stat1.Hash || stat0.Hash != stat2.Hash {
|
||||
t.Fatal("BatchCopy failed : Copy err")
|
||||
}
|
||||
@@ -111,16 +113,16 @@ func testBatchCopy(t *testing.T) {
|
||||
|
||||
func testBatchDelete(t *testing.T) {
|
||||
|
||||
bucket.Copy(nil, bkey, bnewkey1)
|
||||
bucket.Copy(nil, bkey, bnewkey2)
|
||||
bucket.Copy(nil, batchTestKey, batchTestNewKey1)
|
||||
bucket.Copy(nil, batchTestKey, batchTestNewKey2)
|
||||
|
||||
_, err := bucket.BatchDelete(nil, bnewkey1, bnewkey2)
|
||||
_, err := bucket.BatchDelete(nil, batchTestNewKey1, batchTestNewKey2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err1 := bucket.Stat(nil, bnewkey1)
|
||||
_, err2 := bucket.Stat(nil, bnewkey2)
|
||||
_, err1 := bucket.Stat(nil, batchTestNewKey1)
|
||||
_, err2 := bucket.Stat(nil, batchTestNewKey2)
|
||||
|
||||
//这里 err1 != nil,否则文件没被成功删除
|
||||
if err1 == nil || err2 == nil {
|
||||
@@ -131,9 +133,9 @@ func testBatchDelete(t *testing.T) {
|
||||
func testBatch(t *testing.T) {
|
||||
|
||||
ops := []string{
|
||||
URICopy(bucketName, bkey, bucketName, bnewkey1),
|
||||
URIDelete(bucketName, bkey),
|
||||
URIMove(bucketName, bnewkey1, bucketName, bkey),
|
||||
URICopy(bucketName, batchTestKey, bucketName, batchTestNewKey1),
|
||||
URIDelete(bucketName, batchTestKey),
|
||||
URIMove(bucketName, batchTestNewKey1, bucketName, batchTestKey),
|
||||
}
|
||||
|
||||
var rets []BatchItemRet
|
||||
@@ -145,3 +147,21 @@ func testBatch(t *testing.T) {
|
||||
t.Fatal("len(rets) != 3")
|
||||
}
|
||||
}
|
||||
|
||||
func testDeleteAfterDays(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
err := bucket.DeleteAfterDays(ctx, batchTestNewKey1, 5)
|
||||
if err == nil {
|
||||
t.Fatal("Expect an error")
|
||||
}
|
||||
|
||||
bucket.Copy(ctx, batchTestKey, batchTestNewKey1)
|
||||
|
||||
err = bucket.DeleteAfterDays(ctx, batchTestNewKey1, 5)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1
vendor/qiniupkg.com/api.v7/kodo/token.go
generated
vendored
1
vendor/qiniupkg.com/api.v7/kodo/token.go
generated
vendored
@@ -75,6 +75,7 @@ type PutPolicy struct {
|
||||
Checksum string `json:"checksum,omitempty"` // 格式:<HashName>:<HexHashValue>,目前支持 MD5/SHA1。
|
||||
UpHosts []string `json:"uphosts,omitempty"`
|
||||
DeleteAfterDays int `json:"deleteAfterDays,omitempty"`
|
||||
FileType int `json:"fileType,omitempty"`
|
||||
}
|
||||
|
||||
func (p *Client) MakeUptoken(policy *PutPolicy) string {
|
||||
|
||||
5
vendor/qiniupkg.com/api.v7/kodocli/upload.go
generated
vendored
5
vendor/qiniupkg.com/api.v7/kodocli/upload.go
generated
vendored
@@ -178,7 +178,10 @@ func (p Uploader) put(
|
||||
lastLine := fmt.Sprintf("\r\n--%s--\r\n", writer.Boundary())
|
||||
r := strings.NewReader(lastLine)
|
||||
|
||||
bodyLen := int64(b.Len()) + size + int64(len(lastLine))
|
||||
bodyLen := int64(-1)
|
||||
if size >= 0 {
|
||||
bodyLen = int64(b.Len()) + size + int64(len(lastLine))
|
||||
}
|
||||
mr := io.MultiReader(&b, data, r)
|
||||
|
||||
contentType := writer.FormDataContentType()
|
||||
|
||||
Reference in New Issue
Block a user