Skip to content

Commit

Permalink
update 3.24.9
Browse files Browse the repository at this point in the history
  • Loading branch information
noaccident committed Oct 9, 2024
1 parent 5105f9c commit 2092dc5
Show file tree
Hide file tree
Showing 16 changed files with 232 additions and 42 deletions.
12 changes: 12 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
Version 3.24.9

New Features:
1. Added list POSIX Object API.

Documentation & Demo:

Resolved Issues:
1. Optimize error log printing.

-----------------------------------------------------------------------------------

Version 3.24.6

New Features:
Expand Down
13 changes: 13 additions & 0 deletions README_CN.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
Version 3.24.9

新特性:
1. 新增listPosixObject接口。

资料 & demo:

修复问题:

1. 优化错误日志打印。

-----------------------------------------------------------------------------------

Version 3.24.6

新特性:
Expand Down
26 changes: 26 additions & 0 deletions obs/client_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,32 @@ func (obsClient ObsClient) ListObjects(input *ListObjectsInput, extensions ...ex
return
}

// ListPosixObjects lists objects in a posix.
//
// You can use this API to list objects in a posix. By default, a maximum of 1000 objects are listed.
func (obsClient ObsClient) ListPosixObjects(input *ListPosixObjectsInput, extensions ...extensionOptions) (output *ListPosixObjectsOutput, err error) {
if input == nil {
return nil, errors.New("ListPosixObjects is nil")
}
output = &ListPosixObjectsOutput{}
err = obsClient.doActionWithBucket("ListPosixObjects", HTTP_GET, input.Bucket, input, output, extensions)
if err != nil {
output = nil
} else {
if location, ok := output.ResponseHeaders[HEADER_BUCKET_REGION]; ok {
output.Location = location[0]
}
if output.EncodingType == "url" {
err = decodeListPosixObjectsOutput(output)
if err != nil {
doLog(LEVEL_ERROR, "Failed to get ListPosixObjectsOutput with error: %v.", err)
output = nil
}
}
}
return
}

