mirror of
https://github.com/eiblog/eiblog.git
synced 2026-02-09 16:12:26 +08:00
302 lines
7.8 KiB
Go
302 lines
7.8 KiB
Go
package cdn
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"io/ioutil"
|
||
"net/http"
|
||
"strings"
|
||
|
||
"github.com/qiniu/api.v7/auth/qbox"
|
||
)
|
||
|
||
// Fusion CDN服务域名
|
||
var (
|
||
FusionHost = "http://fusion.qiniuapi.com"
|
||
)
|
||
|
||
// CdnManager 提供了文件和目录刷新,文件预取,获取域名带宽和流量数据,获取域名日志列表等功能
|
||
type CdnManager struct {
|
||
mac *qbox.Mac
|
||
}
|
||
|
||
// NewCdnManager 用来构建一个新的 CdnManager
|
||
func NewCdnManager(mac *qbox.Mac) *CdnManager {
|
||
return &CdnManager{mac: mac}
|
||
}
|
||
|
||
// TrafficReq 为批量查询带宽/流量的API请求内容
|
||
// StartDate 开始日期,格式例如:2016-07-01
|
||
// EndDate 结束日期,格式例如:2016-07-03
|
||
// Granularity 取值粒度,取值可选值:5min/hour/day
|
||
// Domains 域名列表,彼此用 ; 连接
|
||
type TrafficReq 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]TrafficData `json:"data,omitempty"`
|
||
}
|
||
|
||
// TrafficData 为带宽/流量数据
|
||
type TrafficData struct {
|
||
DomainChina []int `json:"china"`
|
||
DomainOversea []int `json:"oversea"`
|
||
}
|
||
|
||
// GetBandwidthData 方法用来获取域名访问带宽数据
|
||
// StartDate string 必须 开始日期,例如:2016-07-01
|
||
// EndDate string 必须 结束日期,例如:2016-07-03
|
||
// Granularity string 必须 粒度,取值:5min / hour /day
|
||
// Domains []string 必须 域名列表
|
||
func (m *CdnManager) GetBandwidthData(startDate, endDate, granularity string,
|
||
domainList []string) (bandwidthData TrafficResp, err error) {
|
||
domains := strings.Join(domainList, ";")
|
||
reqBody := TrafficReq{
|
||
StartDate: startDate,
|
||
EndDate: endDate,
|
||
Granularity: granularity,
|
||
Domains: domains,
|
||
}
|
||
|
||
resData, reqErr := postRequest(m.mac, "/v2/tune/bandwidth", reqBody)
|
||
if reqErr != nil {
|
||
err = reqErr
|
||
return
|
||
}
|
||
umErr := json.Unmarshal(resData, &bandwidthData)
|
||
if umErr != nil {
|
||
err = umErr
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
// GetFluxData 方法用来获取域名访问流量数据
|
||
// StartDate string 必须 开始日期,例如:2016-07-01
|
||
// EndDate string 必须 结束日期,例如:2016-07-03
|
||
// Granularity string 必须 粒度,取值:5min / hour /day
|
||
// Domains []string 必须 域名列表
|
||
func (m *CdnManager) GetFluxData(startDate, endDate, granularity string,
|
||
domainList []string) (fluxData TrafficResp, err error) {
|
||
domains := strings.Join(domainList, ";")
|
||
reqBody := TrafficReq{
|
||
StartDate: startDate,
|
||
EndDate: endDate,
|
||
Granularity: granularity,
|
||
Domains: domains,
|
||
}
|
||
|
||
resData, reqErr := postRequest(m.mac, "/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 方法用来刷新文件或目录
|
||
// urls 要刷新的单个url列表,单次方法调用总数不超过100条;单个url,即一个具体的url,
|
||
// 例如:http://bar.foo.com/index.html
|
||
// dirs 要刷新的目录url列表,单次方法调用总数不超过10条;目录dir,即表示一个目录级的url,
|
||
// 例如:http://bar.foo.com/dir/,
|
||
func (m *CdnManager) RefreshUrlsAndDirs(urls, dirs []string) (result RefreshResp, err error) {
|
||
if len(urls) > 100 {
|
||
err = errors.New("urls count exceeds the limit of 100")
|
||
return
|
||
}
|
||
if len(dirs) > 10 {
|
||
err = errors.New("dirs count exceeds the limit of 10")
|
||
return
|
||
}
|
||
|
||
reqBody := RefreshReq{
|
||
Urls: urls,
|
||
Dirs: dirs,
|
||
}
|
||
|
||
resData, reqErr := postRequest(m.mac, "/v2/tune/refresh", reqBody)
|
||
if reqErr != nil {
|
||
err = reqErr
|
||
return
|
||
}
|
||
umErr := json.Unmarshal(resData, &result)
|
||
if umErr != nil {
|
||
err = reqErr
|
||
return
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// RefreshUrls 刷新文件
|
||
func (m *CdnManager) RefreshUrls(urls []string) (result RefreshResp, err error) {
|
||
return m.RefreshUrlsAndDirs(urls, nil)
|
||
}
|
||
|
||
// RefreshDirs 刷新目录
|
||
func (m *CdnManager) RefreshDirs(dirs []string) (result RefreshResp, err error) {
|
||
return m.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条
|
||
func (m *CdnManager) PrefetchUrls(urls []string) (result PrefetchResp, err error) {
|
||
if len(urls) > 100 {
|
||
err = errors.New("urls count exceeds the limit of 100")
|
||
return
|
||
}
|
||
|
||
reqBody := PrefetchReq{
|
||
Urls: urls,
|
||
}
|
||
|
||
resData, reqErr := postRequest(m.mac, "/v2/tune/prefetch", reqBody)
|
||
if reqErr != nil {
|
||
err = reqErr
|
||
return
|
||
}
|
||
|
||
umErr := json.Unmarshal(resData, &result)
|
||
if umErr != nil {
|
||
err = umErr
|
||
return
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// 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域名访问日志的下载链接
|
||
func (m *CdnManager) GetCdnLogList(day string, domains []string) (
|
||
listLogResult ListLogResult, err error) {
|
||
//new log query request
|
||
logReq := ListLogRequest{
|
||
Day: day,
|
||
Domains: strings.Join(domains, ";"),
|
||
}
|
||
|
||
resData, reqErr := postRequest(m.mac, "/v2/tune/log/list", logReq)
|
||
if reqErr != nil {
|
||
err = fmt.Errorf("get response error, %s", reqErr)
|
||
return
|
||
}
|
||
|
||
if decodeErr := json.Unmarshal(resData, &listLogResult); decodeErr != nil {
|
||
err = fmt.Errorf("get response error, %s", decodeErr)
|
||
return
|
||
}
|
||
|
||
if listLogResult.Error != "" {
|
||
err = fmt.Errorf("get log list error, %d %s", listLogResult.Code, listLogResult.Error)
|
||
return
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// RequestWithBody 带body对api发出请求并且返回response body
|
||
func postRequest(mac *qbox.Mac, path string, body interface{}) (resData []byte,
|
||
err error) {
|
||
urlStr := fmt.Sprintf("%s%s", FusionHost, path)
|
||
reqData, _ := json.Marshal(body)
|
||
req, reqErr := http.NewRequest("POST", urlStr, bytes.NewReader(reqData))
|
||
if reqErr != nil {
|
||
err = reqErr
|
||
return
|
||
}
|
||
|
||
accessToken, signErr := mac.SignRequest(req)
|
||
if signErr != nil {
|
||
err = signErr
|
||
return
|
||
}
|
||
|
||
req.Header.Add("Authorization", "QBox "+accessToken)
|
||
req.Header.Add("Content-Type", "application/json")
|
||
|
||
resp, respErr := http.DefaultClient.Do(req)
|
||
if respErr != nil {
|
||
err = respErr
|
||
return
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
resData, ioErr := ioutil.ReadAll(resp.Body)
|
||
if ioErr != nil {
|
||
err = ioErr
|
||
return
|
||
}
|
||
|
||
return
|
||
}
|