1.4.5.2
This commit is contained in:
163
EdgeNode/internal/oss/provider_aliyun_oss.go
Normal file
163
EdgeNode/internal/oss/provider_aliyun_oss.go
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build plus
|
||||
|
||||
package oss
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ossconfigs"
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type AliyunOSSProvider struct {
|
||||
bucket *oss.Bucket
|
||||
}
|
||||
|
||||
func NewAliyunOSSProvider() *AliyunOSSProvider {
|
||||
return &AliyunOSSProvider{}
|
||||
}
|
||||
|
||||
func (this *AliyunOSSProvider) Init(options ossconfigs.OSSOptions, bucketName string) error {
|
||||
realOptions, ok := options.(*ossconfigs.AliyunOSSProviderOptions)
|
||||
if !ok {
|
||||
return errors.New("invalid options for 'AliyunOSSProvider'")
|
||||
}
|
||||
|
||||
client, err := oss.New(realOptions.Endpoint, realOptions.AccessKeyId, realOptions.AccessKeySecret)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bucket, err := client.Bucket(bucketName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
this.bucket = bucket
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *AliyunOSSProvider) Head(key string) (httpResponse *http.Response, nativeErrCode string, err error) {
|
||||
header, respErr := this.bucket.GetObjectMeta(key)
|
||||
if err != nil {
|
||||
nativeErrCode, err = this.parseErr(respErr)
|
||||
return
|
||||
}
|
||||
|
||||
// not found
|
||||
if len(header) == 0 {
|
||||
header = http.Header{"Content-Length": []string{"0"}}
|
||||
|
||||
httpResponse = &http.Response{
|
||||
StatusCode: http.StatusNotFound,
|
||||
Header: header,
|
||||
Body: io.NopCloser(bytes.NewReader(nil)),
|
||||
ContentLength: 0,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
httpResponse = &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Header: header,
|
||||
Body: io.NopCloser(bytes.NewReader(nil)),
|
||||
ContentLength: types.Int64(header.Get("Content-Length")),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *AliyunOSSProvider) Get(key string) (httpResponse *http.Response, nativeErrCode string, err error) {
|
||||
body, respErr := this.bucket.GetObject(key)
|
||||
if respErr != nil {
|
||||
nativeErrCode, err = this.parseErr(respErr)
|
||||
return
|
||||
}
|
||||
|
||||
resp, ok := body.(*oss.Response)
|
||||
if ok {
|
||||
httpResponse = &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Header: resp.Headers,
|
||||
Body: resp.Body,
|
||||
ContentLength: types.Int64(resp.Headers.Get("Content-Length")),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
httpResponse = &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: body,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *AliyunOSSProvider) GetRange(key string, bytesRange string) (httpResponse *http.Response, nativeErrCode string, err error) {
|
||||
rangeResult, parseOk := httpRequestParseRangeHeader(bytesRange)
|
||||
if !parseOk || len(rangeResult) == 0 {
|
||||
return this.Get(key)
|
||||
}
|
||||
|
||||
var firstRange = rangeResult[0]
|
||||
var start = firstRange.Start()
|
||||
var end = firstRange.End()
|
||||
if start < 0 || end < 0 || start > end {
|
||||
return this.Get(key)
|
||||
}
|
||||
|
||||
body, respErr := this.bucket.GetObject(key, oss.Range(start, end))
|
||||
if respErr != nil {
|
||||
nativeErrCode, err = this.parseErr(respErr)
|
||||
return
|
||||
}
|
||||
|
||||
resp, ok := body.(*oss.Response)
|
||||
if ok {
|
||||
httpResponse = &http.Response{
|
||||
StatusCode: resp.StatusCode,
|
||||
Header: resp.Headers,
|
||||
Body: resp.Body,
|
||||
ContentLength: types.Int64(resp.Headers.Get("Content-Length")),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
httpResponse = &http.Response{
|
||||
StatusCode: http.StatusPartialContent,
|
||||
Body: body,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *AliyunOSSProvider) parseErr(err error) (errCode string, resultErr error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resultErr = err
|
||||
|
||||
serviceErr, ok := err.(oss.ServiceError)
|
||||
if ok {
|
||||
errCode = serviceErr.Code
|
||||
|
||||
// 特殊错误
|
||||
if errCode == "NoSuchBucket" {
|
||||
resultErr = errNoBucket
|
||||
return
|
||||
}
|
||||
|
||||
if errCode == "NoSuchKey" {
|
||||
resultErr = errNotFound
|
||||
}
|
||||
|
||||
if errCode == "RequestTimeout" {
|
||||
resultErr = errRequestTimeout
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user