// ListVersions lists versioning objects in a bucket.
//
// You can use this API to list versioning objects in a bucket. By default, a maximum of 1000 versioning objects are listed.
Expand Down
1 change: 1 addition & 0 deletions obs/client_part.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func (obsClient ObsClient) UploadPart(_input *UploadPartInput, extensions ...ext
input.PartNumber = _input.PartNumber
input.UploadId = _input.UploadId
input.ContentMD5 = _input.ContentMD5
input.ContentSHA256 = _input.ContentSHA256
input.SourceFile = _input.SourceFile
input.Offset = _input.Offset
input.PartSize = _input.PartSize
Expand Down
26 changes: 20 additions & 6 deletions obs/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const (
HEADER_GRANT_FULL_CONTROL_DELIVERED_OBS = "grant-full-control-delivered"
HEADER_REQUEST_ID = "request-id"
HEADER_ERROR_CODE = "error-code"
HEADER_ERROR_INDICATOR = "x-reserved-indicator"
HEADER_ERROR_MESSAGE = "error-message"
HEADER_BUCKET_REGION = "bucket-region"
HEADER_ACCESS_CONRTOL_ALLOW_ORIGIN = "access-control-allow-origin"
Expand Down Expand Up @@ -121,6 +122,8 @@ const (
HEADER_HOST = "host"
HEADER_AUTH_CAMEL = "Authorization"
HEADER_MD5_CAMEL = "Content-MD5"
HEADER_SHA256_CAMEL = "Content-SHA256"
HEADER_SHA256 = "content-sha256"
HEADER_LOCATION_CAMEL = "Location"
HEADER_CONTENT_LENGTH_CAMEL = "Content-Length"
HEADER_CONTENT_TYPE_CAML = "Content-Type"
Expand Down Expand Up @@ -210,6 +213,7 @@ var (
allowedRequestHTTPHeaderMetadataNames = map[string]bool{
"content-type": true,
"content-md5": true,
"content-sha256": true,
"content-length": true,
"content-language": true,
"expires": true,
Expand All @@ -235,12 +239,13 @@ var (
}

allowedLogResponseHTTPHeaderNames = map[string]bool{
"content-type": true,
"etag": true,
"connection": true,
"content-length": true,
"date": true,
"server": true,
"content-type": true,
"etag": true,
"connection": true,
"content-length": true,
"date": true,
"server": true,
"x-reserved-indicator": true,
}

allowedResourceParameterNames = map[string]bool{
Expand Down Expand Up @@ -291,6 +296,15 @@ var (
"customdomain": true,
"mirrorbacktosource": true,
"x-obs-accesslabel": true,
"object-lock": true,
"retention": true,
"x-obs-security-token": true,
"truncate": true,
"length": true,
"inventory": true,
"directcoldaccess": true,
"attname": true,
"cdnnotifyconfiguration": true,
}

obsStorageClasses = []string{
Expand Down
68 changes: 58 additions & 10 deletions obs/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,16 @@ import (
"time"
)

func cleanHeaderPrefix(header http.Header) map[string][]string {
func cleanHeaderPrefix(header http.Header, isObs bool) map[string][]string {
responseHeaders := make(map[string][]string)
for key, value := range header {
if len(value) > 0 {
key = strings.ToLower(key)

if !isObs && strings.HasSuffix(key, HEADER_EXPIRES_OBS) {
responseHeaders[key] = value
continue
}
if strings.HasPrefix(key, HEADER_PREFIX) || strings.HasPrefix(key, HEADER_PREFIX_OBS) {
key = key[len(HEADER_PREFIX):]
}
Expand Down Expand Up @@ -425,7 +430,7 @@ func convertAbortIncompleteMultipartUploadToXML(abortIncompleteMultipartUpload A
}

// ConvertLifecycleConfigurationToXml converts BucketLifecycleConfiguration value to XML data and returns it
func ConvertLifecycleConfigurationToXml(input BucketLifecycleConfiguration, returnMd5 bool, isObs bool) (data string, md5 string) {
func ConvertLifecycleConfigurationToXml(input BucketLifecycleConfiguration, returnMd5, isObs, enableSha256 bool) (data string, md5OrSha256 string) {
xml := make([]string, 0, 2+len(input.LifecycleRules)*9)
xml = append(xml, "<LifecycleConfiguration>")
for _, lifecycleRule := range input.LifecycleRules {
Expand Down Expand Up @@ -463,7 +468,7 @@ func ConvertLifecycleConfigurationToXml(input BucketLifecycleConfiguration, retu
xml = append(xml, "</LifecycleConfiguration>")
data = strings.Join(xml, "")
if returnMd5 {
md5 = Base64Md5([]byte(data))
md5OrSha256 = Base64Md5OrSha256([]byte(data), enableSha256)
}
return
}
Expand Down Expand Up @@ -921,10 +926,11 @@ func ParseGetObjectOutput(output *GetObjectOutput) {
}

// ConvertRequestToIoReaderV2 converts req to XML data
func ConvertRequestToIoReaderV2(req interface{}) (io.Reader, string, error) {
func ConvertRequestToIoReaderV2(req interface{}, enableSha256 bool) (io.Reader, string, error) {
data, err := TransToXml(req)
md5OrSha256 := Base64Md5OrSha256(data, enableSha256)
if err == nil {
return bytes.NewReader(data), Base64Md5(data), nil
return bytes.NewReader(data), md5OrSha256, nil
}
return nil, "", err
}
Expand All @@ -950,7 +956,7 @@ func parseResponseBodyOutput(s reflect.Type, baseModel IBaseModel, body []byte)
// ParseCallbackResponseToBaseModel gets response from Callback Service
func ParseCallbackResponseToBaseModel(resp *http.Response, baseModel IBaseModel, isObs bool) error {
baseModel.setStatusCode(resp.StatusCode)
responseHeaders := cleanHeaderPrefix(resp.Header)
responseHeaders := cleanHeaderPrefix(resp.Header, isObs)
baseModel.setResponseHeaders(responseHeaders)
if values, ok := responseHeaders[HEADER_REQUEST_ID]; ok {
baseModel.setRequestID(values[0])
Expand All @@ -976,27 +982,34 @@ func ParseResponseToBaseModel(resp *http.Response, baseModel IBaseModel, xmlResu
var body []byte
body, err = ioutil.ReadAll(resp.Body)
if err == nil && len(body) > 0 {

name := reflect.TypeOf(baseModel).Elem().Name()
if xmlResult {
err = ParseXml(body, baseModel)
} else {
s := reflect.TypeOf(baseModel).Elem()
name := reflect.TypeOf(baseModel).Elem().Name()
if name == "GetBucketPolicyOutput" || name == "GetBucketMirrorBackToSourceOuput" {
parseResponseBodyOutput(s, baseModel, body)
} else {
err = parseJSON(body, baseModel)
}
}
if err != nil {
doLog(LEVEL_ERROR, "Unmarshal error: %v", err)
doLog(LEVEL_ERROR, "body: %s", body)
if _, ok := baseModel.(*ObsError); !ok && name == "CopyObjectOutput" {
doLog(LEVEL_ERROR, "Unmarshal error: %v, try parse response to ObsError", err)
err = ParseResponseToObsError(resp, isObs)
} else {
doLog(LEVEL_ERROR, "Unmarshal error: %v", err)
}
}
}
} else {
readCloser.setReadCloser(resp.Body)
}

baseModel.setStatusCode(resp.StatusCode)
responseHeaders := cleanHeaderPrefix(resp.Header)
responseHeaders := cleanHeaderPrefix(resp.Header, isObs)
baseModel.setResponseHeaders(responseHeaders)
if values, ok := responseHeaders[HEADER_REQUEST_ID]; ok {
baseModel.setRequestID(values[0])
Expand All @@ -1017,13 +1030,16 @@ func ParseResponseToObsError(resp *http.Response, isObs bool) error {
doLog(LEVEL_WARN, "Parse response to BaseModel with error: %v", respError)
}
obsError.Status = resp.Status
responseHeaders := cleanHeaderPrefix(resp.Header)
responseHeaders := cleanHeaderPrefix(resp.Header, isObs)
if values, ok := responseHeaders[HEADER_ERROR_MESSAGE]; ok {
obsError.Message = values[0]
}
if values, ok := responseHeaders[HEADER_ERROR_CODE]; ok {
obsError.Code = values[0]
}
if values, ok := responseHeaders[HEADER_ERROR_INDICATOR]; ok {
obsError.Indicator = values[0]
}
return obsError
}

Expand Down Expand Up @@ -1115,6 +1131,38 @@ func decodeListObjectsOutput(output *ListObjectsOutput) (err error) {
return
}

func decodeListPosixObjectsOutput(output *ListPosixObjectsOutput) (err error) {
output.Delimiter, err = url.QueryUnescape(output.Delimiter)
if err != nil {
return
}
output.Marker, err = url.QueryUnescape(output.Marker)
if err != nil {
return
}
output.NextMarker, err = url.QueryUnescape(output.NextMarker)
if err != nil {
return
}
output.Prefix, err = url.QueryUnescape(output.Prefix)
if err != nil {
return
}
for index, value := range output.CommonPrefixes {
output.CommonPrefixes[index].Prefix, err = url.QueryUnescape(value.Prefix)
if err != nil {
return
}
}
for index, content := range output.Contents {
output.Contents[index].Key, err = url.QueryUnescape(content.Key)
if err != nil {
return
}
}
return
}

func decodeListVersionsOutput(output *ListVersionsOutput) (err error) {
output.Delimiter, err = url.QueryUnescape(output.Delimiter)
if err != nil {
Expand Down
17 changes: 9 additions & 8 deletions obs/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ import (
// ObsError defines error response from OBS
type ObsError struct {
BaseModel
Status string
XMLName xml.Name `xml:"Error"`
Code string `xml:"Code" json:"code"`
Message string `xml:"Message" json:"message"`
Resource string `xml:"Resource"`
HostId string `xml:"HostId"`
Status string
XMLName xml.Name `xml:"Error"`
Code string `xml:"Code" json:"code"`
Message string `xml:"Message" json:"message"`
Resource string `xml:"Resource"`
HostId string `xml:"HostId"`
Indicator string
}

// Format print obs error's log
func (err ObsError) Error() string {
return fmt.Sprintf("obs: service returned error: Status=%s, Code=%s, Message=%s, RequestId=%s",
err.Status, err.Code, err.Message, err.RequestId)
return fmt.Sprintf("obs: service returned error: Status=%s, Code=%s, Message=%s, RequestId=%s, Indicator=%s.",
err.Status, err.Code, err.Message, err.RequestId, err.Indicator)
}
1 change: 0 additions & 1 deletion obs/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ func WithCustomHeader(key string, value string) extensionHeaders {
if strings.TrimSpace(value) == "" {
return fmt.Errorf("set header %s with empty value", key)
}
allowedRequestHTTPHeaderMetadataNames[strings.ToLower(key)] = true
headers[key] = []string{value}
return nil
}
Expand Down
3 changes: 3 additions & 0 deletions obs/model_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ type GetBucketPolicyOutput struct {
type SetBucketCorsInput struct {
Bucket string `xml:"-"`
BucketCors
EnableSha256 bool `xml:"-"`
}

// GetBucketCorsOutput is the result of GetBucketCors function
Expand Down Expand Up @@ -261,6 +262,7 @@ type BucketLifecycleConfiguration struct {
type SetBucketLifecycleConfigurationInput struct {
Bucket string `xml:"-"`
BucketLifecycleConfiguration
EnableSha256 bool `xml:"-"`
}

// GetBucketLifecycleConfigurationOutput is the result of GetBucketLifecycleConfiguration function
Expand All @@ -285,6 +287,7 @@ type GetBucketEncryptionOutput struct {
type SetBucketTaggingInput struct {
Bucket string `xml:"-"`
BucketTagging
EnableSha256 bool `xml:"-"`
}

// GetBucketTaggingOutput is the result of GetBucketTagging function
Expand Down
19 changes: 19 additions & 0 deletions obs/model_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ type ListObjectsInput struct {
Marker string
}

type ListPosixObjectsInput struct {
ListObjectsInput
}

// ListObjectsOutput is the result of ListObjects function
type ListObjectsOutput struct {
BaseModel
Expand All @@ -52,6 +56,20 @@ type ListObjectsOutput struct {
EncodingType string `xml:"EncodingType,omitempty"`
}

type ListPosixObjectsOutput struct {
ListObjectsOutput
CommonPrefixes []CommonPrefix `xml:"CommonPrefixes"`
}

type CommonPrefix struct {
XMLName xml.Name `xml:"CommonPrefixes"`
Prefix string `xml:"Prefix"`
MTime string `xml:"MTime"`
Mode string `xml:"Mode"`
InodeNo string `xml:"InodeNo"`
LastModified time.Time `xml:"LastModified"`
}

// ListVersionsInput is the input parameter of ListVersions function
type ListVersionsInput struct {
ListObjsInput
Expand Down Expand Up @@ -236,6 +254,7 @@ type PutObjectBasicInput struct {
ObjectOperationInput
HttpHeader
ContentMD5 string
ContentSHA256 string
ContentLength int64
}

Expand Down
Loading

0 comments on commit 2092dc5

Please sign in to comment.